Source nodes now drive funnel inflow rates via computeInflowRates() which
sums source allocations before each simulation tick. Source width scales
with flowRate, funnel height scales linearly with capacity, and valve/
capacity drag handles are always visible on hover (no inline-edit needed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
onChange handler was resetting _tweetImages on every sync event,
undoing local deletions before they could round-trip. Now only
updates state in readonly mode; edit mode preserves local changes.
Also add cache-busting timestamps to uploaded/generated image URLs
to prevent browser from showing stale cached images.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Automerge proxy objects silently ignore property writes outside
change() calls. When this._thread was a proxy, removeTweetImage's
assignment to this._thread.tweetImages was silently discarded,
causing deleted photos to reappear.
Fix by deep-cloning all Automerge reads (subscribeOffline, onChange,
loadDraft) so this._thread is always a plain mutable object.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace hardcoded dark colors with --rs-* CSS variables from theme.css
- Add theme.css import and theme initialization script
- Respond to theme changes via localStorage event listener
- Upgrade visibility selector from <select> to radio card UI
- Add subtle gradient background and focus ring styles
- Remove hardcoded data-theme="dark" from body/header
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the title input and header image upload/generate section from
the thread builder editor. Title is now auto-derived from first tweet.
Add link preview cards that render inline in tweet content, similar to
Twitter's URL card unfurling. Server-side /api/link-preview endpoint
fetches OG metadata (title, description, image) with caching.
URLs in tweet text are rendered as clickable links.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace infographic/typography prompts with atmospheric abstract art
prompts. Images now use flowing gradients, organic shapes, and moody
lighting to evoke the tweet's theme without any text or typography.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace generic "dark themed, minimal" prompts with detailed
infographic-style prompts that generate bold, shareable visuals
with typography overlays, iconic symbols, and data-viz elements.
Add try/catch error handling around fal.ai calls to prevent
unhandled network errors from crashing the request handler.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The folk-campaign-planner imports SocialsLocalFirstClient which pulls
in Automerge WASM — needs vite-plugin-wasm and alias like other
local-first module builds.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Switch source/outcome nodes from SVG shapes to foreignObject HTML cards
with white backgrounds, gradient headers, status badges, and progress bars
- Add foreignObject text overlay to funnel nodes (keep SVG tank shape)
- Fix Sankey edge widths: flow-value-relative formula instead of percentage
- Smooth drag: rAF throttle + lightweight edge path patching during drag
- Add dot grid canvas background, arrowhead markers, larger port dots
- Fixed node sizes: source 220x120, outcome 220x180
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pass /data/ paths through subdomain routing without rewriting so
generated image files are accessible on *.rspace.online subdomains.
Move image upload/generate section above the compose textarea in the
thread builder editor layout.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Automerge throws "Cannot create a reference to an existing document
object" when assigning an Automerge proxy object back into the doc.
Now JSON round-trips the thread data before writing, and strips null
fields that should be absent rather than null in the document.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- tweetImages and imageUrl set to null instead of undefined when empty
(Automerge rejects undefined as invalid JSON)
- Updated ThreadData schema to allow null for optional fields
- This was the root cause of the 404 on image generation: saveDraft
threw on undefined, so the thread never synced to the server, and
the server-side route returned "Thread not found"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use DOM API (createElementNS + createElement) to build foreignObject
panel instead of innerHTML, ensuring proper HTML namespace for
querySelector to traverse SVG→HTML boundary
- Query buttons/inputs from HTML panel root instead of SVG overlay
- Remove wallet address requirement for demo mode (use zero address)
- Add console logging and .catch() for Transak widget debugging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs:
- subscribeOffline() bailed if runtime wasn't initialized yet (race with
shell.ts init). Now waits for runtime to appear, then awaits init().
- getDoc() called runtime.getDoc() which doesn't exist — method is
runtime.get(). Caused "e.getDoc is not a function" crash in listThreads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Increase funnel base size (280×250), source nodes (140-280 dynamic),
outcome nodes (220×120) for better visibility
- Simplify to 2 threshold lines (Min/Max) and 3 labeled zones:
Critical (below min), Sufficient (min-max), Overflow (above max)
- Position overflow pipes at max threshold line instead of fixed 55%
- Make drain width proportional to desiredOutflow (physical metaphor)
- Replace popup config panel with draggable handles for funnels:
valve handle (horizontal drag → outflow rate) and height handle
(vertical drag → capacity)
- Increase edge stroke widths (3-28px) for more visible flow changes
- Source nodes: tall/thin for small recurring, short/thick for large chunks
- Keep config panel for source/outcome node types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All callers of saveDraft() and saveToAutomerge() in generateImage,
uploadImage, uploadTweetImage, generateTweetImage, removeTweetImage,
and share handler now properly await these async methods. Without await,
runtime.change() fires before the Automerge doc subscription resolves,
causing "Document not open" errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
basePath was always returning /{space}/rsocials/ which works for path-based
routing (rspace.online/jeff/rsocials/) but double-prefixes on subdomain
routing (jeff.rspace.online/jeff/rsocials/ → rewritten to /jeff/jeff/rsocials/).
Now detects subdomain hosts (*.rspace.online, *.rsocials.online) and returns
/rsocials/ without the space prefix, since the space is the subdomain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs fixed:
- attachShadow called unconditionally in connectedCallback, crashing on
re-insertion ("Shadow root cannot be created on a host which already
hosts a shadow tree")
- saveToAutomerge/deleteFromAutomerge called runtime.change() before the
async subscribeOffline() had resolved, causing "Document not open" errors
Now tracks the subscribe promise and awaits it before any write operation.
Also guards shadow root creation in gallery and campaign manager components.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Inline config panel now appears beside (right of) the node instead of
beneath it
- Funnel config simplified to single $/mo outflow slider (0-3000) that
auto-derives all thresholds: min=1mo, sufficient=4mo, overflow=6mo
- Updated deriveThresholds to 4mo sufficient (was 3mo)
- Demo presets updated to match new 4mo formula
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Single click on a node now opens the inline config panel directly
(instead of requiring double-click which was broken by pointer capture)
- New nodes from toolbar open inline editor instead of side panel
- Click-outside handler uses shadow root instead of document to avoid
event retargeting that dismissed the panel on any interaction
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instance-agnostic scripts to configure standalone Twenty CRM instances
(crypto-commons and VOTC) with 7-stage pipeline, custom opportunity/company
fields, and saved views (My Pipeline kanban, Needs Follow-up, Stale Leads).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The click-outside handler used event.target at the document level,
which in shadow DOM is retargeted to the host element. Clicking any
input inside the inline config panel (foreignObject) would immediately
dismiss it. Use composedPath() to correctly detect clicks inside the
shadow DOM boundary.
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>
Adds a "dump & layout" feature where users can paste or drag-drop unstructured
content onto the canvas and have Gemini 2.5 Flash analyze it, classify each piece
into the appropriate folk-* shape type, and propose a multi-shape layout with
semantic connections.
- POST /api/mi/triage endpoint with structured JSON output from Gemini
- TriageManager orchestrator (analyze, removeShape, commitAll via MiActionExecutor)
- MiTriagePanel floating preview UI with shape cards, connections, Create All/Cancel
- Canvas drag/drop overlay + paste handler integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The reverse proxy couldn't work for a Next.js SPA — it caused double
space prefix in redirects and couldn't handle /_next/* static assets.
Switch to iframe approach with demo.rsocials.online directly. Fix
template literal bugs where getSchedulerUrl() was passed as a string
literal instead of being evaluated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rSpace Traefik router catches demo.rsocials.online (priority 120)
before the Postiz container can serve it, making iframe embedding fail.
Replace the iframe approach with a reverse proxy: /rsocials/scheduler/*
proxies to the Postiz container (postiz:5000) on the Docker network.
Rewrites redirect headers to stay within the scheduler path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch /crm and ?view=app from custom folk-crm-view component to
renderExternalAppShell iframe embedding crm.rspace.online. Also fix
twentyQuery endpoint from /api to /api/graphql for the data proxy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rSocials refactor commit overwrote the canvas route changes.
Re-adds: default canvas view, ?view=feed for old demo feed,
?view=landing for landing page, and vite build entry for
folk-socials-canvas.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The folk-flows-app sub-build imports Automerge which requires WASM support.
Added wasm() plugin, esnext target, and Automerge alias to the sub-build config.
Also adds folk-socials-canvas.ts and socials-canvas.css that were on the server
but missing from git, causing the vite build to fail.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Multi-workspace mode caused crm.rspace.online to redirect to
admin-crm.crm.rspace.online which doesn't exist. Space-level tenancy
is handled by rSpace's per-space API tokens instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Toolbar buttons now smoothly widen on hover/click to reveal title text
instead of using CSS tooltips. Reorganized from 7 groups into 9 (Note,
Connect, Media, Embed, AI, Create, Decide, Spend, Travel) with better
categorization. Collapse button uses chevron instead of dots. Mobile
tap targets increased to 48px min-height for accessibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Placeholder modules not yet built out as full rApps. Removes them
from the dropdown/tab bar until they have proper schemas, components,
and local-first support.
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>
Open rFlows directly into the interactive canvas instead of the landing
page. Adds a full flow storage system (Automerge for authenticated users,
localStorage for demo/anon) with CRUD operations, auto-save with 1.5s
debounce, flow switching via toolbar dropdown, and a management modal
for rename/duplicate/export/import/delete. Viewport state (zoom/pan)
persists per-flow in localStorage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rNetwork: upgrade folk-graph-viewer with pan/zoom/drag, fitView, touch
pinch-zoom, zoom controls, persisted node positions, and incremental
drag updates. rSocials: new folk-socials-canvas component with campaign
and thread card nodes, Postiz slide-out panel, and canvas interactions.
Default / route now renders canvas view; old feed moved to ?view=feed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The shell now imports RSpaceOfflineRuntime which transitively pulls in
Automerge WASM. Without the wasm() plugin and esnext target on the
shell build step, vite fails with "ESM integration proposal for Wasm
is not supported".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>