Earlier version only skipped when postizPostId was set. If a send attempt
failed (no postizPostId but postizStatus='failed'), the sweep retried every
60s and hammered Postiz's throttler. Retries now require the user to clear
postizStatus — same gate as a fresh node.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Postiz's /public/v1/posts expects a nested envelope:
{ type, date, shortLink, tags, posts: [{ integration:{id}, value:[{content}], settings:{__type} }] }
The earlier shim's flat {content, integrationIds, type, scheduledAt} was
rejected with "All posts must have an integration id" (the field is named
integration, not integrationIds; it's a nested object, not an array of strings).
Also: Postiz treats PostItem.value[] as thread segments, so createThread now
sends ONE request with multiple value entries rather than N grouped posts.
Callers now pass full {id, identifier} tuples so settings.__type is set
correctly (otherwise Postiz can't route to the provider handler).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Postiz's Nest backend expects Authorization: <apiKey> (no "Bearer"
prefix) and the public API is reverse-proxied at
<hostname>/api/public/v1/*. Our client was hitting /public/v1/*
directly and using Bearer, which 401'd.
Tolerate both config.url shapes (with or without /api) so older
module settings that point at the root host keep working.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per-post "Schedule to Postiz" button on Post nodes (rSpace → Postiz), a 60s
server sweep that auto-pushes Scheduled posts within a 10min lead window,
and a Postiz → rSpace reconcile poll that flips postizStatus to
'published' (or 'failed') and records publishedAt + releaseURL.
- schemas: PostNodeData gains postizPostId, postizIntegrationId,
postizStatus, postizError, postizSentAt, postizCheckedAt,
postizReleaseURL, publishedAt.
- postiz-client: listPosts(startDate, endDate) for reconciliation.
- mod.ts: sendCampaignNodeToPostiz() helper, POST /api/campaign/flows/
:flowId/nodes/:nodeId/send-postiz, postizSweep() + postizReconcile()
wired into onInit via startPostizScheduler.
- folk-campaign-planner: button + status badge in Post inspector,
timeline/table dot colors reflect postizStatus (queued=purple,
published=green, failed=red). Timeline bucket stays by scheduledAt.
- campaign-planner.css: postiz state pill styles.
- Bump campaign-planner JS/CSS to ?v=2 to bust CF cache.
Mock-Postiz smoke against the client lib passes 20/20 assertions.
Live Postiz round-trip pending deploy to Netcup.
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.
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.
Phase B's full booking UI + admin dashboard + cancel page bundles are
now built. Bumping cache version forces Cloudflare + browser to fetch
the new code instead of the Phase A stub.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lib/availability.ts (getAvailableSlots) was imported by mod.ts but never
committed — caused module load to fail on server, leaving renderShell
callers with undefined 'modules' and producing 500s on every rschedule
route. Plus small updates to booking/admin/cancel components and mod.ts
wiring.
Schema for the new Calendly-style rSchedule port plus two new shared
canvas components (folk-app-canvas, folk-widget) that replace per-rApp
tab-based nav with a unified widget-on-canvas surface.
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>
Files existed on disk and were referenced by vite.config.ts entry
config, but were never git-added when the rschedule→rminders rename
happened in dda7760. Build on a fresh clone failed with "Could not
resolve entry module modules/rschedule/components/folk-schedule-app.ts"
because vite was picking up the stale pre-rename config on disk.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Traefik → container hop in the rSpace stack sets x-forwarded-proto: http
even when the real client request is https. That was leaking into the
"Open in <rApp>" links emitted in chronicle.mw. Simplify: any non-local
host gets https, period.
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>
- docker-compose.yml: rspace service now uses
localhost:3000/jeffemmett/rspace-online:${IMAGE_TAG:-latest} so
CI's `docker pull ... && docker compose up -d --no-build` actually
picks up the new image without a manual retag step.
- modules/rpast/mod.ts: base URL defaults to https for any non-loopback
host, honoring x-forwarded-proto only when set to http|https. Fixes
"Open in <rApp>" links previously emitted as http:// on CF/Traefik.
Adds `GET /` to rpast routes. Without it, /rpast on a space subdomain
404'd because the sub-app had no root handler. Now matches the rNotes
pattern: bare domain → marketing landing, in-space URL → app shell with
<rpast-viewer>.
Expanded folk-campaign-planner with richer live state, styled dashboard
refresh, and schema + mod updates to match the new planner flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 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>
All internal rMeets links were hardcoded to /{space}/rmeets, so clicking
Quick Meet on https://demo.rspace.online/rmeets landed on
https://demo.rspace.online/demo/rmeets/<id> — a banned path-with-subdomain
URL. Added rmeetsBase(c) that returns /rmeets on {space}.rspace.online and
/{space}/rmeets elsewhere; swept all five `base` sites plus the inline
meeting page's meetsBase.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Published hosted_url, pdf_url, epub_url, and all links in the reader
page now use {space}.rspace.online/rpubs/... (subdomain form) instead
of path-scoped rspace.online/{space}/rpubs/... — matching the site
convention that space slugs always appear as subdomains.
The server already rewrites subdomain → path-scope internally for
routing, so Hono route mounts stay the same.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add Web Speech API captions overlay in the default Jitsi meeting view,
broadcasting final/interim transcripts over Jitsi's data channel so each
participant sees everyone's speech in real time.
- Toggle via the MI FAB dropdown; degrades gracefully where SR is unsupported.
- miApiFetch + /api/mi-proxy now forward X-MI-Internal-Key so the Meeting
Intelligence recordings/search/meetings lists resolve from the backend
without per-user tokens.
- docker-compose exposes MEETING_INTELLIGENCE_API_URL, MI_INTERNAL_KEY,
JITSI_URL to the rspace container.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- epub-gen.ts: reflowable (markdown → styled xhtml) and fixed-layout
(Typst per-page PNGs wrapped as pre-paginated EPUB3). No new deps.
- typst-compile.ts: compileDocumentToPages() rasterizes Typst directly
to PNG via the CLI (no poppler/mupdf needed).
- Persistent publications store at /data/rpubs-publications/{space}/{slug}
with public reader page, PDF + EPUB downloads at /{space}/rpubs/publications/{slug}.
- Preview/Press step now has quick EPUB download buttons next to PDF.
- Publish panel: "Publish to {space}" is now the primary action, showing
hosted URL + copy-link after publishing. EPUB variants remain in downloads.
- Dockerfile: new PUBS_DIR volume for persistence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Banzhaf & Shapley-Shubik power index computation via DP, integrated
into trust engine 5-min cycle. Power tab in rNetwork 3D graph viewer
with animated bar chart, Gini/HHI gauges, and Banzhaf-scaled node
sizes. On-demand computation when DB empty. Left-drag now rotates.
New files:
- src/encryptid/power-indices.ts (pure math: Banzhaf DP, SS DP, Gini, HHI)
- modules/rnetwork/components/folk-power-indices.ts (standalone component)
API: GET /api/power-indices, GET /api/power-indices/:did,
POST /api/power-indices/simulate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restructured rTime from pool+weaving side-by-side to commitment entry
form (left 50%) and pool orb visualization (right 50%). Inline form
replaces modal for pledging time. Commitments list shows below form.
Weaving SVG moved to separate toggled view via "Weave" button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Enable chat notifications (brief popup for all participants)
- Move chat panel to right side via CHAT_PANEL_POSITION
- Applied to both clean room mode and folk-jitsi-room shell mode
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add "recording" to Jitsi toolbarButtons in both clean room mode
and folk-jitsi-room shell mode so users can trigger Jibri recording
- Add "View Transcript & Summary" link on meeting-ended screen
- Jibri network connectivity fixed on Netcup (was on wrong Docker
network, couldn't reach Prosody XMPP)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add conditional mediation to sign-in modal so mobile browsers show
saved passkeys with usernames in the autofill area (desktop parity)
- Add publicWrite to rcred module so recompute route's own auth runs
instead of being blocked by the global write-access middleware
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add shell tabs: Commitment Pool, Fulfillment, Open in Cyclos
- Move stats (hours, contributors, skill breakdown) into pool legend
- Remove internal tab-bar and stats-bar from component
- Listen for rapp-tab-change shell events for view switching
- Legacy routes redirect to new tab paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add pool-out port to folk-commitment-pool, two new applets (weaving-coverage
for rTime, resource-coverage for rTasks), fetchLiveData polling in FolkApplet,
and canvas AI tool declarations for both new applets.
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>
serveStatic resolves relative to dist/, so /dist/modules/ doubled the
prefix and 404'd. All other modules use /modules/rcred/file.js.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace inline filter buttons with standard shell sub-tabs (Members,
People, Companies, Trust, Layers). Default view now renders the 3D graph
on the Members tab with proper shell navigation.
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>
Triggers recomputeSpace('demo') 10s after init if no scores exist.
Allows unauthenticated recompute on demo space so visitors can click
the Recompute button.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 1 integration: fetch Drips account state via GraphQL API (eth_call fallback),
map streams → Source nodes and splits → Outcome nodes with auto-layout, import into
canvas flows with dedup and resync tracking. Schema v5→v6 adds dripsSyncs to CanvasFlow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Week view: replace calc()-based absolute positioning with a mirror grid
overlay (grid-template-columns: 44px repeat(7,1fr)) so event columns
align pixel-perfectly with the underlying CSS grid at any browser zoom.
Fix min-interval padding to match min display size in week view
(20→23 min for 18px height) and day-horizontal view (30→45 min for
60px width), preventing visual bleed between adjacent short events.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simulation now has a 🔁 button that auto-replays the flow visualization.
Detects steady state, pauses briefly, resets to initial snapshot, repeats.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single-click module to zoom into cluster with smooth camera animation,
revealing doc labels. Double-click to open in new tab. Breadcrumb bar
for back-navigation. Non-focused nodes dim to 15% for context.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>