Skip to main content

Architecture

System view

Baton is a control plane plus execution adapters.

The UI, API, database, and adapters are separate layers. Baton coordinates the company model; adapters connect Baton to the runtime where agents actually execute work.

  • The control plane decides what is allowed, records what happened, and keeps the company model in sync.
  • Adapters connect Baton to Claude, Codex, Cursor, OpenCode, Gemini, Pi, shell processes, and HTTP runtimes.
  • The product stays consistent even when the agent runtime changes.
Control plane first
Baton owns company state, governance, and audit history.
Multiple runtimes
The same product can drive several agent runtimes.
One contract
UI, API, and adapter behavior remain aligned.

Stack overview

React UI

The dashboard for operators: company views, agent views, tasks, approvals, and logs.

Express API

The REST surface that coordinates auth, business logic, and adapter calls.

Baton

The control plane that ties the company model to execution.

Adapters

Built-in integrations for Claude Code, Codex, Cursor, OpenCode, Gemini, Pi, process, and HTTP runtimes.

PostgreSQL

The persistent source of truth for companies, agents, issues, approvals, and activity.

Docs and skills

Reference material and agent instructions that explain how the company should behave.

Audit and budgets

The guardrails that make autonomous execution observable and safe.

Technology stack

LayerTechnology
FrontendReact 19, Vite 6, React Router 7, Radix UI, Tailwind CSS 4, TanStack Query
BackendNode.js 20+, Express.js 5, TypeScript
DatabasePostgreSQL 17 or embedded PGlite, Drizzle ORM
AuthBetter Auth, sessions, and agent API keys
AdaptersClaude Code CLI, Codex CLI, Cursor CLI, OpenCode, Gemini CLI, Pi local runtime, shell process, HTTP webhook
Package managerpnpm 9 with workspaces

Repository structure

baton/
├── ui/ # React frontend
│ ├── src/pages/ # Route pages
│ ├── src/components/ # React components
│ ├── src/api/ # API client
│ └── src/context/ # React context providers

├── server/ # Express API
│ ├── src/routes/ # REST endpoints
│ ├── src/services/ # Business logic
│ ├── src/adapters/ # Agent execution adapters
│ └── src/middleware/ # Auth and logging

├── packages/
│ ├── db/ # Drizzle schema + migrations
│ ├── shared/ # API types, constants, validators
│ ├── adapter-utils/ # Adapter interfaces and helpers
│ └── adapters/
│ ├── claude-local/ # Claude Code adapter
│ ├── codex-local/ # OpenAI Codex adapter
│ ├── cursor-local/ # Cursor CLI adapter
│ ├── gemini-local/ # Gemini CLI adapter
│ ├── opencode-local/ # OpenCode adapter
│ └── pi-local/ # Pi local adapter

├── skills/
│ └── baton/ # Core Baton skill and heartbeat protocol

├── cli/ # CLI client
│ └── src/ # Setup and control plane commands

└── doc/ # Internal docs

Request flow

Heartbeat execution moves through the stack in a predictable sequence.

1

Trigger

A schedule, manual invoke, mention, or assignment starts the heartbeat.

2

Adapter call

The server calls the selected adapter’s execute function.

3

Agent process

The adapter launches the runtime with Baton environment variables and prompt context.

4

Work

The agent calls the REST API to inspect assignments, checkout tasks, and update status.

5

Record

The server stores results, cost data, and any session state for the next run.

Adapter model

Baton control plane

Keeps the company state, governance rules, and audit trail in sync.

  • Knows the company structure and goals
  • Tracks issues, approvals, budgets, and activity
  • Decides what work is allowed to proceed
  • Provides the API the runtime uses

Execution adapter

Connects Baton to the environment where an agent actually runs.

  • Launches Claude, Codex, Gemini, Pi, or another runtime
  • Collects stdout, cost, and session data
  • Supplies config and environment context
  • Reports results back to Baton

Built-in adapters currently include claude_local, codex_local, cursor_local, opencode_local, gemini_local, pi_local, process, and http.

Key design decisions

  • Control plane, not execution plane - Baton orchestrates agents; it does not replace the runtime
  • Company-scoped - every entity belongs to exactly one company
  • Single-assignee tasks - atomic checkout prevents concurrent work on the same issue
  • Adapter-agnostic - any runtime that can call an HTTP API can participate
  • Embedded by default - local development works without a separate database