Agentic orchestrator for parallel coding agents — plans tasks, spawns agents, and autonomously handles CI fixes, merge conflicts, and code reviews.
Go to file
Pritom14 67f42150b4 fix(terminal): make creackPTY.Close idempotent to avoid shutdown deadlock
The session run loop closes the PTY after copyOut returns, and session.close
(via Manager.Close) closes the same PTY again. creackPTY.Close called cmd.Wait
each time, and a second concurrent Wait on the same process blocks forever, so
daemon shutdown deadlocked whenever a terminal was still attached. fakePTY is
idempotent via sync.Once, so the unit suite never exercised this; a real tmux
attach surfaced it.

Guard close+kill+wait with a sync.Once so Wait runs exactly once. Add a
regression test that double-closes a real PTY under a watchdog.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 20:46:12 +05:30
.github/workflows ci: add Go build/test and gitleaks secret-scan workflows 2026-05-26 21:02:58 +05:30
backend fix(terminal): make creackPTY.Close idempotent to avoid shutdown deadlock 2026-05-31 20:46:12 +05:30
docs docs: document the LCM + Session Manager lane (architecture + status) 2026-05-27 14:08:13 +05:30
frontend chore: scaffold backend/ and frontend/ skeletons for rewrite 2026-05-26 15:22:36 +05:30
.gitignore feat(backend): SQLite storage layer + CDC pipeline, LCM/reaper wiring 2026-05-30 16:02:07 +05:30
README.md feat(backend): HTTP daemon skeleton (Phase 1a) — #10 (#14) 2026-05-29 10:02:53 +05:30

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 binary in backend/ is the HTTP daemon — a loopback-only
sidecar the Electron supervisor will spawn (Phase 1c). Phase 1a landed the
skeleton: chi router, middleware stack (recoverer → request-id → logger →
real-ip), /healthz + /readyz, atomic running.json PID/port handshake,
graceful shutdown on SIGINT/SIGTERM.

Run

cd backend
go run .                          # binds 127.0.0.1:3001 with all defaults
AO_PORT=3019 go run .             # 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 ./...