docs: refresh README to reflect current main (#147)
This commit is contained in:
parent
b13f413515
commit
95f8b421ff
175
README.md
175
README.md
|
|
@ -1,58 +1,161 @@
|
||||||
# agent-orchestrator
|
# ReverbCode
|
||||||
|
|
||||||
Rewrite of the agent-orchestrator: a long-running Go backend daemon (`backend/`)
|
A Go-backed agent orchestration daemon for supervising parallel coding-agent
|
||||||
paired with a placeholder Electron + TypeScript frontend shell (`frontend/`).
|
sessions, with an `ao` CLI today and an Electron supervisor planned. The Go
|
||||||
|
module and packages remain `agent-orchestrator`; "ReverbCode" is the public name.
|
||||||
|
|
||||||
See [`docs/`](docs/README.md) for architecture and status — start with the
|
See [`docs/architecture.md`](docs/architecture.md) for the backend mental model
|
||||||
Lifecycle Manager + Session Service lane in [`docs/architecture.md`](docs/architecture.md).
|
and [`AGENTS.md`](AGENTS.md) for the contributor / worker contract.
|
||||||
|
|
||||||
## Backend daemon
|
## What's shipped today
|
||||||
|
|
||||||
The Go backend now has a Cobra-based `ao` CLI in [`backend/cmd/ao`](backend/cmd/ao).
|
- Loopback-only HTTP daemon (`backend/internal/httpd`) controlling projects,
|
||||||
The CLI controls the HTTP daemon — a loopback-only sidecar the Electron
|
sessions, orchestrators, and hook callbacks over `127.0.0.1`.
|
||||||
supervisor will also use. The daemon skeleton includes the chi router,
|
- `ao` Cobra CLI (`backend/cmd/ao`) — a thin client over the daemon for daemon
|
||||||
middleware stack (recoverer → request-id → logger → real-ip), `/healthz` +
|
control, project/session/orchestrator management, and worker spawning.
|
||||||
`/readyz`, atomic `running.json` PID/port handshake, graceful shutdown on
|
- Worker/orchestrator spawn into isolated `git worktree` workspaces, launched
|
||||||
SIGINT/SIGTERM, SQLite storage, CDC polling, and lifecycle/reaper wiring.
|
inside a `zellij` runtime adapter.
|
||||||
|
- Live per-PR observation via the provider-neutral SCM observer
|
||||||
|
(`backend/internal/observe/scm/`): polling loop, ETag guards, semantic
|
||||||
|
diffing, CI/check/review-thread tracking, and lifecycle nudges for CI
|
||||||
|
failures, review feedback, and merge conflicts.
|
||||||
|
- Agent adapters under `backend/internal/adapters/agent/`: `claude-code`,
|
||||||
|
`codex`, `opencode`, `grok`, `cursor`, `qwen`, `copilot`, `kimi`, plus
|
||||||
|
shared activity-dispatch / hook utilities.
|
||||||
|
- SQLite store (`backend/internal/storage/sqlite/`) with sqlc-generated
|
||||||
|
queries, DB-triggered change-data-capture into `change_log`, and a CDC
|
||||||
|
poller/broadcaster (`backend/internal/cdc/`) feeding in-process subscribers
|
||||||
|
and an SSE replay endpoint.
|
||||||
|
- Session lifecycle manager + reaper (`backend/internal/lifecycle/`,
|
||||||
|
`backend/internal/observe/reaper/`): runtime/activity/PR facts reduced into
|
||||||
|
the small durable session state, display status derived at read time.
|
||||||
|
|
||||||
### Run
|
## Quick start
|
||||||
|
|
||||||
|
Requirements: Go 1.25+, [`zellij`](https://zellij.dev/) on `PATH` for the
|
||||||
|
runtime adapter, and `gh` (or `GITHUB_TOKEN`) if you want the SCM observer to
|
||||||
|
authenticate against GitHub. The SQLite driver is the pure-Go
|
||||||
|
`modernc.org/sqlite` — no system SQLite library is required.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
cd backend
|
||||||
go run ./cmd/ao start # start the daemon and wait for readiness
|
go build -o /tmp/ao ./cmd/ao
|
||||||
go run ./cmd/ao status # inspect PID/port/health/readiness
|
|
||||||
go run ./cmd/ao stop # gracefully stop the daemon
|
|
||||||
go run ./cmd/ao daemon # internal daemon entrypoint
|
|
||||||
|
|
||||||
go run . # compatibility wrapper; starts the daemon
|
# Start the daemon and wait for /readyz.
|
||||||
AO_PORT=3019 go run ./cmd/ao start # override per invocation
|
/tmp/ao start
|
||||||
|
|
||||||
|
# Register a local git repo as a project. The id defaults to the lowercased
|
||||||
|
# base of --path; pass --id explicitly when the directory name doesn't match.
|
||||||
|
/tmp/ao project add --path /path/to/your/repo --id your-repo --name your-repo
|
||||||
|
|
||||||
|
# Spawn a worker session running the default agent.
|
||||||
|
/tmp/ao spawn --project your-repo --prompt "Refactor the auth module"
|
||||||
|
|
||||||
|
# Inspect what's running.
|
||||||
|
/tmp/ao status
|
||||||
|
/tmp/ao session ls
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## CLI surface
|
||||||
|
|
||||||
|
The CLI is intentionally thin: every product command resolves to a daemon HTTP
|
||||||
|
route. Run `ao <command> --help` for the authoritative flag shape; the table
|
||||||
|
below groups what's on `main` today.
|
||||||
|
|
||||||
|
| Lane | Command | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| Daemon | `ao start` | Start the daemon in the background and wait for `/readyz`. |
|
||||||
|
| Daemon | `ao stop` | Graceful shutdown via loopback `POST /shutdown`. |
|
||||||
|
| Daemon | `ao status` | Report PID/port/health/readiness from `running.json`. |
|
||||||
|
| Daemon | `ao daemon` | Hidden internal entrypoint used by `ao start`. |
|
||||||
|
| Project | `ao project add` | Register a local git repo as a project. |
|
||||||
|
| Project | `ao project ls` | List registered projects. |
|
||||||
|
| Project | `ao project get <id>` | Fetch one project. |
|
||||||
|
| Project | `ao project rm <id>` | Remove a project. |
|
||||||
|
| Session | `ao spawn` | Spawn a worker session in a registered project. |
|
||||||
|
| Session | `ao session ls` | List sessions (filter by project, include terminated). |
|
||||||
|
| Session | `ao session get <id>` | Fetch one session. |
|
||||||
|
| Session | `ao session kill <id>` | Terminate a session. |
|
||||||
|
| Session | `ao session rename <id> <name>` | Rename a session. |
|
||||||
|
| Session | `ao session restore <id>` | Relaunch a terminated session. |
|
||||||
|
| Session | `ao session cleanup` | Reclaim eligible workspaces for terminated sessions. |
|
||||||
|
| Session | `ao session claim-pr <session> <pr>` | Attach an existing PR to a session. |
|
||||||
|
| Orchestrator | `ao orchestrator ls` | List orchestrator sessions. |
|
||||||
|
| Messaging | `ao send` | Send a message to a running agent session. |
|
||||||
|
| Utility | `ao doctor` | Local health checks (config, data dir, DB, `git`, `zellij`). |
|
||||||
|
| Utility | `ao completion <shell>` | Generate bash/zsh/fish/powershell completions. |
|
||||||
|
| Utility | `ao version` | Print build metadata. |
|
||||||
|
| Internal | `ao hooks <agent> <event>` | Hidden adapter hook callback. |
|
||||||
|
|
||||||
|
See [`docs/cli/`](docs/cli/) for the daemon-control intent and command shape.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
All configuration is env-driven; the daemon takes no config file. The bind
|
||||||
|
host is hard-coded to `127.0.0.1` — the daemon has no auth, CORS, or TLS, and
|
||||||
|
exposing it beyond loopback would be a security regression.
|
||||||
|
|
||||||
|
| Var | Default | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `AO_PORT` | `3001` | Bind port; daemon fails fast if taken. |
|
||||||
|
| `AO_REQUEST_TIMEOUT` | `60s` | Per-request timeout (Go duration). |
|
||||||
|
| `AO_SHUTDOWN_TIMEOUT` | `10s` | Graceful-shutdown hard cap. |
|
||||||
|
| `AO_RUN_FILE` | `<UserConfigDir>/agent-orchestrator/running.json` | PID + port handshake path. |
|
||||||
|
| `AO_DATA_DIR` | `<UserConfigDir>/agent-orchestrator/data` | SQLite DB, WAL files, managed state. |
|
||||||
|
| `AO_AGENT` | `claude-code` | Default agent adapter id used by `ao spawn`. |
|
||||||
|
| `AO_SESSION_ID` | _(unset)_ | Set inside spawned sessions; read by `ao send` and `ao hooks`. |
|
||||||
|
| `GITHUB_TOKEN` | _(unset)_ | Used by the GitHub SCM and tracker adapters. Falls back to `gh auth token`. |
|
||||||
|
|
||||||
Health check:
|
Health check:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl localhost:3001/healthz # includes status/service/pid
|
curl localhost:3001/healthz
|
||||||
curl localhost:3001/readyz # includes status/service/pid
|
curl localhost:3001/readyz
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration (env only)
|
## Architecture
|
||||||
|
|
||||||
The bind host is always `127.0.0.1`: the daemon is a loopback-only sidecar
|
The daemon is a long-running supervisor. Adapters observe external facts (PR
|
||||||
and binding any other interface would be a security regression, so the host
|
state, agent activity, runtime liveness); the lifecycle manager reduces those
|
||||||
is intentionally not env-configurable.
|
into a small set of durable session facts (`activity_state`, `is_terminated`,
|
||||||
|
PR rows). Display status is _derived_ from those facts at read time — it is
|
||||||
|
never stored. SQLite triggers append every user-visible change to `change_log`,
|
||||||
|
and the CDC poller broadcasts those events to in-process subscribers and an
|
||||||
|
SSE stream.
|
||||||
|
|
||||||
| Var | Default | Purpose |
|
Full mental model and load-bearing rules: [`docs/architecture.md`](docs/architecture.md).
|
||||||
|---|---|---|
|
Package-by-package ownership: [`docs/backend-code-structure.md`](docs/backend-code-structure.md).
|
||||||
| `AO_PORT` | `3001` | bind port; fails fast if taken |
|
|
||||||
| `AO_REQUEST_TIMEOUT` | `60s` | per-request timeout (Go duration) |
|
|
||||||
| `AO_SHUTDOWN_TIMEOUT` | `10s` | graceful-shutdown hard cap |
|
|
||||||
| `AO_RUN_FILE` | `<UserConfigDir>/agent-orchestrator/running.json` | PID + port handshake path |
|
|
||||||
| `AO_DATA_DIR` | `<UserConfigDir>/agent-orchestrator/data` | SQLite DB, WAL files, and managed state |
|
|
||||||
|
|
||||||
### Test
|
## Testing
|
||||||
|
|
||||||
|
The local gate is the backend Go build and race-enabled test suite:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run lint
|
cd backend && go build ./... && go test -race ./...
|
||||||
# optional deeper backend pass:
|
|
||||||
cd backend && go test -race ./...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
GitHub Actions is the authoritative pre-merge gate; mirror its commands here
|
||||||
|
when in doubt. See [`AGENTS.md`](AGENTS.md) for the regen workflow when
|
||||||
|
touching the daemon API surface (`npm run sqlc`, `npm run api`).
|
||||||
|
|
||||||
|
## Status and roadmap
|
||||||
|
|
||||||
|
Current `main` ships the CLI surface above, the SCM observer end-to-end
|
||||||
|
(issues [#75](https://github.com/aoagents/agent-orchestrator/issues/75),
|
||||||
|
[#108](https://github.com/aoagents/agent-orchestrator/issues/108),
|
||||||
|
[#109](https://github.com/aoagents/agent-orchestrator/issues/109)), the agent
|
||||||
|
adapter platform, and the CDC pipeline with SSE replay. The Tracker observer
|
||||||
|
([#112](https://github.com/aoagents/agent-orchestrator/issues/112)) and live
|
||||||
|
`pr_*` event consumers ([#110](https://github.com/aoagents/agent-orchestrator/issues/110))
|
||||||
|
are in flight. The Electron supervisor under `frontend/` is still a placeholder
|
||||||
|
shell — daemon logic stays in the Go backend.
|
||||||
|
|
||||||
|
Tracking milestone:
|
||||||
|
[`rewrite`](https://github.com/aoagents/agent-orchestrator/milestone/1) on GitHub.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Repo layout and the worker contract live in [`AGENTS.md`](AGENTS.md). Keep
|
||||||
|
changes surgical, follow the package boundaries documented in
|
||||||
|
[`docs/backend-code-structure.md`](docs/backend-code-structure.md), and prefer
|
||||||
|
adding daemon HTTP routes over leaking storage / runtime into the CLI.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue