# 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 (see `docs/spec.md` in `bmad-marketplace`).

## How it fits

- **Authors** publish a single repo with `.claude-plugin/plugin.json` that
  works in both Claude Code's plugin marketplace and BMAD-METHOD.
- **Users** install via this skill — no CLI required. Modules land in
  `_bmad/<bmad.code>/` alongside the official modules.
- **BMAD-METHOD** treats community-installed modules as a new `source: 'community'`
  row in `manifest.yaml`; re-running `bmad install` preserves them (with the
  paired `manifest-generator.js` patch).

## 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.yaml` carries the source/version/sha tuple.
- **`update`** refuses to overwrite locally-modified files (hash mismatch
  against the recorded hash). Move overrides into `_bmad/custom/<code>/`
  and retry.
- **`remove`** without `--purge` preserves `_bmad/custom/<code>/` so a
  re-install picks the customizations back up. `--purge` deletes them.
- **Hooks / MCP / LSP / Claude subagents** declared in the module manifest
  are _copied_ but NOT auto-activated by this skill. 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 `_bmad/` without `node_modules` and never
runs `npm install` there:

- `manifest.yaml` is read/written with a **vendored copy of the real `yaml`
  library** (`lib/vendor/yaml.mjs`, regenerated by `lib/vendor/build-vendor.mjs`)
  so it stays byte-identical to BMAD core's writer.
- `semver` validity/range checks use a small `node:`-only helper
  (`lib/semver-lite.mjs`).

They re-use no BMAD-METHOD internal modules — the same code runs during
development inside `bmad-marketplace` and after the skill is PR'd into
BMAD-METHOD core.

## 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/`.
