swarm-codex
v1.1.1
Published
Spin up Codex agent teams from openteams YAML topologies. Ships the runtime that backs the swarm-codex Codex plugin: MCP servers (opentasks, agent-inbox, minimem), lifecycle hooks, and a topology runner.
Maintainers
Readme
swarm-codex (plugin)
Spin up Codex agent teams from openteams YAML topologies.
This directory is both:
- A Codex plugin (manifest at
.codex-plugin/plugin.json) installed via the marketplace at the repo root. - The npm package
swarm-codexthat provides the runtime (MCP servers, hooks, topology runner) the plugin shells out to vianpx.
Install (as a Codex plugin)
From inside Codex:
/plugin marketplace add alexngai/swarm-codex
/plugin install swarm-codex
/reload-pluginsThe first time the plugin's hooks run, Codex will prompt you to trust them.
See docs/codex-hook-trust.md for what that
covers and how to manage trust in CI.
Then launch a team:
/swarm gsdInstall (as an npm CLI)
npm install -g swarm-codex
swarm-codex --helpTwo run modes (v1.1+)
swarm-codex supports two orchestration shapes, both exported from the library barrel:
runSwarm(topology)— bounded wave mode (the default/swarmpath). Static openteams DAG, parallel within waves, terminates when the DAG drains. Best for declared multi-role workflows likegsdandbmad-method.runDispatchedSwarm({ taskSource, roleMap })— unbounded autonomous-dispatch mode powered by swarm-dispatch. Polls ataskSource(e.g.createOpenTasksSource(openTasksClient)) and spawns a role per task. Best for queue-driven batch processing, long-lived workers, or hub integrations like OpenHive.
Both modes share the same CoordinationPlane, the same CodexMcpDriver,
and the same event vocabulary on the core run.role.* events. Wave-only
events use run.wave.*; dispatch-only events use run.dispatch.*.
What /swarm <topology> does
- Resolves the topology by name (built-in
gsd/bmad-method) or local path. - Derives a wave-based execution schedule from
spawn_rulesadjacency. - Generates per-role artifacts under
.swarm/codex-swarm/tmp/teams/<template>/. - Writes a per-run
CODEX_HOMEthat — when their daemons are reachable — registersopentasksandagent-inboxas MCP servers for role threads (minimemis opt-in viaSWARM_MINIMEM_ENABLED). With no reachable daemon, nothing is registered and the run degrades cleanly to marker-only signalling. - Starts
codex mcp-serverwith thatCODEX_HOME— role threads created via thecodexMCP tool inherit the coordination MCP tools. - Walks the schedule wave by wave, parsing signals from each role's output, routing peer messages via
codex-replyto live roles or buffering them for not-yet-spawned subscribers. - Emits a NDJSON progress stream on stdout (
run.init,wave.start,role.start,signal.emitted,message.delivered,role.done,run.done, …) for the/swarmskill to relay. - Halts on the terminal condition — explicit
<<run-complete>>marker, configured terminal signal (MILESTONE_COMPLETEfor gsd,IMPLEMENTATION_COMPLETEfor bmad, overridable viaSWARM_TERMINAL_SIGNAL),SWARM_MAX_TURNSbackstop, or wave exhaustion.
Inspect a run after the fact:
swarm-codex status [run-id]
swarm-codex coord statusConfiguration
Resolved in this order (highest priority first):
- Environment variables (
SWARM_*) - Project config (
.swarm/codex-swarm/config.json) - Global config (
~/.swarm-codex/config.json)
Env vars worth knowing:
| Variable | Default | What it controls |
|---|---|---|
| SWARM_TEMPLATE | (none) | Topology to run when /swarm is invoked without an argument |
| SWARM_TERMINAL_SIGNAL | per-topology default | Override the run's terminal signal |
| SWARM_MAX_TURNS | 50 | Hard backstop on scheduler turns |
| SWARM_MAX_PARALLEL | unlimited | Cap concurrent roles within a wave |
| SWARM_GATE_MODE | permissive | Set to strict to require a subscribed signal from a parent before spawning |
| SWARM_MAP_SERVER | (disabled) | MAP server URL |
| SWARM_MAP_SCOPE | derived | MAP scope name |
| SWARM_INBOX_AGENT_ID | <template>-user | Identity used to drain inbox in the UserPromptSubmit hook |
| SWARM_RETRY_MAX | 0 (off) | Auto-retry budget per role on driver.startRole failure (v1.1+) |
| SWARM_RETRY_DELAY_MS | 2000 | Constant delay between retry attempts |
| SWARM_SKILLTREE_ENABLED | false | Enable per-role skill-tree loadouts (v1.1+) |
| SWARM_SKILLTREE_BASE_PATH | .swarm/skill-tree | SkillBank storage directory |
| SWARM_SKILLTREE_DEFAULT_PROFILE | (none) | Profile fallback when no team.yaml override |
| SWARM_TOPOLOGIES_DIR | ~/.swarm-codex/topologies | Custom user-topology lookup dir (v1.1+) |
| SWARM_OPENTASKS_ENABLED | false | Register the opentasks MCP for role threads |
| SWARM_MINIMEM_ENABLED | false | Register the minimem MCP for role threads |
Layout
plugins/swarm-codex/
├── .codex-plugin/plugin.json # Codex manifest
├── .mcp.json # MCP server manifest (empty — coordination servers register per-run via CODEX_HOME)
├── hooks/hooks.json # SessionStart / UserPromptSubmit / PostToolUse
├── skills/swarm/SKILL.md # /swarm — launch a team from a topology
├── skills/swarm-mcp/SKILL.md # /swarm-mcp — inspect coordination MCP surface (v1.1+)
├── topologies/ # Built-in template stubs (real bodies via openteams)
├── docs/ # Hook trust, daemons, migration, verification
├── bin/swarm-codex.mjs # npm bin entry
├── src/ # Runtime: cli, mcp/, hooks/, topology/, run/, coord/
└── package.jsonDocs
docs/codex-hook-trust.md— per-hook trust gate explaineddocs/coordination-daemons.md— daemon install, CODEX_HOME registration, degraded modedocs/migrating-from-claude-code-swarm.md— what's the same, renamed, redesigneddocs/verification-status.md— what's tested vs. what still needs a live run
Status
v1.1.1 (release candidate). Hermetic suite: 494 tests, 490 passing,
0 failing, 4 live skips. Live suite covers the full coordination pipeline
against a real authenticated codex mcp-server. See
verification-status.md for the
verified/unverified breakdown.
What's in v1.1
runDispatchedSwarm— autonomous-dispatch run mode powered by swarm-dispatch. Peer ofrunSwarm(the wave mode); see "Two run modes" above.- Skill-tree per-role loadouts — opt-in via
SWARM_SKILLTREE_ENABLED. Roles get rendered skill markdown prepended to their prompt based on a team.yamlskilltree:block or openteamsloadout.skillsoverlay. - Auto-retry policy — opt-in via
SWARM_RETRY_MAX. The wave scheduler retries a role ondriver.startRolefailure with constant backoff; newrole.retriedevent annotates the lifecycle. - Boundary-RSS instrumentation —
role.start.rss_at_start_kb/role.done.rss_at_done_kb/rss_delta_kbfields added to event payloads for memory characterization. Token capture wired but gated on codex MCP surfacing usage (currently doesn't; queued for v1.2). - Custom user-topologies — drop a
team.yamlunder~/.swarm-codex/topologies/<name>/and use it by name. Override the dir viaSWARM_TOPOLOGIES_DIR. /swarm-mcpskill — inspect the coordination MCP surface (which daemons are reachable, what's wired into the per-runCODEX_HOME).- Minimem FS watcher — bridges direct
.mdwrites to MAP observers; complements the existing MCP-tool path.
Operational notes
Shared coordination (opentasks / agent-inbox) needs the daemons started
outside the Codex sandbox — run swarm-codex daemons up in a normal
terminal first. Without them the run degrades cleanly to marker-only
signalling. Role → orchestrator signalling is marker-based by design.
