Stack

Boring parts. Fast product.

A Laravel core, a local-first Svelte client, one small Go binary on every machine and a relay for terminals. Here is every piece, and how a run moves through them.

Architecture

One core. Many machines.

One central core serves many organisations. Browsers sync with it, daemons take orders from it, and terminal bytes travel through the relay so the core never carries them.

The daemon dials out: HTTPS to the core, a websocket to the relay. Terminal bytes never pass through the core.

Versions

What it runs on.

No exotic dependencies. The Go side has exactly one: a websocket library.

PieceBuilt withWhy it is there
Core
FrameworkLaravel 13, PHP 8.4The one central core
DatabaseMySQLOrg boundary as composite foreign keys
QueuesRedis + HorizonJobs, imports, the scheduler's work
RealtimeReverbLive events to clients and daemons
FilesS3Attachments and images
AuthFortify, SocialiteMagic link, Google, GitHub, passkeys, device flow
Agents and APIlaravel/mcp, ScrambleMCP server and REST API docs
QualityPest 4, Larastan, PintSuite runs on SQLite and MySQL
Client
UISvelte 5 (runes), TypeScriptThe whole app
BuildVite 8, Tailwind 4Fast builds, tokens for light and dark
Offlinevite-plugin-pwa, Workbox, idbInstallable, data in IndexedDB
LiveEcho + ReverbEvents the moment they happen
Terminalxterm.js 6Agent sessions in the browser
EditorTipTap 3Issues, documents, mentions
TablesTanStack table + virtualLong lists that stay fast
LookLucide, GeistIcons and type
Machines
DaemonGo 1.27, coder/websocketOne binary per machine, runs agents in tmux
RelayGo 1.27, coder/websocketTerminal bytes between browser and daemon
Updatessha256 + ed25519Signed self-update, atomic swap
Servicelaunchd, systemdKeeps the daemon running across updates
How a run flows

From backlog to train, station by station.

What happens between "queue this issue" and a green PR on the release branch.

  1. 01

    Queue

    You queue an issue, or a release train queues a whole project. The issue already carries its spec, order and readiness, so the agent never guesses.

  2. 02

    Placement

    The core places the run on the machine with the shortest wait, ordered by skip-queue, rank, train position, priority and time queued. Private machines only take work from their owner and members.

    slotsaccountsquota
  3. 03

    The daemon starts the agent

    The daemon on that machine makes a git worktree for the run and starts the agent CLI in tmux, with a brief and the profile's model and effort. The agent uses the login that already lives on the machine.

    tmuxworktreeclaude · codex · grok
  4. 04

    The agent talks back

    Inside the worktree the agent reports with short verbs. A question lands on your phone; your answer goes straight back into its session.

    statusaskblockedattachgatedone
  5. 05

    Pull request

    done reports the PR. The GitHub App links it to the issue by branch, title and magic words, and moves the issue by your team's rules.

  6. 06

    Gate job

    One gate job per PR head runs on your fleet. A conflict starts a conflict run with a brief of the colliding changes.

  7. 07

    Train merge

    Green PRs merge into the release branch, never into main. When the train is done it opens one ship PR from release to your default branch, and a person merges it.

Local-first sync

Your device answers first.

Every view reads from IndexedDB on your device. The server keeps the order of things, the client keeps them close.

One way to change anything. Every change, from a person, an agent, the API or an import, goes through one mutation bus. Each change writes one event with a sequence number. There is no second path that could skip it.

The server is the clock. The sequence comes from the core, so every client agrees on what happened in which order. Clients never decide time on their own.

Optimistic, then confirmed. Your edit shows at once from a local outbox, gets its sequence from the core, and arrives live on every other screen over Reverb.

bootstrap

The first load: everything you can see, into IndexedDB.

delta

Every event since the last sequence you have.

lazy

Parts that load only when you open them.

mutate

Your changes, sent from the outbox.

outbox→mutation bus→event→Reverb→IndexedDB
48211issue.updateAGT-134 state
48212comment.addAGT-136
48213run.statusmac-mini · claude
48214issue.updateAGT-131 assignee
48215label.addAGT-140
livein sync
Example data
Security

Built so the worst case is small.

Org boundary in the database

Composite foreign keys keep every row inside its organisation. A row cannot point at another organisation's data.

No agent credentials

Agent logins stay on your machines. The core never stores them, so there is nothing there to leak.

Signed binaries

The daemon checks a sha256 and an ed25519 signature before it swaps itself, atomically.

Pair a machine.
Watch it all move.

Start buildingSee what shipped