# modem-dev/sideshow architecture

> Architecture diagram of the GitHub repository modem-dev/sideshow, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/modem-dev/sideshow
- Repository: https://github.com/modem-dev/sideshow

## Overview

#### Purpose and entry points
Sideshow is a live visual-surface system for coding agents: agents publish typed, composable content cards and users view them live in a browser, respond in threads, or connect through HTTP/MCP/CLI. Primary Node entry points are `bin/sideshow.js` and `server/index.ts`; demo seeding is `bin/demoData.js`. The browser viewer begins at `viewer/src/main.tsx`.

#### Server application and API
The Node application assembles HTTP routes, static viewer delivery, session/surface APIs, and runtime services in `server/app.ts` and `server/index.ts`. Surface creation/update logic and post-oriented surface handling sit in `server/postSurfaces.ts`; externally consumable/API-oriented views are defined in `server/apiViews.ts`. This is the boundary between agent-facing writes and viewer-facing reads.

#### Persistence and migration
A storage abstraction permits local persistence implementations behind the app layer: `server/storage.ts`, `server/sqlStore.ts`, and `server/sqliteStorage.ts`. Data-directory and data-model evolution is handled by `server/migrateDataDir.ts`. This isolates sessions, posts/surfaces, comments, and assets from Node versus Worker deployment concerns.

#### Live updates and interaction flow
Agents publish surfaces through HTTP or MCP; the server persists them and broadcasts updates through `server/events.ts`. The viewer consumes API/event state via `viewer/src/api.ts` and `viewer/src/state.ts`, then renders session timelines and cards. User feedback travels back as posts/notes, with viewer-side handling in `viewer/src/viewerPost.ts` and `viewer/src/notes.ts`.

#### Viewer rendering boundary
The Solid/Vite viewer is a self-contained client application rooted in `viewer/src/App.tsx`. It dispatches typed surface parts to native renderers such as `viewer/src/TraceSurface.tsx`, `viewer/src/JsonSurface.tsx`, and `viewer/src/ImageSurface.tsx`; themes are applied through `viewer/src/theme.ts`. Agent-authored HTML is a distinct rendering/security boundary, while markdown, diffs, code, Mermaid, JSON, terminal output, and traces are rendered using viewer-owned chrome and styles.

#### Agent integrations
The CLI launches and connects local instances through `bin/sideshow.js`. MCP support has both transport/runtime handling and a formal tool specification in `server/mcpHttp.ts` and `server/mcpSpec.ts`; a stdio MCP server is exposed from `mcp/server.ts`. Claude integration is distributed as plugin/skill metadata under `plugin/.claude-plugin/plugin.json` and `plugin/skills/sideshow/SKILL.md`; a lightweight extension exists at `extensions/sideshow.js`.

#### Cloudflare deployment and image capture
A Cloudflare Worker entry point adapts the service for remote/shared deployments in `workers/index.ts`, with public-serving behavior in `workers/public.ts`. Worker storage/runtime typing is represented by `workers/modules.d.ts`. PNG surface capture is Worker-only and integrates Cloudflare Browser Rendering through `workers/screenshot.ts`; local Node deliberately does not provide this headless-browser capability. Wrangler deployment configuration is `wrangler.jsonc`.

#### Terminal sibling
`sideshow-term/` is an alpha sibling rather than the browser viewer: it parses and renders terminal surface markup through `sideshow-term/src/parse.ts`, `sideshow-term/src/render.ts`, and CLI preview/watch flows such as `sideshow-term/src/previewCli.ts`. It has its own server and package boundary at `sideshow-term/server.ts`.

Main entry points: [`server/postSurfaces.ts`](https://github.com/modem-dev/sideshow/blob/main/server/postSurfaces.ts) (Surface API), [`server/app.ts`](https://github.com/modem-dev/sideshow/blob/main/server/app.ts) (HTTP application), [`viewer/src/App.tsx`](https://github.com/modem-dev/sideshow/blob/main/viewer/src/App.tsx) (Viewer app), [`server/storage.ts`](https://github.com/modem-dev/sideshow/blob/main/server/storage.ts) (Storage layer)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_node["Node service"]
  node_demo["Demo seeding<br/>Node script<br/>[demoData.js]"]
  node_node_entry["Node entry<br/>Node runtime<br/>[index.ts]"]
  node_app["HTTP application<br/>app assembly<br/>[app.ts]"]
  node_surface_api["Surface API<br/>write/read boundary<br/>[postSurfaces.ts]"]
  node_api_views["API views<br/>API projection<br/>[apiViews.ts]"]
  node_storage[("Storage layer<br/>persistence abstraction<br/>[storage.ts]")]
  node_sqlite[("SQLite storage<br/>local persistence<br/>[sqliteStorage.ts]")]
  node_migration["Data migration<br/>data evolution<br/>[migrateDataDir.ts]"]
  node_events["Live events<br/>update broadcast<br/>[events.ts]"]
end

subgraph group_viewer["Browser viewer"]
  node_viewer_app["Viewer app<br/>Solid/Vite client<br/>[App.tsx]"]
  node_viewer_entry["Viewer entry<br/>browser entry<br/>[main.tsx]"]
  node_viewer_state["API and state<br/>client data layer<br/>[state.ts]"]
  node_surface_renderers["Typed renderers<br/>surface rendering<br/>[TraceSurface.tsx]"]
  node_feedback["Posts and notes<br/>viewer interaction<br/>[viewerPost.ts]"]
end

subgraph group_integrations["Agent integrations"]
  node_cli["CLI launcher<br/>Node CLI<br/>[sideshow.js]"]
  node_mcp_http["MCP HTTP runtime<br/>MCP transport<br/>[mcpHttp.ts]"]
  node_mcp_stdio["MCP stdio server<br/>MCP server<br/>[server.ts]"]
end

subgraph group_worker["Cloudflare deployment"]
  node_worker_entry["Worker entry<br/>Cloudflare runtime<br/>[index.ts]"]
  node_screenshot["PNG capture<br/>Worker-only capture<br/>[screenshot.ts]"]
end

subgraph group_terminal["Terminal sibling"]
  node_term["Terminal renderer<br/>terminal markup pipeline<br/>[render.ts]"]
  node_term_server["Terminal server<br/>sibling runtime<br/>[server.ts]"]
end

node_cli -->|"launches"| node_node_entry
node_demo -->|"seeds"| node_surface_api
node_node_entry -->|"starts"| node_app
node_app -->|"routes requests"| node_surface_api
node_app -->|"serves static app"| node_viewer_app
node_surface_api -->|"projects reads"| node_api_views
node_surface_api -->|"persists"| node_storage
node_storage -->|"local implementation"| node_sqlite
node_migration -->|"evolves data"| node_storage
node_surface_api -->|"broadcasts changes"| node_events
node_viewer_entry -->|"mounts"| node_viewer_app
node_viewer_app -->|"uses"| node_viewer_state
node_viewer_state -->|"reads API"| node_api_views
node_events -->|"live updates"| node_viewer_state
node_viewer_app -->|"renders parts"| node_surface_renderers
node_feedback -->|"posts feedback"| node_surface_api
node_mcp_http -->|"publishes surfaces"| node_surface_api
node_mcp_stdio -->|"uses transport"| node_mcp_http
node_worker_entry -.->|"adapts service"| node_app
node_worker_entry -->|"enables capture"| node_screenshot
node_term_server -->|"serves preview"| node_term

click node_cli "https://github.com/modem-dev/sideshow/blob/main/bin/sideshow.js"
click node_demo "https://github.com/modem-dev/sideshow/blob/main/bin/demoData.js"
click node_node_entry "https://github.com/modem-dev/sideshow/blob/main/server/index.ts"
click node_app "https://github.com/modem-dev/sideshow/blob/main/server/app.ts"
click node_surface_api "https://github.com/modem-dev/sideshow/blob/main/server/postSurfaces.ts"
click node_api_views "https://github.com/modem-dev/sideshow/blob/main/server/apiViews.ts"
click node_storage "https://github.com/modem-dev/sideshow/blob/main/server/storage.ts"
click node_sqlite "https://github.com/modem-dev/sideshow/blob/main/server/sqliteStorage.ts"
click node_migration "https://github.com/modem-dev/sideshow/blob/main/server/migrateDataDir.ts"
click node_events "https://github.com/modem-dev/sideshow/blob/main/server/events.ts"
click node_viewer_app "https://github.com/modem-dev/sideshow/blob/main/viewer/src/App.tsx"
click node_viewer_entry "https://github.com/modem-dev/sideshow/blob/main/viewer/src/main.tsx"
click node_viewer_state "https://github.com/modem-dev/sideshow/blob/main/viewer/src/state.ts"
click node_surface_renderers "https://github.com/modem-dev/sideshow/blob/main/viewer/src/TraceSurface.tsx"
click node_feedback "https://github.com/modem-dev/sideshow/blob/main/viewer/src/viewerPost.ts"
click node_mcp_http "https://github.com/modem-dev/sideshow/blob/main/server/mcpHttp.ts"
click node_mcp_stdio "https://github.com/modem-dev/sideshow/blob/main/mcp/server.ts"
click node_worker_entry "https://github.com/modem-dev/sideshow/blob/main/workers/index.ts"
click node_screenshot "https://github.com/modem-dev/sideshow/blob/main/workers/screenshot.ts"
click node_term "https://github.com/modem-dev/sideshow/blob/main/sideshow-term/src/render.ts"
click node_term_server "https://github.com/modem-dev/sideshow/blob/main/sideshow-term/server.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_demo,node_node_entry,node_app,node_surface_api,node_api_views,node_storage,node_sqlite,node_migration,node_events toneBlue
class node_viewer_app,node_viewer_entry,node_viewer_state,node_surface_renderers,node_feedback toneAmber
class node_cli,node_mcp_http,node_mcp_stdio toneMint
class node_worker_entry,node_screenshot toneRose
class node_term,node_term_server toneIndigo
```

## Components

### Node service

- [Demo seeding](https://github.com/modem-dev/sideshow/blob/main/bin/demoData.js): Node script · `bin/demoData.js`
- [Node entry](https://github.com/modem-dev/sideshow/blob/main/server/index.ts): Node runtime · `server/index.ts`
- [HTTP application](https://github.com/modem-dev/sideshow/blob/main/server/app.ts): app assembly · Combines routes, static viewer delivery, APIs, and runtime services. · `server/app.ts`
- [Surface API](https://github.com/modem-dev/sideshow/blob/main/server/postSurfaces.ts): write/read boundary · Handles agent writes and viewer-facing surface views. · `server/postSurfaces.ts`
- [API views](https://github.com/modem-dev/sideshow/blob/main/server/apiViews.ts): API projection · `server/apiViews.ts`
- [Storage layer](https://github.com/modem-dev/sideshow/blob/main/server/storage.ts): persistence abstraction · Persists sessions, surfaces, comments, and assets across runtimes. · `server/storage.ts`
- [SQLite storage](https://github.com/modem-dev/sideshow/blob/main/server/sqliteStorage.ts): local persistence · `server/sqliteStorage.ts`
- [Data migration](https://github.com/modem-dev/sideshow/blob/main/server/migrateDataDir.ts): data evolution · `server/migrateDataDir.ts`
- [Live events](https://github.com/modem-dev/sideshow/blob/main/server/events.ts): update broadcast · `server/events.ts`

### Browser viewer

- [Viewer app](https://github.com/modem-dev/sideshow/blob/main/viewer/src/App.tsx): Solid/Vite client · Renders live session timelines and cards. · `viewer/src/App.tsx`
- [Viewer entry](https://github.com/modem-dev/sideshow/blob/main/viewer/src/main.tsx): browser entry · `viewer/src/main.tsx`
- [API and state](https://github.com/modem-dev/sideshow/blob/main/viewer/src/state.ts): client data layer · Consumes API state and live events. · `viewer/src/state.ts`
- [Typed renderers](https://github.com/modem-dev/sideshow/blob/main/viewer/src/TraceSurface.tsx): surface rendering · Dispatches surface parts to viewer-owned renderers. · `viewer/src/TraceSurface.tsx`
- [Posts and notes](https://github.com/modem-dev/sideshow/blob/main/viewer/src/viewerPost.ts): viewer interaction · Sends user feedback back as posts or notes. · `viewer/src/viewerPost.ts`

### Agent integrations

- [CLI launcher](https://github.com/modem-dev/sideshow/blob/main/bin/sideshow.js): Node CLI · Launches and connects local instances. · `bin/sideshow.js`
- [MCP HTTP runtime](https://github.com/modem-dev/sideshow/blob/main/server/mcpHttp.ts): MCP transport · `server/mcpHttp.ts`
- [MCP stdio server](https://github.com/modem-dev/sideshow/blob/main/mcp/server.ts): MCP server · `mcp/server.ts`

### Cloudflare deployment

- [Worker entry](https://github.com/modem-dev/sideshow/blob/main/workers/index.ts): Cloudflare runtime · Adapts the service for shared remote deployments. · `workers/index.ts`
- [PNG capture](https://github.com/modem-dev/sideshow/blob/main/workers/screenshot.ts): Worker-only capture · Uses Cloudflare Browser Rendering; unavailable locally. · `workers/screenshot.ts`

### Terminal sibling

- [Terminal renderer](https://github.com/modem-dev/sideshow/blob/main/sideshow-term/src/render.ts): terminal markup pipeline · Parses and renders terminal surfaces. · `sideshow-term/src/render.ts`
- [Terminal server](https://github.com/modem-dev/sideshow/blob/main/sideshow-term/server.ts): sibling runtime · `sideshow-term/server.ts`

## Connections

- CLI launcher → Node entry: launches
- Demo seeding → Surface API: seeds
- Node entry → HTTP application: starts
- HTTP application → Surface API: routes requests
- HTTP application → Viewer app: serves static app
- Surface API → API views: projects reads
- Surface API → Storage layer: persists
- Storage layer → SQLite storage: local implementation
- Data migration → Storage layer: evolves data
- Surface API → Live events: broadcasts changes
- Viewer entry → Viewer app: mounts
- Viewer app → API and state: uses
- API and state → API views: reads API
- Live events → API and state: live updates
- Viewer app → Typed renderers: renders parts
- Posts and notes → Surface API: posts feedback
- MCP HTTP runtime → Surface API: publishes surfaces
- MCP stdio server → MCP HTTP runtime: uses transport
- Worker entry → HTTP application: adapts service
- Worker entry → PNG capture: enables capture
- Terminal server → Terminal renderer: serves preview
