* feat(web): add project-based dashboard architecture - Add project query parameter to API routes - Filter sessions by project in both SSR and SSE - Update useSessionEvents hook to accept project param - Update Dashboard and pass project to hook - Add unit tests for project filtering - Add architecture spec document Implements project-based architecture as defined in docs/specs/project-based-dashboard-architecture.md: - GET /api/sessions?project=X returns sessions for project X - GET /api/events?project=X streams only sessions for project X - Dashboard uses project filter from config - SSE URL includes project param when provided - Project matching uses projectId and sessionPrefix - Full backward compatibility maintained (no param = all sessions) * fix: remove duplicate export default in page.tsx * fix(web): clean project-scoped dashboard verification * fix(web): scope dashboard using project id * fix(web): address Bugbot findings in project-scoped dashboard - Consolidate triplicated matchesProject into shared lib/project-utils.ts - Fix Dashboard to receive both projectId (for SSE filtering) and projectName (for display) - Remove inline matchesProject definitions from page.tsx, sessions/route.ts, events/route.ts * fix(web): resolve Bugbot issues in project-scoped dashboard - Add ?project=all query param support in SSR page to show all sessions (previously getPrimaryProjectId() always returned non-empty, making else branches unreachable) - Exclude orchestrator sessions from SSE stream to match SSR/API behavior (orchestrator sessions get their own button, not a card) - Add tests for SSE stream orchestrator exclusion and project filtering Addresses Bugbot issues: - #2903595986: Dead else branches when project filter always applied - #2903595995: SSE stream includes orchestrator sessions unlike SSR/API * feat(web): add project navigation sidebar Add visible left sidebar with project navigation for multi-project setups: - ProjectSidebar component with active state styling - /api/projects endpoint to fetch configured projects - getAllProjects() helper in project-name.ts - Sidebar appears only when 2+ projects configured - Click navigation updates ?project= query param - Active project highlighted with accent color Tests: - ProjectSidebar component tests (8 tests) - API routes tests with proper mocking - All 386 web tests passing Manual test steps: 1. Configure 2+ projects in agent-orchestrator.yaml 2. Start dashboard - sidebar should appear on left 3. Click different projects - URL updates, sessions filter 4. Click "All Projects" - shows all sessions across projects 5. Active project highlighted in sidebar * fix(web): remove duplicate import in test file * fix(web): consolidate ProjectInfo type to shared source Remove duplicated ProjectInfo interface definitions from Dashboard.tsx and ProjectSidebar.tsx. Both now import the type from @/lib/project-name where it is exported as the single source of truth. This addresses Bugbot issue #2906835895: Triplicated ProjectInfo type instead of shared import. * fix(web): integrate globalPause state from main * fix(web): consolidate duplicate @/lib/types import * feat(web): add project-based dashboard architecture - Add project query parameter to API routes - Filter sessions by project in both SSR and SSE - Update useSessionEvents hook to accept project param - Update Dashboard and pass project to hook - Add unit tests for project filtering - Add architecture spec document Implements project-based architecture as defined in docs/specs/project-based-dashboard-architecture.md: - GET /api/sessions?project=X returns sessions for project X - GET /api/events?project=X streams only sessions for project X - Dashboard uses project filter from config - SSE URL includes project param when provided - Project matching uses projectId and sessionPrefix - Full backward compatibility maintained (no param = all sessions) * fix: remove duplicate export default in page.tsx * fix(web): clean project-scoped dashboard verification * fix(web): scope dashboard using project id * fix(web): address Bugbot findings in project-scoped dashboard - Consolidate triplicated matchesProject into shared lib/project-utils.ts - Fix Dashboard to receive both projectId (for SSE filtering) and projectName (for display) - Remove inline matchesProject definitions from page.tsx, sessions/route.ts, events/route.ts * fix(web): resolve Bugbot issues in project-scoped dashboard - Add ?project=all query param support in SSR page to show all sessions (previously getPrimaryProjectId() always returned non-empty, making else branches unreachable) - Exclude orchestrator sessions from SSE stream to match SSR/API behavior (orchestrator sessions get their own button, not a card) - Add tests for SSE stream orchestrator exclusion and project filtering Addresses Bugbot issues: - #2903595986: Dead else branches when project filter always applied - #2903595995: SSE stream includes orchestrator sessions unlike SSR/API * feat(web): add project navigation sidebar Add visible left sidebar with project navigation for multi-project setups: - ProjectSidebar component with active state styling - /api/projects endpoint to fetch configured projects - getAllProjects() helper in project-name.ts - Sidebar appears only when 2+ projects configured - Click navigation updates ?project= query param - Active project highlighted with accent color Tests: - ProjectSidebar component tests (8 tests) - API routes tests with proper mocking - All 386 web tests passing Manual test steps: 1. Configure 2+ projects in agent-orchestrator.yaml 2. Start dashboard - sidebar should appear on left 3. Click different projects - URL updates, sessions filter 4. Click "All Projects" - shows all sessions across projects 5. Active project highlighted in sidebar * fix(web): remove duplicate import in test file * fix(web): consolidate ProjectInfo type to shared source Remove duplicated ProjectInfo interface definitions from Dashboard.tsx and ProjectSidebar.tsx. Both now import the type from @/lib/project-name where it is exported as the single source of truth. This addresses Bugbot issue #2906835895: Triplicated ProjectInfo type instead of shared import. * fix(web): integrate globalPause state from main * fix(web): consolidate duplicate @/lib/types import * fix(web): restore global pause state and membership refresh * fix(web): satisfy lint in project-scoped page defaults * fix(web): remove dead global pause reducer action Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix(web): restore global pause resume time Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * chore(web): retrigger bugbot after thread reset * refactor(web): centralize project session filtering helpers * fix(web): reset pause banner dismissal on new pause * fix(web): remove useless orchestrator assignment * fix(web): derive header stats from live session state * fix(web): restore project name in dashboard header * fix(web): restore backlog poller startup in events stream * refactor(web): keep project-utils helpers internal * chore: retrigger bugbot evaluation * chore: retrigger stuck bugbot check * fix: address latest bugbot findings for dashboard events * test(web): add dashboard bugbot regression coverage * refactor(web): simplify projectId selection in dashboard props * fix(web): derive selected project name from project filter * refactor(web): initialize dashboard defaults before service load * fix(web): satisfy lint in dashboard page error path |
||
|---|---|---|
| .changeset | ||
| .cursor | ||
| .github/workflows | ||
| .husky | ||
| artifacts | ||
| changelog | ||
| docs | ||
| examples | ||
| packages | ||
| scripts | ||
| tests/integration | ||
| .gitignore | ||
| .gitignore-template | ||
| .gitleaks.toml | ||
| .npmrc | ||
| .prettierignore | ||
| .prettierrc | ||
| ARCHITECTURE.md | ||
| DASHBOARD_FIXES_SUMMARY.md | ||
| DESIGN-OPENCLAW-PLUGIN.md | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
| SETUP.md | ||
| TROUBLESHOOTING.md | ||
| agent-orchestrator.yaml.example | ||
| eslint.config.js | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| test-ao-config.yaml | ||
| test-ao-config2.yaml | ||
| tsconfig.base.json | ||
README.md
Agent Orchestrator — The Orchestration Layer for Parallel AI Agents
Spawn parallel AI coding agents, each in its own git worktree. Agents autonomously fix CI failures, address review comments, and open PRs — you supervise from one dashboard.
Agent Orchestrator manages fleets of AI coding agents working in parallel on your codebase. Each agent gets its own git worktree, its own branch, and its own PR. When CI fails, the agent fixes it. When reviewers leave comments, the agent addresses them. You only get pulled in when human judgment is needed.
Agent-agnostic (Claude Code, Codex, Aider) · Runtime-agnostic (tmux, Docker) · Tracker-agnostic (GitHub, Linear)
Quick Start
Option A — From a repo URL (fastest):
# Install
git clone https://github.com/ComposioHQ/agent-orchestrator.git
cd agent-orchestrator && bash scripts/setup.sh
# One command to clone, configure, and launch
ao start https://github.com/your-org/your-repo
Auto-detects language, package manager, SCM platform, and default branch. Generates agent-orchestrator.yaml and starts the dashboard + orchestrator.
Option B — From an existing local repo:
cd ~/your-project && ao init --auto
ao start
Then spawn agents:
ao spawn my-project 123 # GitHub issue, Linear ticket, or ad-hoc
Dashboard opens at http://localhost:3000. Run ao status for the CLI view.
How It Works
ao spawn my-project 123
- Workspace creates an isolated git worktree with a feature branch
- Runtime starts a tmux session (or Docker container)
- Agent launches Claude Code (or Codex, or Aider) with issue context
- Agent works autonomously — reads code, writes tests, creates PR
- Reactions auto-handle CI failures and review comments
- Notifier pings you only when judgment is needed
Plugin Architecture
Eight slots. Every abstraction is swappable.
| Slot | Default | Alternatives |
|---|---|---|
| Runtime | tmux | docker, k8s, process |
| Agent | claude-code | codex, aider, opencode |
| Workspace | worktree | clone |
| Tracker | github | linear |
| SCM | github | — |
| Notifier | desktop | slack, composio, webhook |
| Terminal | iterm2 | web |
| Lifecycle | core | — |
All interfaces defined in packages/core/src/types.ts. A plugin implements one interface and exports a PluginModule. That's it.
Configuration
# 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
reactions:
ci-failed:
auto: true
action: send-to-agent
retries: 2
changes-requested:
auto: true
action: send-to-agent
escalateAfter: 30m
approved-and-green:
auto: false # flip to true for auto-merge
action: notify
CI fails → agent gets the logs and fixes it. Reviewer requests changes → agent addresses them. PR approved with green CI → you get a notification to merge.
See agent-orchestrator.yaml.example for the full reference.
CLI
ao status # Overview of all sessions
ao spawn <project> [issue] # Spawn an agent
ao send <session> "Fix the tests" # Send instructions
ao session ls # List sessions
ao session kill <session> # Kill a session
ao session restore <session> # Revive a crashed agent
ao dashboard # Open web dashboard
Why Agent Orchestrator?
Running one AI agent in a terminal is easy. Running 30 across different issues, branches, and PRs is a coordination problem.
Without orchestration, you manually: create branches, start agents, check if they're stuck, read CI failures, forward review comments, track which PRs are ready to merge, clean up when done.
With Agent Orchestrator, you: ao spawn and walk away. The system handles isolation, feedback routing, and status tracking. You review PRs and make decisions — the rest is automated.
Prerequisites
- Node.js 20+
- Git 2.25+
- tmux (for default runtime)
ghCLI (for GitHub integration)
Development
pnpm install && pnpm build # Install and build all packages
pnpm test # Run tests (3,288 test cases)
pnpm dev # Start web dashboard dev server
See CLAUDE.md for code conventions and architecture details.
Documentation
| Doc | What it covers |
|---|---|
| Setup Guide | Detailed installation and configuration |
| Examples | Config templates (GitHub, Linear, multi-project, auto-merge) |
| CLAUDE.md | Architecture, conventions, plugin pattern |
| Troubleshooting | Common issues and fixes |
Contributing
Contributions welcome. The plugin system makes it straightforward to add support for new agents, runtimes, trackers, and notification channels. Every plugin is an implementation of a TypeScript interface — see CLAUDE.md for the pattern.
License
MIT