This work was developed in a separate bmad-marketplace repo and is now landing directly in BMAD-METHOD, so the migration framing is obsolete: - remove links to docs/spec.md (only existed in the temp repo) and the bmad-marketplace / 'upstream patch' / 'sibling checkout' references in README, the integration test, and the acme-md-lint fixture - drop dead 'spec §N' pointers in install.mjs, install-plan.mjs, and plugin-json.mjs (including a user-facing reserved-code error message) - reword the manifest-generator 'patch' note as in-repo behavior - correct the documented install path from _bmad/ to the IDE skills directories the installer now distributes skills to (.claude/skills/, etc.) No behavior change. Integration suite: 73 pass / 0 fail. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| scripts | ||
| tests | ||
| README.md | ||
| SKILL.md | ||
README.md
bmad-module
The core BMAD skill for installing, updating, removing, and listing community BMAD modules. Modules are standalone GitHub repos that conform to the BMAD Module Manifest Spec.
How it fits
- Authors publish a single repo with
.claude-plugin/plugin.jsonthat works in both Claude Code's plugin marketplace and BMAD-METHOD. - Users install via this skill — no CLI required. Modules are staged under
_bmad/<bmad.code>/, then their skills are distributed to the coding assistants the user chose atbmad installtime (theides:list in_bmad/_config/manifest.yaml), exactly like official modules. - BMAD-METHOD treats community-installed modules as a new
source: 'community'row inmanifest.yaml; re-runningbmad installpreserves them (manifest-generator.jscarriessource: 'community'rows through regeneration).
Verbs
bmad-module install <source> [--ref <r>] [--channel <c>] [--dry-run]
bmad-module update <code|--all> [--ref <r>] [--channel <c>]
bmad-module remove <code> [--purge]
bmad-module list [--json]
<source> accepts owner/repo, a full git URL, or a local path.
Behavior notes
- Source of truth for what was installed is
_bmad/_config/files-manifest.csv(per-file hashes) and_bmad/_config/skill-manifest.csv(one row per shipped skill).manifest.yamlcarries the source/version/sha tuple. updaterefuses to overwrite locally-modified files (hash mismatch against the recorded hash). Move overrides into_bmad/custom/<code>/and retry.removewithout--purgepreserves_bmad/custom/<code>/so a re-install picks the customizations back up.--purgedeletes them. Remove also prunes the module's skills from every configured IDE.- IDE distribution runs after every install/update/remove via a self-contained bundle of BMAD's real IDE engine, shipped at
lib/vendor/ide-sync.mjs(built fromtools/installer/ide/*bylib/vendor/build-ide-sync.mjs, gated byvendor:check). The skill execs it locally — no npx, no network. The same engine also backs thebmad ide-syncCLI command and the full installer's IDE setup, so all three stay in lockstep. If the bundle is unreachable on an older install, the skill says so and points the user atbmad ide-sync. - Hooks / MCP / LSP / Claude subagents declared in the module manifest are copied but NOT auto-activated by this skill (they are Claude Code plugin surfaces, not skills). Use Claude Code's plugin manager to wire them up.
Implementation
The skill itself is a thin verb router (SKILL.md). scripts/bmad-module.mjs is a zero-import launcher that guards the import graph (a missing/corrupt runtime file becomes a documented exit code, not a raw stack trace); the verb dispatcher lives in scripts/cli.mjs and all filesystem work happens in the lib/ modules. These carry no registry dependencies — important because the installer copies the skill into the IDE skills directories (e.g. .claude/skills/bmad-module/) without node_modules and never runs npm install there:
manifest.yamlis read/written with a vendored copy of the realyamllibrary (lib/vendor/yaml.mjs, regenerated bylib/vendor/build-vendor.mjs) so it stays byte-identical to BMAD core's writer.semvervalidity/range checks use a smallnode:-only helper (lib/semver-lite.mjs).
Exit codes
See SKILL.md for the full table. The script's stderr always names the condition; the codes are stable so tooling can branch.
Tests
Integration tests live in tests/integration.test.sh and run end-to-end on a fresh BMAD install. Fixtures for negative cases (collisions, path traversal, reserved codes) are under tests/fixtures/.