Multi-Root Workspaces
How to attach additional directories to one AGH workspace for monorepos, shared agents, and project clusters.
- Audience
- Operators running durable agent work
- Focus
- Workspaces guidance shaped for scanability, day-two clarity, and operator context.
A multi-root workspace has one primary root and zero or more additional roots. The primary root owns the workspace config. All roots can contribute agents and skills.
Use multi-root when one session should operate from a main repository while also seeing reusable
project-local agents or skills from nearby directories. AGH starts the agent in the primary root and
sends the additional roots to ACP as additional_dirs.
Register Additional Roots
agh workspace add /Users/you/src/acme/checkout \
--name checkout \
--add-dir /Users/you/src/acme/shared-agents \
--add-dir /Users/you/src/acme/platformAdd or remove roots later:
agh workspace edit checkout \
--add-dir /Users/you/src/acme/ops-playbooksagh workspace edit checkout \
--remove-dir /Users/you/src/acme/platformThe CLI prevents adding and removing the same directory in one edit command.
What Multi-Root Changes
| Surface | Primary root | Additional roots | Global home |
|---|---|---|---|
Agent process cwd | yes | no | no |
ACP additional_dirs | no | yes | no |
.agh/config.toml | yes | no | global config is separate |
.agh/mcp.json top-level sidecar | yes | no | global sidecar is separate |
.agh/agents/*/AGENT.md | yes, highest precedence | yes, in registered order | yes, lowest precedence |
.agh/skills/*/SKILL.md | yes, highest precedence | yes, in registered order | yes, lowest filesystem precedence |
.agh/memory/ | yes | no | global memory is separate |
The session start options use:
cwd = <workspace root>
additional_dirs = [<additional root 1>, <additional root 2>, ...]That means provider support for additional_dirs depends on the ACP-compatible agent. AGH still
uses the additional roots for its own agent and skill discovery before the subprocess starts.
Precedence
Discovery order is first-wins:
- Primary workspace root
- Additional roots, in the order stored on the workspace
- Global AGH home
For agents, the first AGENT.md whose parsed name matches wins. AGH does not merge two agent
definitions with the same name.
For skills, the first skill directory name wins. AGH does not merge two SKILL.md files with the
same directory name.
Rendering diagram...
Monorepo Pattern
Use the repository root as the workspace root when one .agh/config.toml should govern the whole
monorepo:
acme-platform/
.agh/
config.toml
agents/
monorepo-maintainer/AGENT.md
skills/
architecture-map/SKILL.md
services/
checkout/
billing/
packages/
ui/Register once:
agh workspace add /Users/you/src/acme-platform --name acme-platformStart sessions from the named workspace:
agh session new --workspace acme-platform --agent monorepo-maintainerThis keeps one config overlay and one workspace memory scope for the whole monorepo.
Shared Resource Pattern
Use additional roots when each project needs its own config and memory, but the team wants shared agents or skills:
acme/
checkout/
.agh/
config.toml
memory/
MEMORY.md
billing/
.agh/
config.toml
memory/
MEMORY.md
shared-agent-kit/
.agh/
agents/
incident-reviewer/AGENT.md
skills/
runbook-reader/SKILL.mdRegister each project with the same shared root:
agh workspace add /Users/you/src/acme/checkout \
--name checkout \
--add-dir /Users/you/src/acme/shared-agent-kitagh workspace add /Users/you/src/acme/billing \
--name billing \
--add-dir /Users/you/src/acme/shared-agent-kitNow checkout and billing can both use incident-reviewer, but each keeps its own primary
config and workspace memory.
Nested Workspace Pattern
Nested directories can be registered as separate workspaces because AGH resolves registered rows, not a Git-style nearest-parent marker.
acme-platform/
.agh/
config.toml
agents/
platform/AGENT.md
services/
checkout/
.agh/
config.toml
agents/
checkout/AGENT.mdYou can register both:
agh workspace add /Users/you/src/acme-platform --name platformagh workspace add /Users/you/src/acme-platform/services/checkout --name checkoutThen target the desired scope explicitly:
agh session new --workspace platform --agent platformagh session new --workspace checkout --agent checkoutIf you run agh session new from inside services/checkout without --workspace, the CLI sends
that current directory as workspace_path. AGH resolves or registers that exact directory. It does
not walk upward to find the nearest ancestor that already has .agh/.
Path Normalization And Duplicates
AGH normalizes every root with filepath.Abs, os.Stat, and filepath.EvalSymlinks.
| Case | Behavior |
|---|---|
| Additional root is relative | API validation rejects it; resolver normalization also requires an existing directory. |
| Additional root does not exist | Registration or update fails. |
| Additional root equals the primary root after canonicalization | It is skipped. |
| Additional root appears twice after canonicalization | The duplicate is skipped. |
| Two workspace registrations use the same canonical root | The second registration fails with workspace path already registered. |
| A stored symlink root later points somewhere else | Resolve updates the stored canonical root_dir to the current target. |
Config Boundary
Additional roots do not load config:
checkout/
.agh/config.toml # loaded
shared-agent-kit/
.agh/config.toml # ignored for checkout
.agh/agents/... # discovered
.agh/skills/... # discoveredUse global ~/.agh/config.toml for settings shared across workspaces. Use the primary root
<workspace>/.agh/config.toml for project-specific settings. Avoid putting shared runtime policy in
additional roots, because AGH will not read it for the parent workspace.
Inspect A Multi-Root Workspace
agh workspace info resolves the workspace and shows the sessions, visible agents, and visible
skills:
agh workspace info checkoutThe JSON shape includes the stored registration plus resolved resources:
{
"workspace": {
"id": "ws_8f33a913d23c4fd1",
"name": "checkout",
"root_dir": "/Users/you/src/acme/checkout",
"add_dirs": ["/Users/you/src/acme/shared-agent-kit"]
},
"agents": [{ "name": "incident-reviewer", "provider": "claude" }],
"skills": [
{
"name": "runbook-reader",
"source": "additional",
"dir": "/Users/you/src/acme/shared-agent-kit/.agh/skills/runbook-reader"
}
]
}Use this command after editing --add-dir values. It exercises the same resolver path session
creation uses.
Related Pages
- Workspace Resolver explains the registration and lookup model.
- Config Overlays explains why config comes only from the primary root.
- Skills Overview explains how workspace skill paths overlay the global registry.
- Agent Definitions documents agent discovery and parser behavior.