agent-orchestrator/AGENTS.md

6.9 KiB

AGENTS.md

Operational guidance for coding agents working in this repository. Keep changes small, match the current rewrite architecture, and prefer the documented daemon/API boundaries over behavior from the old TypeScript implementation.

Repo layout

  • backend/ — Go rewrite of Agent Orchestrator: Cobra ao CLI, loopback HTTP daemon, services, SQLite storage, lifecycle/reaper, runtime/workspace/agent/tracker adapters, terminal mux, and tests.
  • frontend/ — Electron + React supervisor wired to the daemon via the generated typed client. Treat it as a thin supervisor/UI surface; do not move daemon logic into it.
  • docs/ — current architecture/status notes. Start here before changing lifecycle, CLI, agents, storage, or daemon behavior.
  • test/ — external smoke/e2e assets, including the CLI fresh-install container check.
  • .github/workflows/ — CI definitions. Mirror these commands locally when possible.

Commands

From the repo root unless noted:

npm run lint                         # backend go test ./... + golangci-lint v2.12.2
npm run frontend:typecheck           # frontend TypeScript check
npm run sqlc                         # regenerate backend/internal/storage/sqlite/gen from queries/schema
npm run api                          # regenerate OpenAPI spec + frontend TS types (see API contract changes below)
npx @redwoodjs/agent-ci run --all    # local workflow validation; requires Docker socket

Backend-specific checks:

cd backend
go build ./...
go test ./...
go test -race ./...
go vet ./...
go run ./cmd/ao start

Frontend-specific checks:

cd frontend
npm run typecheck
npm run build

Where to look first

  • README.md — current run/config/test quickstart.
  • docs/README.md — docs index.
  • docs/architecture.md — backend mental model, package layout, lifecycle/session/service boundaries, and load-bearing rules.
  • docs/STATUS.md — what is shipped on main today and what is still in flight.
  • docs/cli/README.md — intended CLI shape: thin Cobra client over daemon HTTP, never direct storage/runtime access.
  • docs/agent/README.md — agent adapter contract and hook behavior.
  • CLAUDE.md — compatibility pointer for Claude Code; it directs agents back to AGENTS.md.

For code entry points:

  • CLI commands: backend/internal/cli/*.go; follow nearby command/test patterns before adding a new style.
  • HTTP controllers and DTOs: backend/internal/httpd/controllers/.
  • Service read/write boundaries: backend/internal/service/.
  • Domain vocabulary: backend/internal/domain/.
  • Port contracts: backend/internal/ports/.
  • SQLite queries/migrations/store: backend/internal/storage/sqlite/.
  • Generated sqlc code: backend/internal/storage/sqlite/gen/.

Coding conventions

  • Keep every change surgical and directly tied to the task. Avoid drive-by cleanup, broad renames, formatting churn, speculative abstractions, and architectural refactors unless the task explicitly asks for them.
  • Follow existing Go package boundaries. CLI code should call daemon HTTP routes through shared CLI client helpers; it should not open SQLite, spawn runtimes, or call adapters directly.
  • Keep Cobra commands in the relevant command file and table-test them in the style of backend/internal/cli/*_test.go.
  • Mirror existing response/request DTOs in the CLI instead of importing HTTP controller packages into CLI code, unless the package already establishes that dependency.
  • Return usage errors as usageError so CLI misuse exits 2; runtime/daemon failures should exit 1.
  • Preserve API error envelopes and request IDs when surfacing daemon errors.
  • Use context.Context as the first argument for functions that do I/O or blocking work.
  • Do not add abstractions for one-off use cases. Add helpers only when they remove duplication across real call sites.
  • Tests should cover the user-visible behavior and boundary being changed: happy path, validation/missing args, daemon error envelopes, and any destructive confirmation path.

Hard rules and boundaries

  • The daemon is a loopback-only sidecar. Do not make the bind host configurable or expose it beyond 127.0.0.1.
  • The CLI is a thin client. Do not port old in-process TypeScript CLI behavior that bypasses daemon HTTP routes.
  • Do not store derived/display session status. Status is derived from durable facts (activity_state, is_terminated, PR/check/comment facts) at service read time.
  • Do not treat failed/unknown runtime probes as proof a session is dead.
  • Do not force-delete dirty registered worktrees.
  • Do not modify already-merged SQLite migrations. Add a new migration instead.
  • Do not hand-edit backend/internal/storage/sqlite/gen/*; change backend/internal/storage/sqlite/queries/* or migrations and run npm run sqlc.
  • SQLite change events come from DB triggers into change_log; do not add parallel manual CDC emission from store methods unless the architecture changes explicitly.
  • Keep generated OpenAPI/API DTO drift in mind: controller response shapes live in backend/internal/httpd/controllers/dto.go and tests may assert CLI/HTTP wire compatibility.
  • Do not add network calls to tests unless the package already has an integration/e2e pattern for them. Prefer httptest, fakes, and injected dependencies.
  • Do not commit local run state, daemon data, temporary worktrees, build outputs, or credentials.

API contract changes

The daemon API is code-first. The OpenAPI spec and frontend TypeScript types are generated artifacts — edit the source, then regenerate.

Source files to edit:

  • backend/internal/httpd/controllers/dto.go — request/response shapes.
  • backend/internal/httpd/apispec/specgen/build.go — operation registry; add a schemaNames entry for any new named type.

Regenerate after editing:

npm run api          # runs api:spec then api:ts in sequence

This is equivalent to running:

npm run api:spec     # cd backend && go generate ./internal/httpd/apispec/...
npm run api:ts       # npx openapi-typescript@7.4.4 backend/internal/httpd/apispec/openapi.yaml -o frontend/src/api/schema.ts

Verify:

cd backend && go test ./internal/httpd/...    # spec drift + route/spec parity tests (does not cover schema.ts — that is checked by the api-drift CI job)

Commit openapi.yaml and frontend/src/api/schema.ts together with the Go changes. CI will regenerate both files and fail if the committed versions are out of date. The CLI hand-mirrored DTOs remain a deliberate manual boundary and are not generated.

PR hygiene

  • Branch from main unless explicitly continuing an existing PR.
  • Keep one issue per PR. If asked for separate work, create a separate branch and PR.
  • Use conventional commit messages (feat:, fix:, docs:, test:, chore:).
  • Explain intentional omissions in the PR body, especially when the TypeScript original had more behavior than the Go rewrite domain currently supports.
  • Run the narrowest relevant tests first, then the repo/CI commands that match the touched area.