Compare commits

...

2 Commits

Author SHA1 Message Date
pbean bca9388750 docs(bmad-module): drop stale temp-repo references and install paths
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>
2026-06-01 18:00:32 -07:00
pbean 4d036bc18b docs(bmad-module): correct script location to installed IDE skills dir
Step 4 pointed at _bmad/core/skills/bmad-module/, but the new module
system distributes skills verbatim into the selected IDE directories
(.claude/skills/, .agents/skills/, etc.). Resolve the script relative
to SKILL.md instead, and route the missing-script case to the existing
exit-code-5 reinstall guidance.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 17:44:34 -07:00
8 changed files with 14 additions and 16 deletions

View File

@ -1,12 +1,12 @@
# 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`).
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.json` that 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 at `bmad install` time (the `ides:` list in `_bmad/_config/manifest.yaml`), exactly like 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).
- **BMAD-METHOD** treats community-installed modules as a new `source: 'community'` row in `manifest.yaml`; re-running `bmad install` preserves them (`manifest-generator.js` carries `source: 'community'` rows through regeneration).
## Verbs
@ -29,13 +29,11 @@ bmad-module list [--json]
## 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:
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.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.

View File

@ -59,7 +59,7 @@ Run from the project root (the dir containing `_bmad/`):
node <skill-dir>/scripts/bmad-module.mjs <verb> [args...]
```
`<skill-dir>` is wherever the skill files live in the current install. After this skill ships into BMAD-METHOD that's `_bmad/core/skills/bmad-module/`; during development it's this repo's `src/core-skills/bmad-module/`.
`<skill-dir>` is this skill's own directory — the script ships alongside this `SKILL.md`, so it lives wherever `bmad install` distributed skills for the coding assistant you're running under. That's `<target_dir>/bmad-module/` (e.g. `.claude/skills/bmad-module/` for Claude Code, `.agents/skills/bmad-module/` for Cursor/Copilot/etc.), making the script `<target_dir>/bmad-module/scripts/bmad-module.mjs`. During development in this repo it's `src/core-skills/bmad-module/scripts/bmad-module.mjs`. Resolve it relative to this `SKILL.md` rather than assuming a fixed path. If the script isn't found next to it, the skill's bundled runtime is missing — that's the exit-code-5 case (see CRITICAL RULES and EXIT CODES): relay the "reinstall the skill" guidance rather than guessing another location.
Stream stdout and stderr verbatim. Do NOT silence or rewrite them — the script's own messages are designed for end-user consumption.

View File

@ -58,7 +58,7 @@ export async function runInstall(opts) {
EXIT.PREFIX_COLLISION,
`code "${code}" already used by ${existingEntry.source} module ` +
`${existingEntry.repoUrl || existingEntry.rawSource || existingEntry.npmPackage || '(local)'}. ` +
`Module authors should pick a unique bmad.code (spec §7.1).`,
`Module authors should pick a unique bmad.code.`,
);
}

View File

@ -39,8 +39,8 @@ export function buildIgnoreMatcher(userPatterns) {
};
}
// Load user ignore patterns from manifest first, then .bmadignore. Spec §15
// disallows both at once — readUserIgnores enforces it.
// Load user ignore patterns from manifest first, then .bmadignore. Declaring
// both at once is disallowed — readUserIgnores enforces it.
export async function readUserIgnores(sourceDir, manifest) {
const fromManifest = manifest?.bmad?.install?.ignore;
const ignoreFilePath = path.join(sourceDir, '.bmadignore');

View File

@ -3,8 +3,8 @@ import path from 'node:path';
import { valid as semverValid, validRange as semverValidRange } from './semver-lite.mjs';
import { EXIT, BmadModuleError } from './exit.mjs';
// Reserved bmad.code values — must match docs/spec.md §7.1 and the
// validator's RESERVED_CODES set. Single source of truth for the runtime.
// Reserved bmad.code values — must match the validator's RESERVED_CODES
// set. Single source of truth for the runtime.
export const RESERVED_CODES = new Set([
'core',
'bmm',
@ -70,7 +70,7 @@ export async function readAndValidateManifest(sourceDir) {
throw new BmadModuleError(EXIT.BAD_MANIFEST, `plugin.json#bmad.code "${m.bmad.code}" must match ${CODE_REGEX}`);
}
if (RESERVED_CODES.has(m.bmad.code)) {
throw new BmadModuleError(EXIT.RESERVED_PREFIX, `plugin.json#bmad.code "${m.bmad.code}" is reserved (spec §7.1)`);
throw new BmadModuleError(EXIT.RESERVED_PREFIX, `plugin.json#bmad.code "${m.bmad.code}" is reserved`);
}
if (!semverValidRange(m.bmad.compatibility.bmadMethod)) {
throw new BmadModuleError(

View File

@ -4,7 +4,7 @@ This directory holds **self-contained, generated** copies of third-party librari
## Why vendor at all?
The `bmad-module` skill is **copied into a user's project** at `_bmad/core/skills/bmad-module/` by `npx bmad-method install`. The installer:
The `bmad-module` skill is **copied into a user's project** — into the IDE skills directories chosen at `bmad install` time (e.g. `.claude/skills/bmad-module/`, `.agents/skills/bmad-module/`) — by `npx bmad-method install`. The installer:
- strips `node_modules` while copying (`tools/installer/core/installer.js`),
- ships **no** `package.json` under the skill, and

View File

@ -2,7 +2,7 @@
A minimal BMAD module: one skill that lints markdown files under `_bmad/` for heading-hierarchy mistakes and broken relative links.
This is the **smallest valid module** that conforms to the [BMAD Module Manifest Specification](https://github.com/bmad-code-org/bmad-marketplace/blob/main/docs/spec.md). Use it as a starting template.
This is the **smallest valid module** that conforms to the BMAD Module Manifest Specification. Use it as a starting template.
## Install

View File

@ -4,7 +4,7 @@
# Hermetic: fabricates a minimal _bmad/_config/manifest.yaml skeleton in a
# tmp dir and exercises every verb against the vendored reference modules
# (tests/fixtures/examples/) and negative fixtures. Does NOT require
# BMAD-METHOD's installer; the upstream patch (§5) is verified separately.
# BMAD-METHOD's installer; installer integration is verified separately.
#
# Run from anywhere:
# bash src/core-skills/bmad-module/tests/integration.test.sh
@ -17,7 +17,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
MODULE_JS="${SKILL_DIR}/scripts/bmad-module.mjs"
# Reference modules are vendored under tests/fixtures/examples/ so the suite is
# self-contained — it does not depend on a sibling bmad-marketplace checkout.
# self-contained — the fixtures travel with the test, no external checkout.
EXAMPLES="${SCRIPT_DIR}/fixtures/examples"
FIXTURES="${SCRIPT_DIR}/fixtures"