Skip to main content
Agent Orchestrator supports managing multiple projects simultaneously, each with its own configuration, tracker, and agent settings.

Basic Multi-Project Configuration

Define multiple projects in agent-orchestrator.yaml:
dataDir: ~/.agent-orchestrator
worktreeDir: ~/.worktrees
port: 3000

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

projects:
  frontend:
    name: Frontend
    repo: org/frontend
    path: ~/frontend
    defaultBranch: main
    sessionPrefix: fe
  
  backend:
    name: Backend API
    repo: org/backend
    path: ~/backend
    defaultBranch: main
    sessionPrefix: api
  
  mobile:
    name: Mobile App
    repo: org/mobile
    path: ~/mobile
    defaultBranch: main
    sessionPrefix: mob
Each project gets:
  • Independent session namespace (fe-1, api-1, mob-1)
  • Separate git worktrees
  • Individual session metadata directories
  • Project-specific configuration overrides

Session Prefixes

Session prefixes help you identify which project a session belongs to:
projects:
  frontend:
    sessionPrefix: fe    # Sessions: fe-1, fe-2, fe-3...
  
  backend:
    sessionPrefix: api   # Sessions: api-1, api-2, api-3...
  
  mobile:
    sessionPrefix: mob   # Sessions: mob-1, mob-2, mob-3...
Without prefixes:
my-app-1
my-app-2
my-app-3
With prefixes:
fe-1, fe-2, fe-3      # Frontend
api-1, api-2, api-3   # Backend
mob-1, mob-2, mob-3   # Mobile
This makes it easy to:
  • Filter sessions by project: ao session ls -p frontend
  • Open all project sessions: ao open frontend
  • Identify sessions at a glance: ao status
Prefixes default to the project ID if not specified. Set explicit prefixes for better readability.

Project-Specific Overrides

Override default settings per project:
defaults:
  runtime: tmux
  agent: claude-code
  workspace: worktree

projects:
  frontend:
    # Uses defaults (tmux, claude-code, worktree)
    repo: org/frontend
    path: ~/frontend
    defaultBranch: main
  
  backend:
    # Override agent and runtime
    agent: codex
    runtime: docker
    repo: org/backend
    path: ~/backend
    defaultBranch: main
    
    agentConfig:
      model: gpt-4
      permissions: skip
  
  legacy:
    # Use clone instead of worktree (old git version)
    workspace: clone
    repo: org/legacy-app
    path: ~/legacy-app
    defaultBranch: master
Use different AI agents per project:
projects:
  frontend:
    agent: claude-code  # Best for complex UI logic
  
  backend:
    agent: codex  # Fast for API routes
  
  data-science:
    agent: aider  # Good for notebooks

Different Trackers per Project

Use GitHub Issues for one project and Linear for another:
projects:
  frontend:
    repo: org/frontend
    path: ~/frontend
    defaultBranch: main
    
    tracker:
      plugin: github  # Uses GitHub Issues
  
  backend:
    repo: org/backend
    path: ~/backend
    defaultBranch: main
    
    tracker:
      plugin: linear  # Uses Linear
      teamId: "your-team-id"
Spawning with different trackers:
# GitHub issue
ao spawn frontend #123

# Linear issue
ao spawn backend INT-1234

Supported Trackers

TrackerConfiguration
GitHubplugin: github (no config needed)
Linearplugin: linear, teamId: "..."
CustomImplement Tracker interface

Project-Specific Agent Rules

Define coding standards per project:
projects:
  frontend:
    agentRules: |
      Use TypeScript strict mode.
      Follow React best practices.
      Always run `pnpm test` before pushing.
      Use conventional commits (feat:, fix:, chore:).
  
  backend:
    agentRules: |
      All endpoints require auth middleware.
      Add OpenAPI docs for new routes.
      Run `pnpm test` and `pnpm lint` before pushing.
      Use async/await, not callbacks.
  
  mobile:
    agentRulesFile: .agent-rules.md  # External file
External rules file (mobile/.agent-rules.md):
# Mobile App Agent Rules

## Code Style
- Use React Native best practices
- Follow platform-specific guidelines (iOS HIG, Material Design)
- Optimize for performance (avoid unnecessary re-renders)

## Testing
- Write unit tests with Jest
- Add E2E tests with Detox for critical flows
- Test on both iOS and Android simulators

## Commits
- Use conventional commits: `feat:`, `fix:`, `chore:`
- Reference Jira tickets: `feat: add biometric auth (MOB-123)`

Project-Specific Reactions

Configure different automation levels per project:
projects:
  # Production backend — conservative
  backend:
    reactions:
      ci-failed:
        auto: true
        retries: 1
        escalateAfter: 1
      
      approved-and-green:
        auto: false  # Manual merge only
        action: notify
  
  # Experimental project — aggressive
  experiments:
    reactions:
      ci-failed:
        auto: true
        retries: 5
      
      approved-and-green:
        auto: true  # Auto-merge enabled
        action: auto-merge
  
  # Frontend — moderate
  frontend:
    reactions:
      ci-failed:
        auto: true
        retries: 2
      
      approved-and-green:
        auto: false
        action: notify

Managing Multiple Dashboards

Run separate orchestrator instances for different project groups:

Single Dashboard (All Projects)

agent-orchestrator.yaml:
port: 3000

projects:
  frontend: { ... }
  backend: { ... }
  mobile: { ... }
Start:
ao start
Dashboard shows all projects at http://localhost:3000

Multiple Dashboards (Separate Teams)

team-frontend.yaml:
port: 3000
dataDir: ~/.agent-orchestrator/frontend

projects:
  frontend: { ... }
  design-system: { ... }
team-backend.yaml:
port: 3001
dataDir: ~/.agent-orchestrator/backend

projects:
  api: { ... }
  workers: { ... }
Start separate instances:
# Terminal 1: Frontend team
ao start --config team-frontend.yaml

# Terminal 2: Backend team
ao start --config team-backend.yaml
Dashboards:
  • Frontend: http://localhost:3000
  • Backend: http://localhost:3001
Each orchestrator instance needs:
  • Different port (e.g., 3000, 3001, 3002)
  • Different dataDir (separate metadata)
  • Separate config file
Conflicts occur if multiple instances share the same port or data directory.

Spawning Across Projects

Spawn for Specific Project

ao spawn frontend #123
ao spawn backend INT-456
ao spawn mobile MOB-789

Batch Spawn Across Projects

# Frontend issues
ao batch-spawn frontend #101 #102 #103

# Backend issues
ao batch-spawn backend INT-1 INT-2 INT-3

# Mobile issues
ao batch-spawn mobile MOB-10 MOB-11 MOB-12

View Status Across All Projects

ao status
Output:
Frontend:
  fe-1    feat/add-login    #42   ✓   ✓   0   active   2m
  fe-2    feat/dashboard    #43   ⋯   ⋯   2   ready    5m

Backend API:
  api-1   fix/auth-bug      #15   ✗   △   0   active   1h
  api-2   feat/webhooks     #18   ✓   ✓   0   ready    10m

Mobile App:
  mob-1   feat/biometric    #7    ⋯   ⋯   0   active   30m

Filter by Project

ao status -p frontend
ao session ls -p backend
ao session cleanup -p mobile

Opening Sessions by Project

Open all sessions for a project in terminal tabs:
# Open all frontend sessions
ao open frontend

# Open all backend sessions
ao open backend

# Open all sessions across all projects
ao open all

Example: Full Multi-Project Config

examples/multi-project.yaml:
dataDir: ~/.agent-orchestrator
worktreeDir: ~/.worktrees
port: 3000

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

projects:
  frontend:
    name: Frontend
    repo: org/frontend
    path: ~/frontend
    defaultBranch: main
    sessionPrefix: fe
    
    tracker:
      plugin: github
    
    agentRules: |
      Use TypeScript strict mode.
      Follow React best practices.
      Always run `pnpm test` before pushing.
  
  backend:
    name: Backend API
    repo: org/backend
    path: ~/backend
    defaultBranch: main
    sessionPrefix: api
    
    tracker:
      plugin: linear
      teamId: "your-team-id"
    
    agentRules: |
      All endpoints require auth middleware.
      Add OpenAPI docs for new routes.
      Run `pnpm test` and `pnpm lint` before pushing.
    
    reactions:
      approved-and-green:
        auto: false  # Backend requires manual merge

notifiers:
  slack:
    plugin: slack
    webhook: ${SLACK_WEBHOOK_URL}
    channel: "#agent-updates"

notificationRouting:
  urgent: [desktop, slack]
  action: [desktop, slack]
  warning: [slack]
  info: [slack]

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
    action: notify
    priority: action

Workspace Isolation

Each project’s worktrees are isolated:
~/.worktrees/
  fe-1/        # Frontend session 1
  fe-2/        # Frontend session 2
  api-1/       # Backend session 1
  api-2/       # Backend session 2
  mob-1/       # Mobile session 1
Worktrees:
  • Share the .git directory with the main repo
  • Have independent working directories
  • Can be on different branches simultaneously
  • Are cleaned up when sessions are killed

Metadata Organization

Session metadata is organized by project:
~/.agent-orchestrator/
  sessions/
    frontend/
      fe-1/
        id=fe-1
        projectId=frontend
        ...
      fe-2/
        ...
    backend/
      api-1/
        id=api-1
        projectId=backend
        ...
    mobile/
      mob-1/
        ...
  events.jsonl  # Global event log

Best Practices

1

Use descriptive prefixes

Choose short, recognizable prefixes:
  • fe, api, mob
  • project1, p1, x
2

Group related projects

Keep frontend/backend/mobile in one config if they’re part of the same product.
3

Separate critical from experimental

Use different reaction configs:
  • Critical: Manual merge, conservative retries
  • Experimental: Auto-merge, aggressive retries
4

Shared notification channels

Route all projects to the same Slack channel for unified monitoring.
5

Consistent agent rules

Establish org-wide standards and include them in all projects.

Troubleshooting

Port Conflicts

Error: EADDRINUSE: address already in use ::1:3000 Solution: Use different ports for multiple instances:
port: 3001

Session Prefix Collisions

Problem: Two projects with same prefix create conflicting session names. Solution: Use unique prefixes:
projects:
  frontend-web:
    sessionPrefix: web
  frontend-mobile:
    sessionPrefix: mob

Worktree Path Conflicts

Problem: Multiple projects try to use the same worktree directory. Solution: Ensure worktreeDir is shared but session names are unique (via prefixes).

Next Steps

Custom Workflows

Create advanced automation with CI/CD integration

Auto-Reactions

Configure automated responses per project

Build docs developers (and LLMs) love