Introduces backend/.golangci.yml (27 linters across correctness, dead-code/ boilerplate, style, and security), wires it into CI as a blocking job, and fixes every finding so the tree starts at zero. Config: - 27 linters: errcheck, govet, staticcheck, errorlint, bodyclose, sqlclosecheck, rowserrcheck, nilerr, makezero, unused, unparam, unconvert, wastedassign, copyloopvar, prealloc, dupl, revive (incl. exported-symbol doc comments), gocritic, misspell, usestdlibvars, predeclared, nakedret, gosec, … - Tuned for signal over noise: govet/shadow and gocritic hugeParam/rangeValCopy/ unnamedResult disabled (idiomatic-Go false positives); sqlc-generated code and tests get scoped exclusions; gosec G304 excluded (paths are config/run-file/ worktree-derived, not user input); nilerr excluded in cli/status.go (probe failures are the reported status, not a command error). CI: - New blocking lint job (golangci-lint-action, latest binary for Go-version compatibility). - go-version now read from go.mod (was pinned 1.22 while go.mod declares 1.25). Cleanup to reach zero (no behavior change): - errcheck: wrap deferred/inline Close()/Remove()/Rollback() with `_ =`. - gosec: tighten dir/file perms (0755->0750, 0644->0600). - unparam: drop always-nil error return from startLifecycle; drop unused shellPath param (zellij PowerShell) and always-500 fallbackStatus param (writeProjectError). - gocritic: regexp \d, s != "", switch->if, combined appends. - revive: doc comments on all exported symbols; rename project.ProjectRow -> project.Row (stutter); rename `max` locals shadowing the builtin. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| backend | ||
| docs | ||
| frontend | ||
| test/cli | ||
| .gitignore | ||
| README.md | ||
README.md
agent-orchestrator
Rewrite of the agent-orchestrator: a long-running Go backend daemon (backend/)
paired with an Electron + TypeScript frontend (frontend/).
See docs/ for architecture and status — start with the
Lifecycle Manager + Session Manager lane in docs/architecture.md.
Backend daemon
The Go backend now has a Cobra-based ao CLI in backend/cmd/ao.
The CLI controls the HTTP daemon — a loopback-only sidecar the Electron
supervisor will also use. The daemon skeleton includes the chi router,
middleware stack (recoverer → request-id → logger → real-ip), /healthz +
/readyz, atomic running.json PID/port handshake, graceful shutdown on
SIGINT/SIGTERM, SQLite storage, CDC polling, and lifecycle/reaper wiring.
Run
cd backend
go run ./cmd/ao start # start the daemon and wait for readiness
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
AO_PORT=3019 go run ./cmd/ao start # override per invocation
Health check:
curl localhost:3001/healthz # {"status":"ok"}
curl localhost:3001/readyz # {"status":"ready"}
Configuration (env only)
The bind host is always 127.0.0.1: the daemon is a loopback-only sidecar
and binding any other interface would be a security regression, so the host
is intentionally not env-configurable.
| Var | Default | Purpose |
|---|---|---|
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 |
Test
cd backend
gofmt -l . && go build ./... && go vet ./... && go test -race ./...