Skip to content

feat(web): scripted full-screen product demo mode#3927

Closed
vibegui wants to merge 3 commits into
mainfrom
vibegui/interactive-studio-demo
Closed

feat(web): scripted full-screen product demo mode#3927
vibegui wants to merge 3 commits into
mainfrom
vibegui/interactive-studio-demo

Conversation

@vibegui

@vibegui vibegui commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

A public, fully-mocked, full-screen product demo (oya.ai-style) that animates the real Studio chat components from a scripted stream — no backend, MCP transport, or auth. The whole thing is a reusable framework: a demo reads top-to-bottom like a storyboard.

await d.user("Here's my store: https://acme.com — make it faster");
await d.tool(takeScreenshot({ url, image }));
await d.stream(DIAGNOSIS, { instant: true });

Two demos, each on its own URL (light mode)

  • /demo/storefront — business user drops in a URL → accurate perf+SEO diagnosis scorecard (real GFM table) → fix plan → parallel fixes → re-audit before/after → deploy.
  • /demo/agents — Studio as a web Conductor: the ghost cursor clicks Connect desktop → the real link modal opens → a mocked iTerm window runs `bunx decocms link` then minimizes → modal flips to Connected → work runs across two orgs in parallel (chat + live preview), switching context while the first org keeps building in the background.
  • /demo — a chooser linking to both. No cross-scenario auto-advance.

How it works (apps/mesh/src/web/demo/)

  • Director — non-React class owning all timing via `@decocms/std` `sleep`; mutates external `Store`s that components read through `useSyncExternalStore`, so no `useEffect` is needed to animate (the one lifecycle effect is documented, same pattern as `live-timer.tsx`).
  • Chat seam — `DemoChatStreamProvider` supplies a scripted `ChatStreamContextValue` (via a new exported `DemoChatStreamContext`), so the real `Chat.Messages` → `MessageAssistant` → tool-call renderers paint it identically to a live stream.
  • DemoProviders — mock `ProjectContext` + a network-free `QueryClient` (no auth gate).
  • Multi-track chats, org switching, iframe previews, ghost cursor, typed terminal — all driven by the same Director primitives.

The autoplay runner is guarded by a per-`stores` singleton with deferred teardown, so the dev runtime's spurious passive-effect re-runs (React Compiler / StrictMode) can't abort + restart a scenario mid-play.

Affected areas

  • New: `apps/mesh/src/web/demo/**`, `routes/demo.tsx`, `routes/demo-scenario.tsx`
  • Touched: `web/index.tsx` (register `/demo` + `/demo/$scenario` as public routes), `components/chat/chat-context.tsx` (export the chat-stream context for the demo seam — one line)
  • No backend/server changes.

Testing

  • `bun run check` ✅ · `bun run lint` ✅ · `bun run fmt:check` ✅
  • Verified end-to-end with Playwright: both demos run to completion in a stable loop with 0 console errors; zero network requests beyond static assets.
  • Screenshots: view live at `/demo/storefront` and `/demo/agents` (dev). UI is fully scripted/animated; static frames don't capture the motion.

🤖 Generated with Claude Code


Summary by cubic

Adds a public, full-screen Demo Mode that scripts the real Studio chat UI with no backend or auth. Now includes inline sprint/PR/daily-digest cards and an agent sidebar with background notifications; each demo plays once and then shows a CTA end card.

  • New Features

    • Inline chat cards: work plan (approve then live task ticks), pull request (checks → merge), and daily digest (connect Slack/Teams) via a tiny part-renderer registry.
    • Storefront demo: capture page → audit → show diagnosis → approve sprint → PR checks+merge → deploy → re‑audit → connect daily digest.
    • Agents demo: Studio-style sidebar to switch agents; work continues in the background with a notification dot; connect-desktop dialog + mocked iTerm and live preview panes.
  • Refactors

    • Core chat accepts external part renderers before its built-in switch; demo registers its cards, app behavior unchanged.
    • Exported DemoChatStreamContext; updates to card outputs are applied immutably so memoized components re-render reliably.

Written for commit 813d948. Summary will update on new commits.

Review in cubic

vibegui and others added 3 commits June 15, 2026 14:39
Add a public, fully-mocked walkthrough that drives the REAL Studio chat
components from a recorded stream — no backend, MCP transport, or auth.

Framework (apps/mesh/src/web/demo/):
- Director: a non-React class that owns all timing via @decocms/std sleep
  and mutates external Stores; components subscribe via useSyncExternalStore,
  so no useEffect is needed to animate. Screenplays read as a storyboard
  (await d.user/stream/think/tool/parallel/endTurn) and support multiple
  parallel chat tracks plus org switching, previews, a ghost cursor, and a
  typed terminal.
- Chat seam: DemoChatStreamProvider supplies a scripted ChatStreamContextValue
  (via an exported DemoChatStreamContext) so the real renderers paint it
  identically to a live stream.
- DemoProviders: mock ProjectContext + a network-free QueryClient.

Two demos, each on its own URL (/demo chooser, /demo/<id>), light mode:
- /demo/storefront — business user drops in a URL and gets an accurate
  perf+SEO diagnosis scorecard, a fix plan, parallel fixes, and a re-audit.
- /demo/agents — Studio as a web Conductor: ghost cursor opens the connect-
  desktop modal, a mocked iTerm runs `bunx decocms link` then minimizes to
  "connected", then work runs across two orgs in parallel (chat + live
  preview) while switching context.

The autoplay runner is guarded by a per-stores singleton with deferred
teardown so the dev runtime's spurious effect re-runs can't restart a
scenario mid-play.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reworked the scripted demos for rhythm and a real ending.

- Pacing: deliberate beats with anticipation captions, reading holds after
  big content (diagnosis / result tables), staggered parallel fixes, and
  smoother typing speeds.
- Transitions: caption fade/slide, org-workspace crossfade on switch, preview
  iframe fade-in on change, and cursor-driven org switching (the ghost cursor
  glides to and clicks the org tab) instead of hard cuts.
- Ending: the demo no longer loops silently — after a full play-through it
  shows an end card ("Get started free" / "Watch again"). The runner plays
  once, then awaits a replay signal.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Storefront demo:
- The agent now proposes a real WORK PLAN inline in the chat — a sprint of
  task cards — and waits for the viewer to approve (ghost cursor clicks
  "Approve & start"). Tasks then tick live; the first deliverable is a
  pull-request card (checks → merge), then deploy + re-audit.
- Ends with a "get this every morning" card to connect Slack / Teams for a
  daily automated audit.
- Inline cards render via a tiny part-renderer registry
  (chat/message/parts/extra-part-renderers.ts) the demo registers into — the
  core chat renderer stays demo-agnostic (empty registry in normal use).

Agents demo:
- Replaced the top org tabs with a real Studio-style sidebar of agents. You
  switch agents from the sidebar; background work keeps running and a
  notification dot appears on an agent's icon when its task finishes.

Fix: card outputs are replaced immutably on each update so the compiler-memoized
cards actually re-render (in-place mutation was silently dropped).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant