Add r⭐ badge for rcred in favicon, app-switcher, and tab-bar badge
maps. Render 'r' with #dc8300 orange in badge pills across all three
components (favicon SVG tspan, app-switcher HTML spans, tab-bar HTML
spans). App names (e.g. "rDocs") intentionally left uncolored.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Persistent chat panel accessible from any page via header icon.
Sliding right panel (360px) with channel selector, message feed,
composer, and unread badge. REST polling with localStorage state
persistence. Includes unread-count API endpoint for badge updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tours were demoing stale features and auto-triggering annoyingly.
TourEngine.start() now returns immediately (no-ops). Shell welcome
tour JS/CSS/HTML removed. "Start Guided Tour" links stripped from
all 27 landing pages. Tour CSS selectors removed from info panel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remote cursor arrows and focus rings from peers viewing a different
note in rDocs are now suppressed. A generic viewId concept on the
collab overlay lets any rApp with sub-views opt in via a
rspace-view-change CustomEvent. Peers on a different view appear
dimmed in the people panel with a document icon hint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Store shape listener refs in Map, remove in unregisterShape() (critical leak)
- Compact Automerge history every 500 changes via clone() to cap WASM heap
- Clean shapeLastPos entries on shape removal
- Store outside-click handler ref, clean up in disconnectedCallback()
- Cap MI messages at 50 and prompt messages at 30 to prevent unbounded growth
- Store keep-alive interval handle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show red alert dot on "My Account" dropdown item when email, multi-device,
or social recovery tasks are incomplete. Remove postal address section
from the account modal (render, state, loader, listeners).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace three separate mic controls (bar dictation, bar miC, panel miC)
with a single 🎤 toggle in the bar that activates the full voice loop:
speech-to-text → auto-submit after 1.5s silence → TTS response.
- Remove standalone dictation mode (#dictation, #interimText)
- Remove panel header miC button
- Single mic button uses voice mode state animations (pulse red = listening,
spin amber = thinking, pulse cyan = speaking)
- Tighten TTS output to ~2 sentences for succinct responses
- Voice strip still shows in panel with waveform, status, and stop button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add r<emoji> badges for rDocs, rDesign, rSheets, rTime, rGov, rAgents,
rExchange to both MODULE_BADGES and FAVICON_BADGE_MAP
- Add MODULE_CATEGORIES entries for all new modules
- Add "Govern" category for rGov
- Sort modules alphabetically within each function category
- Add sort toggle (By Function / A-Z) at bottom of sidebar, persisted
in localStorage
- Add star/pin button on each rApp — pinned items appear in a "Pinned"
section above "Recent", persisted in localStorage
- Fix rAuctions module ID: 'auctions' → 'rauctions' for consistency,
with alias in MODULE_ALIASES for backward compat
- Change rAuctions emoji from 🏛 to 🎭
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add per-object visibility levels (viewer/member/moderator/admin) across
all rSpace modules. Objects default to 'viewer' (open), so existing data
remains visible. Server-side GET handlers resolve caller role and filter;
MCP tools filter lists and check single-item access; frontend components
do defense-in-depth filtering with visibility picker (mod+) and lock badges.
- shared/membrane.ts: types + isVisibleTo, filterByVisibility, filterArrayByVisibility
- 9 schema files: visibility field on TaskItem, NoteItem, CalendarEvent, etc.
- 8 module routes: GET handlers filter by caller role
- 6 MCP tool files: list filtering + single-item visibility checks
- 4 frontend components: client filtering, picker, lock badges
- 18 unit tests (all passing)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- MI bar z-index lowered to 1 so dropdowns render above it; panel
gets z-index 10001 only when open
- SW registration URL bumped to v=8 to match cache version
- rtime: pool and weaving are now two separate scrollable sections
on mobile (50vh/60vh min-heights) with a "Commitment Weaving"
section header visible on constrained screens
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add /api/auth/*, /api/register/*, /api/account/* proxy routes to
rspace-online server, forwarding to encryptid container internally.
This eliminates cross-origin requests that Safari blocks via ITP or
Cloudflare security challenges.
- Change client auth URLs from https://auth.rspace.online to same-origin
in rstack-identity, rspace-header, login-button, and session modules.
- Add PRF extension try/catch fallback in webauthn.ts — Safari throws
TypeError on the unsupported PRF extension, now retries without it.
- Bump SW cache version v7→v8 to bust stale cached bundles.
Fixes passkey login for Safari/macOS users (e.g. christina) who were
getting "Network error when attempting to reach resource".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Red pulsing alert dot on avatar when social recovery not configured
- SVG puzzle piece visualization for guardian slots (empty/pending/accepted)
- Key assembly animation when 2+ guardians accepted
- Recovery drill system: test the full guardian approval flow without actual recovery
- POST /api/recovery/drill/initiate, GET .../status, POST .../complete
- Drill-specific emails with "TEST ONLY" branding
- Live polling UI with puzzle pieces filling in as guardians approve
- Drill timestamp tracking (last_drill_at on users table)
- Solo walkthrough modal: 5-step animated preview of how recovery works
- Approval page detects drill flag, shows DRILL badge
- Account status now returns acceptedGuardianCount and lastDrillAt
- Recovery section shows emergency override messaging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Sign-in modal: detect email input and send as { email } to auth/start
- Add "Send Magic Link" button alongside passkey sign-in
- Registration: optional email field sent with register/complete
- Enter on username field tabs to email; Enter on email submits
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- getAllKnownUsernames() now pulls from 4 sources: current session,
rspace-username cache, known-personas list, and encryptid-known-accounts
- On specific space: stay on that page (reload only, no redirect away)
- On landing: go straight to dashboard (hardcode "rspace" module)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display known accounts as clickable buttons in the sign-in modal so users
pick their username rather than typing it — prevents accidental new passkey
creation from typos. Falls back to manual input via "Use a different account".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds always-visible home button in tab bar, toggleable dashboard overlay,
widget card system with 8 widgets (tasks, calendar, activity, members,
tools, quick actions, wallet, flows), customize mode with toggle/reorder,
and dashboard summary API endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Browser-side:
- Fix switchSpace() to LRU-evict idle space WebSocket connections (cap: 3)
- Add runtime.unsubscribe() to disconnectedCallback in 24 components
- Fix DocSyncManager.unsubscribe() to clean up syncStates, timers, listeners
- Fix 14 components leaking RAF loops, ResizeObservers, MutationObservers,
document/window listeners, setIntervals, MapLibre WebGL contexts, and
AbortControllers on disconnect
- Deduplicate Automerge WASM: module builds now use global shim from
shell-offline instead of bundling ~2.5MB each (8 modules affected)
Server-side:
- Add LRU eviction to SyncServer.#docs (cap: 500, evicts idle docs with
no subscribers, persists to disk before eviction)
- registerWatcher() now returns unsubscribe function
Data:
- Cap unbounded CRDT arrays: rexchange chatMessages (200), rcart events (200)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 2-3 of the rNotes/rDocs split. Rewrites rNotes from a full TipTap
editor (~1800 lines) into a lightweight Obsidian/Logseq vault sync and
browse module (~560 lines). Rich editing features remain in rDocs.
rNotes vault browser:
- VaultDoc schema: metadata-only in Automerge (title, tags, hash, wikilinks)
- ZIP vault uploads stored on disk at /data/files/uploads/vaults/
- File tree browser, search, read-only markdown preview
- Wikilink graph data endpoint for visualization
- 5 MCP tools: list_vaults, browse_vault, search_vault, get_vault_note, sync_status
- Browser extension compat shim redirects old API calls to rDocs
Cleanup:
- Removed dead editor files from rnotes (converters, components, local-first-client)
- Updated MI integration to use getRecentVaultNotesForMI
- Updated ONTOLOGY.md with new module descriptions
- Bumped JS cache versions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds Figma-style threaded comment markers anchored to data-collab-id
elements across all module pages. Comments stored in per-space Automerge
doc, synced via existing local-first stack. Bell is now context-aware
(canvas pins on canvas, module pins on module pages). Notifications
route through existing WS/push/email system with new module_comment
and module_mention event types.
New files: module-comment-types, module-comment-schemas,
rstack-module-comments component. Updated: shell, comment bell,
notification routes. Added data-collab-id to crowdsurf, rtime, rmeets.
Fixed pre-existing SKILL_LABELS import error in rtime/mod.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a ✕ button next to the + tab button that closes all open rApp tabs
and returns to the user dashboard. Shows a confirm() prompt with tab count
before proceeding.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The collab overlay was running a 5s setInterval GC timer on every page
load even with zero peers. Now the timer starts only when the first
peer arrives and stops when all peers are garbage collected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HMAC-signed stateless tokens let external respondents vote on rChoices
polls or RSVP to rCal events via a single tap — no account required.
Routes mounted at /respond/:token bypass space auth. Typed EventAttendee
schema replaces unknown[] on CalendarEvent.attendees. Invite endpoints
on both modules generate tokens and optionally send email invitations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three client-side registration flows still had authenticatorAttachment: 'platform'
hardcoded, blocking Samsung Passkey and Linux users:
- lib/rspace-header.ts (main site header registration)
- shared/components/rstack-identity.ts (2 occurrences)
Also added server-side validation for missing userId in register/complete
to return 400 instead of crashing with TypeError.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts 4420d9c — the FAB change was applied to the wrong component.
The intended target is the rSpace canvas toolbar, not the app switcher.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Repositions the rApp switcher as a floating action button in the bottom-right
corner that expands upward into a rounded panel. Removes all sidebar push-offset
CSS since the panel now overlays content without layout shift.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pointerdown on document was hiding the dropdown before click could fire
on My Account / My Spaces / My Wallets buttons. Switching to click lets
stopPropagation in item handlers prevent premature close.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Audit and fix ~60 violations across 47 files where URLs were constructed
as /{space}/moduleId instead of /moduleId (subdomain provides the space).
- Add getModuleApiBase() helper to shared/url-helpers.ts
- Fix client components: use getModuleApiBase() for fetch URLs,
rspaceNavUrl() for navigation
- Fix server routes: use c.get("isSubdomain") for redirects and
JSON response URLs
- Fix OAuth callbacks (notion, google, clickup): subdomain-aware redirects
- Fix email notification URLs (rvote): use {space}.rspace.online format
- Fix webhook registration (rtasks/clickup): subdomain-aware endpoint URL
- Replace broken #getSpaceSlug() methods in folk-feed, folk-splat
- Replace NODE_ENV checks with proper isSubdomain checks (rdata, rnetwork)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add MoonPay as the primary card payment provider for rCart. MoonPay
uses HMAC-SHA256 signed URLs (no session API needed, no IP whitelisting).
Falls back to Transak if MoonPay keys aren't configured.
- shared/moonpay.ts: URL builder with HMAC signing, currency mapping
- New /api/payments/:id/card-session endpoint picks provider automatically
- Frontend uses unified startCardPayment() with multi-provider message handling
- Set MOONPAY_API_KEY + MOONPAY_SECRET_KEY to activate
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Production gateway rejects tokens from api.transak.com. Try getting
the access token from the gateway endpoint first (which staging
confirms works), then fall back to the legacy API endpoint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transak now requires widget URLs to be generated server-side via their
gateway session API. Direct query-parameter URLs are deprecated.
- Add getAccessToken() with 7-day caching for partner access tokens
- Add createSecureWidgetUrl() that calls the gateway session endpoint
- Falls back to legacy direct URL if gateway returns an error (e.g.
production IP not yet whitelisted)
- Update rCart and rFlows to use the secure API
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Space creation popup slug field now shows input followed by .rspace.online
suffix instead of rspace.online/ prefix. Also fixes rtasks notification
link and browser extension help text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Modules now declare their canvas shapes and AI tools (canvasShapes/canvasToolIds
on RSpaceModule), creating a single source of truth that the canvas enforces:
- Phase 1: Extended RSpaceModule + ModuleInfo, added moduleId to CanvasToolDefinition
with getToolsForModules() filter, added moduleOf() to ShapeRegistry, populated
declarations in 9 modules, fixed 8 ungated toolbar buttons (rchoices, rwallet, rsocials)
- Phase 2: AI prompt sends enabledModules, server filters Gemini tool declarations
- Phase 3: folk-commitment-pool and folk-task-request show lock overlay when rtime disabled
- Phase 4: Extracted MODULE_META into shared lib/module-display.ts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fire commitment_accepted/commitment_declined notifications when solver
results are accepted/rejected in intent-routes.ts
- Fire commitment_declined when a connection is deleted in mod.ts
- Add metadata (resultId, fromCommitmentId) to commitment_requested notify
- Fix actionUrl to use /rtime (subdomain-relative), not /{space}/rtime
- Add Accept/Decline action buttons in notification bell for
commitment_requested events (same pattern as space_invite)
- Add email delivery channel to notification-service: sends from
{space}-agent@rspace.online via SMTP, respects emailEnabled preference,
inline HTML template with dark theme
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add folk-mermaid-gen web component: AI-powered diagram generation via
Ollama, client-side SVG preview via mermaid.js, animated GIF export via
mermaid.rspace.online API
- Register in canvas tools, toolbar, and shape registry
- Add role selector dropdown to share panel invite form (backend already
supports role parameter)
- Fix pre-existing TS errors: SankeyNode missing address field,
SpaceMember type mismatch in WebSocket auth fallback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- App switcher: only show "Manage rApps" when there are actually
disabled modules or active restrictions. Move "Available to Add"
above "Remove" to prioritize adding. Eliminates duplicate module
listing when all modules are enabled.
- Shell: update app switcher on modules-changed event (was only
updating tab bar and folk-rapp, not the sidebar itself).
- SMTP: use space-agent@rspace.online as From for invite/approval
emails with proper envelope sender for DKIM alignment.
- Shell CSS: fix banner z-index, smooth header transition on banner.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remote cursors were broadcast as viewport-relative (clientX/Y), causing
them to appear at wrong positions when users had different scroll offsets.
Now sends page-relative coords and converts back on the receiver side.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Space switcher: clamp menu left to prevent right-edge overflow,
add max-width: calc(100vw - 8px), scrollable tabs with smaller
padding on mobile
- Auth/edit modals: add max-height: 90dvh + overflow-y: auto so
virtual keyboard doesn't push modal off-screen, reduce padding
on small screens
- Identity dropdown: raise z-index from 100 to 10002 so it renders
above the app-switcher sidebar (10001)
- Device nudge toast: constrain max-width to viewport width
- App switcher: add translucent backdrop overlay on mobile (<640px)
with tap-to-dismiss
- Add :active pseudo-class alongside :hover on interactive elements
for touch tap feedback
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Connections are per-user, not per-space. Move the platform connections
dashboard from the space settings modal (5th tab) to the My Account
modal as a collapsible section. Add selective sharing: users connect
platforms to their personal data store, then choose which community
spaces to share data into via per-provider space checkboxes.
New endpoints: GET/POST /api/oauth/sharing for per-user sharing config.
Sharing config stored as Automerge doc {userSpace}:oauth:sharing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New "Connections" tab in space settings with n8n-style visual dashboard
showing platform cards (Google, Notion, ClickUp live + 7 coming soon)
connected via SVG bezier lines to central rSpace hub node. Includes
OAuth connect/disconnect flows and GET /api/oauth/status endpoint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TabCache.init() wraps all #app children into a .rspace-tab-pane div,
breaking the flex layout introduced in 2cbff89. Make active panes flex
columns so subnav/tabbar/rapp-content flex properties are respected.
Wrap fragment-loaded content in .rapp-content for consistent scrolling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove rstack-space-settings slide-out panel. Enhance the existing tabbed
modal in rstack-space-switcher with add-member (username search + email
invite) and pending email invites (with revoke). Header gear now calls
openSettingsModal() on the space switcher instead of toggling the old panel.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>