Stories in, merged PRs out.
An unattended orchestrator that runs the full delivery pipeline for every story in your sprint — dev, review, PR, CI, merge.
The pipeline · Install · Invoke · Sample input/output · Docs
bmad-dev-loop is an OpenCode / Claude skill that turns a list of story keys into merged PRs — with one human confirmation at the start and nothing else.
You give it a list. It walks the list. For each story it:
- dispatches a dev subagent running
bmad-dev-story, - dispatches a review subagent running
bmad-code-review, - creates a branch and a PR,
- polls CI and auto-fixes on transient failure,
- squash-merges the PR,
- moves on to the next story.
The original version of this skill shipped as bmad-loop inside leanproxy-mcp via PR #245. This repo is the standalone, hardened, distributable packaging — same state machine, more polish.
flowchart LR
A[Story list] --> B[Validate]
B --> C[Confirm]
C --> D[Dev subagent]
D --> E[Review subagent]
E --> F{Issues?}
F -- yes --> D
F -- no --> G[Branch]
G --> H[PR]
H --> I{CI passing?}
I -- no, retries left --> J[CI fix subagent]
J --> H
I -- no, out of retries --> K[HALT]
I -- yes --> L[Merge]
L --> M{More stories?}
M -- yes --> B
M -- no --> N[Done]
# One line — into your current project
git clone https://github.com/mmornati/bmad-dev-loop.git /tmp/bmad-dev-loop
node /tmp/bmad-dev-loop/bin/bmad-dev-loop.js installThat's it. The CLI copies skills/bmad-dev-loop/ from the package into ./.opencode/skills/bmad-dev-loop/ in your project. Run it from your repo root.
Other flavors:
# Globally (every project you open)
git clone https://github.com/mmornati/bmad-dev-loop.git /tmp/bmad-dev-loop
node /tmp/bmad-dev-loop/bin/bmad-dev-loop.js install --scope global
# To a custom directory
node /tmp/bmad-dev-loop/bin/bmad-dev-loop.js install --target ./my-project/.opencode/skills
# Or just copy by hand
git clone https://github.com/mmornati/bmad-dev-loop.git
cp -R bmad-dev-loop/skills/bmad-dev-loop /your/project/.opencode/skills/The package is a skill, not an npm library.
package.jsonexists for CLI metadata and local scripts, not for registry publishing. Install from source.
Validate the install:
node /tmp/bmad-dev-loop/bin/bmad-dev-loop.js validate
# validation passed./bmad-dev-loop 4-1 4-2 4-3
/bmad-dev-loop epic-4
/bmad-dev-loop 4-1
The skill confirms the plan once, then runs unattended.
The shipped skills/bmad-dev-loop/examples/ folder contains real sample data so you can preview the loop without writing any project-specific content.
epics:
- id: 4
title: Dry-run & CLI hardening
stories:
- key: "4-1"
title: dry-run-mode
status: ready-for-dev
- key: "4-2"
title: posix-compliant-cli
status: ready-for-dev
- key: "4-3"
title: ide-extension-socket
status: ready-for-devstatus: done
total_stories: 3
current_index: 3
stories:
- key: "4-1"
status: merged
branch: "story/4-1-dry-run-mode"
pr_number: 247
ci_attempts: 1
- key: "4-2"
status: merged
branch: "story/4-2-posix-compliant-cli"
pr_number: 248
ci_attempts: 1
- key: "4-3"
status: merged
branch: "story/4-3-ide-extension-socket"
pr_number: 249
ci_attempts: 2 # one CI retry, then green
summary:
total_prs_merged: 3
total_ci_failures: 1
duration_seconds: 2146Full sample data and an end-to-end demo: mmornati.github.io/bmad-dev-loop/examples.
Without bmad-dev-loop |
With bmad-dev-loop |
|---|---|
| Implement, review, PR, CI, merge — five round trips per story. | One invocation, one confirmation. |
| "Did I forget to push?" / "Did CI run?" — manual checking. | loop-status.yaml is the audit trail. |
| Halt-and-restart loses your place. | Resume reads current_index and continues. |
| "Will CI flake?" | Auto-fix subagent handles it, configurable retries. |
| Each story is a fresh prompt. | Three BMAD skills compose into one pipeline. |
The skill is configured through a 3-layer TOML system. Defaults live in skills/bmad-dev-loop/customize.toml; override per team in _bmad/custom/bmad-dev-loop.toml and per user in _bmad/custom/bmad-dev-loop.user.toml.
[workflow]
review_model_override = "claude-sonnet-4-20250514"
merge_strategy = "squash" # or "merge" / "rebase"
ci_poll_interval_seconds = 30
ci_max_retries = 3
ci_timeout_minutes = 30
dry_run = false # true = preview onlySee the full customization reference.
The skill never:
- Force-pushes to
main. - Skips a story silently (skips are logged with a warning).
- Runs subagents in the background.
- Auto-merges a red PR.
- Opens a PR against a non-
mainbase without an explicit--base.
It always HALTs with a typed status (done / blocked / halted_dry_run) and a blocking_condition when something goes wrong. Re-running the loop reads current_index from loop-status.yaml and resumes at the first non-merged story. See Safety & HALT.
Full docs live on GitHub Pages: mmornati.github.io/bmad-dev-loop
- Installation
- Quickstart
- The workflow
- Customization
- Safety & HALT
- Troubleshooting
- CLI reference
- Schema
See CONTRIBUTING.md. The short version:
git checkout -b feat/your-change
# edit skills/bmad-dev-loop/ or docs/
node bin/bmad-dev-loop.js validate
pnpm docs:build
# open a PROriginally delivered as bmad-loop in leanproxy-mcp#245. The state machine, phases, edge cases, and HALT taxonomy are faithful to the original; the standalone repo adds a 3-layer TOML config, dry-run mode, branch prefix customization, CI timeout, a CLI wrapper, sample data, and a VitePress docs site.
MIT © 2026 Marco Mornati