Commit Graph

128 Commits

Author SHA1 Message Date
Jeff Emmett 131f64abe3 Replace 🌌 emoji favicon with [rS] logo on all pages
Use the actual favicon.png ([rS] brand mark) instead of the galaxy emoji
across index, create-space, and admin pages to match canvas.html.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:39:56 -08:00
Jeff Emmett bcef750249 feat: change 2-finger gestures from zoom to pan on canvas
Two-finger touch and trackpad scroll now pan instead of zoom.
Zoom is still available via Ctrl+wheel or trackpad pinch (ctrlKey).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:52:15 -08:00
Jeff Emmett 900eac2e21 feat: notes module reads from Automerge docs via WebSocket sync (Tier 1)
Notebook detail view now subscribes to Automerge docs instead of REST,
enabling real-time sync across tabs. Note creation and editing use
Automerge.change() with debounced sync. REST fallback after 5s timeout.
Notebook list and search remain REST-based.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 08:32:37 +00:00
Jeff Emmett 5b3c41c559 Add internal provision endpoint for rSpace Registry
Auth-free POST /api/internal/provision creates community via Hono route,
triggers onSpaceCreate for all registered modules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:30:22 -08:00
Jeff Emmett 07a7a083f4 feat: standardize AppSwitcher and EcosystemFooter across all rApps
- Update AppSwitcher with all 26 r*Apps in 8 categories
- Add EcosystemFooter component with consistent ecosystem links
- Categories: Creating, Planning, Communicating, Deciding,
  Funding & Commerce, Social & Media, Work & Productivity,
  Identity & Infrastructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:47:54 -08:00
Jeff Emmett be1067bed9 refactor: migrate EncryptID URLs from encryptid.jeffemmett.com to auth.ridentity.online
Part of the ridentity.online branding migration. The EncryptID auth
server is now accessible at auth.ridentity.online (with the legacy
encryptid.jeffemmett.com kept as a backward-compatible alias).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:22:15 -08:00
Jeff Emmett f8f7889bd7 feat: run PG→Automerge migration — 19 docs, 292 rows, 0 errors
Added run-migration.ts script and getDocIds() method on SyncServer.
All 11 module adapters ran successfully against live demo data.
Docs persisted to /data/docs/, backups to /data/docs-backup/.
Idempotent: re-runs skip existing docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 06:10:51 +00:00
Jeff Emmett ca3e8f42ab feat: add auth.ridentity.online as EncryptID route alias
Add ridentity.online and auth.ridentity.online to Traefik router rules,
WebAuthn Related Origins, and CORS allowed origins. This enables the
ridentity.online domain to serve as the branded identity layer while
keeping the RP ID on rspace.online (no passkey breakage).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:47:47 -08:00
Jeff Emmett 3d5a142062 feat: wire DocSyncManager into rSpace WebSocket server
Protocol multiplexing on existing /ws/{slug} endpoint:
- Messages with docId (subscribe/unsubscribe/sync/awareness) → SyncServer
- Messages without docId → legacy canvas handlers (unchanged)

New files: doc-persistence.ts (debounced Automerge save/load),
sync-instance.ts (SyncServer singleton with participant mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 05:19:21 +00:00
Jeff Emmett 1cb361637d fix: switch all module shell themes from light to dark
The light theme was causing the header bar to render with a white
background, clashing with the dark-themed module content underneath.
All modules and both shell renderers now default to dark theme.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:42:33 -08:00
Jeff Emmett 073a444c04 feat: rebrand AppSwitcher with pastel badges, rStack header, updated categories
- Pastel rainbow badges (rS, rN, rP, rC, rT...) replace plain emoji icons
- Emoji moved to right of app name in dropdown items
- rStack header with gradient badge at top of dropdown
- rStack footer link at bottom
- Canvas renamed to rSpace
- rMaps moved to Planning category
- "Sharing & Media" renamed to "Social & Sharing" with rNetwork at top
- Trigger button shows pastel badge + app name

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 19:36:58 -08:00
Jeff Emmett 2468177c26 feat: add folk-canvas shape, WS cascade enforcement, and at-rest encryption
Phase 3: folk-canvas nested space renderer with live WS connection,
auto-scaling viewport, collapsed/expanded views, permission badges.

Phase 4: WS cascade permission enforcement — nest filter on broadcasts,
addShapes/deleteShapes checks, readOnly enforcement for nested connections.

Phase 5: AES-256-GCM at-rest encryption for Automerge documents with
transparent encrypt-on-save/decrypt-on-load and API toggle endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:43:30 -08:00
Jeff Emmett 183089d6d8 feat: implement nested spaces architecture with permission cascade
Spaces are now nestable — any space can embed references to other spaces
via SpaceRef, with a permission cascade model (most-restrictive-wins at
each nesting boundary). Every EncryptID registration auto-provisions a
sovereign space at <username>.rspace.online with consent-based nesting
controls.

Key additions:
- NestPolicy per space (open/members/approval/closed consent levels)
- SpaceRef CRUD with allowlist/blocklist, permission ceiling enforcement
- Approval flow for nest requests with admin review
- Reverse lookup (nested-in) so owners see where their space appears
- Source space admins can always revoke (sovereignty guarantee)
- cascadePermissions() for multi-depth permission intersection
- Client-side types for nested space rendering
- Full spec at docs/SPACE-ARCHITECTURE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:27:10 -08:00
Jeff Emmett de0835c4d8 feat: rFunds landing page overhaul with EncryptID auth and space-scoped flows
Enhanced landing page with gradient hero, 5-card features grid, auth-aware
"Your Flows" section, and 3-step "How TBFF Works" walkthrough. Added
EncryptID token verification on flow creation, space_flows DB table for
per-space flow association, and space-scoped flow listing API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 02:19:23 +00:00
Jeff Emmett 470895c6a8 fix: serve /admin directly in fetch handler to bypass /:space catch-all
Hono's parameterized /:space route was capturing /admin before the
explicit route. Move admin.html serving into the Bun.serve fetch
handler so it runs before Hono routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:34:36 -08:00
Jeff Emmett 033f4a3d92 feat: add admin dashboard at /admin with space overview
Adds a new /admin page showing all spaces with stats (shape count,
member count, file size, visibility), search/filter/sort controls,
and links to open or export each space.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:29:15 -08:00
Jeff Emmett b2f1bebbd2 fix: resolve all TypeScript build errors across modules
- Change sql.unsafe() param arrays from unknown[] to any[] (9 modules)
- Exclude sw.ts and demo-sync.ts from tsconfig (separate build targets)
- Add type stub for @mkkellogg/gaussian-splats-3d (CDN-loaded)
- Rename private title → designTitle in folk-swag-designer (HTMLElement conflict)
- Fix Hono context typing and instanceof cast in splat module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:42:44 -08:00
Jeff Emmett 772726f420 feat: wire rspace to pull secrets from Infisical at startup
Add entrypoint.sh that authenticates with Infisical via universal-auth
and injects secrets as env vars before starting the Bun server.
Uses Bun's built-in fetch API instead of Node.js http module.

Secrets removed from docker-compose.yml (now fetched at runtime):
INTERNAL_API_KEY, HETZNER_API_TOKEN, CLOUDFLARE_API_TOKEN,
CLOUDFLARE_ZONE_ID, TWENTY_API_TOKEN, R2_*, X402_*, SMTP_PASS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:36:27 -08:00
Jeff Emmett 5b5c0be732 feat: restructure rFunds — landing page + multi-view TBFF flow
rfunds.online now shows a landing page with TBFF info and flow list
instead of the river demo. The river is one tab in a 3-tab flow detail
view (Table | River | Transactions).

- Add folk-funds-app.ts: main app component with landing + detail views
- Extract mapFlowToNodes to shared lib/map-flow.ts
- Simplify folk-budget-river.ts to pure renderer (no API fetching)
- Restructure routes: / = landing, /demo = demo detail, /flow/:id = flow
- Expand funds.css for landing, tabs, table cards, transaction list
- Add folk-funds-app.ts build entry to vite.config.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:18:01 -08:00
Jeff Emmett ae8d306a62 feat: scrollable categorized rApp dropdown, rSpaces rename, overlap prevention
- rApp dropdown now scrollable (max-height: 70vh) with apps grouped into
  5 categories: Creating, Planning, Discussing & Deciding, Funding &
  Commerce, Sharing & Media
- Renamed canvas object terminology from "shapes" to "rSpaces" in UI labels
- New shapes placed on canvas automatically find free positions using
  spiral search to avoid overlapping existing shapes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 16:20:41 -08:00
Jeff Emmett 05dfa6d3a0 Add migration dry-run script and standardize space slugs
dry-run.ts validates all 11 adapters against live DB (19 docs, 292 rows,
0 errors). Standardized rwork slug rspace-dev→demo and rvote slug
community→demo so all seeded data uses consistent space identifier.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 01:46:28 +00:00
Jeff Emmett 3a0d376f23 Add 7-layer local-first data infrastructure
Crypto (PRF/HKDF/AES-256-GCM per-doc keys), Document (schema + manager),
Storage (encrypted IndexedDB), Sync (multi-doc WebSocket client + server),
Compute (local/server-delegated transforms), Query (views + search),
and Memory Card interchange format. 2919 lines across 10 files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 01:12:06 +00:00
Jeff Emmett b412063684 Fix 4 migration adapters, add 7 new ones, add safety features
Notes/work/cal/vote adapters had wrong table names and missing fields.
Now match actual PG schemas. Added books, cart, providers, files, trips,
inbox, splat adapters. Engine gains idempotency, dry-run, disk backup,
per-row error recovery, and progress logging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 01:05:14 +00:00
Jeff Emmett 4cd985c29a Remove rnotes.online routing — re-deployed standalone with Memory Card spec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:53:11 +00:00
Jeff Emmett 4afce2dc37 Add sample splats + photo/video upload pipeline for rSplat
Seed gallery with real Bonsai and Nike Shoe splat scenes from Hugging Face,
replacing the synthetic Rainbow Sphere. Add photo/video upload endpoint
(POST /api/splats/from-media) with processing status tracking for future
COLMAP + OpenSplat generation. Gallery now shows upload mode toggle
(splat file vs photos/video) and processing status overlays on cards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 03:27:41 +00:00
Jeff Emmett 3c986f1709 Add standalone docker-compose for all 20 modules
Each module can run as an independent container using its standalone.ts
entrypoint. Reuses the same rspace-online image with CMD override.

Usage:
  docker compose -f docker-compose.yml -f docker-compose.standalone.yml \
    up -d rtrips-standalone

All services share rspace-db and traefik-public. Module-specific deps
mapped: books/files/swag volumes, OSRM for trips, IMAP for inbox,
R2 for tube, payment network for cart/funds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 03:07:09 +00:00
Jeff Emmett d25bb3ec5e Route 15 standalone domains through rSpace unified server
Add domain→module rewrite in Bun.serve fetch handler for standalone
domains (rbooks, rpubs, rchoices, rfunds, rforum, rvote, rnotes, rwork,
rcal, rtrips, rwallet, rdata, rnetwork, rtube, rmaps). Requests to
these domains get rewritten to /demo/{moduleId}/... and served by the
existing Hono module routes.

Adds Traefik labels at priority 120 for all 15 domains. Keeps rcart,
rfiles, swag, and providers on their own containers.

This retires ~25 legacy containers, freeing significant memory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 00:44:52 +00:00
Jeff Emmett 095d6e1eb9 feat: add newsletter signup section to landing page
Adds a Listmonk-powered newsletter form at the bottom of the rSpace
landing page, matching the dark theme and gradient styling of existing
sections. Uses rSpace list UUID for subscriber routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 17:37:38 -07:00
Jeff Emmett 91d600ed93 Fix rSplat viewer: add file extension to URL for format detection
GaussianSplats3D infers format from URL file extension. Changed file
serve route to /api/splats/:id/:filename so URLs end in .splat/.ply/.spz.
Also fixed camera orientation (Y-up) and scale values in test data.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 00:31:46 +00:00
Jeff Emmett e703405f68 Move conic trajectory visualization into rTrips as route planner
Relocate the conic intersection calculator from standalone rConic module
into rTrips at /routes sub-page. Adds enhanced visualization with ghost
conic curves, distinct arc colors, overlap zones, crossing angle lines,
pulsing intersection markers, arc labels, and SVG legend.

- New math: sampleConicCurve() for ghost curve tracing, conicTangentAt()
  for tangent/crossing angle computation
- Route planner served at /{space}/trips/routes with OSRM proxy
- Removed standalone conic module registration from server/index.ts
- Updated vite build config to build folk-route-planner under trips

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 00:10:52 +00:00
Jeff Emmett f3314477d8 Separate landing page from space creation
Move the create-space form out of the landing page into its own
route at /create-space. Landing page now shows CTA buttons for
"Create a Space" and "Try the Demo". /new redirects to /create-space.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:55:25 +00:00
Jeff Emmett c99c25f174 Add rSplat module — Gaussian splat viewer with x402 gated uploads
New rSpace module for 3D Gaussian splat viewing. Gallery + full-viewport
Three.js/GaussianSplats3D viewer loaded via CDN importmap. EncryptID auth
on uploads, optional x402 micro-transaction gate. Reusable x402 Hono
middleware in shared/x402/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 20:55:45 +00:00
Jeff Emmett cf3be7d7a9 Wire real auth and backends into all 21 rSpace modules
- Auth: 10 modules now use EncryptID token verification on write
  routes (vote, inbox, forum, files, notes, work, cal, trips,
  cart, providers). All POST/PUT/DELETE without valid token → 401.
- Tube: S3Client for Cloudflare R2 bucket (upload, streaming, range)
- Data: Umami analytics proxy (stats, active, tracker, events)
- Wallet: Safe Global API proxy with 12 chains + cache headers
- Network: Twenty CRM GraphQL client (people, companies, graph)
- Maps: sync-url endpoint for WebSocket connection
- Inbox: background IMAP sync worker (30s poll via ImapFlow)
- Forum: provisioner already wired (Hetzner + Cloudflare + cloud-init)
- Config: .gitignore fix, docker-compose env vars + rmail network,
  added @aws-sdk/client-s3, imapflow, mailparser deps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 19:37:26 +00:00
Jeff Emmett 2015a9c277 Include all apps with standalone domains and user-accessible spaces
App switcher:
- Add standaloneDomain to ModuleInfo (exposed via /api/modules)
- Add missing standaloneDomain to 5 modules: funds, files, wallet,
  choices, forum (20/21 modules now have standalone domains)
- Show external link arrow on hover for each app's standalone site

Space switcher:
- Pass auth token when fetching /api/spaces so the API returns
  private (authenticated/members_only) spaces the user owns or
  is a member of
- Group spaces into "Your spaces" (with role badge) and "Public
  spaces" sections
- Reload space list on auth-change (sign-in/sign-out)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:44:12 +00:00
Jeff Emmett 69d382cb70 Add app/space switcher dropdowns to landing and canvas pages
Replace legacy mountHeader() (identity only) with the full rstack
shell header on both index.html and canvas.html. Both pages now
show rstack-app-switcher (21 modules), rstack-space-switcher, and
rstack-identity — matching the module pages rendered by renderShell().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 01:04:23 +00:00
Jeff Emmett fa740e09ca feat: add 13 new modules — complete r-suite platform unification
Port all remaining r-suite apps as rSpace modules:

Batch 1: vote, notes, maps, wallet
- rVote: conviction voting engine with quadratic credit costs
- rNotes: markdown note-taking with notebooks and tags
- rMaps: interactive map viewer with markers and routes
- rWallet: multi-chain crypto wallet viewer (Safe Global API)

Batch 2: work, trips, cal, network
- rWork: kanban board with configurable status columns
- rTrips: trip planner with destinations, itinerary, expenses, packing
- rCal: calendar with lunar phase computation and cross-module linking
- rNetwork: graph visualization placeholder (Automerge + CRM proxy)

Batch 3: tube, inbox, data
- rTube: video library + HLS live streaming (Cloudflare R2)
- rInbox: collaborative email with multisig approval workflow
- rData: privacy-first analytics dashboard (Umami proxy)

All 21 modules registered, built, deployed, and verified at
rspace.online/demo/{moduleId}. Each module has:
- mod.ts (Hono routes + RSpaceModule export)
- standalone.ts (independent deployment)
- folk-* web component (Shadow DOM, no framework)
- CSS + DB schema (where needed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 23:59:00 +00:00
Jeff Emmett 682c995cc3 feat: add files and forum modules — Phase 7+8
Files module (rFiles): file upload/download, share links with
expiry/password/download limits, memory cards CRUD, access logging,
cleanup timers replacing Django Celery tasks.

Forum module (rForum): Discourse cloud provisioner with Hetzner VPS
creation, Cloudflare DNS, cloud-init for automated Discourse install,
async provisioning pipeline with step logging, instance management.

All 10 modules now active: Canvas, rBooks, rPubs, rCart, Providers,
Swag, rChoices, rFunds, rFiles, rForum.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 23:25:18 +00:00
Jeff Emmett 92edaaed45 feat: add choices and funds modules — Phase 5+6
Phase 5 — Choices: Lightweight module wrapping the canvas-native
folk-choice-vote/rank/spider components. Lists choice shapes from the
space's Automerge doc, links to canvas for creation/interaction.

Phase 6 — Funds: Port of rfunds-online BudgetRiver visualization to
vanilla web component. Includes simulation engine (pure functions),
types (stripped @xyflow), demo presets, and SVG sankey river with
animated waterfalls, overflow branches, and sufficiency badges.
Flow-service API proxy for same-origin frontend calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 23:11:48 +00:00
Jeff Emmett d9cc86637c feat: add cart, providers, swag modules — Phase 4 cosmolocal commerce
Port the three cosmolocal print-on-demand services (rCart, Provider Registry,
Swag Designer) into the unified rSpace module system. Each module includes
Hono API routes, folk-* web components, DB schemas, and standalone servers.

- Cart: catalog ingest, orders with state machine, x402 detection, rFunds flow deposit
- Providers: 6 seeded providers, earthdistance proximity queries, capability matching
- Swag: product templates (sticker/poster/tee), Sharp image processing, artifact envelopes
- DB: cube + earthdistance extensions, rcart + providers schemas
- Docker: swag-artifacts volume, payment-network for flow service

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:59:19 +00:00
Jeff Emmett f313d9395d fix(encryptid): allow self-signed TLS for internal SMTP
Mailcow at mail.rmail.online uses a self-signed certificate.
Set tls.rejectUnauthorized: false for the SMTP transport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:41:46 +00:00
Jeff Emmett ca5c1363ce feat: add pubs module — Phase 3 port of rPubs to rSpace platform
Port pocket-press (Next.js + Typst) as an rSpace module with Hono routes,
vanilla folk-pubs-editor web component, and Typst v0.13.1 for PDF generation.
Includes all 4 format templates (A7, A6, Quarter Letter, Digest), artifact
envelope creation with cosmolocal spec, and standalone deployment support.

Typst binary installed in Docker via multi-stage build from debian:bookworm-slim.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:41:10 +00:00
Jeff Emmett 88de4c30dd feat(encryptid): guardian recovery, device linking, enhanced profile
Add 2-of-3 guardian recovery system:
- Guardian invite via email or shareable link
- One-click approval page for recovery requests
- Social recovery initiation (anti-enumeration)
- 7-day recovery request expiry

Add second device linking:
- QR code + link for cross-device passkey registration
- 10-minute link expiry, one-time use

Enhanced profile page:
- Account security checklist (email, device, guardians)
- Guardian management (add/remove, max 3)
- Device linking with QR code display
- Recovery initiation form for lost devices

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:07:40 +00:00
Jeff Emmett b42179cff7 feat: add books module — Phase 2 port of rBooks to rSpace platform
Port rbooks-online (Next.js + React) as an rSpace module with Hono routes,
vanilla web components, and shared PostgreSQL schema. Includes library grid
(folk-book-shelf), flipbook PDF reader (folk-book-reader), upload with
EncryptID auth, IndexedDB caching, and standalone deployment support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:07:34 +00:00
Jeff Emmett eed7b2f151 feat: unified module system — Phase 0 shell + Phase 1 canvas module
Implement the rSpace module architecture that enables all r-suite apps
to run as modules within a single-origin platform at rspace.online,
while each module can still deploy standalone at its own domain.

Phase 0 — Shell + Module System:
- RSpaceModule interface (shared/module.ts) with routes, metadata, hooks
- Shell HTML renderer (server/shell.ts) for wrapping module content
- Three header web components: rstack-app-switcher, rstack-space-switcher,
  rstack-identity (refactored from rspace-header.ts into Shadow DOM)
- Space registry API (server/spaces.ts) — /api/spaces CRUD
- Hono-based server (server/index.ts) replacing raw Bun.serve fetch handler
  while preserving all WebSocket, API, and subdomain backward compat
- Shared PostgreSQL with per-module schema isolation (rbooks, rcart, etc.)
- Vite multi-entry build: shell.js + shell.css built alongside existing entries
- Module info API: GET /api/modules returns registered module metadata

Phase 1 — Canvas Module:
- modules/canvas/mod.ts exports canvasModule as first RSpaceModule
- Canvas routes mounted at /:space/canvas with shell wrapper
- Fallback serves existing canvas.html for backward compatibility
- /:space redirects to /:space/canvas

URL structure: rspace.online/{space}/{module} (e.g. /demo/canvas)
All existing subdomain routing (*.rspace.online) preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:54:15 +00:00
Jeff Emmett 7210888aed feat: unify EncryptID passkeys across all r*.online apps
Simplify resolveRpId() to always return 'rspace.online' so passkeys
registered from any r*.online domain share the same RP ID. Browsers
use .well-known/webauthn Related Origins to validate cross-domain
passkey usage. This makes one passkey work everywhere.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:38:26 +00:00
Jeff Emmett cac038ed0d chore: migrate SMTP from mx.jeffemmett.com to mail.rmail.online
Update EncryptID SMTP defaults to use rmail.online Mailcow instance.
From address now noreply@rspace.online instead of noreply@jeffemmett.com.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:14:58 +00:00
Jeff Emmett 2d0cf499f6 fix: mobile input focus, toolbar UX, and viewport clipping
- folk-shape: skip preventDefault on touch events targeting inputs/textareas
  so mobile keyboards can open inside shapes
- toolbar: replace unreadable emoji-only strip with FAB toggle (+) that
  opens a 3-column grid overlay with emoji + labels; auto-closes on tool
  select; separate always-visible zoom strip at bottom-left
- canvas: remove overflow:hidden from #canvas so viewport moves with
  pan/zoom instead of clipping at initial bounds
- canvas-content: add width/height 100% and overflow:visible for robust
  containing block

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:55:43 +00:00
Jeff Emmett 34a1e3b640 feat: mobile toolbar + infinite canvas pan/zoom
- Mobile toolbar: icon-only scrollable strip with horizontal swipe
- Infinite canvas: separate viewport (grid) from content layer (shapes)
- Single-finger pan via pointer events on empty canvas background
- Widen zoom range from 0.25-4x to 0.05-20x
- Fix Automerge sync fallback to full doc reconciliation when no patches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:32:48 +00:00
Jeff Emmett 7fcef2c2b2 Fix JWT verify calls for Hono 4.11.10 — add required 'HS256' alg
Hono 4.11.10 made the `alg` parameter required in `verify()`. All 6
verify() calls were failing with "JWT verification requires alg option
to be specified", causing every token verification to return 401. This
broke space creation and all authenticated operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:07:51 +00:00
Jeff Emmett 9050298c6f Fix CORS for dynamic rspace.online subdomains in EncryptID
The allowedOrigins array only listed explicit subdomains (auth, cca, demo,
app, dev) so any canvas slug subdomain like create.rspace.online was
rejected by CORS. Switch to a function-based origin check that allows all
*.rspace.online subdomains dynamically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:55:42 +00:00