The rspace module's outputPaths caused renderModuleSubNav to render an
unwanted "rspace | Canvases" bar across the canvas. Skip subnav for the
root rspace module since the canvas has its own chrome.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix z-index (9000 → 10001) so popup renders above header and tab bar
- Center popup as a proper modal with blurred backdrop overlay
- Header now shows module emoji icon + name (fetched from API)
- Bigger, bolder CTA buttons with gradient fills and hover effects
- Tour/guide links auto-promoted to prominent purple-accent buttons
- Loading spinner animation, Escape key to dismiss, click-outside-to-close
- Mobile: slides up from bottom instead of top-right corner
- Also: rcart/rwallet subnav route support, rcart tour simplification
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
Subnav and tabbar were rendered outside <main id="app">, causing them
to be hidden behind the fixed header. Move them inside <main>, add
sticky positioning (top: 92px), and consolidate pill CSS into a shared
.rapp-nav-pill class. Also refactors tabbar to use URL subpaths instead
of ?tab= query params.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The directory API only returns space members, and jeff isn't in demo space.
Hardcode the known DID with SEED_JEFF_DID env var override support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rspace container doesn't have DATABASE_URL for the encryptid DB.
Use the /api/users/directory endpoint via HTTP to resolve jeff's DID,
with retry-on-restart if encryptid isn't reachable yet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces CRDT-native token infrastructure stored as Automerge documents.
Seeds 5 cUSDC to user jeff on startup. Adds token API routes and a
"Local Tokens" section in the rWallet viewer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-rendered tab bar via renderShell tabs option. Tabs use ?tab= query
params with history.replaceState and dispatch rapp-tab-change events.
Migrated rNetwork CRM from internal Shadow DOM tabs to the shared system.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
Person-to-person delegation within spaces across 5 authority verticals
(voting, moderation, curation, treasury, membership). Trust engine
recomputes scores every 5 min with time decay, transitive BFS, and
50% per-hop discount. Graph viewer shows trust-weighted node sizing
with authority selector. New Delegations tab in CRM with management
UI and Sankey flow visualization.
Schema: delegations, trust_events, trust_scores tables
API: delegation CRUD, trust scores, events, user directory
Frontend: folk-delegation-manager, folk-trust-sankey, graph trust mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Add card background, glow effect, and contextual hint explaining
the empty state. Rename "Get Started" to "Load Sample Data" with
+ icon for clarity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When accessing demo.rspace.online/demo/rcart/pay/123, the subdomain
router was prepending the space again, creating /demo/demo/rcart/pay/123
which returned 404. Now detects when first path segment matches the
subdomain and passes through without double-prefixing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add og:title, og:description, og:image, twitter:card meta tags to landing page
- Add default OG tags to renderShell for all module pages
- Generate 1024x576 OG banner image via fal.ai Flux Pro (dark indigo + network pattern)
- Update meta description: "rSpace is a local-first platform where communities own their tools, data, and governance"
- Update page title to "rSpace — Own Your Community Infrastructure"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-side SystemClock broadcasts tick/5min/hourly/daily events via
WebSocket to all connected clients. Events are ephemeral (not persisted
in CRDT). Client-side fallback clock activates when server connection
is lost.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace TBFF preset with 19-node BCRG Community Flow (2 sources →
central funnel → 5 person funnels → 11 outcomes). Seed matching
BCRG Outcomes board in rTasks (4 DONE, 5 IN_PROGRESS, 2 TODO).
Add SyncServer.registerWatcher() for cross-module doc change hooks.
When an rFlows outcome is marked "completed", auto-create a DONE task
in rTasks with ref:rflows:outcome:{id} deduplication.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fake demo data with real HuggingFace CDN Gaussian splats (train,
truck, garden) that open in an inline 3D viewer without server round-trips.
Add "Generate from Image" tab that sends images to fal.ai Trellis for
AI-powered 3D model generation. Add gallery header and progress UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add shared ViewHistory<V> utility class that provides a proper navigation
stack for rApps with hierarchical views. Replaces hardcoded data-back
targets with stack-based back navigation across 10 rApps: rtrips, rmaps,
rtasks, rforum, rphotos, rvote, rnotes, rinbox, rschedule, rcart.
Rename rWork module to rTasks — directory, component (folk-tasks-board),
CSS, exports, domains, and all cross-module references updated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Slot the rApp info button into the tab-bar's tab-actions area so it
appears immediately left of the view-toggle (layer icon) instead of
after it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The external app iframe was missing media permissions in its allow
attribute, preventing Jitsi from accessing camera/microphone/screen
when embedded in rMeets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Personal space (slug=username) forced to private so it doesn't appear
as both public and private. Dropdown now groups spaces: Private (red)
at top, Permissioned (yellow) middle, Public (green) bottom.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix tab duplication by syncing tabBar state after layer-add, deduplicating
Automerge layers, and syncing app-switcher tabs to CommunitySync. Add info
icon popover that lazy-loads module landing page content with auto-show on
first visit. Add 5-step guided tour for rFlows with spotlight overlay,
auto-advance on click, and toolbar restart button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add <rstack-module-setup> component for inline module configuration
(replaces static "Not Configured" instructions). Enhance settings
gear panel to show the current module's settingsSchema at the top.
Pass module-id through shell rendering and tab-cache switching.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Notification routes: wrap GET / and GET /count in try-catch, return
graceful fallbacks instead of 500s when DB table is missing/unavailable
- getUnreadCount: add null safety (row?.count ?? 0) and catch DB errors
- Service worker: add .catch(() => {}) to all cache.put() calls to
suppress NetworkError on quota-exceeded or corrupted cache entries
- On-ramp error display: coerce err.error to string so alerts show the
actual message instead of [object Object]
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline SVG emoji (🌌) favicons with /favicon.png in all four
shell renderers and both landing page renderers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the last tab is closed, a dashboard appears showing the user's
spaces (sorted by most recent visit), notifications, and quick actions.
Clicking any item creates a new tab and hides the dashboard. Browser
back/forward handles dashboard state correctly.
Also adds proper cache headers for HTML and Vite-hashed assets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds rMeets module with hub page (Quick Meet, Join Room, Jitsi Lobby)
and room pages that embed jeffsi.localvibe.live via renderExternalAppShell.
Jitsi URL configurable via JITSI_URL env var.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The main server's Related Origins list was stale — it listed 5 generic
r*.online domains instead of the priority domains where passkey ceremonies
actually happen. This caused p2pf socials (socials.p2pfoundation.net) and
other external domains to fail WebAuthn authentication because browsers
couldn't verify them as related origins for RP ID rspace.online.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move settings gear to header right (next to identity) on all pages.
Add history clock button in header left that opens a new slide-out
history panel with Activity feed and Time Machine tabs. Embed author
identity (DID, username, timestamp) in Automerge change messages via
JSON envelope, with backward-compatible parsing for old plain strings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1 — Fix scope system: new scope-resolver.ts resolves global vs
space-scoped docId prefixes. Server middleware sets effectiveSpace on
Hono context. All 18 modules updated to use dataSpace for Automerge
doc access while keeping space for display. Client runtime gets
setModuleScopes() and resolveDocSpace() for local-first scope
resolution.
Phase 2 — Seamless cross-space navigation: TabCache now tracks panes
per space:module key. OfflineRuntime maintains lazy WebSocket
connections per space. Space-switcher dispatches space-switch event
handled client-side with history.pushState instead of full reload.
Phase 3 — Spaces as layers: Layer type extended with spaceSlug and
spaceRole. Tab bar gains "Add Space Layer" picker. Canvas renders
cross-space shapes with visual indicators. Space layers persisted as
SpaceRefs via nesting API. Runtime provides getAllActiveSpaces() and
subscribeModuleAcrossSpaces() for module-level data aggregation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New folk-image-studio canvas shape with multi-image style analysis
(Gemini vision), img2img via fal.ai FLUX and Gemini Nano Banana models,
and image attachment support in folk-prompt chat.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the title input and header image upload/generate section from
the thread builder editor. Title is now auto-derived from first tweet.
Add link preview cards that render inline in tweet content, similar to
Twitter's URL card unfurling. Server-side /api/link-preview endpoint
fetches OG metadata (title, description, image) with caching.
URLs in tweet text are rendered as clickable links.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass /data/ paths through subdomain routing without rewriting so
generated image files are accessible on *.rspace.online subdomains.
Move image upload/generate section above the compose textarea in the
thread builder editor layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build generates SHA-256 content hashes per asset file and appends
?v=<hash> to all module/shell URLs in rendered HTML automatically.
Eliminates manual ?v=N bumping in mod.ts files. Versioned assets
get Cache-Control: immutable headers, and the service worker cleans
stale entries on activation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a "dump & layout" feature where users can paste or drag-drop unstructured
content onto the canvas and have Gemini 2.5 Flash analyze it, classify each piece
into the appropriate folk-* shape type, and propose a multi-shape layout with
semantic connections.
- POST /api/mi/triage endpoint with structured JSON output from Gemini
- TriageManager orchestrator (analyze, removeShape, commitAll via MiActionExecutor)
- MiTriagePanel floating preview UI with shape cards, connections, Create All/Cancel
- Canvas drag/drop overlay + paste handler integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Placeholder modules not yet built out as full rApps. Removes them
from the dropdown/tab bar until they have proper schemas, components,
and local-first support.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The tab bar was setting its `active` attribute synchronously on click,
before TabCache.switchTo() finished fetching and injecting the new pane.
This caused a visual desync where the tab highlighted immediately but
the content area showed a blank flash or stale content.
Now the tab bar dispatches the layer-switch event without changing its
own active state. The shell event handler sets active only after
switchTo() confirms the pane is ready, eliminating the race condition.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add shared RSpaceOfflineRuntime singleton that coordinates IndexedDB
persistence (EncryptedDocStore), WebSocket sync (DocSyncManager), and
in-memory Automerge docs (DocumentManager) for all module web components.
- Phase 0: runtime.ts singleton, shell integration, beforeunload flush
- Phase 1: rstack-offline-indicator status dot in shell header
- Phase 2: service worker stale-while-revalidate for API GETs + offline fallback
- Phase 3: storage-quota.ts with LRU eviction (30d) and quota warnings (70%)
- Phase 4: Tier 1 single-doc modules (rFlows, rCal, rBooks, rSplat)
- Phase 5: Tier 2 multi-doc modules (rNotes, rWork, rInbox, rVote, rTrips, rFiles)
with doc-list-request/response wire protocol for document discovery
- Phase 6: Tier 3 special cases (rCart hybrid, rForum global doc, rSchedule)
Data now loads instantly from IndexedDB, syncs via WebSocket when online,
and remains browsable offline. rNotes migrated from inline Automerge WS
to shared runtime. All modules fall back to REST when runtime unavailable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Logged-in users visiting demo.rspace.online were auto-redirected to
their personal space on page load. Now only provisions the space
silently without redirecting. Also removes the redundant "Public
spaces" section from the dropdown and filters the /api/spaces endpoint
to only return demo, user's own spaces, and permissioned spaces.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The active tab was stored in Automerge's shared doc (activeLayerId),
causing different browser windows/sessions to fight over which tab
is highlighted. When one window switched to rInbox, another window
showing rFlows would have its tab bar update to highlight rInbox
while still displaying rFlows content.
Changes:
- Active tab is now always determined locally by the URL/currentModuleId
- Automerge sync only manages the tab LIST (which modules are open)
and flows, not which tab is active
- Removed sync.setActiveLayer() calls on tab switch
- Removed activeLayerId reads from Automerge on connect and on
remote change events
- TabCache continues to manage active state correctly when switching
tabs within the same page load
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove overflow:hidden from header__left on mobile (was clipping
app-switcher and space-switcher triggers)
- Add white-space/overflow/text-overflow to both trigger buttons so
they truncate gracefully on narrow screens
- Add <rstack-space-switcher> to module landing and sub-page info
shells so the spaces dropdown always appears next to the rApps dropdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Bare-domain URLs like rspace.online/rsocials/thread now render an info
page with CTAs instead of silently serving the functional app. The
functional app only appears inside a {space} context (e.g.
demo.rspace.online/rsocials/thread). API routes still pass through.
- Add SubPageInfo interface to shared/module.ts
- Add renderSubPageInfo() renderer to server/shell.ts
- Modify bare-domain routing: api/ passthrough → info page → demo fallback
- Add subPageInfos to 8 modules (rsocials, rflows, rnetwork, rtrips,
rbooks, rphotos, rinbox, rsplat)
- Add window.__rspaceSaveGate() auth prompt on write operations
- Wire save-gate into rsocials Thread Builder save handler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>