Commit Graph

257 Commits

Author SHA1 Message Date
Jeff Emmett 24c1598e60 fix: contain MI bar z-index within header stacking context on mobile
On desktop the header is position:fixed which creates a stacking
context, containing the MI bar's z-index:10001. On mobile the header
switches to position:sticky without z-index, so no stacking context
is created and the MI bar's z-index leaks out above the tab row
(z-index:9998). Fix by adding z-index:9999 to the header on mobile.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:32:36 -07:00
Jeff Emmett 6c7c00dc95 fix: hide MI bar on mobile to prevent overlap with rApp tab row
The MI bar (header center section) was wrapping to a full-width
third row on mobile, overlapping the rApp slider tab bar below it.
Hide both the MI bar and its header container on mobile. Users can
still access MI via Cmd+K or the floating pill.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:27:33 -07:00
Jeff Emmett c82646c458 feat: settings gear shows members first, comment bell gets dropdown panel
Settings panel now shows Members + Add Member sections at the top
regardless of which rApp is active, making invite/membership the
primary action. Comment bell replaced with a dropdown panel showing
all comment threads sorted by recency, with a "New Comment" button
to enter pin-placement mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:16:30 -07:00
Jeff Emmett 3be0fb6eed fix: collab overlay stuck on 'Connecting' in demo/standalone pages
The offline runtime is not created for demo space (spaceSlug==="demo"),
so the collab overlay polled forever waiting for it. Now gives up after
~10s and transitions to connected state for standalone display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 09:55:23 -07:00
Jeff Emmett 7fec0cb699 fix: deduplicate online user count by username
Same user with multiple tabs/connections (different peer IDs) was
counted multiple times. Now deduplicates by username, keeping the
most recently seen entry per user for badge count and panel display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:27:35 -07:00
Jeff Emmett 2d39fcac1d refactor(tabs): consolidate [+] button with app-switcher sidebar
The tab bar [+] button now opens the same sidebar as the header's
rApp dropdown instead of its own duplicate menu. Reduces UI clutter
and gives one consistent place to browse/add rApps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 04:48:10 +00:00
Jeff Emmett 58e319b8c8 feat(rinbox): add markdown rendering + TipTap collaborative editing
- Extract markdown-tiptap.ts and yjs-ws-provider.ts to shared/ for reuse
- Thread bodies render as formatted markdown via marked
- Replace compose textarea with TipTap rich-text editor + Yjs collab
- Add formatting toolbar (bold, italic, lists, code, links, etc.)
- Add TipTap comment editor with tiptap-json storage format
- Server accepts content_format on comment API
- Full ProseMirror + collab cursor CSS scoped to shadow DOM
- Editors cleaned up on navigation and disconnect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:40:49 -07:00
Jeff Emmett 28bfa37199 fix: collab overlay stuck on 'Connecting' — init race + timeout
- Runtime now sets isInitialized after IndexedDB (before WS connect)
  so the overlay can detect it within ~500ms instead of waiting 30s+
- Overlay no longer gives up polling after 15s (slows to 2s instead)
- Overlay subscribes to runtime onConnect/onDisconnect for live updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:16:01 -07:00
Jeff Emmett 6a0ad06c11 fix: sync collab overlay connection state with runtime WS status
The overlay was blindly setting 'connected' on runtime ready without
checking actual WebSocket state, and never subscribed to connect/disconnect
events — causing stale "Reconnecting…" badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 19:48:57 -07:00
Jeff Emmett f9457a0e11 perf(shell): add fragment mode for fast rApp tab switching
When switching rApps from the dropdown, TabCache now requests
?fragment=1 which returns a lightweight JSON payload (~200 bytes)
instead of re-rendering the full 2000-line shell HTML template.
This eliminates server-side shell rendering and client-side
DOMParser overhead. Also prefetches fragments on hover.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 02:28:09 +00:00
Jeff Emmett e8d88cd10e fix(rnotes): resolve anonymous identity in comments, suggestions, and cursors
Session was stored as { claims: { username, sub } } but getSessionInfo()
read sess.username (top-level) instead of sess.claims.username — always
falling back to "Anonymous". Fixed in all 3 locations: folk-notes-app,
comment-panel, collab-presence.

Also fixed awareness race: Yjs provider broadcast initial awareness before
user field was set, creating a ghost "anonymous" peer. Now identity is set
on awareness before provider connects, and the duplicate set is removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:34:08 -07:00
Jeff Emmett 696ab3cfd9 feat(mi): load context suggestions on component init for bar placeholder rotation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:16:05 -07:00
Jeff Emmett 77ac0c1e32 feat(rsocials): newsletter drafts, subscribers + MI route updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:11:31 -07:00
Jeff Emmett f966f02909 feat(spaces,rsocials): invite-based member adds + clickable campaign content
Space invites: Convert both username-add and email-invite (existing user)
paths from direct-add to invite flow — creates space_invite via EncryptID,
sends invite email with Accept button, dispatches space_invite notification
with Accept/Decline buttons in the notification bell. No one gets forcefully
added to a space anymore.

rSocials content linking: All generated campaign content now links through
to actual editable content. Draft post cards in thread gallery are clickable
(thread editor or campaign view). Campaign manager post cards expand on click
and thread badges link to thread editor. Wizard success screen shows
individual thread links. CampaignPost schema gains threadId field, stored on
commit so posts maintain their thread association.

Also includes canvas social media tools, social shape components
(folk-social-thread, folk-social-campaign, folk-social-newsletter),
and MI context-aware suggestion registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:03:52 -07:00
Jeff Emmett b5a54265ee feat(collab): show all space members in People panel — offline with grey dots
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:20:59 -07:00
Jeff Emmett 676e29902e feat(encryptid): device management — labeled passkey list + nudge fix
Add label column to credentials, PATCH/DELETE endpoints for rename/remove,
device list UI in account modal with rename/remove actions, and clear stale
nudge dismiss timestamp after device registration so multiDevice API check
takes over permanently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:04:20 -07:00
Jeff Emmett aa02473d0d fix(shell): evict tab pane from cache on script load failure
When a module script (e.g. canvas-*.js) fails to load (502 during
deploy, network error), the pane stayed in cache with a blank canvas.
Subsequent tab switches showed the broken cached pane instead of
re-fetching. Now script onerror removes the failed tag and evicts
the pane, so the next switchTo does a fresh fetch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:10:23 -07:00
Jeff Emmett 1c338529bf fix(presence): relay presence-leave messages and clean up listener on disconnect
- Server now relays presence-leave alongside presence messages for immediate peer removal
- Overlay properly unsubscribes leave listener on disconnectedCallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:42:49 -07:00
Jeff Emmett 2f8ce08e3c feat: add rDesign module metadata, collab presence-leave cleanup
- Register rDesign in folk-rapp MODULE_META and shell FAVICON_BADGE_MAP
- Handle explicit presence-leave messages for immediate peer cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:35:10 -07:00
Jeff Emmett 6b81f808f5 feat(canvas): mobile toolbar flush, zoom icon toggle, SW update banner
- Mobile toolbar collapsed position now flush with bottom-toolbar (bottom: 8px)
- Toolbar defaults to collapsed on mobile (<768px)
- Zoom expand/minimize uses distinct icons (magnifier +/-) instead of CSS rotation
- SW update banner on all pages: "New version available — Tap to update"
  - Detects controllerchange + updatefound events
  - Purple gradient bar, dismissible, reloads on tap
  - Added to both shell.ts (module pages) and canvas.html (standalone)
- folk-rapp: filter picker/switcher by enabled modules
- server/shell: react to modules-changed event for runtime module toggling
- collab-presence: minor overlay updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:34:48 -07:00
Jeff Emmett 59d2cc9933 feat(spaces): add visibility/description to settings panel, merge invite sources
- Space Settings section in dropdown with visibility (public/permissioned/private)
  and description fields, matching the full edit space modal
- GET /api/spaces/:slug now includes description field
- listSpaceInvites merges both space_invites and identity_invites tables
  so email invites appear in Pending Invites
- revokeSpaceInvite falls through to identity_invites table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:29:33 -07:00
Jeff Emmett 0753b31990 fix(spaces): correct API paths for member/invite operations in settings panel
All fetch calls in rstack-space-settings were missing the /api/spaces prefix,
causing 404s for add-by-username, invite-by-email, change-role, remove-member,
and load-invites. Also add color-scheme: light dark to fix native select
dropdowns rendering in light mode on dark theme.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 15:15:33 -07:00
Jeff Emmett 8071b620e1 fix(auth): throttle session validation, typed auth-change events, misc fixes
- rstack-identity.ts: throttle server session validation to every 5min,
  add reason detail to all auth-change events (signin/signout/revoked/
  refresh/persona-switch), remove redundant location.reload on signout
- shell.ts: skip UI side-effects on token refresh, only redirect home
  on genuine signout/revocation
- server.ts: add PUT to CORS allowMethods
- folk-inbox-client.ts: pass auth token on mailbox API fetch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 12:21:26 -07:00
Jeff Emmett c2d7e8b238 fix(shell): prevent infinite loop when rapidly switching tabs
Abort previous in-flight fetch when switchTo() is called again, and
guard the shell's fallback navigation against stale callbacks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:44:38 -07:00
Jeff Emmett 06a58f1bba fix(ui): theme-adaptive rSocials buttons + device link textbox
- campaign-wizard.css: fix undefined --rs-surface-hover → --rs-bg-hover
- campaign-workflow.css: replace hardcoded blue colors with theme vars
  (--rs-primary-hover, --rs-bg-active, --rs-border, --rs-primary)
- rstack-identity.ts: device link URL input --rs-bg-inset → --rs-input-bg
  (--rs-bg-inset was never defined in theme.css, dark fallback always won)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:39:14 -07:00
Jeff Emmett 423d2612af fix(auth): preserve active tab through login on bare domain
The identity component's inline _getCurrentModule() assumed path-based
routing (/{space}/{moduleId}) for non-subdomain URLs, returning "rspace"
instead of the actual module. On bare domain (rspace.online/rnotes),
this caused login to redirect to the canvas instead of rnotes.

Add _isBareDomain() check so _getCurrentSpace() returns "demo" and
_getCurrentModule() reads parts[0] (the module) on the bare domain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:27:30 -07:00
Jeff Emmett 22b5c00a13 fix(routing): prevent domain stacking and remove Try Demo button
- Fix server-side redirect to always use canonical rspace.online as base
  domain instead of deriving from hostClean (prevents demo.rspace.rspace.online)
- Fix bare-domain check to exact match instead of .includes() (prevents
  stacked subdomains from triggering bare-domain routing)
- Fix client-side rspaceNavUrl to guard against reserved subdomain names
  being used as space subdomains (e.g. rspace.rspace.online)
- Fix identity component _navUrl with same canonical domain guards
- Remove "Try Demo" header button from all shell rendering functions
- Remove demo-btn CSS styles
- Fix pre-existing SchemaType error in Gemini tool declarations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:16:46 -07:00
Jeff Emmett dd46905e12 feat(mi): agentic upgrade — multi-turn loop, LiteLLM, media gen, live data
Transform MI from single-shot chat into an agentic system:

- LiteLLM provider with Claude Sonnet/Haiku models via proxy
- Agentic loop (max 5 turns): stream → parse actions → execute server-side → feed results back
- Server-side media generation (fal.ai + Gemini) as first-class MI actions
- Module data queries (rnotes, rtasks, rcal) read directly from Automerge
- System prompt enriched with recent notes, open tasks, and calendar events
- Client handles new NDJSON types (turn, action-start, action-result)
- Extracted shared media helpers, refactored image/video endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:26:56 -07:00
Jeff Emmett 3596bb9d7c fix(ui): raise MI search z-index and unclip header overflow
Search dropdown was rendering behind overlays and getting clipped by
the header's overflow:hidden. Bump z-index to 10001 and set overflow
to visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:02:04 -07:00
Jeff Emmett efa5a5c315 fix(collab): read username from session.claims.username instead of session.username
The encryptid session stores username at claims.username, not at the
top level. Also falls back to the rspace-username localStorage key
that rstack-identity sets on login.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:03:01 -07:00
Jeff Emmett cefc1aa5b7 fix(collab): rename Solo/Share to Online/Offline, use EncryptID usernames
Swap toggle labels to Online/Offline (more intuitive). Resolve canvas
peer usernames from encryptid_session instead of rspace-username fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:45:55 -07:00
Jeff Emmett e70b40df9a fix(collab): theme-aware N-online badge and people panel
The collab overlay badge used --rs-bg-secondary (which doesn't exist in
the theme system), causing it to always fall back to dark hardcoded values.
Updated all Shadow DOM CSS to use proper theme variables (--rs-glass-bg,
--rs-glass-border, --rs-text-primary, etc.) with light-mode-safe fallbacks
so the badge and panel are readable in both dark and light themes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:39:40 -07:00
Jeff Emmett 41051715b9 feat(rtasks): ClickUp two-way sync integration
Add bidirectional sync between rTasks and ClickUp:
- API client with 100 req/min rate limiter
- OAuth2 + personal API token connection flows
- Import wizard (workspace → space → list picker)
- Outbound push queue (5s intervals, 10-item batches)
- Inbound webhook with HMAC-SHA256 validation
- Field-level conflict detection (rTasks wins)
- Source badges (purple CU) with sync status dots on task cards
- Sync status indicator in board header for connected boards

Also fix 6 pre-existing TS errors across crowdsurf, rcal, rnotes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:37:01 -07:00
Jeff Emmett e8379541cc fix(tabs): strip duplicate shell elements from canvas tab injection
The canvas.html body contained <rstack-tab-bar>, <rstack-space-settings>,
and <rstack-history-panel> elements that weren't being stripped by
extractCanvasContent (the tab-row regex failed due to extra children).
When injected via TabCache, these duplicate elements interfered with the
shell's tab management, causing tabs to appear wiped.

Fixes:
- Server: robust div-counting strip for rstack-tab-row + explicit strips
  for space-settings and history-panel
- Client: DOM-based safety strip in TabCache.extractContent()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:21:52 -07:00
Jeff Emmett 13a7e44e24 feat(identity): replace device nudge toast with QR code for mobile linking
Instead of a "Set up now" button, the device nudge now generates a device
link token and displays a scannable QR code + copyable link URL directly
in the toast, making it easy to link a phone or tablet.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:06:29 -07:00
Jeff Emmett df8631360e feat(collab): unified presence system across all 27 rApps
Harmonize the two disconnected presence systems into one:
- New shared/collab-presence.ts utility (broadcastPresence, startPresenceHeartbeat)
- Collab overlay now listens to custom presence messages, shows module context in people panel
- Fixed Shadow DOM focus tracking using composedPath() for focus rings through shadow boundaries
- Replaced rNotes custom presence with shared utility (kept sidebar dots)
- Added presence heartbeat to all 27 rApp components with dynamic context strings
- Bumped cache versions in all modified mod.ts files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:56:06 -07:00
Jeff Emmett 677a69645e debug(shell): add console logging to trace tab-switch failure for rspace
Adds diagnostic console.log to layer-switch handler, TabCache.switchTo,
fetchAndInject, and reconcileRemoteLayers to identify why clicking the
rspace tab closes all tabs and shows the dashboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:32:57 -07:00
Jeff Emmett 433833da0c fix(shell): prevent remote sync from wiping all tabs and showing dashboard
reconcileRemoteLayers() could wipe all local tabs when Automerge sync
or BroadcastChannel delivered empty layer data (CRDT initial state,
sync race). This caused clicking tabs to show an infinite-loading
dashboard. Now: empty remote layers are rejected when an active module
exists, and the current module always stays in the tab list.

Also adds 10s fetch timeout to TabCache.fetchAndInject() to prevent
infinite loading spinners on slow/failed module fetches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:23:45 -07:00
Jeff Emmett 50edf06900 feat(encryptid): periodic nudge toast for users without a second device
Shows a dismissible toast notification 3s after page load when the user
has only one passkey. Links directly to the device section in My Account.
Dismissal remembered for 7 days via localStorage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:14:59 -07:00
Jeff Emmett a7eda3c53f feat(encryptid): post-signup prompt recommending second device linking
After registration, users now see a welcome modal that prominently
recommends linking a second device via QR code before entering their
space. Provides backup access and cross-device sign-in awareness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:05:50 -07:00
Jeff Emmett 772e5e4352 fix(shell): header button reliability — history, settings, comments
History panel: lazy doc acquisition from CommunitySync/offline runtime
on open + listen for community-sync-ready event for late connections.

Space settings: reposition panel after every re-render (async data loads
were destroying inline positioning styles), clamp max-height to viewport,
fix wrong global name (__rspaceCommunitySync → __communitySync).

Comment bell: render DOM once, update badge without innerHTML churn,
listen for community-sync-ready event, cache sync reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:04:11 -07:00
Jeff Emmett a83c714f5a fix(auth): username-first flow in rstack-identity sign-in modal
The actual login UI lives in rstack-identity.ts, not login-button.ts.
Added username input to the sign-in modal, pass allowCredentials from
server to WebAuthn so the browser auto-selects the matching passkey.
Shows "No account found" if username not recognized. Enter key support
and auto-focus on the username field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 14:44:39 -07:00
Jeff Emmett 4536b5cab1 fix: remove rvote proposals from space dashboard + fix protocol in redirects
1. Remove all rvote/proposals fetching from rstack-user-dashboard.
   rApp-specific data (proposals) should stay within the rVote module,
   not leak into the space-level dashboard.

2. Fix url.protocol in bare-domain redirects — TLS is terminated by
   Cloudflare/Traefik so url.protocol is always http: internally.
   Use https: for production domains.

3. Rewrite /{space}/api/... paths internally on bare domain instead
   of redirecting to subdomain (avoids CORS + mixed content issues).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 12:29:15 -07:00
Jeff Emmett 8f1ad52557 feat(collab): unify header & tab-row — shared people-panel across all rApps
Canvas now uses the same rstack-collab-overlay component as all other
rApps instead of its own custom #people-online-badge. Header restructured
to match renderShell() layout (history/settings in dropdown-wraps on left).
Bridge API (updatePeer/removePeer/setConnState/clearPeers) lets canvas
feed CommunitySync peers into the shared component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 11:46:26 -07:00
Jeff Emmett f9767191e8 fix(auth): reload page on logout and redirect logged-in users from space grid
After logout, reload the page so the server re-renders the current rApp
in logged-out/demo mode instead of showing a blank screen. Cross-tab
logout also triggers a reload. Space dashboard now redirects logged-in
users to the rSpace canvas instead of showing the rApp grid.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 10:54:35 -07:00
Jeff Emmett 4722aca065 fix(auth): wire cross-session logout in rstack-identity + encryptid profile
rstack-identity is the actual sign-out component used in production.
clearSession() now calls /api/session/logout, and connectedCallback
validates the session with the server to detect revocation. Also
updated the auth.rspace.online profile page handleLogout().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 10:46:44 -07:00
Jeff Emmett aa4a200f32 feat(history): add "Revert to this point" button in Time Machine panel
Forward Automerge change that overwrites content fields with snapshot data,
preserving meta and full history. Also fixes pre-existing TS errors in
folk-flow-river (undefined exitX) and test-full-loop (StepResult type).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 19:08:15 -07:00
Jeff Emmett 0c46e33148 fix(collab): embed online badge in tab row instead of fixed overlay
The "N online" collab badge was position:fixed at top:8px, overlapping
the header login area. Move it into the tab bar slot (main shell) or
header-right section (standalone shells) so it flows inline with other
chrome elements.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 18:19:29 -07:00
Jeff Emmett 1282ba5325 feat(history): humanize activity entries with icons and timestamps
Replace raw Automerge change messages (e.g. "Update shape abc-123-uuid")
with human-readable text and contextual icons. Add per-entry timestamps
for clearer chronology within author groups.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:56:13 -07:00
Jeff Emmett 30f037c2a0 feat(dashboard): redesign space dashboard with members, activity, votes
Replace the global "Your Spaces" grid with a space-centric dashboard showing
members, previously open tools, recent activity, active votes, and quick
actions. Fix layout cut-off by positioning dashboard fixed below header+tab
row (top: 92px) with sidebar-push support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:57:54 -07:00
Jeff Emmett 389dc70e77 fix(settings): position dropdown below and to the right of gear icon
The panel was right-aligned relative to the button which pushed it
off-screen since the gear is on the left side of the header. Now
left-aligns with the button and clamps to stay within viewport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:37:25 -07:00
Jeff Emmett afd2a5a40b fix(canvas): persistent drawing tools + online/offline label + drag fixes
Drawing/shape tools (pencil, line, rect, circle) now stay active for
multiple strokes instead of resetting to selector after each use.
Renamed collab overlay badge from "Solo/Share" to "Offline/Online".
Prevent canvas drag when interacting with image-gen and prompt content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:03:15 -07:00
Jeff Emmett 8649598c26 fix(tab-cache): add Accept header so tab fetch works on private spaces
The TabCache fetchAndInject() was sending fetch() without Accept: text/html,
causing the server to treat it as an API request and return 401 on private
spaces. Also adds .catch() fallbacks to shell tab handlers for resilience.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:00:51 -07:00
Jeff Emmett f5de97c60c feat(ux): move comment button to header bar with unresolved badge
Move the "Leave Comment" button from the bottom canvas toolbar to the
top header bar as <rstack-comment-bell>, positioned left of the
notification bell. Shows a red badge with unresolved comment pin count.
Wires canvas via comment-pin-activate/comment-pins-changed custom events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 14:02:27 -07:00
Jeff Emmett b91233092b fix(ux): move people-online badge into sub-tab header bar
- Move people badge + panel from fixed position to inline in .rstack-tab-row
- Badge sits right of the layer toggle icon with a subtle separator
- Panel drops down from badge position instead of floating fixed
- Online/Offline toggle replaces Solo/Multi labels for clarity
- Badge shows "Offline" with gray dot when in offline mode
- Mobile: hide text label, show dots only
- Tab bar gets flex:1 + min-width:0 to share row space

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:29:45 -07:00
Jeff Emmett d458a00550 fix(ux): instant bulk-delete dialog + post-login space routing
Bulk delete dialog: switch from click to pointerdown for instant
touch response, raise z-index above all overlays, add hover/active
feedback and keyboard support.

Post-login routing: reload page when logging in on a non-demo space
so access gates clear and CRDT sync reconnects with auth. Silently
provisions personal space in background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:21:03 -07:00
Jeff Emmett 1930d7dab0 feat(identity): local persona switcher for client-side multi-account
Store known personas in localStorage, auto-register on login. Dropdown
shows other personas with one-click switch (triggers passkey re-auth),
add/remove persona buttons, and cross-tab sync.

Also fix pre-existing TS errors: non-null assert on filtered functionCall,
add optional VerifyOptions param to authenticateWSUpgrade type declaration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 12:10:55 -07:00
Jeff Emmett 73cc1d1cc4 feat(spaces): add Create Space modal with member invites and invite links
Adds an intermediate modal when creating a space: name/slug editing with
availability check, description, visibility radio cards, discoverable
toggle, member search with @username lookup and email invites, and a
shareable invite link generated post-creation.

Server: adds discoverable field to CommunityMeta, extends PATCH /:slug,
adds POST /:slug/invites for generic invite token creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 12:04:27 -07:00
Jeff Emmett 48d11f5ec9 feat(canvas): simplify comment pins — optional notes + link rNotes
Pins no longer require a message. Added "Link existing rNote" picker
to attach space notes to pins. Linked notes show as clickable links
in the popover with unlink option.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 19:13:58 -07:00
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 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 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 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 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 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 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 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 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 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 64f9603e39 fix(spaces): stop module settings selects from polluting scope overrides
Module settings selects (notebook-id, select types) shared the .scope-select
CSS class with actual data-scope selects, causing their values to be sent as
scopeOverrides — triggering "Invalid scope '' for rnotes" on save.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:49:17 -07:00
Jeff Emmett acafe15c4b feat(spaces): resolve member DIDs to usernames in space settings
Add POST /api/users/resolve-dids batch endpoint in EncryptID, proxy
/api/users/* through rspace server, and batch-resolve missing displayNames
in the space settings panel so owners and members show usernames not DIDs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:39:48 -07:00
Jeff Emmett a415d6c308 fix(mi): only minimize on Escape when input empty, fix mobile transform
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:25:06 -07:00
Jeff Emmett b7aadf66cd feat(sync): proxy /api/user/* to EncryptID for cross-session tab state
Adds catch-all proxy route so client tab sync requests (saveTabs/syncTabsFromServer)
reach the EncryptID container. Also fixes rstack-mi panel positioning and
Shadow DOM click-outside handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:22:37 -07:00
Jeff Emmett b679fc9f1f feat(spaces): bridge email invites with EncryptID identity system
New users get sent to /join for passkey registration + auto-space-join.
Existing users are directly added with in-app + email notification.
Add-by-username now also sends email notification if email is on file.

- Add id to /api/users/lookup response
- Enhance /api/internal/user-email/:userId with recovery + profile email
- Add GET /api/internal/user-by-email for email→DID resolution
- Rewrite POST /:slug/invite to use identity invite flow
- Add email notification to POST /:slug/members/add
- Add success/error feedback to space settings invite UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:04:22 -07:00
Jeff Emmett ad2120f4fb fix(spaces): keep create-space dropdown open during interaction
The dropdown closed on every click (radio buttons, input focus, etc.)
because a global document click listener removed the "open" class.

- Add menu-level stopPropagation so clicks inside the dropdown don't
  close it
- Only close on clicks outside both trigger and menu
- Preserve form state (name, visibility, open/closed) across
  close/reopen so content isn't lost when accidentally clicking away

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 15:59:31 -07:00
Jeff Emmett f8ab716722 feat(x402): bridge on-chain USDC payments with CRDT token ledger
Connects x402 (on-chain USDC via Base) and CRDT token system (Automerge cUSDC)
in both directions: on-chain payments auto-mint cUSDC to payer's DID, and users
can pay with cUSDC balance via new "crdt" payment scheme. 402 responses now
return both exact and crdt payment options.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 14:23:24 -07:00
Jeff Emmett 4793f9c117 feat(crowdsurf): restore module and add Elo pairwise ranking layer
Restore CrowdSurf as standalone module with full integration (server,
app-switcher, shell favicon, rchoices tab, vite build). Add sortition-
based pairwise Elo ranking: users compare two activities head-to-head,
updating Elo ratings. Includes API endpoints (/api/crowdsurf/pair,
/api/crowdsurf/compare), Rank tab with leaderboard, and Elo badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:51:24 -07:00
Jeff Emmett d99b85046c feat(rswag): full feature parity — POD clients, dithering, AI gen, fulfillment
8-phase implementation bringing rSwag module to parity with standalone rswag.online:
- Printful v2 + Prodigi v4 API clients with sandbox mode
- 11 dithering algorithms + screen-print color separations
- Gemini AI design generation + user artwork upload
- ~15 new API routes (designs, mockups, storefront, fulfillment, admin)
- 4-tab frontend UI (Browse, Create, HitherDither, Orders)
- Interactive revenue Sankey diagram on landing page
- Fulfillment bridge routing orders to nearest POD provider

Also includes: rChats module scaffold, rVote enhancements, crowdsurf removal,
rchoices cleanup, rwallet tweaks, app-switcher updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 23:21:53 -07:00
Jeff Emmett d4972453a3 feat(onboarding): add module-specific connect/import/create CTAs
Declarative onboardingActions on RSpaceModule lets each rApp define its
own onboarding cards (import, upload, link, create). renderOnboarding()
renders them as a responsive card grid with upload handling. Adds ICS
import endpoint to rCal (POST /api/import-ics). 15 modules wired up.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 14:17:19 -07:00
Jeff Emmett df77c9c903 feat(shell): cross-tab sync via BroadcastChannel + keyboard shortcuts & swipe gestures
Add BroadcastChannel for instant same-browser tab sync — opening/closing
tabs in one window propagates immediately to sibling tabs. Extract
reconcileRemoteLayers() helper shared by BroadcastChannel and Automerge,
which cleans up cached DOM panes on remote removal and handles
active-tab-closed scenarios.

Also adds configurable rApp shortcuts (Ctrl/Alt+1-9), header swipe
gestures for rApp cycling, and body data-module-id attr for swipe context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:04:31 -07:00
Jeff Emmett 73ad020812 fix(spaces): fix space creation routing and use /rspace URLs
Space creation was broken because the canvas module has id "rspace" but
all navigation URLs used "/canvas". On production subdomain routing this
resulted in 404s after creating a space.

- Switch create-space form from deprecated /api/communities to /api/spaces
- Replace all /canvas navigation URLs with /rspace to match module ID
- Fix DID matching in space listing to check both sub and did:key formats
- Add proper client DID support in EncryptID registration flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:07:01 -07:00
Jeff Emmett 39ec09bb3b fix(compat): improve cross-browser support for Firefox, Safari, and older browsers
Add global polyfills for AbortSignal.timeout() (Safari <17, Firefox <122)
and crypto.randomUUID() (Safari <15.4, Firefox <95) in shell HTML templates.
Add -webkit-backdrop-filter prefix across 13 files for older Safari support.
Add Firefox scrollbar (scrollbar-width/scrollbar-color), range input
(::-moz-range-thumb/track), and color-mix() rgba fallbacks. Create shared
compat.ts utility module. Lowers browser floor from Safari 17/Firefox 122
to Safari 15.4/Firefox 95.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:43:38 -07:00
Jeff Emmett a736321189 feat(rnotes): add real-time Yjs collaboration, comments, and suggestions
Replace whole-content Automerge sync with character-level Yjs CRDT for
NOTE-type notes. Adds cursor presence, inline comments with threaded
replies, and track-changes suggesting mode.

- Custom Yjs WebSocket provider bridging over existing rSpace WS
- Server-side yjs-sync/yjs-awareness message relay (pure broadcast)
- y-indexeddb for offline persistence, periodic plaintext sync to Automerge
- Comment mark + panel with resolve/reply/delete
- Suggestion insert/delete marks with accept/reject support
- Schema v3→v4 (collabEnabled, comments fields)
- Collab toolbar: comment button, suggesting toggle, peer indicators

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 10:36:09 -07:00
Jeff Emmett 315a29a6d7 fix(shell): hide notification/share/settings icons on mobile, add to identity dropdown
On mobile (<=640px), the header right section was too crowded with icons.
Now hides notification bell, share panel, and settings gear buttons, and
adds equivalent mobile-only items in the identity dropdown menu. Share
uses native navigator.share() when available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 20:58:52 -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 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 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 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 bf28e96ae6 Unrestrict 3D layer view camera — full x/y/z orbit
- Add rotateY axis (drag left/right rotates Y, up/down rotates X)
- Shift+drag for Z-axis roll
- Remove 10-80° clamp on rotateX — full ±180° range
- Remove backface-visibility:hidden so layers visible from all angles
- Fix overflow:hidden → overflow:visible for proper 3D perspective
- Increase layer spacing 80→120px for more dramatic depth
- Increase viewport height 340→420px, perspective origin centered

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 13:49:13 -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 3b3a642813 fix(routing): remove hardcoded /demo/ path prefix from URLs
demo.rspace.online subdomain already identifies the space, so paths
should not redundantly include /demo/. Replaced 7 occurrences across
rcart, rswag, rpubs, rschedule, and space-switcher with either relative
paths or full demo.rspace.online URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:48:20 -07:00
Jeff Emmett 357e0bb4c0 refactor(transak): split API keys by environment (staging/production)
Add getTransakApiKey() and getTransakWebhookSecret() helpers that
resolve TRANSAK_API_KEY_STAGING or TRANSAK_API_KEY_PRODUCTION based
on TRANSAK_ENV, with fallback to legacy TRANSAK_API_KEY. All consumers
(rcart, rflows, transak-onramp) now use the shared helpers instead of
reading env vars directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:06:33 -07:00
Jeff Emmett 9d34eca103 fix(transak): default to STAGING environment for all purchases
Switch TRANSAK_ENV default from PRODUCTION to STAGING in shared/transak.ts,
docker-compose.yml, and rflows config endpoint. All card purchases now
route through Transak's staging gateway until production is ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:54:42 -07:00
Jeff Emmett c668d5700c fix(transak): derive referrerDomain from request hostname instead of hardcoding
Resolves T-INF-101 Access Denied when accessing payment links from
subdomains like demo.rspace.online. Adds extractRootDomain() helper
to shared/transak.ts, used by both rcart and rflows onramp adapters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:49:29 -07:00
Jeff Emmett 9091c988ff feat: add subnav outputPaths for rcart, rmeets, rwallet; CRM URL-path tabs
- rcart: add subscriptions outputPath
- rmeets: add rooms + recordings outputPaths
- rwallet: add wallets, tokens, transactions outputPaths
- folk-crm-view: read active tab from URL pathname instead of ?tab=
  query param (with backward compat fallback)
- rstack-app-switcher: rename rtasks category to "Work & Productivity"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 01:37:05 -07:00
Jeff Emmett 0c3d8728a0 fix: graph 3d-force-graph resolution, DID/username display, space role checks
- Switch 3d-force-graph CDN from jsdelivr to esm.sh with bundle-deps
  to resolve missing "three-forcegraph" bare specifier error
- Fix storeCredential() to pass displayName and DID to createUser()
  (prevents NULL did column for credential-first user creation)
- Fix invite acceptance to use claims.did instead of claims.sub for
  space_members.user_did (DID format consistency)
- Fix session refresh to look up username from DB when missing from
  old token (prevents empty username after token refresh)
- Fix resolveCallerRole() in spaces.ts to check both claims.sub and
  claims.did against ownerDID and member keys (auto-provisioned spaces
  store ownerDID as did🔑, API-created as raw userId)
- Refactor CRM route to use URL subpath tabs with renderCrm helper

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 01:31:24 -07:00
Jeff Emmett 8efe18280c feat: consolidate domains, install deps, fix EncryptID types
- TASK-24: Install h3-js, @xterm/xterm, @xterm/addon-fit
- TASK-51.3: Remove app switcher external link arrows, update
  ridentity.online UI links to /rids paths
- TASK-51.4: Prune allowedOrigins (~30 → 16), simplify JWT aud
  to 'rspace.online', remove standalone domains from webauthn,
  update EncryptID HTML template links. Keep ridentity.online as
  canonical EncryptID/OIDC domain.
- Fix EncryptIDClaims type: add username, did fields; update aud
  type to string | string[] — resolves pre-existing TS error
- TASK-12: Update backlog status (80% code-complete, blocked on
  security audit)
- Backlog task updates for TASK-25/37/40/44, new TASK-110

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:55:39 -07:00
Jeff Emmett adb0d173d8 feat(shell): add module sub-nav bar + rCart UX polish + fix TS errors
- Add secondary pill navigation bar between tab-row and <main> showing
  each module's outputPaths + subPageInfos as navigable links with
  client-side active highlighting
- Rename rcart /buy/:id route to /group-buy/:id, add payments and
  group-buys outputPaths, rename products → catalog
- Add outputPaths (mailboxes) to rinbox module
- Polish group buy page: hero stat cards, fill-up liquid progress
  visual with tier markers, warm amber→green gradient, pledge avatars,
  green CTA button, price box, responsive improvements
- Fix centering for narrow rcart form pages (flex layout in cart.css)
- Fix TS error: add walletAddress to rstack-identity SessionState type
- Fix TS errors: add ambient type declarations for 3d-force-graph and
  three (dynamically imported in folk-graph-viewer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:44:45 -07:00
Jeff Emmett 96b77278d4 fix(transak): use direct widget URL instead of broken gateway API
The Transak gateway session API consistently returns 401 despite valid
access tokens. Switch to direct URL construction (query params on
global.transak.com) which Transak still supports and is simpler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:32:23 -07:00
Jeff Emmett 1460d2b579 feat(ecosystem): implement cross-app embedding protocol (TASK-46)
Add ecosystem manifest protocol, EcosystemBridge class, server proxy
routes, port/event integration for folk-rapp, sandboxed iframe mode
with origin-validated postMessage, and SW caching for ecosystem modules.

Security: no allow-same-origin on sandboxed iframes, redirect: error
on proxy fetches, origin validation on all postMessage handlers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 18:32:28 -07:00