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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
Move <rstack-space-settings> outside the header element so its position:fixed
is relative to the viewport instead of the 56px header (backdrop-filter creates
a containing block for fixed descendants). Bump panel z-index above all canvas
elements. Also migrate hardcoded colors to CSS theme variables across shell
components.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update remaining references from legacy 4-value visibility model
(public/public_read/authenticated/members_only) to simplified 3-value
model (public/permissioned/private) in rInbox, rVote, identity component,
admin panel, and create-space page. Add tab trackRecent calls in shell.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pre-populated 4-node workflow template (trigger→action→condition→output) with blue arrows
- Add folk-choice-vote, folk-choice-rank, folk-choice-spider component libraries
- New rstack-space-settings component
- EncryptID encrypted vault schema and server endpoints
- Space management and community store enhancements
- Shell, landing, and module CSS refinements
- Tab bar, app switcher, identity, and MI component updates
- rNotes app improvements
- rFunds diagram adjustments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Blocking <head> script restores canvas-theme from localStorage
with prefers-color-scheme fallback (no FOUC)
- New theme.css with CSS custom properties for dark/light
- Removed data-theme from body/header/tab-row (now on <html>)
- Theme toggle writes to documentElement instead of body
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore canvas-theme from localStorage on page load with a blocking
script before first paint (body) and a fixup for header/tab-row.
Applied to all three shell renderers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Logged-in users visiting demo.rspace.online were auto-redirected to
their personal subdomain. Remove this redirect so the demo stays
accessible regardless of auth state.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 5 — EncryptID → DocCrypto bridge:
- Add EncryptedDocBridge connecting WebAuthn PRF to document encryption
- Add per-doc relay mode to SyncServer (encrypted spaces bypass participant mode)
- Wire encryption toggle to syncServer.setRelayOnly() on PATCH /:slug/encryption
- Restore relay mode for encrypted spaces on server startup
- Initialize DocBridge from PRF on login, clear on sign-out (both login-button + identity)
- Use bridge helpers for encrypted backup toggle in My Account
Phase 6 — Space scoping UI:
- Add "Modules" tab to Edit Space modal (enable/disable modules, scope toggles, encryption)
- Auto-filter app switcher by space's enabledModules via renderShell()
- Show "G" badge on global-scoped modules in app switcher
- Show lock icon in header for encrypted spaces
- Add getSpaceShellMeta() helper for auto-populating shell options
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- App-switcher now dispatches module-select event instead of full page navigation
for same-origin links; shell routes through TabCache for instant tab switching
- Tab pane gets height:100% in canvas-layout mode so #canvas fills the viewport
(fixes pan/zoom not working on empty canvas background)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When loading the rspace canvas directly (not via tab navigation),
#app lacked the canvas-layout class. Without it, #canvas collapses
to 0 height and pointer events for panning miss the canvas element.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Demo pages now render the same clean shell as regular spaces — just the
<folk-*> component full-page, no marketing wrapper (hero, feature cards,
CTA). Descriptions belong on landing pages, not demos.
- Remove demo branch from 7 module route handlers (rcal, rcart, rfunds,
rnotes, rtrips, rtube, rvote)
- Delete 7 demo.ts files (~1200 lines of dead markup)
- Remove renderDemoShell() and DEMO_PAGE_CSS from server/shell.ts
- Remove demoPage field from RSpaceModule interface
- Rename top rApp dropdown item from "rSpace" to "rStack"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-side middleware creates the user's personal space when they visit
{username}.rspace.online for the first time (token in cookie, verified once).
Client-side redirect sends logged-in demo users to their personal space.
"Try Demo" button sets a sessionStorage flag to bypass the redirect.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The header demo button is now hidden via data-hide when the user has
an active EncryptID session. Reacts to auth-change events so it
appears on logout and disappears on login without page reload.
Landing page hero CTAs already swap to "Go to My Space" when logged in.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Email forwarding (EncryptID):
- New mailcow.ts API client for alias CRUD via Mailcow REST API
- Schema: email_forward_enabled + email_forward_mailcow_id columns
- API endpoints: GET/POST email-forward status, enable, disable
- Profile email change hook updates/disables alias automatically
- Docker: rmail-mailcow network + MAILCOW_API_URL/KEY env vars
Private spaces:
- Access gate overlay blocks members_only spaces for unauthenticated users
- Space visibility injected into HTML via middleware
- Auto-provision creates spaces as members_only by default
- Personalized "Create {username}'s Space" CTA in space switcher
- Removed unused /notifications endpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All 22 module directories under modules/ now match their module IDs
(e.g. modules/cart → modules/rcart, modules/canvas → modules/rspace).
Updated all import paths, vite build config, HTML template asset refs,
docker-compose standalone commands, and .gitignore accordingly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously loaded tabs stay in the DOM and are shown/hidden via CSS.
New tabs are fetched via fetch() + DOMParser on first visit, then
cached. Switching back is instant with no network request.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dropdown menus in app-switcher and space-switcher were clipped by
overflow:hidden on .rstack-header__left (mobile). Changed from
position:absolute to position:fixed with dynamic getBoundingClientRect
positioning. Bumped shell asset versions to v=5 to bypass CF cache.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ?view=app iframe integration for 4 existing modules (rNetwork→Twenty CRM,
rSocials→Postiz, rForum→Discourse, rFiles→Seafile) and 2 new modules
(rDocs→Docmost, rDesign→Affine). Each module shows its demo view by default
with an "Open Full App" button to switch to the iframe-embedded external app.
Also includes: splat demo data seeding, MI search bar mobile layout fix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On screens <= 640px, the header wraps to two rows: logo/app-switcher
and identity on top, "Ask Mi Anything" search bar full-width below.
Header and tab row switch from fixed to sticky positioning on mobile,
eliminating the need for magic padding-top values on #app.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shell CSS: add body background (#0f172a) so all module pages have the
dark theme instead of transparent/white on mobile. Add mobile media
queries for #app padding and nav wrapping.
Calendar: add day-detail panel that opens on tap (crucial for mobile
where event labels are hidden). Improve touch targets, add source
badges in event modal, shorter weekday headers for narrow screens.
Cache-bust shell.css, cal JS, and swag JS via ?v=2 query params to
bypass Cloudflare edge cache.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the 177KB static Next.js landing with a server-rendered page using
the same shell, theme, and rl-* CSS utilities as all module landings. Fixes
the 354KB logo.png → 1.6KB favicon.png glitch across all pages. Dynamic
ecosystem grid is always in sync with registered modules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>