Agentic orchestrator for parallel coding agents — plans tasks, spawns agents, and autonomously handles CI fixes, merge conflicts, and code reviews.
Go to file
Harshit Singh Bhandari 378addf4a0
test(scm): end-to-end integration coverage for SCM observer (#109) (#115)
* test(scm): end-to-end integration coverage for SCM observer (#109)

Adds backend/internal/integration/scm_observer_test.go, the regression
guard for the SCM observer wiring landed in PR #114. Drives
scmobserve.Observer.Poll against a real sqlite.Store, a real
lifecycle.Manager with a recording messenger spy, and a canned
observe/scm.Provider, asserting the full observation -> reducer ->
store -> messenger pipeline.

Three table-driven subtests, each on its own tmpdir fixture:

- A CI-failing observation persists the pr row (provider-neutral
  columns + semantic hashes), persists pr_checks mirroring the
  observation, delivers exactly one nudge with the failed-log tail,
  persists last_nudge_signature, and produces no additional nudge on
  an identical re-poll.
- A Merged: true observation MarkTerminated's the session and sends
  no nudge.
- A branch with no open PR writes nothing and sends no nudge.

Closes #109

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* test(scm): address review — drop string key indirection, document idempotency path

- Key cannedSCMProvider.observations/reviews by PR number directly so
  the fake no longer carries a string key that resembled (but did not
  actually need to mirror) the observer's internal prKey. Every case
  in this test uses scmTestRepo, so number alone is unambiguous.
- Add an explicit pointer in the CI-failing subtest noting it
  exercises the hash-match short-circuit in prepareForPersistence;
  the ETag-driven 304 short-circuit on the same SHA is covered by
  observe/scm/observer_test.go (Poll_RepoETag304SkipsDetectPR,
  Poll_CIETagChangeRefreshesWhenRepoUnchanged).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 23:46:38 +05:30
.github/workflows feat: automate OpenAPI spec + frontend TS type generation (issue #102) (#103) 2026-06-05 14:45:10 +05:30
backend test(scm): end-to-end integration coverage for SCM observer (#109) (#115) 2026-06-05 23:46:38 +05:30
docs docs: document backend code structure (#41) 2026-06-04 02:32:18 +05:30
frontend feat: automate OpenAPI spec + frontend TS type generation (issue #102) (#103) 2026-06-05 14:45:10 +05:30
test/cli refactor: simplify session lifecycle and zellij runtime (#62) 2026-06-01 08:42:49 +05:30
.envrc Add agent adapters and wire per-session agents into the session manager (#65) 2026-06-02 16:51:32 +05:30
.gitignore Add agent adapters and wire per-session agents into the session manager (#65) 2026-06-02 16:51:32 +05:30
AGENTS.md feat: automate OpenAPI spec + frontend TS type generation (issue #102) (#103) 2026-06-05 14:45:10 +05:30
CLAUDE.md docs: add AGENTS.md (#93) 2026-06-03 04:24:04 +05:30
README.md refactor: move session status assembly to service (#62) (#67) 2026-06-01 23:31:21 +05:30
flake.lock Add agent adapters and wire per-session agents into the session manager (#65) 2026-06-02 16:51:32 +05:30
flake.nix Add agent adapters and wire per-session agents into the session manager (#65) 2026-06-02 16:51:32 +05:30
package-lock.json feat: automate OpenAPI spec + frontend TS type generation (issue #102) (#103) 2026-06-05 14:45:10 +05:30
package.json feat: automate OpenAPI spec + frontend TS type generation (issue #102) (#103) 2026-06-05 14:45:10 +05:30

README.md

agent-orchestrator

Rewrite of the agent-orchestrator: a long-running Go backend daemon (backend/)
paired with a placeholder Electron + TypeScript frontend shell (frontend/).

See docs/ for architecture and status — start with the
Lifecycle Manager + Session Service 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       # includes status/service/pid
curl localhost:3001/readyz        # includes status/service/pid

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
AO_DATA_DIR <UserConfigDir>/agent-orchestrator/data SQLite DB, WAL files, and managed state

Test

npm run lint
# optional deeper backend pass:
cd backend && go test -race ./...