Add ExternalTimeLog schema and REST endpoints for ingesting time entries
from backlog-md CLI. Auto-creates commitments, links to existing tasks,
and supports solo settlement with reputation/skill curve updates.
New Fulfillment dashboard tab shows time logs, skill totals with progress
bars, and inline settle buttons. Export-to-backlog endpoint enables
importing rTime tasks into local backlog.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added hideExchangeScreen, isAutoFillUserData, and paymentMethod params
to both Transak endpoints. This skips the initial exchange screen (we
already provide all required fields) and auto-fills email for Lite KYC,
reducing friction for small transactions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SMTP auth on port 587 was broken across all modules due to stale
credentials. Since rspace is on the mailcow Docker network, all 6
SMTP transports now use unauthenticated relay on port 25 when the
host is the internal postfix container. Fixes emails for: payment
receipts, space invitations, inbox approvals, agent notifications,
scheduled emails, and publication sharing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SMTP auth credentials were stale, causing all payment confirmation
emails to silently fail. Since rspace is on the mailcow Docker network,
use unauthenticated relay on port 25 instead of port 587 with auth.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a payment request is in a terminal state (paid, confirmed, expired,
cancelled, filled), the /pay/:id route now renders a static HTML page
with a clear message instead of loading the full JS component. Prevents
"corrupted content error" and shows a friendly "already paid" message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Text inputs were rendering in light mode making text invisible against
the dark background. Added colorMode: 'DARK' to both Transak widget
endpoints.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When fiatAmount wasn't explicitly set on a payment request, Transak
defaulted to 300 USD. Now for USDC/USDT/DAI/cUSDC, the fiat amount
is inferred from the crypto amount (1:1 peg) so the widget opens with
the correct payment amount.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Orb radius now uses 8-15% of basket radius with sqrt(hours) scaling
instead of fixed pixel sizes (18+hours*9). Prevents orbs from being
oversized on small baskets or undersized on large ones. Hover expansion
also scales proportionally (15% instead of fixed 5px).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add touch-action:none on canvas and preventDefault on pointerdown to
prevent the browser from claiming touch events for scroll/pan gestures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The ascii-art service returns raw HTML, not JSON. Wrap response in
{html, text} JSON envelope and strip tags for plain text version.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add folk-ascii-gen canvas shape with pattern/palette selectors
- Add POST /api/ascii-gen proxy to ascii-art service
- Register create_ascii_art in canvas tools + triage panel
- Fix WAN 2.1 t2v endpoint URL (fal-ai/wan/v2.1 → fal-ai/wan-t2v)
- Convert video gen to async job queue (avoids Cloudflare timeouts)
- Fix Docker API Content-Type bug in sidecar-manager
- Convert scribus-novnc and open-notebook to on-demand sidecars
- Add ensureSidecar("scribus-novnc") to rDesign bridge proxy
- Fix Hono ContextVariableMap and handleTransakMessage type errors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When dragging a commitment to a task, hours are now split (min of
available, needed), the pool orb shrinks or disappears, and
connections track proposed/committed status with approve/decline UI.
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>
Empty compose env vars were blocking Infisical secret injection at startup.
Only TRANSAK_ENV needs to be in compose; API keys and secrets come from Infisical.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spaces are subdomains, not path segments. /rspace is correct since
the space context comes from the subdomain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Seeds demo spaces with a "Build a Climbing Wall" circuit (labor threshold +
capital threshold + proprietor signoff → project) and a "Community Potluck"
circuit (budget knob + RSVPs threshold + venue signoff → project), each
pre-wired with arrows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rich landing page with do-ocratic framing, SVG circuit diagram,
"GovMods" branding, modular governance vs monolithic comparison,
and onboarding action. Module now has landingPage function for
bare-domain rendering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 3-tab layout (Pool/Weave/Collaborate) with 2-tab Canvas + Collaborate.
Canvas tab has collapsible left pool panel with orbs alongside infinite SVG
canvas with pan/zoom (ctrl+wheel zoom, wheel pan, space+drag, touch pinch).
- Long-press orb in pool → drag onto canvas to create commitment node
- Drop on matching task port auto-creates wire connection
- Gold glow highlights unfulfilled task ports matching dragged skill
- "Frame as Tasks" button on solver results creates task nodes with
dashed intent frame on canvas
- Add intentFrameId to Task schema for solver-to-task linkage
- Zoom controls overlay (+/−/reset)
- Light/dark theme support for all new elements
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>
Hardcoded PRODUCTION overrode the Infisical value. Use env var with
STAGING default until Transak production gateway auth issue is resolved.
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>
Transak rejects `cryptoAmount` when combined with fiatCurrency params.
Use `defaultCryptoAmount` which pre-fills the amount without conflicting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The payment request form button was cut off on mobile because the shell
uses height:100vh with overflow:hidden on #app. Add padding-bottom to
the .page container so the button scrolls into view within the flex
overflow:auto content area.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SyncServer.setDoc() was not calling onDocChange, so documents created
via setDoc (including payment requests) were only stored in memory and
lost on container restart. This caused "Payment request not found"
errors after deploys. Now setDoc triggers the same persistence callback
as changeDoc.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Payment request URLs (e.g. /rcart/pay/:id) should be accessible without
authentication, even in private spaces. The API endpoints were already
exempted from auth, but the client-side shell gate was redirecting
unauthenticated visitors to the module landing page. Set
spaceVisibility="public" on the payment page render to bypass this.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transak production also sends X-Frame-Options: SAMEORIGIN, blocking
iframe embeds. Switch to popup window for all environments, not just
staging. Show "payment opened in new window" status with re-open button.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TRANSAK_ENV was set to PRODUCTION but TRANSAK_API_KEY_PRODUCTION was
missing, causing the Transak session endpoint to return 503. Add the
env var reference so rCart card payments work in production.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use `user-${email}` instead of raw `email` as the Openfort player label,
matching the flow-service convention. Openfort rejects colons in labels,
and both codepaths must use the same format so users get the same wallet
regardless of whether they on-ramp via rfunds.online or rspace.online.
Co-Authored-By: Claude Opus 4.6 (1M context) <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>
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>
Enable pasting structured shape data from tldraw, Excalidraw, and generic
JSON into the rSpace canvas, with automatic type conversion and viewport
centering. Ctrl+C on selected shapes writes rSpace JSON to clipboard for
round-trip paste or external consumption.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Connection & exec state persistence (POST /api/connections, PUT exec-state)
- Exec step detail forms for all 5 types (venue, comms, notes, prep, launch)
- Step state machine fix: click to expand/collapse, action button to complete
- Task editor links field with dynamic add/remove and server persistence
- Cyclos-aware launch handler with fallback to demo celebration
- Fix dead EXEC_STEPS[taskId] lookup, auto-place first task on empty canvas
- DID display truncation for unreadable DIDs in intent routes
- Dark/light theme toggle with localStorage persistence
- Hex hover stroke, commitment description in hex nodes, edit pencil on tasks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin encrypted backups and AI-generated files to Kubo (ipfs.jeffemmett.com)
as fire-and-forget redundancy. Filesystem remains primary storage — IPFS
failures are logged and swallowed. Adds /api/ipfs routes for status,
pin/unpin, and gateway proxy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ImapFlow clients were created without .on('error') handlers. Socket
timeouts emitted unhandled errors that crashed the entire process,
taking down all 32 modules. Added error handlers to all 3 ImapFlow
instantiation sites and a process-level uncaughtException/unhandledRejection
safety net.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Dockerfile's healthcheck hit a nonexistent /health endpoint, causing
permanent "unhealthy" status. Override with a check that accepts any HTTP
response (including 401) as proof the service is running.
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>