Multi-Repo Workspaces

Run a single AoE session across several git repositories at once. Each repo gets its own worktree on a shared branch name, all rooted under one workspace directory, attached to one tmux session.

Use this when a unit of work, a feature, a bug fix, an investigation, touches more than one repo and you want one agent driving all of them, not N agents you have to mentally reconcile.

When to Use

ScenarioMulti-repo?
Bug spans backend and frontend reposYes
Refactor across an OSS core and a private wrapperYes
Feature limited to a single repoNo, regular session
Investigating logs that touch many reposYes, agent picks the relevant ones
OSS core is pinned and rarely changesUse on_create hooks instead

Quick Start

1. Register your repos once

aoe project add /path/to/backend
aoe project add /path/to/frontend
aoe project add /path/to/shared-lib

aoe project list shows what is registered.

2. Start a multi-repo session

CLI:

aoe add /path/to/backend \
  --project frontend \
  --project shared-lib \
  -w feat/auth-rewrite -b

TUI: open the new-session dialog (n), enter the worktree branch, focus the Extra Repos field, press Ctrl+R, and pick the registered projects you want to include.

Web: + New session, pick a primary repo, then click registered projects in the Extra repos picker (or paste a path with the free-text input).

Worktree creation across the repos in a workspace runs concurrently, so wall-clock time is roughly that of the slowest single repo rather than the sum (network-bound git fetch and git submodule update dominate). If any repo’s post-checkout hook fails after git worktree add has already checked out the branch, the workspace is still created and the hook output is surfaced as a warning. See Post-Checkout Hooks for details.

3. The agent sees one workspace

The session starts in the workspace root with all the worktrees as siblings:

~/aoe-workspaces/feat-auth-rewrite/
├── backend/      ← branch feat/auth-rewrite
├── frontend/     ← branch feat/auth-rewrite
└── shared-lib/   ← branch feat/auth-rewrite

The agent navigates between them like any normal multi-repo working tree. Use cd and standard git commands; AoE does not impose any cross-repo orchestration.

The Project Registry

Saved repo paths the multi-repo pickers draw from. Two scopes:

ScopeFileVisibility
Global<app_dir>/projects.jsonEvery profile
Profile<app_dir>/profiles/{profile}/projects.jsonOnly that profile

<app_dir> is $XDG_CONFIG_HOME/agent-of-empires/ on Linux, ~/.agent-of-empires/ on macOS.

When both scopes hold the same canonical path, the profile entry wins in merged views (this is how --allow-override is meant to be used: stage a profile-specific name on top of a global default).

Default scope

InvocationDefault scope
aoe project add <path>Global
aoe -p <profile> project add <path>Profile

Pass --scope global or --scope profile to override.

Cross-scope collisions

aoe project add /repo/foo                     # global
aoe -p other project add /repo/foo            # ERROR: same path in global scope
aoe -p other project add /repo/foo --allow-override  # OK, profile shadows global

CLI Reference

# List
aoe project list                       # merged (global + active profile)
aoe project list --scope global        # globals only
aoe project list --scope profile       # active profile only
aoe project list --json                # machine-readable

# Add
aoe project add /path/to/repo                          # global, name = basename
aoe project add /path/to/repo --name shortname        # custom display name
aoe project add /path/to/repo --scope profile         # profile-only
aoe project add /path/to/repo --allow-override        # shadow other-scope entry

# Remove
aoe project remove backend                # by name (case-insensitive)
aoe project remove /path/to/repo          # by canonical path
aoe project remove backend --scope profile

# Use in a session
aoe add /path/to/primary --project name1 --project name2 -w branch -b
aoe add /path/to/primary --repo /literal/path --project registered -w branch -b

--repo and --project may be mixed; the union is passed to the workspace builder. The builder rejects duplicate repo names, so the same repo via two paths is a hard error.

aoe list --json includes a workspace_repos array for each session; the array is empty for single-repo sessions.

Web Dashboard

The Projects page (folder icon in the sidebar footer) is full CRUD over the registry: add, remove, switch scope, opt into allow_override. Read-only servers (aoe serve --read-only) hide the destructive controls.

The new-session wizard surfaces the registry as toggleable chips on the Project step. The free-text input still works for paths that aren’t registered.

Multi-repo sessions are bucketed into a single Multi-repo group at the bottom of the sidebar, regardless of which repo was chosen as the primary. Each session row shows a chip per repo under the title.

Limitations

These are out of scope for the current release; tracked separately:

  • One branch name per workspace: every repo gets the same -w <branch> value. Per-repo branch names is a future feature.
  • No agent-driven repo pull-in mid-session: if the agent realizes it needs another repo, you have to start a new session. Tracked alongside the orchestrator work.
  • No saved workspace templates (“named bundles of repos”): each session picks the set fresh. If your bundle is fixed, register the repos and select them all from the picker.
  • No per-repo PR tracking: AoE does not track PRs today. Coordinated PR workflow happens outside AoE.