A headless harness for spec-driven, multi-agent software development. The harness gives each unit of work an isolated workspace with its own branch, files, and agents, and coordinates those agents through a validated specification package rather than ad-hoc chat.
The design is inspired by Intent from Augment Code but diverges intentionally: headless instead of desktop, coordination rebuilt on a structured spec package that freezes on approval, and all grounding unified under a single Context abstraction.
The project produces two binaries:
| Binary | Purpose |
|---|---|
hub |
API server -- owns user identity, OAuth, workspaces, git hosting, merge queue, carry-patch workflows, secrets, and access control |
afc |
CLI client -- authenticates with the hub and manages resources |
Primary data is stored in an embedded SQLite database (modernc.org/sqlite, pure Go). Audit logs use an embedded DuckDB database (requires CGo). Authentication supports three credential types: admin tokens, user API keys, and workspace-scoped tokens.
The hub binary includes a built-in git smart HTTP server that exposes
workspace repositories at /git/<org>/<slug>.git for clone, fetch, and push
operations.
- Go 1.27+
- CGO enabled (
CGO_ENABLED=1) — required by the DuckDB audit storage driver - A GitHub OAuth application (for user login)
make buildThis builds the hub binary into bin/ and installs afc into $GOBIN
(or $GOPATH/bin).
Create a config.toml in the working directory (or set XDG_CONFIG_HOME to
control the config file location):
[server]
port = 8080
external_url = "http://localhost:8080"
[database]
path = "afhub.db"
[logging]
level = "info"
[[oauth.providers]]
name = "github"
client_id = "${GITHUB_CLIENT_ID}"
client_secret = "${GITHUB_CLIENT_SECRET}"OAuth credentials support ${VAR} env-var substitution. See
Server Configuration for the full reference.
The server can start without any flags:
bin/hubTo bootstrap an admin account, pass --admin-email on first boot. The server
generates an admin token, writes the plaintext to admin_token in the config
directory, and exits immediately:
bin/hub --admin-email=admin@example.comSave the token, then restart without the flag:
export ADMIN_TOKEN=$(cat admin_token)
bin/hubTo rotate the admin token later, use --reset-admin-token (same
generate-and-exit behaviour).
afc loginThis opens a browser for GitHub OAuth, exchanges the code, and saves
credentials to ~/.af/config.toml. From here you can create workspaces,
manage API keys, and issue workspace tokens.
curl http://localhost:8080/healthz
# {"status": "ok"}
curl http://localhost:8080/readyz
# {"status": "ready"}| Document | Description |
|---|---|
| OpenAPI Description | Machine-readable OpenAPI 3.1 description of the full HTTP surface |
| API Reference | REST API endpoints, authentication, request/response schemas |
| CLI Reference | afc commands, flags, and configuration |
| Server Configuration | config.toml reference and environment variables |
| Permissions | Permission model, scopes, and access control |
| Carry-Patch Workflow | Guide to maintaining fork patches with automated rebuild |
make help # list all targets
make check # fmt, vet, lint and test
make test # tests only
make fmt # gofmt in place
make vet # go vet
make lint # golangci-lint, if installed
make doc # Go package docs into docs/generated
make build-containers # build the container images via podman
make hub-reset # reset data and first-boot
make hub-run # run the server locally
make hub-runc # run the hub container
make clean # remove build outputSee LICENSE for details.