Unify space invite emails across three code paths (new-user identity
invite, existing-user invite, add-by-username, plus notification-service
fallback). Template mentions the space name + rSpace, lists shared
collaboration tools, and shows a large gradient CTA button. Pass
spaceName through from server/spaces.ts so the display uses the
friendly name (e.g. "Crypto Commons") instead of the slug.
Also fix a bug in notification-service where actionUrl starting with
http would be double-prefixed with https://{slug}.rspace.online.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fal.ai was returning "invalid images found in the input, failed to
read/process" because it couldn't reliably fetch the staged image URL
through Cloudflare/Traefik. Encode the resized JPEG inline so the fetch
stays inside the fal.ai request and doesn't depend on our origin being
reachable from their crawler.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- rsocials: collapse dead "posts" outputPath into "threads" entry (💬 Posts)
so the sub-nav shows one button linking to the thread gallery + builder
- spaces GET /:slug/modules: redact settingsSchema fields of type 'password'
to '********' for non-owner callers; PATCH preserves existing password
when the sentinel is sent back unchanged
Closes the leak where unauth'd GET returned Listmonk/Postiz credentials in plaintext.
- rApp dropdown no longer shows a "Manage rApps" panel for disabled modules.
Enable/disable lives in Edit Space → Modules only.
- /api/internal/user-email/:userId now resolves by id OR did (real did🔑z6Mk…
or legacy synthetic did🔑<32-char id prefix>), so Edit Space members list
shows display names instead of raw DIDs.
- /api/spaces/:slug/invites admin check now accepts ownerDID stored as either
raw userId or did🔑. Routes the list through a new internal endpoint on
encryptid so Automerge-owned spaces without a space_members row still work.
- /join page registration payload was missing userId, causing every invite
claim to fail with "Missing required fields: userId, credential, username".
Same fix applied to the OIDC accept page flow.
Space-agent and mailbox emails set From to {slug}-agent@rspace.online but
the envelope MAIL FROM was noreply@rmail.online. Rspamd DKIM-signs with
the envelope domain (rmail.online), which fails DMARC alignment against
the rspace.online From header — Gmail was quarantining invites.
Set envelope.from to match the From header so rspamd signs with
rspace.online's DKIM key and SPF/DKIM align. Verified via test send:
DKIM_SIGNED{rspace.online:s=dkim}, FROM_EQ_ENVFROM, no DMARC:Quarantine.
Covers: space invite emails (identity + existing-user paths), agent
notifications, rinbox MI agent blasts, mailbox approval sends.
Replaces the custom Docker Engine API implementation in sidecar-manager.ts
with HTTP calls to Sablier's blocking strategy endpoint. Sablier owns the
Docker socket, handles start + readiness + session-TTL idle stop.
- Drops ~80 lines of Docker API plumbing and the idle-watcher interval
- Public API (ensureSidecar/markSidecarUsed/isSidecarRunning/startIdleWatcher)
unchanged — callers in server/index.ts untouched
- SABLIER_URL defaults to http://sablier:10000 (reachable once sablier is
attached to rspace-online_rspace-internal; dev-ops change separate)
- SIDECAR_SESSION_DURATION env (default 5m) matches previous idle timeout
- Graceful no-op when Sablier unreachable (local dev)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Complete the rename started in dda7760 (which removed rschedule/ but
left callers unmigrated and the rminders/ dir uncommitted). Updates
vite.config.ts build entries, API base fetches in folk-comment-pin,
folk-rapp widget map, module-display meta, calendar reminder-drop
route, docs comment-panel, e2e fixtures, shell/landing/mcp-server
references, and backlog/ONTOLOGY docs.
Fixes vite build failure: "Could not resolve entry module
modules/rschedule/components/folk-schedule-app.ts".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous limits (avg 120/min, burst 30) had no sourceCriterion. Traefik
default groups by request Host, so ALL users of rspace.online shared a
single 120/min bucket — tripped almost immediately under normal load
(repeated 429s in rpast, api/mi/models, etc).
Scope per Cloudflare client IP (CF-Connecting-IP header) and raise to
600/min average with 150 burst — interactive use can spike above 120/min
from one client easily (module loads + polling + autosave).
Adds e2e/tests/rsocials-campaign-flow.spec.ts — 13 tests covering the
unified campaign flow UX: dashboard → planner navigation, brief canvas
node (+ preview banner), markdown import modal, wizard handoff, and
API shape. 36 passed / 3 AI-skipped across chromium/firefox/mobile.
Bug fixes uncovered by the suite:
- markDownstreamStale only redraws when a node actually flips stale,
so typing in an input node no longer destroys the open inline-edit
overlay.
- executeSave wraps the local-first write in try/catch and nulls the
client on failure, so a half-initialised client (WS down, IDB
unavailable) falls through to localStorage instead of throwing
"Document not open".
- init-failure path also nulls the client so the first save after a
failed subscribe doesn't hit a doc that was never opened.
Test infra:
- server/security.ts + server/index.ts honour DISABLE_RATE_LIMIT=1
(and NODE_ENV=test) to bypass HTTP rate limiter and anon WS-per-IP
cap so the suite can run under 8 parallel workers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GET /api/spaces/:slug/members now enriches entries missing displayName
by looking up the username from EncryptID (/api/internal/user-email).
Old member records (particularly owners created before displayName was
passed to setMember) were showing as 'jAV6y4tg8UbKJEkN0npv...' in the
space settings Members tab.
- New rpast module renders a cross-rApp personal timeline
- shared/markwhen/ projection layer hydrates from syncServer docs
- rCal gets a Timeline applet wiring into the same markwhen view
- rstack-markwhen-view component for embedding elsewhere
- Smoke-test fixtures under output/ and scripts/smoke-rpast.ts
- Adds @markwhen/{parser,timeline,calendar,mw} deps
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stale cached HTML fragments referenced old asset hashes (e.g. 404 on
canvas-PlYnCtxh.js while server has canvas-R4rXE5Sc.js) after frequent
rebuilds. Bumping CACHE_VERSION and the SW registration query string
forces the new SW to install and purge all old versioned caches on
activate.
Prior voice-mode prompt leaned too far into caveman/telegraphic speech
('drop articles'). User wants brevity with proper grammar — short
complete sentences, not neanderthal fragments.
- Default voice en-US-AvaMultilingualNeural -> en-US-AndrewMultilingualNeural
(smoother, less feminine timbre).
- Volume 0.55 -> 0.3, rate -8% -> -10%, pitch -2Hz -> -6Hz.
- Browser fallback matches: pitch 0.85, volume 0.3.
- Client passes voiceMode flag to /api/mi/ask; server appends a VOICE
MODE section to the system prompt demanding ≤1-2 short sentences,
no lists/markdown/emoji/preamble — because listening to long replies
is tedious.
- Add saveDocImmediate() for synchronous awaitable saves (no debounce)
- Add SyncServer.flushAll() to iterate all in-memory docs
- Fix eviction race: onDocEvict now uses saveDocImmediate instead of
debounced saveDoc (which could fire after doc deleted from memory)
- Add SIGTERM/SIGINT handlers with 10s timeout safety net
- Add visibilitychange flush on client (reliable on mobile/bfcache)
- Flush pending IDB saves in DocSyncManager.disconnect()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Filter restored tabs against valid moduleIds from moduleList, deduplicate
on every restore path (localStorage, server sync, BroadcastChannel).
Add closed-module tracking to renderExternalAppShell to prevent server
sync from resurrecting tabs closed in the current session.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add app.notFound() handler with themed 404 page instead of Hono's
plain "404 Not Found". Restrict canvas.html SPA fallback to /rspace
sub-paths only — was serving index.html for all unmatched routes,
causing stale "Activated" page to appear on navigation errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reduce tabs to Members (default), Trust, CRM
- Remove empty outputPaths (Connections, Groups placeholders)
- Hide subnav when tabbar is present (avoid double menu)
- CRM tab redirects to the CRM sub-app
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard was empty because folk-cred-dashboard.ts had no Vite build
entry — the JS never got compiled. Add build step to vite.config.ts,
fix script src to /dist/modules/rcred/folk-cred-dashboard.js, and
darken badge background from #fbbf24 to #d97706 so it doesn't blend
with the ⭐ emoji.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
rcred.rspace.online was being treated as a space slug, triggering
auto-provision + redirect to /rspace. Now any subdomain matching a
known module ID (rcred, rvote, etc.) redirects to demo.rspace.online/{moduleId}.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Demo space now seeds a clean welcome card explaining rSpace plus organized
feature cards for all 32+ rApps grouped by category, instead of 75 random
scenario objects.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Send branded welcome email when user first adds profileEmail
- Reframe landing page around group coordination, not app listing
- Wordmark: orange r + teal Space matching favicon branding
- (you)rSpace wordplay in tagline, final CTA, meta tags, email
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
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>
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>
Jitsi's built-in meetingintelligence toolbar button hit their paid API
(404). Replaced with customToolbarButtons entry that opens our own MI
page. Also serve favicon.png for /favicon.ico requests (was 503).
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>
rTime now pulls tasks from rTasks boards instead of maintaining its own
Task type. New WeavingDoc stores canvas overlay data (needs, position,
notes, links) while rTasks BoardDoc remains source of truth for task
metadata. 6 new /api/weave routes, updated connections/exec-state to
WeavingDoc, compat shims on legacy endpoints, task picker for unplaced
rTasks items, MCP tools updated (rtime_list_woven_tasks, rtime_place_task),
migration script for existing data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix 401 errors on rNetwork by passing encryptid-token as Bearer auth
on /api/info, /api/graph, /api/workspaces fetch calls
- Add blender-multiuser replication server (multi-user-server:0.5.8)
to docker-compose with health check and resource limits
- Add Multiplayer tab to folk-blender shape with connection info,
server status check, and setup instructions
- Add /api/blender-multiuser/status endpoint for TCP health probe
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Restrict CORS to known rSpace domains (no more open wildcard)
- Add tiered rate limiting per IP (anon vs authenticated, per endpoint tier)
- UA filtering blocks scrapers/scanners, allows browsers and AI agents
- Prompt injection sanitization: strip MI_ACTION markers, system tags, and
known attack patterns from user-supplied content before LLM ingestion
- Space access control: private/permissioned spaces gate MI data to members
- Auth required on /triage, /execute-server-action, data-driven /suggestions
- MCP guard: require auth or agent UA for /api/mcp/*
- Anonymous WebSocket cap: max 3 per IP with proper cleanup on close
- Knowledge index + conversation memory gated to members+ (viewers get
public canvas data only)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Office documents dropped onto canvas or imported via rDocs are now converted
to Markdown using Microsoft's markitdown CLI. Canvas drops trigger triage;
rDocs imports create rich notes with the original file kept as an attachment.
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>
Replace the 265-line data dump (35 modules × 3 items) in MI system prompts
with a trigram-ranked knowledge index that surfaces only the top-18 most
relevant entries per query. Adds per-space conversation memory persisted
to disk for cross-session context.
New files:
- server/mi-trigrams.ts — trigram + Jaccard similarity utilities
- server/space-knowledge.ts — SpaceKnowledgeIndex with 5-min TTL cache
- server/space-memory.ts — SpaceMemory with debounced disk persistence
Changes:
- mi-routes.ts: ~280 lines removed, replaced with ranked index call
- sync-instance.ts: cache invalidation on doc changes
- rauctions/mod.ts: fix ModuleScoping type (defaultScope, userConfigurable)
- mcp-tools/ragents.ts: fix AccessResult property access (claims.username, claims.sub)
~80% token reduction per MI request (~6,300 → ~1,320 tokens).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use the status_url returned by fal.ai submit instead of constructing
it manually. Add logging for submit success and poll HTTP errors to
debug Seedance queue status polling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moltbook-inspired agent exchange where members' MI agents can:
- Register with name, capabilities, and avatar per space
- Post to topic-based channels (general, packages, custom)
- Reply in threaded discussions
- Share structured JSON data packages alongside posts
- Upvote/downvote to surface the best contributions
Includes Automerge CRDT schemas, 9 REST API endpoints,
6 MCP tools, MI data query integration, and landing page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove erroneous fal-ai/ prefix for bytedance models and fix fast
variant path (seedance-2.0/fast/ not seedance-2.0-fast/).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Seedance 2.0 / 2.0 Fast to video gen with model selector UI,
duration/resolution/aspect-ratio/audio controls. Fix broken port
outputs on both video-gen and image-gen shapes so arrow connections
propagate generated content to downstream shapes. Add input port
listeners for prompt and image data flow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The auth proxy only covered /api/auth/*, /api/register/*, /api/account/*
but the identity component also calls /api/session/verify, /api/session/refresh,
/api/guardians, /api/user/*, /api/device-link/*, /api/recovery/* — all of which
were hitting 404 on the rspace server. The session verify 404 was interpreted
as "session revoked", clearing localStorage and logging users out on every page
load after the 5-minute validation interval.
Also fix profile/recovery links in header that opened empty string (same-origin
root) instead of auth.rspace.online.
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>