From cfb5200b5136a0495106582c3118f793036ef1dd Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Wed, 15 Apr 2026 14:01:29 -0400 Subject: [PATCH] refactor(demo): replace Alpine Explorer scenario with welcome + feature cards 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 --- server/seed-demo.ts | 1129 ++++++++++++++++++------------------------- 1 file changed, 459 insertions(+), 670 deletions(-) diff --git a/server/seed-demo.ts b/server/seed-demo.ts index fc6a21f1..083bafd0 100644 --- a/server/seed-demo.ts +++ b/server/seed-demo.ts @@ -2,7 +2,7 @@ * Demo community seeder for the r* ecosystem * * Creates/ensures a "demo" community with visibility: "public" (anon read+write) - * and populates it with the "Alpine Explorer 2026" cross-app scenario. + * and populates it with a welcome card + feature cards for each rApp. * * Shape IDs are deterministic so re-running is idempotent. */ @@ -17,753 +17,542 @@ import { updateSpaceMeta, } from "./community-store"; -// ── Alpine Explorer 2026 — Demo Scenario ────────────────────────── +// ── Demo Space — Welcome + Feature Showcase ─────────────────────── + +// Grid layout: cards are 280px wide with 20px gap +const COL_W = 300; // card width + gap +const ROW_H = 260; // card height + gap +const CARD_W = 280; +const CARD_H = 240; +const START_X = 50; +const START_Y = 380; // below welcome card + +/** Helper: grid position from col/row index */ +function pos(col: number, row: number) { + return { x: START_X + col * COL_W, y: START_Y + row * ROW_H }; +} const DEMO_SHAPES: Record[] = [ - // ─── rTrips: Itinerary ────────────────────────────────────── + // ─── Welcome Card ─────────────────────────────────────────── { - id: "demo-itinerary-alpine", - type: "folk-itinerary", - x: 50, y: 50, width: 400, height: 300, rotation: 0, - tripTitle: "Alpine Explorer 2026", - startDate: "2026-07-06", - endDate: "2026-07-20", - travelers: ["Maya", "Liam", "Priya", "Omar"], - items: [ - { date: "Jul 6", activity: "Fly Geneva → Chamonix shuttle", category: "travel" }, - { date: "Jul 7", activity: "Acclimatization hike — Lac Blanc", category: "hike" }, - { date: "Jul 8", activity: "Via Ferrata — Aiguille du Midi", category: "adventure" }, - { date: "Jul 9", activity: "Rest day / Chamonix town", category: "rest" }, - { date: "Jul 10", activity: "Train to Zermatt", category: "travel" }, - { date: "Jul 11", activity: "Gornergrat sunrise hike", category: "hike" }, - { date: "Jul 12", activity: "Matterhorn base camp trek", category: "hike" }, - { date: "Jul 13", activity: "Paragliding over Zermatt", category: "adventure" }, - { date: "Jul 14", activity: "Transfer to Dolomites", category: "travel" }, - { date: "Jul 15", activity: "Tre Cime di Lavaredo loop", category: "hike" }, - { date: "Jul 16", activity: "Lago di Braies kayaking", category: "adventure" }, - { date: "Jul 17", activity: "Seceda ridgeline hike", category: "hike" }, - { date: "Jul 18", activity: "Cooking class in Bolzano", category: "culture" }, - { date: "Jul 19", activity: "Free day — shopping & packing", category: "rest" }, - { date: "Jul 20", activity: "Fly home from Innsbruck", category: "travel" }, - ], + id: "demo-welcome", + type: "folk-markdown", + x: 50, y: 50, width: 620, height: 300, rotation: 0, + content: `# Welcome to rSpace + +A **local-first operating system** for communities. Every tool syncs in real-time, works offline, and keeps your data under your control. + +## How it works +- **Create a Space** — your community's home base +- **Add rApps** — modular tools that share data on the canvas +- **Invite members** — passkey login, no passwords or seed phrases +- **Everything syncs** — Automerge CRDTs, end-to-end encrypted + +Drag shapes around, connect them with arrows, and build your community's workspace. Each card below is a tool you can use.`, }, - // ─── rTrips: Destinations ─────────────────────────────────── + // ─── Category: Communicate ────────────────────────────────── { - id: "demo-dest-chamonix", - type: "folk-destination", - x: 500, y: 50, width: 300, height: 200, rotation: 0, - destName: "Chamonix", - country: "France", - lat: 45.9237, - lng: 6.8694, - arrivalDate: "2026-07-06", - departureDate: "2026-07-10", - notes: "Base for Mont Blanc region. Book Aiguille du Midi tickets in advance.", + id: "demo-cat-communicate", + type: "folk-markdown", + x: START_X, y: START_Y - 40, width: 200, height: 30, rotation: 0, + content: "## Communicate", }, { - id: "demo-dest-zermatt", - type: "folk-destination", - x: 500, y: 280, width: 300, height: 200, rotation: 0, - destName: "Zermatt", - country: "Switzerland", - lat: 46.0207, - lng: 7.7491, - arrivalDate: "2026-07-10", - departureDate: "2026-07-14", - notes: "Car-free village. Take the Glacier Express for the scenic route.", + id: "demo-tool-rchats", + type: "folk-markdown", + ...pos(0, 0), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rChats +Real-time messaging for your space. + +- **Channels** — topic-based group conversations +- **Direct messages** — private 1:1 threads +- **Reactions & threads** — keep discussions organized +- **File sharing** — drag-and-drop attachments`, }, { - id: "demo-dest-dolomites", - type: "folk-destination", - x: 500, y: 510, width: 300, height: 200, rotation: 0, - destName: "Dolomites", - country: "Italy", - lat: 46.4102, - lng: 11.8440, - arrivalDate: "2026-07-14", - departureDate: "2026-07-20", - notes: "Stay in Val Gardena. Rifugio Locatelli for Tre Cime views.", + id: "demo-tool-rforum", + type: "folk-markdown", + ...pos(1, 0), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rForum +Threaded discussions for deeper topics. + +- **Categories** — organize threads by topic +- **Rich text** — markdown formatting in posts +- **Threaded replies** — nested conversations +- **Search** — find past discussions`, + }, + { + id: "demo-tool-rinbox", + type: "folk-markdown", + ...pos(2, 0), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rInbox +Shared email for your community. + +- **Shared mailboxes** — team-readable inboxes +- **Multisig approval** — require sign-off before sending +- **Internal comments** — discuss emails before replying +- **Connect accounts** — link existing email`, + }, + { + id: "demo-tool-rmeets", + type: "folk-markdown", + ...pos(3, 0), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rMeets +Video calls with built-in intelligence. + +- **Instant meetings** — one-click video calls +- **Recordings** — auto-saved with transcripts +- **AI summaries** — key points from each meeting +- **Screen sharing** — present to your group`, }, - // ─── rNotes: Notebook ─────────────────────────────────────── + // ─── Category: Organize ───────────────────────────────────── { - id: "demo-notebook-trip", - type: "folk-notebook", - x: 850, y: 50, width: 300, height: 180, rotation: 0, - notebookTitle: "Alpine Explorer Planning", - description: "Shared knowledge base for our July 2026 trip across France, Switzerland, and Italy", - noteCount: 5, - collaborators: ["Maya", "Liam", "Priya", "Omar"], + id: "demo-cat-organize", + type: "folk-markdown", + x: START_X, y: START_Y + ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Organize", + }, + { + id: "demo-tool-rtasks", + type: "folk-markdown", + ...pos(0, 1), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rTasks +Kanban boards for project management. + +- **Drag-and-drop** — move tasks across columns +- **Assignees & priority** — track who's doing what +- **Multiple boards** — separate projects per board +- **ClickUp sync** — import from external tools`, + }, + { + id: "demo-tool-rcal", + type: "folk-markdown", + ...pos(1, 1), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rCal +Shared calendar with external sync. + +- **Google Calendar sync** — two-way sync +- **ICS import** — upload from any calendar app +- **iCal subscriptions** — read-only feeds +- **Event creation** — shared community events`, + }, + { + id: "demo-tool-rschedule", + type: "folk-markdown", + ...pos(2, 1), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rSchedule +Automations and scheduled jobs. + +- **Cron jobs** — recurring tasks on a schedule +- **Reminders** — email notifications +- **Visual workflows** — trigger-condition-action chains +- **Execution log** — full history of runs`, + }, + { + id: "demo-tool-rtime", + type: "folk-markdown", + ...pos(3, 1), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rTime +Time banking for communities. + +- **Pledge hours** — commit time to the pool +- **Track contributions** — log hours worked +- **Balance sheets** — see give/receive ratios +- **Community currency** — time as value exchange`, }, - // ─── rNotes: Notes ────────────────────────────────────────── + // ─── Category: Create ─────────────────────────────────────── { - id: "demo-note-packing", - type: "folk-note", - x: 850, y: 260, width: 300, height: 250, rotation: 0, - noteTitle: "Packing Checklist", - content: "## Essential Gear\n- [ ] Hiking boots (broken in!)\n- [x] Rain jacket\n- [x] Headlamp + batteries\n- [ ] Trekking poles\n- [x] First aid kit\n- [ ] Sunscreen SPF 50\n- [ ] Water filter\n\n## Documents\n- [x] Passports\n- [ ] Travel insurance\n- [x] Hut reservations printout", - tags: ["packing", "gear", "checklist"], - editor: "Maya", - editedAt: "2 hours ago", + id: "demo-cat-create", + type: "folk-markdown", + x: START_X, y: START_Y + 2 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Create", }, { - id: "demo-note-gear", - type: "folk-note", - x: 1180, y: 50, width: 300, height: 200, rotation: 0, - noteTitle: "Gear Research", - content: "## Via Ferrata Kit\nNeed harness + lanyard + helmet. Can rent in Chamonix for ~€25/day.\n\n## Paragliding\nTandem flights in Zermatt: ~€180pp. Book at Paragliding Zermatt (best reviews).\n\n## Camera\nBring the drone for Tre Cime. Check Italian drone regulations!", - tags: ["gear", "research", "equipment"], - editor: "Liam", - editedAt: "5 hours ago", + id: "demo-tool-rdocs", + type: "folk-markdown", + ...pos(0, 2), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rDocs +Rich-text collaborative notebooks. + +- **Real-time editing** — multiple cursors, live sync +- **Import** — from Obsidian, Logseq, Notion, Google +- **Voice transcription** — dictate and auto-transcribe +- **AI assist** — writing help built in`, }, { - id: "demo-note-huts", - type: "folk-note", - x: 1180, y: 280, width: 300, height: 200, rotation: 0, - noteTitle: "Mountain Hut Reservations", - content: "## Confirmed\n- **Rifugio Locatelli** (Jul 15): 4 beds, conf #TRE2026-089\n- **Refuge du Lac Blanc** (Jul 7): 4 beds, conf #LB2026-234\n\n## Pending\n- Hörnlihütte (Matterhorn base): Waitlisted for Jul 12", - tags: ["accommodation", "reservations", "logistics"], - editor: "Priya", - editedAt: "Yesterday", + id: "demo-tool-rnotes", + type: "folk-markdown", + ...pos(1, 2), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rNotes +Vault sync for Obsidian & Logseq. + +- **ZIP upload** — import your entire vault +- **Browse & search** — explore notes by folder +- **Metadata sync** — tags, links, frontmatter +- **On-demand content** — files served from vault ZIP`, }, { - id: "demo-note-emergency", - type: "folk-note", - x: 1180, y: 510, width: 300, height: 180, rotation: 0, - noteTitle: "Emergency Contacts", - content: "## Emergency Numbers\n- **France**: 112 (EU), PGHM: +33 4 50 53 16 89\n- **Switzerland**: 1414 (REGA air rescue)\n- **Italy**: 118 (medical), 112 (general)\n\n## Insurance\nPolicy #: WA-2026-7891\nEmergency line: +1-800-555-0199", - tags: ["safety", "emergency", "contacts"], - editor: "Omar", - editedAt: "3 days ago", + id: "demo-tool-rphotos", + type: "folk-markdown", + ...pos(2, 2), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rPhotos +Photo albums and galleries. + +- **Lightbox viewer** — full-screen with EXIF data +- **Albums** — organize by event or theme +- **Public galleries** — shareable links +- **Smart tags** — AI-powered face & object tagging`, }, { - id: "demo-note-photos", - type: "folk-note", - x: 850, y: 540, width: 300, height: 180, rotation: 0, - noteTitle: "Photo Spots", - content: "## Must-Capture Locations\n1. Lac Blanc reflection of Mont Blanc (sunrise)\n2. Gornergrat panorama with Matterhorn\n3. Tre Cime from Rifugio Locatelli (golden hour)\n4. Seceda ridgeline drone shots\n5. Lago di Braies turquoise water\n\nBring ND filters for long exposure water shots.", - tags: ["photography", "planning", "creative"], - editor: "Liam", - editedAt: "2 days ago", + id: "demo-tool-rtube", + type: "folk-markdown", + ...pos(3, 2), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rTube +Video hosting for your community. + +- **Upload & stream** — host your own videos +- **Playlists** — curate video collections +- **Channels** — organize by creator or topic +- **Embedded player** — share anywhere`, }, - // ─── rVote: Polls ─────────────────────────────────────────── + // ─── Category: Govern ─────────────────────────────────────── { - id: "demo-poll-day5", - type: "demo-poll", - x: 50, y: 400, width: 350, height: 200, rotation: 0, - question: "Day 5 Activity — What should we do in Chamonix?", - options: [ - { label: "Via Ferrata at Aiguille du Midi", votes: 7 }, - { label: "Kayaking on Lac d'Annecy", votes: 3 }, - { label: "Rest day in town", votes: 2 }, - ], - totalVoters: 4, - status: "active", - endsAt: "2026-07-01", + id: "demo-cat-govern", + type: "folk-markdown", + x: START_X, y: START_Y + 3 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Govern", }, { - id: "demo-poll-dinner", - type: "demo-poll", - x: 50, y: 630, width: 350, height: 200, rotation: 0, - question: "First night dinner in Zermatt?", - options: [ - { label: "Traditional fondue at Chez Vrony", votes: 5 }, - { label: "Pizza at Grampi's", votes: 4 }, - { label: "Cook at the Airbnb", votes: 1 }, - ], - totalVoters: 4, - status: "active", - endsAt: "2026-07-05", + id: "demo-tool-rvote", + type: "folk-markdown", + ...pos(0, 3), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rVote +Conviction voting and governance. + +- **Proposals** — submit ideas for community vote +- **Conviction voting** — signal strength over time +- **Pairwise ranking** — Elo-style sortition +- **Results dashboard** — transparent outcomes`, + }, + { + id: "demo-tool-rgov", + type: "folk-markdown", + ...pos(1, 3), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rGov +Governance decision circuits. + +- **Visual circuits** — drag-and-drop governance flows +- **Multisig** — require multiple approvals +- **Quadratic voting** — diminishing returns voting +- **Amendment tracking** — version proposals`, + }, + { + id: "demo-tool-rchoices", + type: "folk-markdown", + ...pos(2, 3), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rChoices +Group decision-making tools. + +- **Spider charts** — multi-criteria radar visualization +- **Drag rankings** — drag-and-drop prioritization +- **Live polls** — real-time voting +- **CrowdSurf** — Tinder-style option swiping`, + }, + { + id: "demo-tool-rnetwork", + type: "folk-markdown", + ...pos(3, 3), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rNetwork +CRM and relationship graphs. + +- **Contact management** — people and organizations +- **Relationship graph** — visualize connections +- **Pipeline tracking** — manage opportunities +- **Delegations** — liquid democracy trust flows`, }, - // ─── rCart: Group Shopping Items ───────────────────────────── + // ─── Category: Finance ────────────────────────────────────── { - id: "demo-cart-firstaid", - type: "demo-cart-item", - x: 50, y: 870, width: 320, height: 60, rotation: 0, - name: "Adventure First-Aid Kit", - price: 85.00, - funded: 85.00, - status: "Funded", - requestedBy: "Omar", - store: "REI", + id: "demo-cat-finance", + type: "folk-markdown", + x: START_X, y: START_Y + 4 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Finance", }, { - id: "demo-cart-waterfilter", - type: "demo-cart-item", - x: 50, y: 940, width: 320, height: 60, rotation: 0, - name: "Portable Water Filter (Sawyer Squeeze)", - price: 45.00, - funded: 45.00, - status: "Funded", - requestedBy: "Maya", - store: "Amazon", + id: "demo-tool-rwallet", + type: "folk-markdown", + ...pos(0, 4), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rWallet +Multi-chain crypto wallet. + +- **Gnosis Safe** — multisig wallet abstraction +- **Token balances** — view across chains +- **DeFi positions** — Aave, Uniswap, etc. +- **Sankey flows** — transaction visualization`, }, { - id: "demo-cart-bearcan", - type: "demo-cart-item", - x: 50, y: 1010, width: 320, height: 60, rotation: 0, - name: "Bear Canister 2x (BV500)", - price: 120.00, - funded: 80.00, - status: "In Cart", - requestedBy: "Liam", - store: "REI", + id: "demo-tool-rflows", + type: "folk-markdown", + ...pos(1, 4), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rFlows +Community funding and budgets. + +- **Collective budgets** — participatory pie charts +- **Personal sliders** — auto-normalizing allocation +- **Community lending** — trust-backed pools +- **Yield projection** — compound interest calculator`, }, { - id: "demo-cart-stove", - type: "demo-cart-item", - x: 50, y: 1080, width: 320, height: 60, rotation: 0, - name: "Camp Stove + Fuel Canister", - price: 65.00, - funded: 65.00, - status: "Funded", - requestedBy: "Priya", - store: "Decathlon", + id: "demo-tool-rcart", + type: "folk-markdown", + ...pos(2, 4), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rCart +Community storefront. + +- **Group shopping** — shared carts +- **Print-on-demand** — catalog with production +- **Group buys** — volume discount campaigns +- **Order tracking** — fulfillment & invoices`, }, { - id: "demo-cart-drone", - type: "demo-cart-item", - x: 50, y: 1150, width: 320, height: 60, rotation: 0, - name: "DJI Mini 4 Pro Rental (2 weeks)", - price: 350.00, - funded: 100.00, - status: "Needs Funding", - requestedBy: "Liam", - store: "LensRentals", - }, - { - id: "demo-cart-starlink", - type: "demo-cart-item", - x: 50, y: 1220, width: 320, height: 60, rotation: 0, - name: "Starlink Mini Rental (2 weeks)", - price: 200.00, - funded: 50.00, - status: "Needs Funding", - requestedBy: "Omar", - store: "StarRent.eu", + id: "demo-tool-rauctions", + type: "folk-markdown", + ...pos(3, 4), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rAuctions +Live auction platform. + +- **Create auctions** — list items for bidding +- **Real-time bids** — live bidding updates +- **Auction history** — completed results +- **Community trust** — reputation-backed bidding`, }, - // ─── rFlows: Expenses ─────────────────────────────────────── + // ─── Category: Travel & Share ─────────────────────────────── { - id: "demo-expense-shuttle", - type: "demo-expense", - x: 400, y: 870, width: 320, height: 60, rotation: 0, - description: "Geneva → Chamonix shuttle (4 pax)", - amount: 186.00, - currency: "EUR", - paidBy: "Maya", - split: "equal", - category: "transport", - date: "2026-07-06", + id: "demo-cat-travel", + type: "folk-markdown", + x: START_X, y: START_Y + 5 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Travel & Share", }, { - id: "demo-expense-hut", - type: "demo-expense", - x: 400, y: 940, width: 320, height: 60, rotation: 0, - description: "Mountain hut reservations (3 nights total)", - amount: 420.00, - currency: "EUR", - paidBy: "Priya", - split: "equal", - category: "accommodation", - date: "2026-07-07", + id: "demo-tool-rtrips", + type: "folk-markdown", + ...pos(0, 5), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rTrips +Collaborative trip planning. + +- **Itineraries** — day-by-day activity plans +- **Destinations** — multi-stop with map pins +- **Route planner** — optimal waypoint ordering +- **Expense splitting** — track who paid what`, }, { - id: "demo-expense-viaferrata", - type: "demo-expense", - x: 400, y: 1010, width: 320, height: 60, rotation: 0, - description: "Via Ferrata gear rental (4 sets)", - amount: 144.00, - currency: "EUR", - paidBy: "Liam", - split: "equal", - category: "activity", - date: "2026-07-08", + id: "demo-tool-rmaps", + type: "folk-markdown", + ...pos(1, 5), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rMaps +Location sharing and routing. + +- **Live locations** — real-time participant map +- **Privacy controls** — precision fuzzing, ghost mode +- **Turn-by-turn routing** — OSRM + indoor nav +- **Meeting points** — coordinate group meetups`, }, { - id: "demo-expense-groceries", - type: "demo-expense", - x: 400, y: 1080, width: 320, height: 60, rotation: 0, - description: "Groceries — Chamonix Carrefour", - amount: 93.00, - currency: "EUR", - paidBy: "Omar", - split: "equal", - category: "food", - date: "2026-07-06", + id: "demo-tool-rbnb", + type: "folk-markdown", + ...pos(2, 5), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rBnb +Community hospitality exchange. + +- **List spaces** — share your home with members +- **Stay requests** — book within your community +- **Trust endorsements** — reputation from stays +- **No fees** — peer-to-peer, no platform cut`, }, { - id: "demo-expense-paragliding", - type: "demo-expense", - x: 400, y: 1150, width: 320, height: 60, rotation: 0, - description: "Paragliding deposit (2 of 4 booked)", - amount: 360.00, - currency: "CHF", - paidBy: "Maya", - split: "custom", - category: "activity", - date: "2026-07-13", + id: "demo-tool-rvnb", + type: "folk-markdown", + ...pos(3, 5), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rVnb +Community vehicle sharing. + +- **List vehicles** — share cars, bikes, vans +- **Rental requests** — book within community +- **Trust endorsements** — reputation from trips +- **Usage tracking** — mileage and availability`, }, - // ─── rFlows: Budget ───────────────────────────────────────── + // ─── Category: Publish ────────────────────────────────────── { - id: "demo-budget-trip", - type: "folk-budget", - x: 400, y: 400, width: 350, height: 250, rotation: 0, - budgetTitle: "Trip Budget", - currency: "EUR", - budgetTotal: 4000, - spent: 1203, - categories: [ - { name: "Transport", budget: 800, spent: 186 }, - { name: "Accommodation", budget: 1200, spent: 420 }, - { name: "Activities", budget: 1000, spent: 504 }, - { name: "Food", budget: 600, spent: 93 }, - { name: "Gear", budget: 400, spent: 0 }, - ], + id: "demo-cat-publish", + type: "folk-markdown", + x: START_X, y: START_Y + 6 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Publish", + }, + { + id: "demo-tool-rpubs", + type: "folk-markdown", + ...pos(0, 6), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rPubs +Zine and book publishing. + +- **MycroZines** — 8-page auto-generated zines +- **PDF output** — print-ready publications +- **Drafts** — work-in-progress documents +- **Community library** — share publications`, + }, + { + id: "demo-tool-rdesign", + type: "folk-markdown", + ...pos(1, 6), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rDesign +Design tools and templates. + +- **Layout editor** — visual design canvas +- **Templates** — reusable design patterns +- **Asset library** — shared design resources +- **Export** — PNG, SVG, PDF output`, + }, + { + id: "demo-tool-rswag", + type: "folk-markdown", + ...pos(2, 6), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rSwag +Merchandise design. + +- **Product designer** — t-shirts, stickers, prints +- **Print-on-demand** — connect to production +- **Sell in rCart** — list directly in your store +- **Size variants** — manage product options`, + }, + { + id: "demo-tool-rsocials", + type: "folk-markdown", + ...pos(3, 6), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rSocials +Social media management. + +- **Campaign builder** — multi-platform scheduling +- **Thread composer** — Twitter/X thread drafting +- **Newsletter editor** — email campaign drafts +- **Analytics** — track engagement metrics`, }, - // ─── rMaps: Location Markers ──────────────────────────────── + // ─── Category: Data & AI ──────────────────────────────────── { - id: "demo-map-chamonix", - type: "demo-map-marker", - x: 750, y: 750, width: 40, height: 40, rotation: 0, - name: "Chamonix", - lat: 45.9237, - lng: 6.8694, - emoji: "🏔️", - category: "destination", - status: "Jul 6-10", + id: "demo-cat-data", + type: "folk-markdown", + x: START_X, y: START_Y + 7 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Data & AI", }, { - id: "demo-map-zermatt", - type: "demo-map-marker", - x: 800, y: 750, width: 40, height: 40, rotation: 0, - name: "Zermatt", - lat: 46.0207, - lng: 7.7491, - emoji: "⛷️", - category: "destination", - status: "Jul 10-14", + id: "demo-tool-rdata", + type: "folk-markdown", + ...pos(0, 7), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rData +Space data explorer. + +- **Content tree** — hierarchical CRDT document view +- **Data cloud** — 3D force-directed graph +- **Analytics** — usage metrics and engagement +- **Search** — find any object in your space`, }, { - id: "demo-map-dolomites", - type: "demo-map-marker", - x: 850, y: 750, width: 40, height: 40, rotation: 0, - name: "Dolomites", - lat: 46.4102, - lng: 11.8440, - emoji: "🏞️", - category: "destination", - status: "Jul 14-20", + id: "demo-tool-rbooks", + type: "folk-markdown", + ...pos(1, 7), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rBooks +Shared PDF library. + +- **Flipbook reader** — page-turning animations +- **Bookmarks & notes** — annotations that sync +- **Collections** — curated reading lists +- **Community library** — upload and share PDFs`, }, { - id: "demo-map-lacblanc", - type: "demo-map-marker", - x: 900, y: 750, width: 40, height: 40, rotation: 0, - name: "Lac Blanc Hike", - lat: 45.9785, - lng: 6.8891, - emoji: "🥾", - category: "activity", - status: "Jul 7", + id: "demo-tool-rsplat", + type: "folk-markdown", + ...pos(2, 7), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rSplat +3D Gaussian splatting. + +- **Interactive 3D** — orbit, pan, zoom in browser +- **Upload .ply/.splat** — share 3D captures +- **Multi-angle** — photorealistic reconstructions +- **Drawing mode** — 3D freehand sketching`, }, { - id: "demo-map-viaferrata", - type: "demo-map-marker", - x: 950, y: 750, width: 40, height: 40, rotation: 0, - name: "Via Ferrata", - lat: 45.8786, - lng: 6.8874, - emoji: "🧗", - category: "activity", - status: "Jul 8", - }, - { - id: "demo-map-trecime", - type: "demo-map-marker", - x: 1000, y: 750, width: 40, height: 40, rotation: 0, - name: "Tre Cime Loop", - lat: 46.6190, - lng: 12.3018, - emoji: "🏔️", - category: "activity", - status: "Jul 15", + id: "demo-tool-ragents", + type: "folk-markdown", + ...pos(3, 7), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rAgents +AI assistants for your space. + +- **Canvas AI** — chat with context of your space +- **Image generation** — fal.ai Flux Pro +- **Video generation** — text-to-video +- **Multi-model** — Gemini, Ollama, Claude`, }, - // ─── rNotes: Packing List (shared with rTrips) ────────────── + // ─── Category: Infrastructure ─────────────────────────────── { - id: "demo-packing-alpine", - type: "folk-packing-list", - x: 1200, y: 750, width: 300, height: 300, rotation: 0, - listTitle: "Alpine Explorer Packing", - items: [ - { name: "Hiking boots (broken in)", packed: true, category: "footwear" }, - { name: "Rain jacket", packed: true, category: "clothing" }, - { name: "Trekking poles", packed: false, category: "gear" }, - { name: "Headlamp + batteries", packed: true, category: "gear" }, - { name: "Sunscreen SPF 50", packed: false, category: "personal" }, - { name: "Water filter", packed: false, category: "gear" }, - { name: "First aid kit", packed: true, category: "safety" }, - { name: "Passport + insurance", packed: true, category: "documents" }, - ], + id: "demo-cat-infra", + type: "folk-markdown", + x: START_X, y: START_Y + 8 * ROW_H - 40, width: 200, height: 30, rotation: 0, + content: "## Infrastructure", }, + { + id: "demo-tool-rspace", + type: "folk-markdown", + ...pos(0, 8), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rSpace Canvas +The infinite collaborative canvas. - // ─── rTokens: Governance Token ───────────────────────────── - { - id: "demo-mint-gov", - type: "folk-token-mint", - x: 1550, y: 50, width: 320, height: 280, rotation: 0, - tokenName: "Governance Token", - tokenSymbol: "GOV", - description: "Equal voting weight for group decisions. Each holder gets one share of governance power.", - totalSupply: 100, - issuedSupply: 100, - tokenColor: "#6d28d9", - tokenIcon: "🗳️", - createdBy: "Maya", - createdAt: "2026-06-15T10:00:00.000Z", +- **Drag & drop** — place any shape on the canvas +- **Arrows** — connect shapes to show relationships +- **Real-time sync** — see collaborators' cursors +- **Nested canvases** — embed spaces within spaces`, }, { - id: "demo-ledger-gov", - type: "folk-token-ledger", - x: 1940, y: 50, width: 380, height: 400, rotation: 0, - mintId: "demo-mint-gov", - entries: [ - { id: "gov-1", holder: "did:key:maya", holderLabel: "Maya", amount: 25, issuedAt: "2026-06-15T10:00:00.000Z", issuedBy: "Maya", memo: "Founding member" }, - { id: "gov-2", holder: "did:key:liam", holderLabel: "Liam", amount: 25, issuedAt: "2026-06-15T10:00:00.000Z", issuedBy: "Maya", memo: "Founding member" }, - { id: "gov-3", holder: "did:key:priya", holderLabel: "Priya", amount: 25, issuedAt: "2026-06-15T10:00:00.000Z", issuedBy: "Maya", memo: "Founding member" }, - { id: "gov-4", holder: "did:key:omar", holderLabel: "Omar", amount: 25, issuedAt: "2026-06-15T10:00:00.000Z", issuedBy: "Maya", memo: "Founding member" }, - ], - }, - { - id: "demo-arrow-gov", - type: "folk-arrow", - x: 0, y: 0, width: 0, height: 0, rotation: 0, - sourceId: "demo-mint-gov", - targetId: "demo-ledger-gov", - color: "#6d28d9", - }, + id: "demo-tool-rfiles", + type: "folk-markdown", + ...pos(1, 8), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rFiles +File storage for your space. - // ─── rTokens: Contribution Credits ───────────────────────── - { - id: "demo-mint-cred", - type: "folk-token-mint", - x: 1550, y: 500, width: 320, height: 280, rotation: 0, - tokenName: "Contribution Credits", - tokenSymbol: "CRED", - description: "Earned through contributions to trip planning. Redeemable for activity priority picks.", - totalSupply: 500, - issuedSupply: 155, - tokenColor: "#059669", - tokenIcon: "⭐", - createdBy: "Maya", - createdAt: "2026-06-20T14:00:00.000Z", +- **Upload anything** — drag-and-drop file uploads +- **Public shares** — shareable download links +- **IPFS pinning** — decentralized backup +- **Version history** — track file changes`, }, { - id: "demo-ledger-cred", - type: "folk-token-ledger", - x: 1940, y: 500, width: 380, height: 400, rotation: 0, - mintId: "demo-mint-cred", - entries: [ - { id: "cred-1", holder: "did:key:maya", holderLabel: "Maya", amount: 50, issuedAt: "2026-06-20T14:00:00.000Z", issuedBy: "Maya", memo: "Organized itinerary" }, - { id: "cred-2", holder: "did:key:liam", holderLabel: "Liam", amount: 40, issuedAt: "2026-06-22T09:00:00.000Z", issuedBy: "Maya", memo: "Gear research & drone rental" }, - { id: "cred-3", holder: "did:key:priya", holderLabel: "Priya", amount: 35, issuedAt: "2026-06-25T11:00:00.000Z", issuedBy: "Maya", memo: "Hut reservations" }, - { id: "cred-4", holder: "omar@example.com", holderLabel: "omar", amount: 30, issuedAt: "2026-06-28T16:00:00.000Z", issuedBy: "Maya", memo: "Emergency planning (escrow)" }, - ], - }, - { - id: "demo-arrow-cred", - type: "folk-arrow", - x: 0, y: 0, width: 0, height: 0, rotation: 0, - sourceId: "demo-mint-cred", - targetId: "demo-ledger-cred", - color: "#059669", - }, + id: "demo-tool-rsheets", + type: "folk-markdown", + ...pos(2, 8), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rSheets +Collaborative spreadsheets. - // ─── rFiles: Shared Documents ────────────────────────────── - { - id: "demo-file-permits", - type: "folk-file", - x: 1550, y: 900, width: 280, height: 80, rotation: 0, - fileName: "Swiss Hiking Permits.pdf", - fileSize: "2.4 MB", - mimeType: "application/pdf", - uploadedBy: "Priya", - uploadedAt: "2026-06-28", - tags: ["permits", "switzerland", "logistics"], +- **Real-time editing** — multi-user spreadsheets +- **Formulas** — standard spreadsheet functions +- **Import/export** — CSV and Excel support +- **Embed** — use spreadsheet data in other rApps`, }, { - id: "demo-file-insurance", - type: "folk-file", - x: 1550, y: 1000, width: 280, height: 80, rotation: 0, - fileName: "Travel Insurance Policy.pdf", - fileSize: "1.1 MB", - mimeType: "application/pdf", - uploadedBy: "Omar", - uploadedAt: "2026-06-25", - tags: ["insurance", "emergency", "documents"], - }, - { - id: "demo-file-topo", - type: "folk-file", - x: 1550, y: 1100, width: 280, height: 80, rotation: 0, - fileName: "Tre Cime Topo Map.gpx", - fileSize: "340 KB", - mimeType: "application/gpx+xml", - uploadedBy: "Liam", - uploadedAt: "2026-07-01", - tags: ["maps", "hiking", "dolomites"], - }, + id: "demo-tool-rexchange", + type: "folk-markdown", + ...pos(3, 8), width: CARD_W, height: CARD_H, rotation: 0, + content: `### rExchange +Peer-to-peer exchange. - // ─── rForum: Discussion Threads ──────────────────────────── - { - id: "demo-forum-weather", - type: "folk-forum-thread", - x: 1870, y: 900, width: 320, height: 160, rotation: 0, - threadTitle: "Weather Contingency Plan", - author: "Omar", - createdAt: "2026-06-30", - replyCount: 8, - lastReply: "Maya — 2 hours ago", - preview: "What's our plan if the Matterhorn trek gets rained out? I found a cheese museum in Zermatt as backup...", - tags: ["planning", "weather"], - }, - { - id: "demo-forum-transport", - type: "folk-forum-thread", - x: 1870, y: 1080, width: 320, height: 140, rotation: 0, - threadTitle: "Train vs Rental Car — Dolomites Transfer", - author: "Liam", - createdAt: "2026-06-28", - replyCount: 5, - lastReply: "Priya — yesterday", - preview: "The Bernina Express is scenic but 6 hours. Rental car is 3.5 hours. Thoughts?", - tags: ["transport", "logistics"], - }, - - // ─── rBooks: Shared Reading ──────────────────────────────── - { - id: "demo-book-alpine", - type: "folk-book", - x: 2350, y: 50, width: 280, height: 200, rotation: 0, - bookTitle: "The Alps: A Human History", - author: "Stephen O'Shea", - coverColor: "#7c3aed", - pageCount: 320, - currentPage: 145, - readers: ["Maya", "Liam"], - status: "reading", - }, - { - id: "demo-book-wild", - type: "folk-book", - x: 2350, y: 280, width: 280, height: 200, rotation: 0, - bookTitle: "Wild: A Journey from Lost to Found", - author: "Cheryl Strayed", - coverColor: "#059669", - pageCount: 315, - currentPage: 315, - readers: ["Priya"], - status: "finished", - }, - - // ─── rPubs: Published Artifacts ──────────────────────────── - { - id: "demo-pub-zine", - type: "folk-pub", - x: 2350, y: 520, width: 300, height: 180, rotation: 0, - pubTitle: "Alpine Explorer Zine", - pubType: "zine", - creator: "Maya", - format: "A5 risograph", - status: "in-production", - copies: 50, - price: 12.00, - currency: "EUR", - description: "Photo zine documenting the Alpine Explorer 2026 trip. Risograph printed on recycled paper.", - }, - - // ─── rSwag: Merchandise ──────────────────────────────────── - { - id: "demo-swag-tee", - type: "folk-swag", - x: 2350, y: 730, width: 280, height: 120, rotation: 0, - swagTitle: "Alpine Explorer 2026 Tee", - swagType: "t-shirt", - designer: "Liam", - sizes: ["S", "M", "L", "XL"], - price: 28.00, - currency: "EUR", - status: "available", - orderCount: 12, - }, - - // ─── rProviders: Local Production ────────────────────────── - { - id: "demo-provider-risograph", - type: "folk-provider", - x: 2350, y: 880, width: 300, height: 160, rotation: 0, - providerName: "Chamonix Print Collective", - location: "Chamonix, France", - capabilities: ["risograph", "screen-print", "letterpress"], - substrates: ["recycled paper", "card stock", "cotton"], - turnaround: "5-7 days", - rating: 4.8, - ordersFulfilled: 127, - }, - - // ─── rTasks: Task Board ───────────────────────────────────── - { - id: "demo-tasks-board", - type: "folk-tasks-board", - x: 750, y: 1350, width: 500, height: 280, rotation: 0, - boardTitle: "Trip Preparation Tasks", - columns: [ - { - name: "To Do", - tasks: [ - { title: "Book paragliding (2 remaining spots)", assignee: "Liam", priority: "high" }, - { title: "Buy trekking poles", assignee: "Maya", priority: "medium" }, - ], - }, - { - name: "In Progress", - tasks: [ - { title: "Research Italian drone regulations", assignee: "Liam", priority: "high" }, - { title: "First aid training refresher", assignee: "Omar", priority: "medium" }, - ], - }, - { - name: "Done", - tasks: [ - { title: "Book hut reservations", assignee: "Priya", priority: "high" }, - { title: "Get travel insurance", assignee: "Omar", priority: "high" }, - { title: "Break in hiking boots", assignee: "Maya", priority: "medium" }, - ], - }, - ], - }, - - // ─── rCal: Shared Calendar ───────────────────────────────── - { - id: "demo-cal-events", - type: "folk-calendar", - x: 50, y: 1350, width: 350, height: 250, rotation: 0, - calTitle: "Alpine Explorer 2026", - month: "July 2026", - events: [ - { date: "Jul 6", title: "Fly to Geneva", color: "#3b82f6" }, - { date: "Jul 7", title: "Lac Blanc Hike", color: "#22c55e" }, - { date: "Jul 8", title: "Via Ferrata", color: "#ef4444" }, - { date: "Jul 10", title: "Train to Zermatt", color: "#3b82f6" }, - { date: "Jul 13", title: "Paragliding", color: "#ef4444" }, - { date: "Jul 14", title: "Transfer to Dolomites", color: "#3b82f6" }, - { date: "Jul 15", title: "Tre Cime Loop", color: "#22c55e" }, - { date: "Jul 18", title: "Cooking Class", color: "#f59e0b" }, - { date: "Jul 20", title: "Fly Home", color: "#3b82f6" }, - ], - }, - - // ─── rNetwork: Contact Graph ─────────────────────────────── - { - id: "demo-network-graph", - type: "folk-network", - x: 1300, y: 1350, width: 400, height: 280, rotation: 0, - networkTitle: "Trip Contacts", - nodes: [ - { id: "maya", label: "Maya", role: "organizer" }, - { id: "liam", label: "Liam", role: "photographer" }, - { id: "priya", label: "Priya", role: "logistics" }, - { id: "omar", label: "Omar", role: "safety" }, - { id: "vrony", label: "Chez Vrony", role: "restaurant" }, - { id: "rega", label: "REGA Rescue", role: "emergency" }, - { id: "locatelli", label: "Rif. Locatelli", role: "hut" }, - ], - edges: [ - { from: "maya", to: "liam" }, - { from: "maya", to: "priya" }, - { from: "maya", to: "omar" }, - { from: "priya", to: "locatelli" }, - { from: "omar", to: "rega" }, - { from: "liam", to: "vrony" }, - ], - }, - - // ─── rTube: Shared Videos ────────────────────────────────── - { - id: "demo-tube-vlog", - type: "folk-video", - x: 2680, y: 50, width: 300, height: 180, rotation: 0, - videoTitle: "Lac Blanc Sunrise — Test Footage", - duration: "3:42", - creator: "Liam", - uploadedAt: "2026-07-08", - views: 24, - thumbnail: "sunrise-lacblanc", - }, - - // ─── rInbox: Group Messages ──────────────────────────────── - { - id: "demo-inbox-msg", - type: "folk-inbox", - x: 2680, y: 260, width: 300, height: 160, rotation: 0, - inboxTitle: "Trip Group Chat", - messages: [ - { from: "Maya", text: "Don't forget passports tomorrow!", time: "10:32 AM" }, - { from: "Liam", text: "Drone batteries charging. All 3 ready.", time: "10:45 AM" }, - { from: "Omar", text: "First aid kit packed. Added altitude sickness meds.", time: "11:02 AM" }, - { from: "Priya", text: "Locatelli confirmed our reservation!", time: "11:15 AM" }, - ], - }, - - // ─── rData: Trip Analytics ───────────────────────────────── - { - id: "demo-data-dashboard", - type: "folk-dashboard", - x: 2680, y: 450, width: 320, height: 220, rotation: 0, - dashTitle: "Trip Statistics", - metrics: [ - { label: "Total Budget", value: "€4,000", trend: "neutral" }, - { label: "Spent", value: "€1,203", trend: "up" }, - { label: "Remaining", value: "€2,797", trend: "down" }, - { label: "Tasks Done", value: "3/7", trend: "up" }, - { label: "Hike Distance", value: "~85 km", trend: "neutral" }, - { label: "Peak Altitude", value: "3,842m", trend: "neutral" }, - ], - }, - - // ─── rChoices: Decision Matrix ───────────────────────────── - { - id: "demo-choices-camera", - type: "folk-choice-matrix", - x: 2680, y: 700, width: 320, height: 200, rotation: 0, - choiceTitle: "Camera Gear Decision", - options: [ - { name: "DJI Mini 4 Pro", score: 8.5, criteria: { weight: 9, quality: 8, price: 7, battery: 10 } }, - { name: "GoPro Hero 12", score: 7.2, criteria: { weight: 10, quality: 6, price: 8, battery: 5 } }, - { name: "Sony A7C II", score: 7.8, criteria: { weight: 4, quality: 10, price: 5, battery: 8 } }, - ], - decidedBy: "Liam", - status: "decided", - winner: "DJI Mini 4 Pro", - }, - - // ─── rSplat: 3D Captures ─────────────────────────────────── - { - id: "demo-splat-matterhorn", - type: "folk-splat", - x: 2680, y: 930, width: 300, height: 160, rotation: 0, - splatTitle: "Matterhorn Base Camp — 3D Scan", - pointCount: "2.4M", - capturedBy: "Liam", - capturedAt: "2026-07-12", - fileSize: "48 MB", - status: "processing", +- **Post intents** — buy or sell anything +- **Add liquidity** — provide exchange liquidity +- **Order matching** — automated intent matching +- **Community trust** — reputation-backed trades`, }, ]; @@ -776,7 +565,7 @@ export async function ensureDemoCommunity(): Promise { if (!exists) { await createCommunity("r* Ecosystem Demo", "demo", null, "public", { - description: "Public demo space showcasing all rStack apps with the Alpine Explorer 2026 scenario", + description: "Public demo space — explore all rSpace tools on the canvas", }); console.log("[Demo] Created demo community with visibility: public"); } else {