Bare-domain rspace.online/{moduleId} now rewrites directly to demo
space instead of rendering marketing landing pages. Also removed
auto-show info panel on first visit — info panel now only opens
via the info button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
localStorage is per-subdomain so dismissing on demo.rspace.online didn't
persist to jeff.rspace.online. Now uses a .rspace.online cookie (10yr
max-age) so one dismiss covers all subdomains.
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>
Shell subnav now skips rendering when module has no outputPaths/subPageInfos
(rTime uses internal tab-bar). Mobile CSS tightened: smaller tabs, condensed
stats-bar, skill legend hidden on narrow screens.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Guard SW controllerchange to only reload on updates (not first install),
remove duplicate SW registration from canvas.html, skip async module
fetch when shell already provided data, hide module-gated toolbar items
by default via CSS. Also collapse toolbar on click-off.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
community-sync: remove DOM shapes that are deleted/forgotten from doc.
shell: treat user's saved tabs as authoritative over Automerge, pass
fromUserAction flag to reconcileRemoteLayers to allow intentional close-all.
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>
- 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>
Previously, visiting a private space on *.rspace.online without a session
redirected to rspace.online, causing a redirect loop after login. Now shows
the sign-in gate in-place so the user logs in and stays on the same page.
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>
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>
Adds a small bug icon (bottom-right) that opens a modal to collect
errors, device info, comments, and optional screenshots, then emails
the report to jeff@jeffemmett.com via the existing SMTP transport.
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>
- rCal landing: strip inline style overrides, use standard rl-* CSS classes
- rCal mod: update standaloneDomain from rcal.online to rspace.online
- Info popup: change from per-rApp auto-show to global one-time auto-show
- Update banner: track dismissal in sessionStorage so it stops re-showing
on every page load within the same session (likely the "persistent banner")
- rpubs landing: fix stale rcart.online URLs → demo.rspace.online/rcart
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a logged-in user visits a private space they don't have access to,
the gate now shows a "Request Access" button (calls POST /api/spaces/:slug/access-requests)
and a "Go to {username}'s Space" secondary link. Handles already-pending (409) gracefully.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Landing, module-landing, and sub-page-info pages showed a stale "Spaces"
dropdown. Now checks encryptid_session and sets the switcher to
{username}'s Space (logged in) or demo (logged out).
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>
- Add appinstalled event listener so browser-initiated installs also
permanently dismiss the banner
- Ensure only one banner shows at a time (update hides install first)
- Refactor dismiss logic into single helper function
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove duplicate purple update banner from website/shell.ts that overlapped
with the server/shell.ts banner. Now a single banner system:
- Browser: "Install rSpace app" prompt (via beforeinstallprompt)
- Installed PWA: "New version available" prompt (via SW update detection)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make #app a flex column with height:100vh so all rApps fill the viewport
exactly. Wrap module body in .rapp-content flex child. Replace all
hardcoded calc(100vh - Npx) with height:100% across 20+ components.
Remove sticky positioning from subnav/tabbar (now flex items).
Generalize mobile body-flex to all pages (not just canvas-layout).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Install banner appears above header when beforeinstallprompt fires
(dismissed state persisted in localStorage, never shows again)
- Update banner appears when a new SW version is detected waiting
(click "Update" → SKIP_WAITING message → SW activates → page reloads)
- SW no longer auto-skipWaiting on install; waits for client message
- Bumped SW cache version to v5 and registration to ?v=5
- Banner CSS: fixed at top, z-index above all chrome, slide-in animation
- Header/tab-row/app offsets adjust when banner visible
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The minimize toggle now lives at the right edge of each rApp's subnav
bar instead of the tab row. When minimized, both header and tab row
slide up and the subnav becomes a thin fixed strip with just the
restore chevron. Every rApp already has a subnav (except canvas which
has its own chrome).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port hcc-mem-staging SPA into rSpace as the rTime module. Canvas-based
commitment pool with physics orbs, SVG weaving editor with hex nodes
and bezier wires, execution panel, and optional Cyclos timebank proxy.
Automerge CRDT persistence, demo seeding, and full landing page
explaining community-based ledgers and emergent collaboration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a [^] chevron button at the right end of the tab row that collapses
all header bars into a thin 24px restore strip. State persists via
localStorage across page reloads. Works on both desktop (fixed) and
mobile (sticky) layouts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
- Add ?v=4 to all SW registration URLs to bypass stale CF CDN cache
- Set Cache-Control: no-cache for sw.js and manifest.json so future
SW updates are never blocked by CDN caching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract autoShowIfFirstVisit() so it runs both on initial page load
and on SPA tab switches. Uses localStorage rapp_info_seen_{moduleId}
to ensure each rApp's landing popup shows exactly once.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
- 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>
- Fix invite accept fetch URL in shell.ts (was missing /api/spaces prefix)
- After accepting invite, redirect to the invited space instead of reloading
- Notification actionUrls now point to the space subdomain (https://slug.rspace.online)
- Direct-add email includes inviter name, role, and space description
- Identity invite email includes space name/role context when inviting to a space
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Increase .rapp-subnav top from 92px to 93px so pill buttons
don't clip under the fixed header + tab-row border.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
- 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>
On subdomain routing (e.g. demo.rspace.online), the space slug belongs
only in the subdomain — never in the URL path. This fixes all server
and client code that was generating /{space}/module paths on subdomains.
Server fixes:
- index.ts: notification actionUrls, template/disabled-module redirects,
subdomain passthrough (now redirects HTML, rewrites API), WS notifications
- output-list.ts: subdomain-aware path prefix for hrefs and fetch URLs
- shell.ts: dashboard pushState URL
Client fixes (basePath getter pattern):
- folk-book-shelf.ts, folk-splat-viewer.ts: _basePath getter
- folk-campaign-wizard.ts: basePath subdomain check
- folk-trips-planner.ts: use __rspaceNavUrl for canvas export
- rschedule/landing.ts: onclick handlers use __rspaceNavUrl
- rsplat/mod.ts: legacy view redirect subdomain check
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
The access gate and space dashboard redirect scripts checked only
localStorage, which is per-origin. When navigating between subdomains
(e.g. demo → jeff), the session wasn't found. Now both scripts also
check the eid_token cross-subdomain cookie and sync it to localStorage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Non-demo space dashboards now redirect logged-out visitors to
rspace.online/ instead of showing another user's rApp grid. Private
space module pages redirect to rspace.online/{moduleId} instead of
showing the sign-in gate overlay.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Changed syncTabsFromServer to replace local tabs with server tabs
instead of merging (union). This prevents tabs closed in browser A
from being resurrected when browser B refreshes. Also added server
sync to the iframe module landing path which was localStorage-only.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
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>
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>
The rspace container cannot resolve encryptid-db hostname, causing
/api/notifications/count to 524 timeout on every 30s poll. Rewrites
notification-routes.ts as an HTTP proxy to encryptid (which has DB
access), adds notification API endpoints to encryptid server, and
wraps BroadcastChannel.postMessage in try/catch to prevent uncaught
errors during navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The single quote in "don't" broke the JS string literal inside the
inline script, causing a SyntaxError that killed the entire script
block including tab bar and header initialization.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server-side HTML gates can't work because auth tokens are in
localStorage, not cookies. Replaced with:
- Client-side gate checks session, then verifies membership via
new /api/space-access/:slug endpoint
- Shows "Sign In" for unauthenticated users
- Shows "no access + return to your space" for non-members
- Server-side gates remain for API/JSON requests and WebSocket
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Non-members of private spaces are now blocked at three layers:
- WebSocket upgrade rejects with 403
- Module middleware shows access denied page (browser) or JSON 403 (API)
- Space root dashboard shows access denied page
Friendly "Private Space" page with link back to user's own space.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both dropdown-wrap buttons now sit in header-left directly after the
space switcher, keeping space-related controls grouped together.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>