Skip to content

duonghb53/ao-rs

Repository files navigation

ao-rs

Spawn parallel AI coding agents. Each gets its own worktree.
They fix CI, address reviews, and merge PRs — autonomously.

A Rust port of Agent Orchestrator — a tool that lets AI coding agents (Claude Code, Codex, Aider…) work autonomously on GitHub issues inside isolated git worktrees, reacting to CI failures and code reviews without human intervention. ao-rs is faster, leaner, and adds features the original doesn't have.

License: MIT Rust


Dashboard

ao-rs dashboard — Orchestrators → Projects → Sessions

Left sidebar groups sessions under their Orchestrator → Project. Lanes (Working / Pending / Review / Merged) update live via SSE.


Why ao-rs?

ao-rs ao-ts
Startup 8 ms 556 ms — 69× slower
Memory 10 MB 97 MB — 9.7× more
Install 12 MB single binary 85 MB node_modules

→ Full benchmark results, feature diff, and plugin comparison: BENCHMARKING.md

Features ao-rs has that ao-ts doesn't

Feature Description
Monthly cost ledger ~/.ao-rs/cost-ledger/YYYY-MM.yaml — permanent per-session cost backup that survives session deletion
ao-rs status --cost Cost column (tokens + USD) in the status table — ao-ts has no equivalent CLI flag
Embedded REST + SSE API axum server built into the single binary — ao-ts requires a separate Next.js server process
Agent rules injection Structured 6-step dev lifecycle (UNDERSTAND/PLAN/IMPLEMENT/VERIFY/REVIEW/DELIVER) injected as agent system prompt
MergeFailed parking loop Mergeable ↔ MergeFailed retry with configurable budget — ao-ts has no merge-retry state
Single binary cargo install and go — no Node.js, no npm, no runtime dependencies

How It Works

graph TB
    orch["🤖 Orchestrator\n(ao-rs orchestrator spawn)"]

    subgraph skills["ai-devkit Skills  (injected into every agent)"]
        direction LR
        sk1["dev-lifecycle\n8-phase SDLC"]
        sk2["memory\nknowledge search"]
        sk3["verify · tdd\nquality gates"]
    end

    subgraph workers["Parallel Agent Sessions  (each in an isolated git worktree)"]
        direction LR
        w1["Claude Code\nissue #1"]
        w2["Cursor\nissue #2"]
        w3["Codex · Aider\nissue #N"]
    end

    orch -->|"spawn"| workers
    skills -.->|"loaded at launch"| workers

    w1 -->|"opens PR"| loop
    w2 -->|"opens PR"| loop
    w3 -->|"opens PR"| loop

    subgraph loop["⚡ Lifecycle Loop  (ao-rs watch — polls every 5s)"]
        direction LR
        ci{"CI?"}
        rev{"Review?"}
        ci -->|"passes"| rev
    end

    loop -->|"CI failed → send logs"| w1
    loop -->|"CI failed → send logs"| w2
    loop -->|"changes requested"| w3
    rev -->|"approved + green"| merge["Auto-Merge"]
    merge --> done["✓ Done"]

    style orch fill:#16a34a,color:#fff,stroke:none
    style done fill:#5c64b5,color:#fff,stroke:none
    style merge fill:#16a34a,color:#fff,stroke:none
Loading
  1. ao-rs orchestrator spawn — an AI orchestrator reads your issue backlog and spawns worker agents in parallel, one per issue
  2. Any agent type — Claude Code, Cursor, Codex, or Aider; configured per-project in ao-rs.yaml
  3. ai-devkit skills loaded at launch — dev-lifecycle (8-phase SDLC), memory (persistent knowledge search/store across sessions), verify + tdd (quality gates). Run ao-rs start to install them.
  4. Each worker gets its own isolated git worktree, tmux session, and agent process — they can't interfere with each other
  5. ao-rs watch — polls every 5s across all sessions: runtime liveness, agent activity, GitHub PR/CI/review state
  6. Reactions close the loop — CI fails? Each agent gets its own logs. Changes requested? That agent addresses them. Approved + green? Auto-merge fires per session.
  7. You get notified — only when human judgment is needed (stuck agent, exhausted retries, merge conflicts)

Quick Start

Prerequisites: Rust 1.89+ · tmux · gh CLI (authenticated) · claude

# Install from crates.io
cargo install ao-rs

# Or build from source
git clone https://github.com/duonghb53/ao-rs
cd ao-rs
cargo install --path crates/ao-cli

# Verify the environment (checks git, gh, tmux, claude on PATH + GitHub auth)
ao-rs doctor

# Initialize a project (generates ao-rs.yaml)
cd /path/to/your/project
ao-rs start

# Spawn an agent on a GitHub issue
ao-rs spawn --issue 42

# Or with a free-form task
ao-rs spawn --task "fix the failing tests"

# Watch the lifecycle loop
ao-rs watch

# Open the embedded React dashboard in a browser
ao-rs dashboard --open

# Check status
ao-rs status --cost --pr

# Clean up worktrees after sessions merge
ao-rs prune

For a complete walkthrough see docs/user-guide.md.


Configuration

ao-rs start generates ao-rs.yaml in your project directory. No config file = no reactions, stdout-only notifications.

reactions:
  ci-failed:
    action: send-to-agent
    message: "CI failed. Read the logs, fix the issue, and push again."
    retries: 3
    escalate_after: 3 # escalate after 3 failed attempts

  changes-requested:
    action: send-to-agent
    retries: 2
    escalate_after: 30m # or escalate after a duration

  approved-and-green:
    action: auto-merge
    priority: info

  agent-stuck:
    action: notify
    threshold: 10m
    priority: warning

notification_routing:
  urgent: [stdout, ntfy, desktop, discord]
  action: [stdout, ntfy]
  warning: [stdout, desktop]
  info: [stdout]
Environment variables
Variable Purpose
AO_NTFY_TOPIC ntfy.sh topic for push notifications
AO_NTFY_URL Custom ntfy server (default: https://ntfy.sh)
AO_DISCORD_WEBHOOK_URL Discord webhook URL
AO_SLACK_WEBHOOK_URL Slack incoming webhook URL
RUST_LOG Log level (default: warn,ao_core=info)

Full config reference: docs/config.md


Dashboard

ao-rs dashboard serves the embedded React UI at / and a REST + SSE API under /api/:

Method Endpoint Description
GET /api/sessions List all sessions (JSON)
GET /api/sessions/:id Get session by id or prefix
POST /api/sessions/:id/message Send message to agent
POST /api/sessions/:id/kill Kill session runtime
POST /api/sessions/:id/restore Restore terminated session
GET /api/orchestrators List orchestrator sessions
POST /api/orchestrators Spawn a new orchestrator
GET /api/issues Aggregate open issues across projects
GET /api/events SSE stream of lifecycle events
ao-rs dashboard --port 3000 --open
curl http://localhost:3000/api/sessions | jq
curl -N http://localhost:3000/api/events   # SSE stream

State Machine

stateDiagram-v2
    [*] --> spawning
    spawning --> working : agent active

    working --> pr_open : PR created
    working --> stuck : idle > threshold
    stuck --> working : agent resumes

    pr_open --> ci_failed
    pr_open --> review_pending
    pr_open --> approved

    ci_failed --> working : agent fixes
    review_pending --> changes_requested
    changes_requested --> working : agent addresses
    approved --> mergeable : CI green

    mergeable --> merged : auto-merge
    mergeable --> merge_failed : merge error
    merge_failed --> mergeable : retry (budget)

    merged --> [*]
Loading

See docs/state-machine.md for the full transition table.


Architecture

ao-rs/
├── crates/
│   ├── ao-core/                    # Types, traits, state machine, reaction engine, cost ledger
│   ├── ao-cli/                     # `ao-rs` binary (clap)
│   ├── ao-dashboard/               # REST API + SSE server (axum)
│   ├── ao-desktop/                 # Dashboard web UI (Vite + React)
│   └── plugins/
│       ├── runtime-tmux/           # Tmux session management
│       ├── agent-claude-code/      # Claude Code adapter + JSONL cost parser
│       ├── agent-cursor/           # Cursor IDE adapter
│       ├── agent-aider/            # Aider adapter
│       ├── agent-codex/            # Codex adapter
│       ├── workspace-worktree/     # Git worktree isolation
│       ├── scm-github/             # GitHub PRs via `gh` CLI
│       ├── scm-gitlab/             # GitLab MRs via REST API
│       ├── tracker-github/         # GitHub Issues via `gh` CLI
│       ├── notifier-stdout/        # Terminal output (always on)
│       ├── notifier-ntfy/          # ntfy.sh push notifications
│       ├── notifier-desktop/       # Native OS notifications
│       └── notifier-discord/       # Discord webhook
├── scripts/
│   └── benchmark.sh                # Performance comparison vs ao-ts
└── docs/                           # Architecture, state machine, reactions, CLI ref, plugin spec
Plugin system — 6 trait slots
Slot Trait Implementations
Runtime Runtime tmux, process
Agent Agent Claude Code, Cursor, Aider, Codex
Workspace Workspace git worktree
SCM Scm GitHub, GitLab
Tracker Tracker GitHub Issues
Notifier Notifier stdout, ntfy, desktop, discord

Design Principles

  1. Shell-out over librariesgit, tmux, gh are subprocesses, not Rust crate bindings
  2. Disk is the source of truth — no in-memory cache; every read walks ~/.ao-rs/sessions/
  3. Trait objects at plugin boundaries — keeps the binary clean, lets tests use mocks
  4. One crate per plugin — clear dependency graph, fast incremental builds
  5. Never port file-by-file — read TS for intent, write idiomatic Rust

Development

cargo build --workspace                            # Build all crates
cargo t --workspace                                # Run tests via nextest (fast + isolated)
cargo test --doc --workspace                       # Run doctests
cargo clippy --workspace --tests -- -D warnings    # Lint
cargo fmt --all -- --check                         # Format check

# Run benchmarks against ao-ts
./scripts/benchmark.sh ~/study/agent-orchestrator

Note on CPU usage: tests run via cargo nextest (aliased as cargo t). Cap threads on laptops: cargo t --workspace --test-threads=2

Documentation

Document Content
user-guide.md Step-by-step walkthrough of all CLI commands and workflows
architecture.md Crate structure, disk layout, design principles
state-machine.md 18-state lifecycle, PR transitions, stuck detection
reactions.md Reaction engine, notification routing, escalation
cli-reference.md All CLI subcommands with flags and examples
config.md Full config file reference
plugin-spec.md Plugin trait contracts, how to add a plugin

Roadmap

  • Core lifecycle + state machine
  • Reaction engine + SCM integration (GitHub + GitLab)
  • Notification routing: stdout, ntfy, desktop, discord
  • Dashboard REST API + SSE
  • Per-session cost tracking + monthly ledger
  • Web dashboard UI (React + Vite, Orchestrator → Projects hierarchy)
  • Additional agent plugins: Cursor, Aider, Codex
  • ao-rs orchestrator — meta-agent that spawns and monitors workers
  • Publish to crates.io
  • Tauri desktop app wrapper (planned)

License

MIT © 2026 Ha Duong

About

Rust port of ComposioHQ/agent-orchestrator — hobby learning project

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors