Repository Configuration & Hooks
AoE supports per-repo configuration via a .agent-of-empires/config.toml file in your project root. This lets you define project-specific defaults and hooks that apply to every team member using AoE on that repo.
Getting Started
Generate a template config:
aoe init
This creates .agent-of-empires/config.toml with commented-out examples. Edit the file to enable the settings you need.
Migrating from
.aoe/? AoE still reads the legacy.aoe/config.tomlpath, but we recommend renaming it:mv .aoe .agent-of-empires. If both exist,.agent-of-empires/takes priority.
Configuration Sections
Hooks
Hooks run shell commands at specific points in the session lifecycle.
[hooks]
# Run once when a session is first created (failures abort creation)
on_create = ["npm install", "cp .env.example .env"]
# Run every time a session starts (failures are logged but non-fatal)
on_launch = ["npm install"]
# Run when a session is deleted, before cleanup (failures are logged but non-fatal)
on_destroy = ["docker-compose down"]
For single commands, you can use a plain string instead of an array:
[hooks]
on_launch = "npm install"
on_create runs only once, when the session is first created. If any command fails, session creation is aborted. Use this for one-time setup like installing dependencies or generating config files.
on_launch runs every time a session starts (including the first time, and every restart). Failures are logged as warnings and do not prevent user-initiated starts. During startup recovery, a timed-out on_launch hook marks the recovered session as errored instead of silently launching with partial setup. Use this for things like ensuring dependencies are up to date.
on_destroy runs when a session is deleted, before worktree and sandbox cleanup. This lets teardown commands access resources that are still available (e.g. running containers). Failures are logged as warnings but never prevent deletion. Use this for cleanup like stopping Docker services or removing temporary resources.
For sandboxed sessions, hooks run inside the Docker container.
Available environment variables
Lifecycle hooks (on_create, on_launch, on_destroy) receive session metadata as environment variables:
| Variable | Value |
|---|---|
AOE_SESSION_ID | Stable session identifier (e.g. s_abc123). |
AOE_SESSION_TITLE | Session title (also the worktree branch name). |
AOE_PROJECT_PATH | Absolute path to the working directory. Equals $PWD inside on_create / on_launch. |
AOE_PROFILE | Resolved profile name. |
AOE_TOOL | Agent tool name (e.g. claude, codex). |
AOE_GROUP_PATH | Group path for grouped sessions; empty otherwise. |
AOE_SESSION_BRANCH | Git branch name. Set only for worktree sessions. |
Quote any expansion that may contain spaces (titles often do):
[hooks]
on_create = ["port \"$AOE_SESSION_TITLE\""]
on_destroy = ["port rm \"$AOE_SESSION_TITLE\""]
Container hooks get the same variables (forwarded via docker exec -e). Status-transition hooks in [status_hooks] add AOE_OLD_STATUS, AOE_NEW_STATUS, and AOE_STATUS_CHANGED_AT.
Session
[session]
default_tool = "opencode" # Override the default agent for this repo
Any supported agent name (run aoe add --help to see the list).
Sandbox
Override sandbox settings for this repo:
[sandbox]
enabled_by_default = true
default_image = "ghcr.io/agent-of-empires/aoe-dev-sandbox:latest"
environment = ["NODE_ENV", "DATABASE_URL", "CUSTOM_KEY=value"]
volume_ignores = ["node_modules", ".next", "target"]
extra_volumes = ["/data:/data:ro"]
cpu_limit = "8"
memory_limit = "16g"
auto_cleanup = true
default_terminal_mode = "host" # "host" or "container"
List fields (environment, volume_ignores, extra_volumes, port_mappings) accept either an array or a single string:
[sandbox]
environment = "ANTHROPIC_API_KEY" # single value
volume_ignores = ["node_modules", ".next"] # multiple values
Worktree
Override worktree settings for this repo:
[worktree]
enabled = true
path_template = "../{repo-name}-worktrees/{branch}"
bare_repo_path_template = "./{branch}"
auto_cleanup = true
delete_branch_on_cleanup = false
Hook Trust System
When AoE encounters hooks in a repo for the first time, it prompts you to review and approve them before execution. This prevents untrusted repos from running arbitrary commands.
- Trust decisions are stored globally (shared across all profiles)
- If hook commands change (e.g., someone updates
.agent-of-empires/config.toml), AoE prompts for re-approval - Use
--trust-hookswithaoe addto skip the trust prompt (useful for CI or repos you control)
# Trust hooks automatically
aoe add --trust-hooks .
Config Precedence
Settings are resolved in this order (later overrides earlier):
- Global config (
~/.agent-of-empires/config.toml) - Profile config (
~/.agent-of-empires/profiles/<name>/config.toml) - Repo config (
.agent-of-empires/config.toml)
Only settings that are explicitly set in the repo config override the global/profile values. Unset fields inherit from the higher-level config.
Example: Full Repo Config
[hooks]
on_create = ["npm install", "npx prisma generate"]
on_launch = ["npm install"]
on_destroy = ["docker-compose down"]
[session]
default_tool = "claude"
[sandbox]
enabled_by_default = true
default_image = "ghcr.io/agent-of-empires/aoe-dev-sandbox:latest"
environment = ["DATABASE_URL", "REDIS_URL", "NODE_ENV=development"]
volume_ignores = ["node_modules", ".next"]
[worktree]
enabled = true
Checking Into Version Control
The .agent-of-empires/config.toml file is meant to be committed to your repo so the entire team shares the same configuration. The hook trust system ensures that each developer explicitly approves hook commands before they run.