CodeDocs Vault

Cloud & Data

The web app, the API, the schema, auth, and the sync layer.

If 01-architecture.md is the desktop's anatomy, this doc is the cloud's. Two databases (cloud Postgres + per-host SQLite), a real-time row-sync layer (Electric SQL), a tunnel (Relay), a streaming layer (Durable Streams), and a broad tRPC + MCP API surface.


1. The Apps

App Path Hosted on Role
Marketing apps/marketing/ Vercel superset.sh — landing, comparisons, blog
Web apps/web/ Vercel app.superset.sh — auth, dashboard, agent UI, tasks, integrations
API apps/api/ Vercel api.superset.sh — Better Auth, tRPC, MCP transport, webhooks
Admin apps/admin/ Vercel Internal admin
Docs apps/docs/ Vercel docs.superset.sh
Electric proxy apps/electric-proxy/ Cloudflare Worker Subscriber for cloud Postgres → desktop, scoped per org
Relay apps/relay/ Fly.io WebSocket tunnel from cloud → device for SDK-routed ops
Streams (small) apps/streams/ — Durable streams adapter helpers
Mobile apps/mobile/ Expo React Native client (read-only-ish dashboard)
Desktop apps/desktop/ electron-builder The product

2. Web App — apps/web/

A Next.js 16 app (file: apps/web/src/app/). It's a thin client over apps/api's tRPC — there are no server-side tRPC routers in apps/web. Auth, agents, tasks, billing, integrations all live here as routes.

Key route groups:

apps/web/src/app/
├── (auth)/sign-in              ← Better Auth
├── (auth)/sign-up
├── (agents)/agents             ← list of agent sessions
├── (agents)/agents/workspace/[workspaceId]   ← per-workspace chat
├── (dashboard-legacy)/integrations           ← GitHub/Slack/Linear setup
├── (dashboard-legacy)/settings/billing       ← Stripe portal
├── tasks/[slug]
├── accept-invitation/[invitationId]
├── cli/auth/code               ← device code flow for CLI
├── auth/desktop/success        ← redirect target post-pair
└── oauth/consent               ← Better Auth consent screen

apps/web/src/trpc/client.ts:7 — tRPC client points to ${API_URL}/api/trpc with httpBatchLink, superjson, and credentials. Same shape as the desktop's electronTrpc — that consistency is the point.


3. API App — apps/api/

The cloud's tRPC server, plus webhooks, plus MCP transports, plus Better Auth.

3.1 tRPC handler

apps/api/src/app/api/trpc/[trpc]/route.ts mounts appRouter from @superset/trpc. Context is built in apps/api/src/trpc/context.ts:

ctx = { session, activeOrganizationId, auth, headers }

3.2 Routers (in packages/trpc/src/router/)

Router Purpose Key procedures
admin Admin-only ops (org, billing)
agent Device command status updates updateCommand
analytics PostHog event tracking trackEvent
apiKey API key lifecycle for MCP create, revoke
automation Cron-like recurring agent runs create, list, run, setPrompt, dispatchToHost
billing Stripe getPlans, updateSeats
chat Chat session CRUD createSession, getModels
device (legacy v1) —
host v2 host registration register, list, updateOnlineStatus
integration Linear/GitHub/Slack OAuth + sync connect, sync, disconnect
organization Orgs, invites, members create, invite, list
project (legacy v1) —
task Task CRUD with external sync create, update, list, get, delete
user Profile/preferences getMe, updatePreferences
v2Host v2 host registration register, updateStatus
v2Project v2 project model create, list
v2Workspace Worktree CRUD create, list, getCurrent
workspace (legacy v1) —

Aggregated in packages/trpc/src/root.ts.

3.3 Webhooks

/api/integrations/slack/*            ← OAuth, events, mentions, home view
/api/integrations/slack/jobs/process-mention  ← async Slack mention → agent invocation
/api/integrations/github/install     ← App install redirect
/api/integrations/github/webhook     ← PR/issue webhooks
/api/integrations/github/callback    ← OAuth callback
/api/github/sync                     ← manual sync

The Slack mention → agent invocation path is interesting: a Slack mention hits the API, gets queued, a job processor selects a target host, writes an agent_commands row, Electric pushes it to the host, the host launches an agent in a worktree, results stream back via Durable Streams.

3.4 MCP transports

/api/agent/[transport] supports SSE / WebSocket / stdio. Auth is via API key (X-API-Key: sk_live_… encoding userId, orgId, defaultDeviceId). apps/api/MCP_TOOLS.md is the public spec for the 15 cloud-immediate + device-routed procedures.

3.5 Chat HTTP

POST /api/chat/{sessionId}              ← create message
GET  /api/chat/{sessionId}/stream       ← SSE proxy (offset/cursor/live)

The SSE proxy returns 204 if up-to-date and forwards Authorization: Bearer ${DURABLE_STREAMS_SECRET} to the upstream Durable Streams service. See 03-llm-integration.md for the streaming details.

3.6 Automations

/api/automations/dispatch/[id]       ← dispatch automation run to relay/host
/api/automations/evaluate            ← evaluate rules (e.g., for Slack triggers)

4. Auth — Better Auth, not Clerk

packages/auth/src/server.ts — the canonical config. The presence of NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY in turbo.jsonc:globalEnv is legacy — the active provider is Better Auth v2.

4.1 Plugins enabled

4.2 Social providers

4.3 Trusted origins

4.4 User creation hook

packages/auth/src/server.ts:102-150 auto-enrolls new users into matching orgs based on email domain (allowedDomains on org). Falls back to creating a personal org if no match.

4.5 Auth flows

Flow Where
Web: email magic link / OAuth /sign-in → /api/auth/[...all]
Desktop pairing Web issues short-lived API key → desktop posts to /api/auth/desktop/connect → JWT
MCP via SDK X-API-Key (validated by API key plugin)
OAuth consent for Superset-as-OIDC-provider /oauth/consent

The session stores activeOrganizationId so a user with multi-org membership has org-scoped queries automatically.


5. Cloud Database — Postgres on Neon

Schema in packages/db/src/schema/. Core entities:

5.1 Auth (in auth.* schema)

5.2 Tasks

5.3 Devices/hosts (v1 + v2)

5.4 Workspaces

5.5 The command queue

5.6 Chat & automation

5.7 Integrations

5.8 Billing

5.9 In-flight (per plans/20260501-linear-team-entity.md)


6. Local Database — SQLite per host

Schema in packages/local-db/src/schema/. Roughly mirrors the cloud's "what does this machine see":

The host-service has its own SQLite too (per ~/.superset/host/{org}/host.db) for its own per-org state — workspace details, host registration, chat history.


7. Sync Layer

Three sync mechanisms, each scoped to a different problem:

7.1 Electric SQL — row-sync from cloud Postgres → desktop SQLite

apps/electric-proxy/src/index.ts:

7.2 Relay tunnel — cloud → device for active calls

apps/relay/src/index.ts:20:

7.3 Durable Streams — append-only event log per chat session

@durable-streams/client:

The cloud chat path layers Durable Streams under SSE; the desktop chat path skips this and runs Mastracode locally (no cloud DB writes).


8. Public SDK — packages/sdk/

Exists so external code (CI, third-party tools, customers) can do what the dashboard does.

import Superset from "@superset_sh/sdk";
 
const client = new Superset({
  apiKey: process.env.SUPERSET_API_KEY,            // sk_live_…
  organizationId: process.env.SUPERSET_ORGANIZATION_ID,
  baseURL: "https://api.superset.sh",              // optional
  relayURL: "https://relay.superset.sh",
  timeout: 60_000,
  maxRetries: 2,
});

Surface (1:1 with MCP):

Errors: APIError, RateLimitError, NotFoundError with parsed bodies.

The split between api-direct (immediate) and relay-routed (device-required) is explicit in the SDK so users can reason about which calls need an online host.


9. Data Flow Diagram

flowchart LR
    subgraph Web["Web Browser"]
        WebClient["dashboard / mobile / marketing"]
    end
    subgraph CloudVercel["Cloud — Vercel"]
        WebApp["apps/web<br/>Next.js 16"]
        APIApp["apps/api<br/>Next.js 16<br/>+ Better Auth<br/>+ tRPC<br/>+ MCP transports"]
    end
    subgraph CF["Cloudflare"]
        ElectricProxy["apps/electric-proxy<br/>row-sync"]
    end
    subgraph Fly["Fly.io"]
        RelayApp["apps/relay<br/>WebSocket tunnel"]
    end
    subgraph DS["Durable Streams (managed)"]
        DurableSt["per-session event log<br/>(chat)"]
    end
    subgraph Neon["Neon Postgres"]
        DBcloud[("@superset/db schema<br/>tasks · auth · workspaces<br/>agent_commands · automations")]
    end
    subgraph DesktopHost["Desktop / remote host"]
        Electron["Electron main"]
        HostSvc["host-service"]
        SQLite[("local SQLite<br/>(local-db + host-db)")]
    end
    subgraph SDKBox["SDK / CLI / external MCP client"]
        SDK["@superset_sh/sdk"]
    end

    WebClient -->|HTTPS| WebApp
    WebApp -->|tRPC| APIApp
    APIApp <-->|Drizzle| DBcloud
    DBcloud -.replication.-> ElectricProxy
    ElectricProxy -->|row sync| HostSvc
    HostSvc <--> SQLite
    Electron -->|tRPC IPC| HostSvc
    SDK -->|HTTPS| APIApp
    APIApp -->|relay| RelayApp
    RelayApp <-->|WebSocket| HostSvc
    APIApp -->|append| DurableSt
    DurableSt -->|SSE GET| WebClient
    HostSvc -->|host registration · chat| APIApp

10. Operational Sketch

Concern Shape today
Migration safety Drizzle: schema diffs + drizzle-kit generate — a Neon dev branch is created per migration, never the prod DB.
Multi-tenant isolation organizationId everywhere; Better Auth activeOrganizationId; Electric proxy filters by org.
Backups Neon point-in-time recovery (out-of-tree).
Observability Sentry + PostHog. PostHog person profiles tagged with billing status (commit 48c0d1dc8).
Secrets secrets table per org × project, encrypted; not loaded into Superset's main process.
CI Turbo task graph + bun run lint:fix + Sherif (per ci-check skill).
Release Desktop via electron-builder, canary path scripted (scripts/release-canary.sh).

11. Most-Important Cloud-Side Files (15)

  1. apps/api/MCP_TOOLS.md — full MCP spec for cloud tools
  2. packages/db/src/schema/schema.ts:94 — tasks (external sync model)
  3. packages/db/src/schema/schema.ts:299 — agent_commands (the queue)
  4. packages/db/src/schema/schema.ts:661 — chat_sessions
  5. packages/db/src/schema/schema.ts:709 — automations (rrule + agent config)
  6. packages/trpc/src/root.ts:24 — appRouter aggregation
  7. packages/auth/src/server.ts:51 — Better Auth config
  8. apps/api/src/app/api/trpc/[trpc]/route.ts — tRPC HTTP handler
  9. apps/api/src/trpc/context.ts — auth/org-scoped context
  10. apps/web/src/trpc/client.ts:7 — tRPC client
  11. apps/relay/src/index.ts:20 — relay tunnel WS
  12. apps/electric-proxy/src/index.ts:35 — Electric proxy + filtering
  13. packages/chat/src/server/trpc/service.ts — chat runtime
  14. packages/local-db/src/schema/schema.ts:68 — local worktree mirror
  15. packages/sdk/README.md — public SDK contract