Agentic orchestrator for parallel coding agents — plans tasks, spawns agents, and autonomously handles CI fixes, merge conflicts, and code reviews.
Go to file
prateek dcfee04e1b
fix: terminal servers compatible with hash-based architecture (#87)
* fix: terminal servers compatible with hash-based architecture

The terminal WebSocket servers (direct-terminal-ws and terminal-websocket)
used config.dataDir to validate sessions, which no longer exists in the
hash-based architecture. Also fixed node-pty failing to find tmux via
posix_spawnp.

Changes:
- Remove config.dataDir dependency, validate via `tmux has-session` instead
- Add resolveTmuxSession() to map user-facing IDs (ao-15) to hash-prefixed
  tmux names (8474d6f29887-ao-15)
- Use explicit tmux path discovery (findTmux) since node-pty's posix_spawnp
  doesn't reliably inherit PATH
- Include /opt/homebrew/bin in fallback PATH for macOS ARM

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

* fix: add session resolution to ttyd server and use exact tmux matching

- Add findTmux() and resolveTmuxSession() to terminal-websocket.ts
  (previously only in direct-terminal-ws.ts), fixing hash-prefixed
  session lookup for the ttyd-based terminal server
- Use tmux exact match prefix (=sessionId) in has-session checks
  to prevent ao-1 from matching ao-15 via prefix matching
- Add server compatibility tests that verify both servers handle
  hash-based architecture correctly (14 tests)
- Include server/ in tsconfig and vitest config for typecheck coverage

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

* refactor: extract tmux-utils and add proper unit tests

- Extract findTmux(), resolveTmuxSession(), validateSessionId() into
  shared server/tmux-utils.ts — eliminates duplication between
  direct-terminal-ws.ts and terminal-websocket.ts
- Add 20 real unit tests with injected mocks that test actual behavior:
  - findTmux: candidate priority, fallback to bare name
  - resolveTmuxSession: exact match, hash-prefix resolution,
    = prefix for preventing tmux prefix matching (ao-1 vs ao-15),
    null when no session found, tmux not running
  - validateSessionId: path traversal, shell injection, whitespace
- Slim down server-compatibility.test.ts to 10 structural checks
  (imports tmux-utils, no loadConfig, no config.dataDir, no existsSync)

Total: 30 tests — all pass on fix branch, 8 fail on main

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

* test: add real integration tests for direct-terminal-ws

- Refactor direct-terminal-ws to export createDirectTerminalServer()
  factory so tests can control server lifecycle without side effects
- Add 10 integration tests that create real tmux sessions, start the
  real server, connect via WebSocket, and verify the full flow:
  - Health endpoint returns 200
  - Missing session parameter → close 1008
  - Path traversal in session ID → close 1008
  - Shell injection in session ID → close 1008
  - Nonexistent tmux session → close 1008
  - Real tmux session → connects and receives terminal output
  - Hash-prefixed session resolution works end-to-end
  - Can send input and receive echoed output
  - Resize messages don't crash the connection
  - Unknown HTTP path → 404
- Tests create/destroy tmux sessions in beforeAll/afterAll
- Server runs on random port (port 0) to avoid conflicts
- Total test suite: 40 tests (20 unit + 10 compatibility + 10 integration)

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

* ci: add web server tests to CI pipeline

The web package was explicitly excluded from CI test runs
(pnpm -r --filter '!@composio/ao-web' test). Add a test-web job
that installs tmux, starts the tmux server, and runs the web
package tests (unit + integration).

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

* fix: address CI failures and bugbot review comments

- Fix lint: replace require() with ESM import in integration test
- Fix base-path mismatch: ttyd now uses user-facing sessionId for
  --base-path/URL and actual tmux name for attach-session
- Fix bare "tmux" in ttyd spawn args: use TMUX constant (full path)
- Scope CI test-web job to server/__tests__/ to avoid pre-existing
  failures in src/__tests__/

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

* test: comprehensive unit and integration test coverage

Unit tests (77): validateSessionId covers all injection vectors (shell,
path traversal, command substitution, special chars, unicode, control
chars), findTmux covers all candidate paths and error types,
resolveTmuxSession covers exact match, hash-prefix resolution, suffix
matching precision, edge cases (single char, long lists, multiple
hyphens, different tmux paths).

Integration tests (45): health endpoint lifecycle (active count tracks
connections/disconnections), HTTP routing (404s for all non-health
paths), WebSocket validation (11 injection/traversal vectors), terminal
connection (resize, multi-resize, invalid JSON, non-resize JSON),
hash-prefixed resolution (suffix match, command passthrough, session key
tracking, cross-match prevention), terminal I/O (Ctrl-C, Tab, Enter,
empty messages, rapid keystrokes, multi-line), connection lifecycle
(cleanup, rapid connect/disconnect, error recovery), server creation
(independent instances).

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

* fix: validate 12-char hex prefix in hash-prefixed session resolution

The previous endsWith("-{sessionId}") suffix match was ambiguous:
"hash-my-app-1" would falsely match a lookup for "app-1". Now validates
that the prefix matches the exact format generated by generateConfigHash
(12-char lowercase hex) before comparing the remainder.

Added unit tests for the ambiguity case and invalid prefix formats.
Updated integration test session names to use proper 12-char hex prefixes.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 03:28:55 +05:30
.changeset feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
.cursor feat: publish to npm under @composio scope (#32) 2026-02-15 04:28:57 +05:30
.github/workflows fix: terminal servers compatible with hash-based architecture (#87) 2026-02-18 03:28:55 +05:30
.husky feat: implement comprehensive security audit and secret leak prevention (#67) 2026-02-16 10:33:50 +05:30
artifacts feat: publish to npm under @composio scope (#32) 2026-02-15 04:28:57 +05:30
changelog fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
docs fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
examples feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
packages fix: terminal servers compatible with hash-based architecture (#87) 2026-02-18 03:28:55 +05:30
scripts fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
.gitignore feat: implement comprehensive security audit and secret leak prevention (#67) 2026-02-16 10:33:50 +05:30
.gitleaks.toml feat: implement comprehensive security audit and secret leak prevention (#67) 2026-02-16 10:33:50 +05:30
.npmrc feat: publish to npm under @composio scope (#32) 2026-02-15 04:28:57 +05:30
.prettierignore chore: add ESLint, Prettier, CI workflow, and comprehensive CLAUDE.md conventions 2026-02-13 18:01:52 +05:30
.prettierrc chore: add ESLint, Prettier, CI workflow, and comprehensive CLAUDE.md conventions 2026-02-13 18:01:52 +05:30
ARCHITECTURE.md fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
CLAUDE.md feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
CLAUDE.orchestrator.md fix: address all review comments, lint/format, bugbot issues 2026-02-13 18:42:45 +05:30
DASHBOARD_FIXES_SUMMARY.md feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
LICENSE feat: publish to npm under @composio scope (#32) 2026-02-15 04:28:57 +05:30
README.md fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
SECURITY.md fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
SETUP.md feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
TROUBLESHOOTING.md fix: migrate to hash-based project isolation architecture 2026-02-18 00:19:55 +05:30
agent-orchestrator.yaml Wire xterm.js terminal embed into web dashboard (#29) 2026-02-15 01:37:07 +05:30
agent-orchestrator.yaml.example feat: layered prompt system for agent sessions (#27) 2026-02-14 20:07:13 +05:30
eslint.config.js feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
package.json feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
pnpm-lock.yaml feat: implement comprehensive security audit and secret leak prevention (#67) 2026-02-16 10:33:50 +05:30
pnpm-workspace.yaml feat: scaffold TypeScript monorepo with all plugin interfaces 2026-02-13 17:02:42 +05:30
test-ao-config.yaml feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
test-ao-config2.yaml feat: seamless onboarding with enhanced documentation (#66) 2026-02-16 22:22:13 +05:30
tsconfig.base.json feat: scaffold TypeScript monorepo with all plugin interfaces 2026-02-13 17:02:42 +05:30

README.md

Agent Orchestrator

Orchestrate parallel AI coding agents across any runtime, any repository, any issue tracker.

Quick Start

git clone https://github.com/ComposioHQ/agent-orchestrator.git
cd agent-orchestrator && bash scripts/setup.sh
cd ~/your-project && ao init --auto && ao start

Dashboard opens at http://localhost:3000

Overview

Agent Orchestrator manages multiple AI coding agents working in parallel on your repository. Each agent operates in isolation using separate git worktrees, handles its own pull request lifecycle, and automatically responds to CI failures and review comments.

Key features:

  • Parallel execution - Work on multiple issues simultaneously
  • Human-in-the-loop - Agents escalate to you only when judgment is needed
  • Fully pluggable - Swap any component (runtime, agent, tracker, SCM)
  • Real-time dashboard - Monitor all agents from a unified interface

Features

  • Agent-agnostic: Claude Code, Codex, Aider, or bring your own
  • Runtime-agnostic: tmux, Docker, Kubernetes, or custom
  • Tracker-agnostic: GitHub Issues, Linear, Jira, or custom
  • Auto-reactions: CI failures, review comments, merge conflicts handled automatically
  • Notifications: Desktop, Slack, Composio, or webhook - only when needed
  • Live terminal: Watch agents work in real-time through the browser

Architecture

Eight plugin slots - every abstraction is swappable:

Slot Interface Default Alternatives
Runtime Runtime tmux docker, k8s, process
Agent Agent claude-code codex, aider, opencode
Workspace Workspace worktree clone
Tracker Tracker github linear, jira
SCM SCM github (gitlab, bitbucket)
Notifier Notifier desktop slack, composio, webhook
Terminal Terminal iterm2 web
Lifecycle core

All interfaces are defined in packages/core/src/types.ts.

Installation

Prerequisites

  • Node 20+
  • Git 2.25+
  • tmux (for tmux runtime)
  • gh CLI (for GitHub integration)

Setup

git clone https://github.com/ComposioHQ/agent-orchestrator.git
cd agent-orchestrator
bash scripts/setup.sh

The setup script installs dependencies with pnpm, builds all packages, rebuilds node-pty from source, and links the ao CLI globally.

Initialize Your Project

cd ~/your-project
ao init --auto  # Auto-detects project type, generates config
ao start        # Launches orchestrator and dashboard

Auto-detection recognizes your git repository, remote, project type (languages, frameworks, test runners), and generates custom agent rules based on your stack.

Usage

Spawn Agents

# Spawn agent for a GitHub issue
ao spawn my-project 123

# Spawn for a Linear issue
ao spawn my-project INT-1234

# Spawn without issue (ad-hoc work)
ao spawn my-project

Monitor Progress

# Command-line dashboard
ao status

# Web dashboard
open http://localhost:3000

Manage Sessions

# List all sessions
ao session ls

# Send message to agent
ao send <session-id> "Fix the linting errors"

# Kill session
ao session kill <session-id>

Auto-Reactions

Configure automatic responses to common scenarios:

reactions:
  ci-failed:
    auto: true
    action: send-to-agent
    retries: 3

  changes-requested:
    auto: true
    action: send-to-agent
    escalateAfter: 1h

  approved-and-green:
    auto: true
    action: auto-merge

Configuration

Basic configuration in agent-orchestrator.yaml:

port: 3000

defaults:
  runtime: tmux
  agent: claude-code
  workspace: worktree
  notifiers: [desktop]

projects:
  my-app:
    repo: owner/my-app
    path: ~/my-app
    defaultBranch: main
    sessionPrefix: app
    agentRules: |
      Always run tests before pushing.
      Use conventional commits.
      Write clear commit messages.      

See agent-orchestrator.yaml.example for complete reference documentation.

Examples

The examples/ directory contains configuration templates:

  • simple-github.yaml - Minimal GitHub Issues setup
  • linear-team.yaml - Linear integration
  • multi-project.yaml - Multiple repositories
  • auto-merge.yaml - Aggressive automation

Development

pnpm install
pnpm build
pnpm dev  # Start web dev server

Project Structure

packages/
  core/          - Core types and services
  cli/           - ao command-line tool
  web/           - Next.js dashboard
  plugins/
    runtime-*/   - Runtime plugins
    agent-*/     - Agent plugins
    workspace-*/ - Workspace plugins
    tracker-*/   - Tracker plugins
    scm-*/       - SCM plugins
    notifier-*/  - Notifier plugins
    terminal-*/  - Terminal plugins

Design Philosophy

Push, not pull: Spawn agents, step away, get notified only when your judgment is needed.

  • Stateless orchestrator (filesystem over database)
  • Plugin everything (no vendor lock-in)
  • Amplify human judgment, don't bypass it
  • Auto-handle routine work, escalate complex decisions

Troubleshooting

See TROUBLESHOOTING.md for common issues and solutions.

Common issues:

  • Terminal not working → node-pty rebuild (automatic via postinstall hook)
  • Port in use → Kill existing server or change port in config
  • Config not found → Run ao init from your project directory

Contributing

Contributions welcome. See CLAUDE.md for code conventions and architecture details.

License

MIT

Documentation