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