This module is two things: the bundled bmad-loop-* skills and the bmad-loop
orchestrator tool (the Python program that actually drives the loop). The skills do
nothing on their own — the orchestrator is what spawns the fresh coding-CLI sessions
that invoke the upstream bmad-build-auto skill (which implements and, re-invoked on
the done spec, runs the follow-up review) plus bmad-loop-sweep and
bmad-loop-resolve, watches their hook signals, and verifies
their artifacts. Installing the tool is part of setup, not
an optional extra.
There are two ways the skills land in a project. The orchestrator's wheel bundles
the three skills, so the simplest path is uv tool install + bmad-loop init, which installs them
itself. Alternatively the BMAD-method installer copies them. Either way the
/bmad-loop-setup skill installs the orchestrator tool, picks which coding CLIs to
drive, and bootstraps the project. For the one-page summary,
see Installing and upgrading in the README.
- Python 3.11+ and a supported coding CLI (
claudeby default). - git 2.34 or newer — every unit of work moves through git, so this one is enforced
rather than advised:
bmad-loop run,sweepandresumerefuse to start below it, andbmad-loop validatereports it as a problem (git.version, exit 1). It is a support floor rather than a capability one — no git command bmad-loop issues needs 2.34 — set so the project stops carrying accommodations for releases it does not test against. 2.34 is Ubuntu 22.04 LTS's stock git; Ubuntu 20.04 (2.25) and Debian 11 (2.30) are below it.git --versionreports what is on yourPATH. - A terminal multiplexer — the orchestrator drives agent sessions through a terminal
multiplexer: tmux (POSIX) and the experimental psmux (native Windows) ship
bundled, and further backends install as separate packages that register themselves
(e.g. the herdr adapter, then
bmad-loop mux set herdr— see Terminal multiplexer backends). A backend is required for launching, attaching, and driving runs (pure TUI observation works without one). The multiplexer sits behind a pluggable seam (TerminalMultiplexer), so a new backend slots in without changing the engine — contributors should start with Porting bmad-loop to a new OS.bmad-loop muxlists the registered backends and shows which is selected (and why);bmad-loop mux set <name>— or the[mux] backendpolicy key, or theBMAD_LOOP_MUX_BACKENDenv var — forces the choice per machine. - OS — Linux or macOS. Windows is supported via WSL, which is Linux: tmux and
every POSIX path work unchanged there, so no special setup is needed.
- Native Windows is experimental. The bundled
psmuxbackend (a ConPTY tmux re-implementation) drives runs there and is selected automatically as the win32 default when its prerequisites are present: thepsmuxandpwsh(PowerShell) binaries onPATH, withpsmux3.3.8 or newer (older releases read as unavailable — see multiplexer backends for why). - It is below the Linux/macOS/WSL support tier; open native-Windows work is in
the roadmap, and the port path is in
Porting bmad-loop to a new OS.
bmad-loop stopworks there too: it lodges its request in a control file the engine reads at item boundaries and mid-session, with no signal delivery involved. - Inside WSL, install with the Linux interpreter. A Windows-installed bmad-loop is
reachable from the bash prompt and silently behaves as Windows
(why). To check:
bmad-loop muxshould readplatform default for linux; if it nameswin32you are running the Windows build, andbmad-loop validatesays so too. (A forced choice —BMAD_LOOP_MUX_BACKENDor[mux] backend— is reported as the reason instead of the platform, so clear it before reading that line as a platform check.)
- Native Windows is experimental. The bundled
The BMAD-method installer copies the three bmad-loop-* skill directories
(bmad-loop-setup, bmad-loop-sweep, bmad-loop-resolve) into your project. It does not carry the orchestrator tool — the installer copies only skill
directories, not their sibling files, so the tool can't ride along in the skill folder.
It is installed separately from Git by the setup skill. The canonical source is
https://github.com/bmad-code-org/bmad-loop. (Going the other way, the tool's wheel
bundles the skills, so bmad-loop init can install them without the BMAD installer —
when the installer already placed them, init simply skips the existing copies.)
After the installer runs, complete setup with one command:
claude "/bmad-loop-setup accept all defaults"/bmad-loop-setup handles both first-time setup and later upgrades — re-run it any time. It:
- Installs or upgrades the
bmad-looptool from Git (see Installing the tool and TUI). On an upgrade it runsuv tool upgrade bmad-loop --reinstall. - Asks which coding CLI(s) the orchestrator should drive, then runs
bmad-loop initto install thebmad-loop-*skills + register hooks + write the.bmad-loop/policy.tomltemplate + add gitignore entries, including policy.toml itself, which is per-machine (see Choosing which CLIs to drive and Initializing CLIs other than claude). On an upgrade it passes--force-skillsso the per-project skill copies are refreshed. - Runs
bmad-loop validateas a preflight (see Verify). - Refreshes
_bmad/bmad-loop/module-help.csv, the module's help entries. That is the only file it writes under_bmad/— module registration, the centralconfig.toml, and the/bmad-helpcatalog are owned by the BMAD installer, which regenerates them on every run.
Run /bmad-loop-setup with plain prompts if you want to choose interactively — e.g.
claude "/bmad-loop-setup cli: claude, codex" to preselect the CLIs.
If you are working from a clone of this repo, sync the project env and let
bmad-loop init lay down the skills (the canonical skills live at
src/bmad_loop/data/skills/ and are bundled into the package):
uv sync --extra tui # the orchestrator tool + TUI
uv run bmad-loop init --project /path/to/project --cli claude # installs skills + hooks + policy
claude "/bmad-loop-setup accept all defaults" # install the tool + wire the projectAdd --cli codex --cli gemini to also populate .agents/skills/. init always
installs all the bundled skills together: bmad-loop-resolve (the interactive
/bmad-loop-resolve <story> escalation workflow), bmad-loop-sweep (automation-only
ledger triage) and bmad-loop-setup (installs the tool, then runs init and
validate); bmad-loop-sweep owns the canonical deferred-work-format.md
the orchestrator normalizes the ledger to. The dev primitive bmad-build-auto
(spelled bmad-dev-auto before the 6.10.1 rename — the orchestrator resolves
whichever name is on disk and invokes that one) is
not bundled: it is the upstream skill the orchestrator drives (for both
implementation and the follow-up review), installed by the BMad Method (bmm)
module. bmad-loop validate checks it — plus any review skills its layers
invoke — are present before a run starts.
Minimum BMAD-METHOD: v6.10.0 for sprint mode. Beyond the primitive itself (with
its customize.toml), bmad-loop validate holds you to no fixed list of review
skills: it reads the primitive you actually have installed and requires the
reviewers that copy will actually invoke — which on current sources is none at all.
- Layer-driven (post-6.10.0) —
customize.tomldefines[[workflow.review_layers]], and a layer'sinstructionmay name a skill to hand off to. Current (6.11) sources define four layers —blind-hunter,edge-case-hunter,verification-gapandintent-alignment— and none of them invokes a skill: each is a self-contained prompt —edge-case-hunterandverification-gapread the primitive's ownreview-prompts/*.md,blind-hunterandintent-alignmentcarry their prompt inline. Such a tree requires no review skill at all. An intermediate release whose layers invoke the mergedbmad-reviewwith one lens each needsbmad-review; an earlier one naming the standalone hunters needs exactly those instead. - v6.10.0 — no
review_layerssection at all;step-04-review.mdnamesbmad-review-adversarial-generalandbmad-review-edge-case-hunterinline, so those two are what is required.
A layer disabled with an empty instruction, or replaced in
_bmad/custom/bmad-build-auto.toml by a recipe that runs something else, requires
nothing. If the shape cannot be read at all, validate falls back to requiring the two
v6.10.0 hunters — which a tree carrying bmad-review satisfies.
bmad-review-verification-gap is required only when your installed layers name it: no
tagged release ships it as a standalone skill, and on current sources it is a thin
forwarder to bmad-review.
Your project overrides in _bmad/custom/bmad-build-auto.toml (team) and
_bmad/custom/bmad-build-auto.user.toml (personal, gitignored by the bmm installer) are
applied before the requirement is computed. (Overrides are keyed by skill directory
name, so a pre-6.10.1 install spells both files bmad-dev-auto*.toml; the deprecated
shim offers to rename them when you first invoke the old name.) The merge follows the
same rules BMAD's own resolver uses: an array of tables merges by key only when
every entry — default and
override alike — carries the same code or id; otherwise the override appends. So
adding a layer with a new id adds a requirement, and replacing one by id moves it.
Two things validate reports but never blocks on, because neither can be decided
without running the review:
- a layer gated by a
whencondition, which the model evaluates against the diff; - a layer naming a skill in a phrasing that is not recognizably a handoff (the
convention is
Invoke the `skill-name` skill).
Both come back as skills.review-layer-unresolved warnings, so a customized layer can
never block a run. What is a problem: every layer
disabled at once (skills.review-layers-empty), which makes the primitive HALT
blocked with no active review layers.
Under isolation = "worktree" the skills your layers name are copied into each unit's
worktree along with _bmad/custom/, so an isolated run resolves the same layers
validate checked — including from the gitignored *.user.toml, which a fresh checkout
would not carry.
bmad-retrospective reads session logs as evidence for its process lessons: why a
session stalled, what it tried and dropped. It doesn't know where bmad-loop keeps them,
so on an epic bmad-loop drove it finds none and skips that analysis. bmad-loop ships no
override for this. To point the skill at the run records, create
_bmad/custom/bmad-retrospective.toml yourself, or bmad-retrospective.user.toml for a
personal copy:
[workflow]
persistent_facts = [
"Session logs for bmad-loop-driven stories are the run directories .bmad-loop/runs/<run-id>/ under {project-root}. Find this epic's runs by grepping their journal.jsonl files for its story keys.",
"journal.jsonl holds one JSON event per line: a session-start (task_id, role, story_key, adapter, model) and a session-end (task_id, tokens, and a status of completed, stalled, timeout, crashed, over_budget or aborted) per coding-CLI session, joined on task_id since session-end carries no story_key, plus review results, retries, rollbacks, pauses and escalations.",
"logs/<task-id>.log is that session's raw terminal capture (escape sequences and repaints included; a readable transcript for the hookless opencode profile). The journal's log_task / log_pos fields name the log file and byte offset each event lines up with. state.json records the run's stories and their outcome.",
"Runs archived by bmad-loop archive or bmad-loop clean are .bmad-loop/archive/<run-id>.tar.gz and still hold journal.jsonl, state.json and logs/: search inside them too. Record a session-log gap only for runs that were deleted.",
]persistent_facts appends to the skill's defaults, so this fact adds to any others you
already set. Don't use a file: glob such as file:.bmad-loop/runs/*/journal.jsonl
instead: it would load every run's full journal into the retro's context.
The records last only as long as the run directory or its archive. bmad-loop clean
compresses finished runs outside the retention window to .bmad-loop/archive/ (with
--hard, or with [cleanup] archive_old = false, it deletes them), and bmad-loop archive
does the same for a single run. Both the retro and the fact above can still read an
archived run. delete, and a clean that deletes, remove a run for good.
clean --keep <run-id> protects a run for that one invocation only, so pass it every
time or retro the epic before its runs are deleted.
The supported adapters are claude (the default), codex, gemini, copilot,
antigravity (Google's agy, experimental — worktree isolation needs the project root trusted; see First-run notes), and opencode
(OpenCode ≥ 1.18 over HTTP/SSE, profile opencode-http — no tmux window; needs the
bmad-loop[opencode] extra and model set as provider/model). You can pick more
than one — register every CLI you intend to use for dev, review, or sweep triage.
There are two layers here, and confusing them is the usual stumbling block:
bmad-loop init --cli <name>registers the orchestrator's hooks for that CLI. Without registered hooks, a CLI can't signal the engine..bmad-loop/policy.toml[adapter]selects which CLI actually runs each stage.
So a mixed setup — say claude for dev and codex for review — needs both: the hooks
registered for each CLI (--cli claude --cli codex) and the role pointed at that CLI in
policy.toml:
[adapter]
name = "claude" # default for every stage
[adapter.review]
name = "codex" # the review pass runs on codex insteadAny CLI named in policy.toml must also have been registered with --cli. To add one later,
re-run bmad-loop init --cli <name>. If you only use a single CLI, leave policy.toml
untouched — the default is correct.
The [tui] extra pulls in the Textual dashboard (textual + tomlkit + pyte) so
bmad-loop tui works. The core tool needs only pyyaml and regex (plus psutil on Windows).
Together (recommended):
uv tool install "bmad-loop[tui] @ git+https://github.com/bmad-code-org/bmad-loop.git"A pinned release tag (reproducible; recommended for day-to-day use): append the tag to the URL,
as in ...bmad-loop.git@v<version> (see the releases for tags).
Without a tag the install tracks main.
Tool first, TUI later (separately): install the core without the extra, then add the
dashboard whenever you want it by re-running the same command with [tui]:
# core tool only
uv tool install "bmad-loop @ git+https://github.com/bmad-code-org/bmad-loop.git"
# add the TUI later — re-run with the extra (uv upgrades the install in place)
uv tool install --upgrade "bmad-loop[tui] @ git+https://github.com/bmad-code-org/bmad-loop.git"Until the extra is present, bmad-loop tui prints a clear error
(the TUI requires optional dependencies — uv tool install 'bmad-loop[tui]') rather than
failing obscurely.
uv tool install drops bmad-loop into uv's own managed tool environment, so there's no
PEP 668 externally-managed conflict and no need for a virtualenv, --user, or --break-system-packages.
Confirm with bmad-loop --version.
Upgrading is two steps: the tool, and the per-project skill copies that init laid down
(a tool upgrade does not touch them). The simplest path is to re-run the setup skill, which
detects the existing install and runs both steps:
claude "/bmad-loop-setup upgrade"By hand (non-Claude CLIs, CI, scripts):
# 1. upgrade the tool; --reinstall is required for a git source, or uv reuses the cached commit
uv tool upgrade bmad-loop --reinstall
# to move to a newer tag instead, re-install with the new ref:
# uv tool install --force "bmad-loop[tui] @ git+https://github.com/bmad-code-org/bmad-loop.git@v<version>"
# 2. re-lay the refreshed skills into each project that uses bmad-loop; without --cli this
# refreshes only the CLIs the policy selects (claude by default), so name every CLI
# you initialized the project for, e.g.:
bmad-loop init --project /path/to/project --force-skills --cli claude --cli codex.bmad-loop/policy.toml is left untouched: new keys are optional and take their defaults.
init gitignores policy.toml because it is per-machine; if yours is already committed, run
git rm --cached .bmad-loop/policy.toml once to stop sharing it (your local copy is kept).
Read the CHANGELOG or the
releases for what changed between tags.
bmad-loop init registers hooks and installs the bundled bmad-loop-* skills per CLI. The
--cli flag is repeatable — pass it once per CLI you want to drive:
# claude only (default)
bmad-loop init --project <project-root> --cli claude
# multiple, e.g. claude + codex + gemini
bmad-loop init --project <project-root> --cli claude --cli codex --cli geminiRun with no --cli and init registers hooks for every CLI the policy.toml references,
so a dual-client setup that's already configured in policy needs no extra flags. Names must
be exactly claude, codex, gemini, copilot, antigravity, or opencode-http (alias
opencode) — init errors on an unknown profile and lists the valid ones. A hookless
profile like opencode-http installs its skills but registers no hooks (it signals over
HTTP/SSE).
Each CLI needs a one-time interactive setup before the first bmad-loop run, because
spawned sessions can't answer first-run dialogs. init prints the relevant notes; relay
them to whoever owns the machine:
- claude — run
claudeonce in the project and accept the workspace-trust + hooks-approval dialogs. - codex — run
codexonce in the project and accept both prompts: workspace trust, then "Hooks need review → Trust all and continue" (untrusted hooks silently never fire). Requires Codex ≥ 0.139. - gemini — authenticate once (browser OAuth or
GEMINI_API_KEY). Requires Gemini CLI ≥ 0.46. - copilot — run
copilotonce in the project and authenticate (gh/ a Copilot subscription). Requires the Copilot CLI GA (≥ 2026-02) — not the VS Code extension. Pin a capable model: the free default (GPT-5 mini) silently skips steps in the multi-step dev/review skills; set[adapter] model = "claude-sonnet-4-6"(→--model). - antigravity — run
agyonce in the project, authenticate, and answer "Yes, I trust this folder" beforebmad-loop run; spawned sessions can't answer that dialog, and a pending one reads as a session timeout. Requires Antigravity CLI (agy≥ 1.1.3). Two limitations to know, both verified against 1.1.3:- Trust is exact-path.
settings.jsontrustedWorkspacesmatches whole paths — trusting a parent does not cover its subdirectories, and--dangerously-skip-permissionsdoes not bypass the dialog (it covers tool permissions only).isolation = "none"(the default) works once the project root is trusted.isolation = "worktree"works too, as long as the project root is trusted: after provisioning each unit worktree, bmad-loop appends its path to~/.gemini/antigravity-cli/settings.jsontrustedWorkspacesbefore any session launches (journaledworktree-trust-seeded). It only ever extends a grant you already made — with the root untrusted nothing is written (worktree-trust-unseeded) and the session will hang on the dialog. Check a path withbmad-loop probe-adapter antigravity --workspace <path>(exit0= trusted). Known limitation: entries are never removed when a worktree is torn down, sotrustedWorkspacesaccumulates one entry per unit — prune stale.bmad-loop/runs/paths by hand if the list grows. - Token usage is not recorded (
usage_parser = "none") — and this is permanent, not a gap: agy's transcript carries no usage data at all (it counts tokens only in an internal SQLite/protobuf store). Runs work; the token columns stay empty.
- Trust is exact-path.
- opencode — install the HTTP client extra (
uv tool install "bmad-loop[tui,opencode] @ git+https://github.com/bmad-code-org/bmad-loop.git") and authenticate once, globally, withopencode auth login(not per-project — there is no workspace-trust dialog to answer). Requires OpenCode ≥ 1.18. Set the model asprovider/model(e.g.[adapter] model = "anthropic/claude-haiku-4-5"). A reasoningeffort(e.g.[adapter.review] effort = "max") is sent as the per-prompt variant and is opencode-only — the tmux CLIs ignore it. No hooks are registered — the adapter drives a headlessopencode serveover HTTP/SSE, so there is no tmux window to attach to; watch a session via itslogs/<task-id>.log— a curated transcript of the agent's prose, tool calls, file edits and permission decisions — or the TUI Log tab. The server's own stdout lands beside it in<task-id>.server.out, and a structured trace of the raw SSE frames in<task-id>.sse.jsonl.
Codex trusts hooks per directory, and an untrusted hook never fires, so a session would never report back. Check trust before the first run:
- In the project root, run
codexand accept both prompts (workspace trust, then "Hooks need review → Trust all and continue"). bmad-loop validate: thehooks.trustcheck must be ok.bmad-loop probe-adapter codexreports Codex's verdict for the project checkout ashook_trustand exits 1 unless it istrusted. It does not account for stageextra_argsor worktree isolation, so always re-check withvalidate.- If the verdict is not
trusted:untrusted, trust is stale: open Codex in that checkout and accept the hook prompt again.untrusted, the relay is not usable or Codex omitted it: re-register it withbmad-loop init --cli codex.unverifiable: fix the cause it names, for example stageextra_argsother than--dangerously-bypass-approvals-and-sandbox, profilelaunch_args, Codex missing fromPATH, or an unreadable.codex/hooks.json. Then check again.
Under [scm] isolation = "worktree", every unit runs in a new worktree that Codex has not trusted yet. validate therefore always fails hooks.trust under worktree isolation; that failure is expected, and probe-adapter codex still reports the project checkout. The run checks trust itself before each Codex session in a worktree. When a check fails, the unit escalates and the run pauses. For each such pause:
- Read the escalation. It names the role, the worktree path, the status and the reason. For
unverifiable, fix the cause first. cdinto the named worktree (it stays mounted under.bmad-loop/runs/<run-id>/worktrees/), runcodex, and accept the hook trust prompt.bmad-loop resolve <run-id> --no-interactiveand answer yes: it re-arms the story and resumes the run. (With--no-resume, runbmad-loop resume <run-id>afterwards.)
Expect one pause per unit: each worktree path needs its own grant. The re-armed story restarts from its baseline. bmad-loop never writes Codex's trust state itself.
claude reads skills from .claude/skills/; codex, gemini, copilot, and antigravity
read from .agents/skills/. init installs the bundled bmad-loop-* skills into the right tree
for each CLI you pass via --cli, so selecting any of the .agents/skills/ CLIs populates it automatically. It skips skill
dirs that already exist — pass --force-skills to overwrite a stale copy, or --no-skills to
manage them yourself.
Preflight the project — config, sprint-status, git, tmux, and the coding CLI:
bmad-loop validate --project <project-root>validate exits non-zero when the project isn't fully ready (e.g. no sprint-status.yaml
yet, or bmad-sprint-planning hasn't run). On a fresh project that is expected — read its
output as a readiness checklist, not an install failure.
For the dashboard itself, see docs/tui-guide.md. For the full policy reference, see the configuration reference.
Removing bmad-loop is the inverse of bmad-loop init:
undo what it laid down (the .bmad-loop/ state, the per-CLI hooks and skills, the gitignore
lines), then uninstall the tool. There is no bmad-loop uninstall command — the steps below
are the documented manual procedure. Work inside the project root, and reclaim disk
before deleting state so no worktrees or archives are orphaned.
Two paths overlap: every project does steps 1–5 and 7; only projects with a _bmad/ tree
also need step 6.
Tear down any leftover worktrees, tmux sessions, and archived runs while the tool is still
installed — once .bmad-loop/ is gone these are unreachable:
bmad-loop clean --hard --retain 0 --project <project-root> # delete every concluded run + its worktrees
bmad-loop cleanup --project <project-root> # kill leftover tmux sessions/windowsclean --hard permanently deletes runs instead of archiving them (we're removing the tool, so
there's nothing to keep), and --retain 0 puts every concluded run past the retention window
(a [cleanup] retention_days you set still keeps newer runs; unset it first). Running it first also matters for the out-of-tree half: each run's
control-plane directory lives under the user-scoped state root, and clean is what collects it
(step 2 covers what is left over). See
Reclaiming sessions and disk and the
CLI reference for what each command touches. Make sure no run is still live (Editor open, session attached) first.
clean never collects paused, crashed or interrupted runs. Run bmad-loop list --project <project-root>
afterwards; for each run still listed, save any work you want from its worktree under
.bmad-loop/runs/<run-id>/worktrees/, then bmad-loop delete <run-id> --project <project-root>
(or archive to keep a tarball). Deleting .bmad-loop/ by hand instead skips their worktree teardown.
Delete the .bmad-loop/ directory. This removes the policy.toml template,
legacy relay copies from older installs, and all per-run state
(runs/, cache/, archive/) in one step:
rm -rf .bmad-loop/One piece is not under .bmad-loop/: each run's hook-event channel lives in a user-scoped
state root outside the project — $XDG_STATE_HOME/bmad-loop, else
~/.local/state/bmad-loop; %LOCALAPPDATA%\bmad-loop\state on Windows; or whatever
BMAD_LOOP_STATE_DIR names. Step 1 collected this project's runs from it, leaving an empty
per-project directory whose name is a digest of the project path — not something to pick out by
hand. That root is shared by every project on this machine, so delete the whole thing only if
you are removing bmad-loop everywhere:
# all projects on this machine — same cascade the orchestrator resolves
rm -rf "${BMAD_LOOP_STATE_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/bmad-loop}"init installed the three bundled bmad-loop-* skill directories — delete only those. Leave
the standard BMAD skills alone; install never touched them.
# claude reads from .claude/skills/ ; codex/gemini read from .agents/skills/
rm -rf .claude/skills/bmad-loop-{dev,review,resolve,sweep,setup}
rm -rf .agents/skills/bmad-loop-{dev,review,resolve,sweep,setup}(Run only the line for the skill tree your CLIs use — drop the other. The dev and review
names are retired — current init never lays them down — but listing them is a harmless no-op
that also cleans up a pre-0.7.0 install.)
init merged its Stop-hook registration into each CLI's existing hook config, so these
files must be edited, not deleted (they hold your own settings too). In each config below,
remove the hook entry whose command ends in bmad-loop relay <Event> (or, on
older installs, is a Python or uv run --no-project python command whose script
path ends in .bmad-loop/bmad_loop_hook.py and whose event argument matches
that hook event):
- claude —
.claude/settings.json - codex —
.codex/hooks.json - gemini —
.gemini/settings.json - copilot —
.github/copilot/settings.json - antigravity —
.agents/hooks.json(thebmad-loophook group)
Edit only the registered CLIs. Match the full relay command and event; leave every
other hook in place. The installed bmad-loop executable is shared with other projects,
so remove it only when uninstalling the package itself.
init appended .bmad-loop/runs/, .bmad-loop/cache/, .bmad-loop/policy.toml and _bmad/render/ to
.gitignore. Remove those four lines (skip any your project relies on for other reasons). If
you had run git rm --cached .bmad-loop/policy.toml to stop sharing the per-machine policy, the
file is untracked — re-add it (git add .bmad-loop/policy.toml) only if you want it back in version control.
There is nothing to hand-unregister: bmad-loop writes no BMAD config. If you installed the
module through the BMAD installer, remove it there — the installer owns _bmad/bmad-loop/,
the central config.toml, and the /bmad-help catalog, and regenerates all three on its
next run.
If you only ever ran /bmad-loop-setup, delete _bmad/bmad-loop/module-help.csv (the one
file it refreshes) — or the whole _bmad/bmad-loop/ directory if the installer never
created it. uv + init-only projects that have no _bmad/ can skip this step.
uv tool uninstall bmad-loopConfirm removal: bmad-loop --version should now fail with a command-not-found error. Repeat
steps 1–6 in every project that used the tool — the tool install is machine-wide, but the
state, skills, and hooks are per-project.