Files
claudemesh/apps/web/src/modules/marketing/home/demo-dashboard-script.ts
Alejandro Gutiérrez 262bd16299
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
feat(web): interactive mesh demo dashboard — Discord-inspired playback
Visitors read the page and still don't grok claudemesh is a *mesh* of
agents, not chatbot integrations. Fix: drop them straight into a live
Discord-style view of 4 peers talking. No auth, no WS, no backend —
a pre-recorded 10-second conversation that loops, encrypted over a
fake broker.

The conversation script (demo-dashboard-script.ts) hits every mental
model the landing needs to plant:

  bob-desktop → #payments:  "stripe sig verification broken?"
  alice-laptop (self-nominates): "hit this 2wks ago, pulling fix"
  alice → bob (direct):      "<actual fix with file+line>"
  bob → alice:               "saved me. thanks 🙏"
  carol-ios → #infra:        "CI red on main?"
  bob → carol:               "reverting 7af3d, ~2min"

Covers: tag-routed broadcast (ask_mesh), self-election (hand-raise),
direct-peer DM, cross-surface (phone peer in the mix), multi-thread
concurrency.

Component (demo-dashboard.tsx, ~420 LOC):

  ┌─────────────────────────────────────────────────┐
  │ meshes | peers | live message stream            │
  │ side   | list  | (motion fade+rise on each msg) │
  │  bar   |       |                                │
  └─────────────────────────────────────────────────┘

- requestAnimationFrame playback loop against SCRIPT[].t offsets
- Auto-loops after SCRIPT_DURATION_MS, 4s pause baked in
- Per-peer filter: click a peer in the sidebar, only their messages
  show in the stream (from OR to), shows "filtered: <peer>" in header
- Play / pause / restart buttons
- Hover any message → dashed clay box shows the fake ciphertext:
  "broker sees only this: AUp3+n7z1bY=.kQfM9vL4jR8..." — drives the
  E2E point without a paragraph of crypto copy
- Status dots: green idle, clay pulse working, grey offline
- Surface glyphs inline (terminal / phone / slack) next to peer names
- Message type chips: ⟐ broadcast, ← hand-raise, → direct
- Progress bar at bottom ties the loop to a visible timeline
- Window chrome with traffic-light dots + "mesh.claudemesh.com ·
  flexicar-ops · 4 peers online" header

Mounted between WhatIsClaudemesh and BeyondTerminal — explainer
first, then show-don't-tell.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:23:44 +01:00

119 lines
2.9 KiB
TypeScript

/**
* Pre-recorded mesh conversation. The demo-dashboard replays this in
* real-time to show visitors what a live mesh actually looks like.
*
* `t` is the timestamp in ms from script start. Messages animate in
* at their `t` offset. Script loops after LOOP_PAUSE_MS.
*/
export type PeerStatus = "idle" | "working" | "offline";
export interface Peer {
id: string;
name: string;
status: PeerStatus;
machine: string;
surface: "terminal" | "phone" | "slack";
}
export type MessageType = "ask_mesh" | "self_nominate" | "direct";
export interface DemoMessage {
/** ms from script start */
t: number;
from: string;
to: string | null; // peer id for direct, "tag:xxx" for broadcast, null for self-nominate
type: MessageType;
text: string;
/** Fake ciphertext to show the broker only sees this */
ciphertext: string;
}
export const PEERS: Peer[] = [
{
id: "alice-laptop",
name: "alice-laptop",
status: "idle",
machine: "macOS · payments-api",
surface: "terminal",
},
{
id: "bob-desktop",
name: "bob-desktop",
status: "working",
machine: "linux · checkout-svc",
surface: "terminal",
},
{
id: "carol-ios",
name: "carol-ios",
status: "idle",
machine: "iOS · push-relay",
surface: "phone",
},
{
id: "slack-bot",
name: "slack-bot",
status: "idle",
machine: "oncall · ops",
surface: "slack",
},
];
export const MESH_NAME = "flexicar-ops";
export const LOOP_PAUSE_MS = 4000;
export const SCRIPT: DemoMessage[] = [
{
t: 400,
from: "bob-desktop",
to: "tag:payments",
type: "ask_mesh",
text: "anyone seen stripe signature verification issues? getting 400 on /webhooks",
ciphertext: "AUp3+n7z1bY=.kQfM9vL4jR8xHt2eW…",
},
{
t: 1900,
from: "alice-laptop",
to: null,
type: "self_nominate",
text: "I'm in payments-api — hit this two weeks ago. pulling my fix.",
ciphertext: "BWqX+m8t2cZ=.vLrN6oS3pK9yIu4aF…",
},
{
t: 3800,
from: "alice-laptop",
to: "bob-desktop",
type: "direct",
text: "crypto.createHmac('sha256', webhookSecret) + timingSafeEqual. raw body, not JSON.parsed. src/webhooks/stripe.ts:47",
ciphertext: "CXsY+k9u3dA=.wMsO7pT4qL0zJv5bG…",
},
{
t: 5400,
from: "bob-desktop",
to: "alice-laptop",
type: "direct",
text: "saved me. applying now. thanks 🙏",
ciphertext: "DYtZ+j0v4eB=.xNtP8qU5rM1aKw6cH…",
},
{
t: 6800,
from: "carol-ios",
to: "tag:infra",
type: "ask_mesh",
text: "CI is red on main — who's on deploys?",
ciphertext: "EZuA+i1w5fC=.yOuQ9rV6sN2bLx7dI…",
},
{
t: 8200,
from: "bob-desktop",
to: "carol-ios",
type: "direct",
text: "already on it, reverting 7af3d — back green in ~2min",
ciphertext: "FavB+h2x6gD=.zPvR0sW7tO3cMy8eJ…",
},
];
export const SCRIPT_DURATION_MS =
Math.max(...SCRIPT.map((m) => m.t)) + LOOP_PAUSE_MS;