Superset — Repository Analysis
"The Code Editor for AI Agents"
A holistic, multi-perspective analysis of the Superset monorepo. This document is the entry point — see siblings in docs/_analysis_/ for deeper dives.
1. Purpose & Problem
Superset is an Electron-based desktop "code editor for AI agents" that orchestrates CLI-based coding agents (Claude Code, OpenAI Codex, Cursor Agent, Gemini CLI, GitHub Copilot, Amp, OpenCode, Pi, Mastracode) in parallel, each isolated in its own git worktree.
Problem solved
Letting a single human pilot a single agent on a single branch is the obvious starting point — but it leaves capacity on the floor. Superset gives one developer a "swarm" UX:
- Parallelism — run 10+ agents simultaneously on the same machine without context switching.
- Isolation — each task gets a worktree (= separate branch + separate working directory) so agents do not stomp on each other or your in-progress work.
- Monitoring & handoff — built-in diff viewer, terminal panes, IDE handoff, GitHub PR integration, attention/notification when an agent has output something needing review.
- Universal compatibility — anything that runs in a terminal works (the abstraction is the PTY, not the agent vendor).
Target user
Power developers who already use multiple AI coding tools and want to run them concurrently. The pricing model (Stripe billing in packages/auth/src/stripe.ts) and team features (orgs, members, invitations) imply small dev teams as the secondary market — but the README's framing is unmistakably individual-first ("Code 10x faster with no switching cost").
Headline source
README.md:1-90, apps/marketing/ (positioning), apps/desktop/package.json ("description": "The last developer tool you'll ever need").
2. Tech Stack At A Glance
| Layer | Choice | Notes |
|---|---|---|
| Package manager | Bun 1.3.11 | No npm/yarn/pnpm anywhere. packageManager pinned in package.json:30. |
| Build/orchestration | Turborepo 2.8.7 | Root turbo.jsonc defines build, dev, test, typecheck, db:* tasks. |
| Lint/format | Biome 2.4.2 | Run at root for speed, not per-package. bun run lint:fix. |
| Frontend | React + TanStack Router (desktop) / Next.js 16 (web/api) | Desktop uses file-based routing under apps/desktop/src/renderer/routes/. |
| UI kit | shadcn/ui + TailwindCSS v4 | Shared packages/ui. components/ui/ uses kebab-case single files (CLI requirement). |
| State (desktop) | Zustand + TanStack Query | Many small per-feature stores (stores/tabs, stores/workspace-init, etc.). |
| Desktop shell | Electron + electron-vite + electron-builder |
Three-process model (main / preload / renderer) plus child host-services. |
| Terminal | node-pty (in a Node-only daemon) | Bun cannot host node-pty's tty.ReadStream; PTY daemon is the lone exception. |
| Cloud DB | Drizzle ORM + Neon Postgres | Schema in packages/db/src/schema/. |
| Local DB | better-sqlite3 + Drizzle | packages/local-db and host-service own their own SQLite dbs. |
| Real-time sync | Electric SQL (cloud) + Durable Streams (chat) | Cloud → desktop row sync; chat is event-sourced via Durable Streams. |
| Tunnel (relay) | Hono on Fly.io | apps/relay/ proxies SDK/MCP commands into a device behind NAT. |
| Auth | Better Auth v2 | OAuth + API keys + Stripe + organizations plugin. (Not Clerk — env vars are legacy.) |
| Agent runtime | Mastracode (@mastra/core 1.26.0-alpha) |
In-app chat sandbox/harness. External CLIs are launched via PTY wrappers. |
| LLM SDK | Vercel AI SDK (@ai-sdk/anthropic, @ai-sdk/openai, @ai-sdk/react) |
Used for small-model tasks (title generation) and chat UI streaming. |
| AST tooling | @ast-grep/napi | Powers semantic diffs. |
| API protocol | tRPC v11 everywhere | Electron IPC, HTTP, WebSocket — all tRPC. Plus MCP for agent-tool exposure. |
| Observability | Sentry + PostHog | sentry.*.config.ts in api/web/desktop; PostHog billing tagging (commit 48c0d1dc8). |
Why these choices (where the code reveals it)
- Bun for everything except node-pty — speed and ergonomics; single explicit hole closed by the Node PTY daemon (
packages/pty-daemon/src/main.ts). - Drizzle + Postgres + Electric — Electric's row-sync model fits Superset's "queue of commands flowing to a device" pattern (the
agent_commandstable). Plain Postgres for everything else keeps tooling minimal. - tRPC over IPC + HTTP + WS — one type system end-to-end, regardless of transport. The desktop's renderer can talk to (a) the Electron main process, (b) the local host-service over HTTP, (c) the cloud API — all using the same client shape.
- Worktrees over Docker — chosen as the primary isolation primitive because they're cheap, native, and let agents see existing dev tooling. Docker would be heavier and would break local IDE workflows.
3. Repo Layout
superset/
├── apps/
│ ├── desktop/ ← Electron app (the product)
│ ├── web/ ← app.superset.sh (dashboard, auth, agent UI)
│ ├── marketing/ ← superset.sh (Next.js marketing site)
│ ├── docs/ ← docs.superset.sh
│ ├── admin/ ← internal admin
│ ├── api/ ← cloud API (Next.js + tRPC + MCP)
│ ├── electric-proxy/ ← Cloudflare Worker proxying Electric SQL
│ ├── relay/ ← Fly.io WebSocket tunnel for SDK→device routing
│ ├── streams/ ← (durable streams adapter — small)
│ └── mobile/ ← Expo React Native client
├── packages/
│ ├── ui/ ← shadcn/ui shared components
│ ├── db/ ← Drizzle schema (cloud Postgres)
│ ├── local-db/ ← Drizzle schema (desktop SQLite)
│ ├── auth/ ← Better Auth setup (server + clients)
│ ├── trpc/ ← Shared tRPC routers (the appRouter)
│ ├── chat/ ← Chat runtime (client + server + shared)
│ ├── mcp/ ← MCP v1 tools
│ ├── mcp-v2/ ← MCP v2 tools (adds automations)
│ ├── desktop-mcp/ ← Desktop-side MCP server
│ ├── host-service/ ← Standalone workspace/git/PTY/chat service
│ ├── pty-daemon/ ← Node-only PTY daemon (survives app restarts)
│ ├── panes/ ← Tab+split layout primitive
│ ├── sdk/ ← Public TypeScript SDK
│ ├── shared/ ← Pure utilities (prompt templates, etc.)
│ ├── durable-session/ ← Session abstraction over durable streams
│ ├── email/ ← Transactional email
│ ├── workspace-fs/ ← Workspace filesystem helpers
│ ├── workspace-client/ ← Workspace client
│ ├── port-scanner/ ← Find free ports
│ ├── macos-process-metrics/ ← Native macOS metrics
│ ├── host-service/ ← (above)
│ ├── cli-framework/ ← CLI plumbing
│ └── cli/ ← `superset` CLI
└── tooling/
└── typescript/ ← Shared tsconfigs
The repo also has top-level plans/ (cross-cutting work-in-progress proposals), docs/ (cookbook, design, tickets), and .agents/commands/ (slash commands shared across Claude Code, Cursor, Codex, OpenCode via symlinks).
4. Reading Order For This Analysis
| File | Topic |
|---|---|
00-overview.md |
This document — purpose, stack, layout |
01-architecture.md |
Process model, host-service, worktrees, IPC patterns, diagrams |
02-execution-flow.md |
Entry points, key flows: workspace creation, terminal launch, agent dispatch |
03-llm-integration.md |
LLM usage, prompts, tools, MCP, Mastra, streaming, guardrails |
04-cloud-and-data.md |
Web/API/DB/auth/sync/SDK/relay |
05-design-patterns.md |
Patterns, V1→V2 transition, tradeoffs, lessons |
06-key-files.md |
Curated map of files → responsibility, prompt index |
5. The 60-Second Mental Model
Picture three concentric rings:
┌─────────────────────────────────┐
│ CLOUD (Vercel + Neon + CF) │
│ apps/api · apps/relay · │
│ apps/electric-proxy │
│ Tasks · Auth · Integrations │
└────────────┬────────────────────┘
│ Better Auth · tRPC · MCP
│ Electric SQL row sync
│ Durable Streams (SSE)
┌────────────┴────────────────────┐
│ DESKTOP — Electron main │
│ apps/desktop/src/main │
│ • Window/Tray/Auto-update │
│ • Manifest-based adoption │
│ • IPC tRPC router (35+ groups)│
└─────┬───────────────┬───────────┘
│ tRPC-electron │ HTTP/WS
┌───────┴────────┐ ┌───┴────────────────┐
│ Renderer (UI) │ │ Host-Service (Hono)│
│ React + Zustand│ │ packages/host-svc │
│ TanStack Router│ │ • workspace CRUD │
│ Mastra UI │ │ • git ops │
└────────────────┘ │ • PTY supervisor │
│ • chat runtime │
│ • SQLite │
└────┬───────────────┘
│ Unix socket
┌────┴───────────────┐
│ pty-daemon (Node) │
│ packages/pty-daemon│
│ • node-pty FDs │
│ • survives restart │
└────┬───────────────┘
│ PTY master
▼
┌────────────────────┐
│ Agent CLI process │
│ claude / codex / │
│ cursor / gemini … │
│ env: SUPERSET_* │
│ PATH=~/.superset/ │
│ bin (wrappers)│
└────────────────────┘
The innermost ring is the agent CLI. Its PATH is rewritten so that claude/codex/etc. resolve to wrapper scripts under ~/.superset/bin/, which post events back to Superset's hooks endpoint. This is how Superset knows when an agent is idle, has emitted a diff, or needs attention — without modifying the agent itself.
The host-service is a deployable process. On a laptop it's a child of Electron; on a server (future state) it's a standalone container. This decoupling is the headline architectural bet (see 01-architecture.md and apps/desktop/HOST_SERVICE_BOUNDARIES.md).
The cloud is mostly a sync hub: tasks, integrations (Linear/GitHub/Slack), billing, and a queue of agent commands that Electric SQL replicates down to whichever device should execute them.