Building from source
Run Controller from source, package desktop builds, and build the docs site.
Build from source to run the latest main, target an architecture without a
prebuilt release, or contribute.
Prerequisites
- Node.js 20+
tmuxfor the persistent embedded terminals.- At least one agent CLI on your
PATH—anita,codex, orclaude.
Run in development
npm install
npm run devThis starts the Express server (port 3102 by default) and the Vite dev server (port
4500) concurrently. Vite proxies /api and /ws/terminal to Express. Open
http://localhost:4500.
Each checkout installs its development CLI and runtime under a distinct
<CONTROLLER_HOME>/dev/ directory. A source server never replaces the packaged
app's CLI or runtime file. If another Controller server is already running,
the new source server shares its state but skips managed skill installation and
the schedules, wakes, and goals loops. A standalone source server runs those
loops itself. Discovery checks an opaque home identifier from each live server;
a server using another CONTROLLER_HOME cannot suppress these loops. Older
packaged apps without that identifier are recognized only through the runtime
URL recorded in the same home. If that legacy runtime is stale, both servers
may temporarily run shared loops until the packaged app is updated. When
invoking a development CLI from a sanitized shell, use the
absolute CLI path printed at server startup.
To run the same app inside the Electron shell:
npm run dev:electronThis starts Express and Vite, waits for the Vite URL, and opens the Electron window at the same React UI. The development path skips the welcome screen.
Package desktop builds
# Unpacked current-OS build (fast, for smoke testing) → release/
npm run package:electron
# Distributable artifacts → release/
# macOS: DMG + ZIP Linux: AppImage
npm run package:electron:distArchitecture notes
- By default
package:electron:distproduces arm64 artifacts when run on an Apple Silicon Mac. To force x64, append--x64to the electron-builder invocation, or run on an Intel Mac / x86_64 Linux host. - Cross-building Linux from macOS is risky.
electron-buildersupports it, butnode-pty's native bindings are the fragile piece. The reliable path is to build Linux artifacts on a Linux host (or in CI), and macOS artifacts on macOS.
Build the docs site
The docs site is a Next.js workspace (output: 'export') under docs/:
# Dev server with hot reload
npm --workspace docs run dev
# Static export → docs/out/
npm --workspace docs run buildThe static export pre-renders every page to docs/out/docs/<slug>/index.html,
plus /llms.txt and the search index. Deployment is automated: the
.github/workflows/docs.yml workflow rebuilds and deploys to GitHub Pages only
when docs/** or the root manifests change.
The docs build is build-time only — it has no runtime dependency on the Controller backend or the Electron shell.