Aileron ControlPlane
import BuildPrereqs from '$lib/components/ui/build-prereqs.svelte';
import BuildExtras from '$lib/components/ui/build-extras.svelte';

End users install pre-built binaries via Homebrew, apt, yum, or apk (see [Getting Started](/getting-started/)). This page is for contributors who want to build everything locally from a fresh clone.

## Prerequisites

Expand each one for per-OS install commands.

<BuildPrereqs client:load />

## Recommended extras

<BuildExtras client:load />

## Build everything

```sh
task build
```

This is the all-in-one entry point. It builds the three binaries, the docs site, the webapp, and the Docker containers. Output lands under `build/`. The first run pulls Go modules and `pnpm install`s the webapp and docs dependencies; subsequent runs are incremental.

## Build a single binary

Each binary has its own Taskfile entry. Output is the same `build/<binary>` path:

```sh
task build:cli      # aileron
task build:mcp      # aileron-mcp
task build:enclave  # aileron-enclave
```

The CLI build embeds the webapp. If you've made changes to it, regenerate first (see the next section).

## Embedded assets

### The local webapp

The daemon ships with the local webapp embedded via `go:embed` from `internal/app/webapp_dist/`. To pick up webapp changes in the daemon:

```sh
task build:webapp   # builds webapp/, copies output into internal/app/webapp_dist
task build:cli      # re-embeds the new webapp bytes into the daemon binary
```

For iterating on the webapp without rebuilding the daemon every change, use `task dev:webapp`. The dev server at `localhost:5173` hot-reloads; `aileron launch` continues serving the embedded build.

### Generated API types

The daemon's HTTP API is defined in `internal/api/openapi.yaml`. Server interfaces and request/response types are generated:

```sh
task generate:api
```

Per the project's CLAUDE.md, the spec is the source of truth. Hand-editing `internal/api/gen/server.gen.go` is not supported; any API change starts in the spec.

## Build the docs site

```sh
task build:docs   # static build under docs/dist/
task dev:docs     # live dev server at localhost:4321
```

The docs site is Astro + Svelte. Pages live under `docs/src/content/docs/` (Markdown / MDX); the sidebar is configured in `docs/src/lib/navigation.ts`. Build artifacts are not committed.

## Build for release

```sh
task release:snapshot   # GoReleaser snapshot (no publish)
```

This produces the same artifacts CI ships on tag pushes: `.deb`, `.rpm`, `.apk`, and the Homebrew formulas. The snapshot run does not publish anything; it's the dry run.

## Reproducibility notes

- The `go.work` workspace pins the Go module set across `cmd/`, `internal/`, `sdk/`, and `test/`. `go build ./...` from the root won't work; always invoke from a specific module directory or use `task`.
- The four binaries are version-coupled. A `task build` is the supported way to get a matched set; ad-hoc `go build` against one of the four is fine for iteration but the resulting binary is only guaranteed to talk to a same-commit peer.

## See also

- [Repo Layout](/development/repo-layout/)
- [Binary Architecture](/development/binary-architecture/)
- [Running Tests](/development/running-tests/)