* feat(agents): set team to software-development on BMM agents
All six BMM agents (analyst, tech-writer, PM, UX designer, architect,
dev) now explicitly declare `team: software-development` in the
module.yaml roster instead of falling back to the module-code default
of `bmm`.
This matches the BMad-wide team convention where agents across modules
that collaborate on software delivery share one named team. Tea's Murat
joins the same team via a parallel PR in bmad-method-test-architecture-
enterprise so party-mode, help catalog, and retrospective skills can
route the full software-delivery roster as a single unit.
* test: update team assertions for explicit software-development
* refactor: remove bmad-skill-manifest yaml; introduce four-layer central config.toml
- Agent essence moves from per-skill bmad-skill-manifest.yaml files
into each module.yaml's `agents:` block (code, name, title, icon,
description). Per-agent customize.toml remains the deep-behavior
source of truth.
- Installer emits four TOML files:
_bmad/config.toml team install answers + agent roster
_bmad/config.user.toml user install answers
_bmad/custom/config.toml team overrides stub
_bmad/custom/config.user.toml personal overrides stub
Prompts declare scope: user to route answers to config.user.toml.
- resolve_config.py merges four layers: base-team -> base-user ->
custom-team -> custom-user.
- Three consumer skills (party-mode, advanced-elicitation,
retrospective) switched from agent-manifest.csv to the resolver.
- installer.js mergeModuleHelpCatalogs now takes the in-memory
agent list from ManifestGenerator -- no CSV roundtrip.
- Deleted: 6 bmad-skill-manifest.yaml files, agent-manifest.csv
emission, collectAgents/getAgentsFromDirRecursive,
paths.agentManifest().
* fix(installer): strip core-key pollution from [modules.*]; soften config headers
- writeCentralConfig now always strips core-module keys from every
[modules.<code>] bucket, even when the module's schema is not
available in src/ (external / marketplace modules like cis, bmb).
Core values belong in [core] only; workflows read them directly.
- When the module's own schema IS available (built-in modules),
also drop any key it does not declare as a prompt — same
spread-pollution filter as before, now layered on top.
- Section-aware headers on both _bmad/config.toml and
_bmad/config.user.toml: [core] / [modules.*] values are
editable (installer reads them as defaults on next install);
[agents.*] is regenerated from module.yaml and will be wiped —
overrides for agents go in _bmad/custom/config*.toml instead.
* docs: cover central config.toml + Diataxis prose pass across three files
Document the new four-file central configuration surface (_bmad/config.toml,
config.user.toml, and custom/ overrides) alongside the existing per-skill
customize.toml. Make editing rules, scope partitioning, and when-to-use-which
guidance explicit.
- customize-bmad.md: new "Central Configuration" section with editing rules,
three worked examples (rebrand, fictional agent, module settings override),
and a "when to use which surface" table. Converted five h4 headers to
bold paragraph intros per style guide.
- expand-bmad-for-your-org.md: two-layer mental model extended to three;
new Recipe 5 with three variants (rebrand, custom crew, pinned team
settings); reinforcement table extended.
- named-agents.md: noted the dual customization surface — per-skill shapes
behavior, central config shapes roster identity.
Diataxis prose pass applied across all three files: banned vocabulary
check, em-dash cap, hypophora / metanoia / amplificatio / stakes-inflation
cleanup, rhythm and burstiness fixes. Structural conformance verified;
markdownlint and prettier clean.
* test+docs: add central config unit tests; fix stale recipe count
- test: two new suites (35 + 36) covering writeCentralConfig and
ensureCustomConfigStubs. Verifies scope partitioning (user_name
lands only in config.user.toml), core-key pollution stripping
from [modules.*], unknown-schema fallthrough (external modules
survive without schema), agent roster baked into config.toml
[agents.*] only, stub-preservation on re-install. 44 new
assertions.
- docs: fixed four stale "four recipes" references to say "five"
after Recipe 5 (Customize the Agent Roster) was added. Touches
frontmatter, opening paragraph, Combining Recipes paragraph,
and the named-agents cross-link blurb.
* fix: address PR review feedback on central config
- resolve_config.py argparse: three-layer → four-layer description
- SKILL/workflow/explanation docs: document all four layers including
_bmad/config.user.toml (was missing from merge-stack descriptions)
- customize-bmad.md + installer headers: drop the false "direct edits to
config.toml persist" claim; installer reads from per-module config.yaml,
not central TOML, so direct edits get clobbered. Route users to
_bmad/custom/config.toml for durable overrides
- writeCentralConfig: warn loudly when a module.yaml can't be parsed
(previously silent — user-scoped keys could mis-file into team config)
- writeCentralConfig: preserve [agents.*] blocks for modules that didn't
contribute fresh agents this run (e.g. quickUpdate skipping modules
whose source is unavailable) so the roster doesn't silently shrink
- add extractAgentBlocks helper + Test Suite 37 covering preservation
Addresses comments from augmentcode and coderabbitai on PR #2285.
* feat(skills): TOML-based agent customization with stdlib Python resolver
Re-applies PR #2282's three-layer customization model (skill defaults →
team → user) but swaps YAML for TOML and uv for stdlib tomllib. Users
no longer need uv, pip, or a virtualenv — plain python3 (3.11+) is
sufficient, since tomllib shipped in the standard library.
## Schema changes vs PR #2282
- Flat agent schema: fields live directly under [agent], no nested
metadata/persona sub-tables. Easier to author, less indentation.
- Non-configurable identity: name and title are declared in
customize.toml as source-of-truth metadata (for future skill-manifest
generation) but SKILL.md ignores overrides there — identity is
hardcoded to preserve brand recognition.
- role redefined: now describes what the skill does for the user
within its module phase, not a restatement of the title.
- persistent_facts replaces the activation-time file-context load AND
the old memories concept. Entries can be literal sentences or
file: prefixed paths/globs; avoids collision with the upcoming
runtime memory sidecar.
- activation_steps_prepend / activation_steps_append harmonized across
agents and workflows (replaces agent-specific critical_actions).
- [workflow] namespace mirrors [agent] for workflow customization.
Same four structural rules, same field vocabulary.
## Resolver (src/scripts/resolve_customization.py)
Four purely structural merge rules, zero field-name hardcoding:
- Scalars: override wins
- Tables: deep merge
- Arrays of tables where every item has `code` or `id`: merge by
that key (matching keys replace, new keys append)
- Any other array: append
No removal mechanism — overrides cannot delete base items. Fork the
skill or override by code with a no-op value to suppress defaults.
## Agents ported (6)
All six BMad agents now ship customize.toml + rewritten SKILL.md:
analyst (Mary), tech-writer (Paige), pm (John), ux-designer (Sally),
architect (Winston), dev (Amelia). Each uses the same 8-step
activation template: resolve → execute prepend → adopt persona →
load persistent facts → load config → greet (with {agent.icon}) →
execute append → dispatch or present menu.
Step 8 supports fast-path invocation: "hey Mary, let's brainstorm"
dispatches the matching menu item directly after greeting, skipping
the menu render when intent is clear. Chat, clarifying questions,
and bmad-help remain available when nothing on the menu fits.
## Installer + tooling
- _bmad/scripts/ provisioned on install (copies src/scripts/)
- _bmad/custom/ seeded with .gitignore for *.user.toml on fresh install
- Non-module-dir filter extended to skip _memory, memory, docs,
scripts, and custom when scanning for modules
- Dead _config/agents/ directory no longer created
- metadata.capabilities removed from agent-manifest.csv and schema
- eslint config extended to cover src/scripts/**
- validate-file-refs.js knows about custom/ as install-only
## Deferred for follow-up
- bmad-product-brief workflow port (the pilot that demonstrates
[workflow] + on_complete)
- Translated docs (cs/fr/vi-vn/zh-cn) — regenerate from English
* feat(skills): port bmad-product-brief to TOML workflow customization
Completes the customization surface rollout by giving the product-brief
workflow the same override model as the six BMad agents, under the
[workflow] namespace instead of [agent].
## customize.toml
Mirrors the agent shape under [workflow] with:
- activation_steps_prepend / activation_steps_append (harmonized across
agents and workflows — same field names, same append semantics)
- persistent_facts with the file: convention, seeded with
file:{project-root}/**/project-context.md
- on_complete scalar (renamed from PR #2282's skill_end for clarity —
reads cleaner as "what runs when the workflow completes")
## SKILL.md
7-step workflow activation:
1. Resolve workflow block
2. Execute prepend steps
3. Load persistent facts (file: or literal)
4. Load config
5. Greet if not already
6. Execute append steps
7. Stage 1 — Understand Intent
python3 + stdlib tomllib invocation; no uv required.
## Prompt file changes
- Path normalization: ../agents/ → agents/, ../resources/ → resources/,
bare foo.md → prompts/foo.md. All references now resolve from the
skill root (matches the convention documented in SKILL.md).
- Paths: meta-line added to each of the 4 prompt files that reference
other files, reinforcing "bare paths resolve from skill root" so the
LLM doesn't lose the convention when operating two hops into a
prompt chain.
- finalize.md terminal stage now calls the resolver for
workflow.on_complete — non-empty values run as the final step.
## Validation
- Resolver output verified: 4 workflow fields returned cleanly.
- validate-file-refs.js: 254 files scanned, 139 refs checked, 0 broken.
- test:refs: passing.
* docs(skills): enterprise customization recipes + workflow template variable
Three independent improvements bundled because they share the same
surface (workflow/agent customization) and landed from the same design
discussion:
## Fallback sentence disambiguated (7 SKILL.md files)
The "if the script fails" fallback used to say `{project-root}/_bmad/
custom/{skill-name}.toml` for the team override and then just `{skill-
name}.user.toml` for the user override, leaving the user file's
location implicit. LLMs could reasonably guess skill root or project
root instead. Replaced with an unambiguous numbered list that spells
out the full path for every file in the merge chain.
## Product-brief: stage promotion + brief_template variable
- Promoted `## Stage 1: Understand Intent` from a nested step inside
"On Activation" to a top-level section. The previous "Step 7: Stage
1 — Understand Intent → Proceed to Stage 1 below" was mechanical
numbering pretending to be a step. Activation now ends cleanly at
Step 6; Stage 1 is a peer section.
- Added `brief_template` as a workflow-level scalar customization
defaulting to `resources/brief-template.md`. Stage 4 reads
`{workflow.brief_template}` instead of the hardcoded path, so orgs
can point at their own template under `{project-root}/...` without
forking the skill.
## New doc: docs/how-to/extend-bmad-for-your-org.md
Four worked recipes that together cover most enterprise scenarios:
1. Shape an agent across every workflow it dispatches (dev agent +
Context7 MCP + Linear search — the highest-leverage pattern)
2. Enforce org conventions inside a specific workflow (product-brief
+ compliance-field persistent_facts)
3. Publish completed outputs to external systems (product-brief +
Confluence + Jira via MCP, gated on user confirmation for Jira)
4. Swap in your own output template (product-brief + brief_template
variable swap)
Opens with the two-layer mental model (agent spans workflows,
workflow is local) so readers pick the right granularity before
reading any recipe. Closes with a "Combining Recipes" section
showing all four composed. Cross-linked from customize-bmad.md.
## Validation
- Resolver: workflow.brief_template returns the default cleanly.
- validate-file-refs.js: 254 files scanned, 146 refs checked
(+7 from this commit), 0 broken.
* docs(skills): encourage CLAUDE.md/AGENTS.md reinforcement of critical rules
Added a "Reinforce Global Rules in Your IDE's Session File" section to
extend-bmad-for-your-org.md. BMad customizations only load when a
skill activates, but IDE session files (CLAUDE.md, AGENTS.md, cursor
rules, copilot-instructions) load every turn — worth restating the
most critical rules there too so they survive ad-hoc chat outside a
BMad skill.
Includes a one-line example reinforcing the Recipe 1 Context7 rule,
plus a scope table that clarifies what each layer is for:
- IDE session file: universal, every session, keep succinct
- Agent customization: persona-specific, every dispatched workflow
- Workflow customization: one workflow run
Emphasizes brevity — noise in the session file crowds out signal.
* docs(skills): add Named Agents explanation doc
New docs/explanation/named-agents.md walking through the three-legged
stool (skills + named agents + customization) with the "Hey Mary,
let's brainstorm" activation flow as the narrative thread.
Covers:
- Why named agents vs menu-driven or prompt-driven alternatives
- The 8-step activation flow and what each step contributes
- How customization scales the model beyond a single developer
- Cross-links to the how-to docs for implementation details
Sits alongside brainstorming.md, quick-dev.md, party-mode.md in the
explanation folder — feature narratives for users who want to
understand why BMad is designed the way it is, not just how to use it.
* docs(skills): clarify that keyed-merge requires a single identifier key per array
Review feedback (PR #2284) flagged that the merge-rules wording was
ambiguous: "every item has a `code` or `id` field" could reasonably
be read as "each item individually has at least one of the two",
allowing arrays to mix `code` and `id` across items.
The resolver has always required all items share the *same* identifier
key (all `code`, or all `id`). Mixed arrays fall through to append —
intentional, because mixing identifier keys within one array is a
schema smell and any guess about which key should merge creates a
worse trap than the append-fallback.
Clarified in three places:
- Merge-rules table in customize-bmad.md: "every item shares the
**same** identifier field"
- `code`/`id` convention paragraph: "pick **one** convention ... and
stick with it across the whole array"
- Resolver docstring and `_detect_keyed_merge_field` docstring:
explicit note that mixed arrays fall through with rationale
No behavior change.
* docs(skills): address CodeRabbit review — fallback rules, OS claim, headless greeting
Three fixes from PR #2284 review feedback:
## 1. Fallback merge wording (7 SKILL.md files)
Every SKILL.md told the LLM to merge the three customization files
"in priority order (later wins)" when the resolver fails. That reads
as shallow last-write-wins — but the resolver does structural merge
(scalars override, tables deep-merge, code/id-keyed arrays merge by
key, other arrays append). Following the old wording manually would
have silently stripped base `principles`, `persistent_facts`, and
`menu` items whenever a team override was present.
Expanded the fallback sentence to restate the four structural rules
explicitly, matching the resolver's behavior.
Applied to all 6 agents + bmad-product-brief workflow.
## 2. Python 3.11 / OS shipping claim (customize-bmad.md)
The docs claimed "macOS 13+, Ubuntu 22.04+, Debian 12+, Fedora 37+
all ship 3.11 or newer." Inaccurate — Ubuntu 22.04 defaults `python3`
to 3.10.6 (3.11 is a separate package), and macOS doesn't really
ship Python by default anymore.
Replaced with honest guidance: check `python3 --version` and note
that macOS without Homebrew and Ubuntu 22.04 default to 3.10 or
earlier.
## 3. Autonomous mode greeting gate (bmad-product-brief)
Product-brief's activation-mode detection documents autonomous mode
as "produce complete brief without interaction" — but Step 5 greeted
unconditionally, adding conversational output before the headless
artifact. Gated the greeting on `{mode}` != `autonomous`.
## Dismissed (replied on thread)
- `.gitignore` migration from *.user.yaml to *.user.toml: YAML
installer code was in reverted #2282, never released. No users
affected. Same rationale as Augment's earlier thread.
Validated: 254 files, 146 refs, 0 broken. test:refs 7/7,
test:install 242/242.
* docs: rename Extend to Expand throughout customization docs
Three-layer customization (skill defaults → team → user) for BMad agents
and any skill that opts in. Users edit `_bmad/custom/{skill-name}.yaml`
(team, committed) or `{skill-name}.user.yaml` (personal, gitignored);
customizations survive updates.
Resolver is a Python script using PEP 723 inline metadata, invoked via
`uv run` so deps auto-install into a cached isolated env on first call.
This aligns with Anthropic's Agent Skills spec and BMB conventions, and
keeps the dependency declared (scannable by pip-audit/Dependabot) rather
than vendored.
## Design choices
- **Agent identity is hardcoded** in SKILL.md (name, title, Overview prose)
so skills can be invoked reliably by role *or* default name. Brand
recognition is preserved; customization shapes behavior, not identity.
- **Luminary-anchored personas** (e.g. "Channels Martin Fowler's
pragmatism and Werner Vogels's cloud-scale realism") deliver ~55%
token savings per agent while preserving distinctive voice beats.
- **Universal per-field merge rules** with v6.1-compatible agent
semantics: metadata shallow-merge, persona replace, critical_actions
and memories append, menu merge-by-code, all else deep-merge.
- **Workflow customization** shares the same surface — `bmad-product-brief`
pilots `activation_steps_prepend`, `activation_steps_append`, and
`skill_end` hooks that any workflow-style skill can adopt.
## Infrastructure
- `_bmad/scripts/` houses shared Python scripts (resolver + future).
- `_bmad/custom/` is provisioned empty with a seeded `.gitignore` for
`*.user.yaml` on fresh installs.
- Installer filters ensure `scripts/`, `custom/`, and sidecar-generated
`memory/` directories are never treated as modules.
- Dead v6.1 code cleaned up: `_config/agents/` no longer created,
`metadata.capabilities` removed from schema and CSV manifest.
* feat(installer): use GitHub API as primary fetch with raw CDN fallback
Corporate proxies commonly block raw.githubusercontent.com while allowing
api.github.com. Add fetchGitHubFile() to RegistryClient that tries the
GitHub Contents API first, falling back to the raw CDN transparently.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(installer): cap redirect depth and preserve dual-fallback errors
Add maxRedirects parameter to fetch() and _fetchWithHeaders() to prevent
unbounded redirect recursion. Wrap CDN fallback in try/catch and throw
AggregateError with both API and CDN errors for better diagnostics.
Extract marketplace repo coordinates into named constants in
external-manager.
* chore(installer): drop unused fetchJson and fetchGitHubJson
Neither method has any callers. Also drop the corresponding test.
* refactor(test): fold registry tests into test-installation-components
No reason for RegistryClient tests to be a separate runner — the same
file already tests the registry consumers in Suite 33. Drop test:registry
from package.json scripts and quality gate.
* fix(installer): include URL, API message, and rate-limit info in HTTP errors
Non-2xx responses previously yielded bare `HTTP 403`. Now surface the
request URL, GitHub's JSON error message (or body snippet), X-RateLimit-Reset
when quota is exhausted, and Retry-After. Turns a mystery 403 into
'rate limit exhausted; resets at 2026-04-15T18:00:00Z' — the difference
between 'try GITHUB_TOKEN' and a wild goose chase.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skills don't nest. Once the manifest generator finds a valid SKILL.md
in a directory, it should not recurse into that skill's subdirectories
looking for more skills. Template files (like bmb's setup-skill-template)
inside a skill's assets/ would be incorrectly scanned and produce
spurious errors.
Add missing move() with cross-device fallback (rename → copy+rm on
EXDEV), needed by OfficialModules.createModuleDirectories for directory
migrations during upgrades.
Honor overwrite/errorOnExist options in copy() to match fs-extra
behavior for callers that pass these flags.
fs-extra routes all operations through graceful-fs, which globally
monkey-patches node:fs with a deferred retry queue. During multi-module
installs (~500+ file ops), retried unlink operations from one module's
remove phase can fire after the next module's copy phase has written
files, silently deleting them non-deterministically.
Replace fs-extra with a thin fs-native.js wrapper over node:fs/promises
and node:fs. All 21 consumers now use native APIs with no global
monkey-patching, eliminating the retry-queue race condition entirely.
Closes#1779
Bob (Scrum Master) was consolidated into Amelia (Developer) in v6.3.0
(#2186) but still appeared in the workflow map diagrams for
sprint-planning, create-story, and retrospective. Updated both English
and French versions to show Amelia and removed the unused Bob CSS class.
Closes#2249
Core and BMM modules live in this repo (src/core-skills, src/bmm-skills)
but the installer UI sourced them from the remote registry. When the
registry was unreachable (VPN, proxy, firewall), the fallback YAML only
had the 4 external modules, so core and bmm disappeared from the install
list entirely.
Now _selectOfficialModules and getDefaultModules always read built-in
modules from the local source via OfficialModules.listAvailable(), then
append external modules from the registry. Network failures only affect
external modules.
Closes#2239
Translate the remaining untranslated English docs to Chinese:
- explanation/analysis-phase.md
- explanation/checkpoint-preview.md
- how-to/install-custom-modules.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore(installer): remove dead code across installer modules
Delete 3 entirely dead files (agent-command-generator, bmad-artifacts,
module-injections) and remove ~50 unused exports from manifest.js,
cli-utils.js, prompts.js, path-utils.js, official-modules.js,
external-manager.js, custom-module-manager.js, and registry-client.js.
Removes corresponding dead tests.
* fix(installer): restore currentProjectDir writes for placeholder expansion
The previous commit removed the three assignments to
OfficialModules.currentProjectDir as dead code, but buildQuestion()
still reads the property to resolve {directory_name} placeholders in
module config defaults during interactive collection. Without the
writes, any module default containing {directory_name} would surface
the literal placeholder to users.
The legacy agent-command-generator, bmad-artifacts helpers, and all 26
IDE template files (combined/ and split/) are unreachable dead code.
The installer now uses verbatim SKILL.md directory copying -- no template
rendering occurs. The files own TODO comments confirm retirement.
* feat(quick-dev): sync sprint-status.yaml on epic-story implementation
When quick-dev infers the intent is an epic story, resolve the full
sprint-status key during step-01's previous-story-continuity sub-step,
then sync sprint-status.yaml at the two workflow boundaries code-review
already owns the trailing half of:
- step-03 start: flip the story to in-progress and lift the parent
epic out of backlog if needed.
- step-05 end: flip the story to review. Code-review keeps ownership
of review -> done.
Resolution uses exact numeric-segment equality on the {epic}-{story}
prefix (never string-prefix match), so 1-1 no longer collides with
1-10. Both sync blocks are idempotent so step-04 loopbacks do not
clobber human edits or bump last_updated without cause. Skips silently
when sprint-status.yaml is missing or the intent is not an epic story.
* feat(quick-dev): add sprint-status sync to one-shot route
Epic stories do get implemented via one-shot in practice. Add the same
in-progress / review sync pair that step-03 and step-05 already have,
with identical idempotency guards and skip-on-missing behavior.
* refactor(quick-dev): extract sprint-status sync into shared file
Replace inline sync blocks in step-03, step-05, and step-oneshot with
one-line callouts to sync-sprint-status.md. The shared file owns all
edge-case handling (idempotency, epic lift, missing file/key) and is
parameterized by {target_status}. Any future route picks it up with a
single Follow line.
* fix(quick-dev): resolve story_key on early-exit resume paths
Extract story-key resolution into a shared subsection referenced by
all early-exit paths and INSTRUCTIONS, ensuring sprint-status sync
works for resumed epic stories.
* refactor(quick-dev): tighten story-key resolution prompt
Remove mechanical details the LLM can infer; keep only the
collision-prevention constraint.
* docs(cs): groom analysis-phase.md translation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(cs): fix AI term and ideation phrasing in analysis-phase.md
Replace "UI" with "AI" (DeepL mistranslation of the AI acronym as
user interface) and rephrase "techniky idealizace" to "techniky
generování nápadů" so the meaning matches the English source.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prevent review subagents from being downgraded to cheaper models.
Rare findings from the Acceptance Auditor tend to be high-severity,
and research shows smaller models have worse recall on rare-event
detection.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The PRFAQ link added in #2238 points to ../explanation/analysis-phase.md
which exists in en, vi-vn, and fr but was missing from the Czech
translation, breaking both CI doc checks.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Analyst (Mary) triggers were listed as BP, RS, CB, WB, DP but the
actual agent source defines BP, MR, DR, TR, CB, WB, DP. Update all
locale agents.md files. Also add PRFAQ Working Backwards hyperlink
to commands.md in en, cs, and vi-vn.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Batch-apply option (added in 9c3e2804) was instructed to "skip
any finding that requires judgment" — but step-03-triage already
guarantees patch findings are unambiguous (the decision-needed
bucket exists precisely to absorb ambiguous ones). The option had
no distinct work to do that option 1 did not already cover, and
its label suggested a meaningful difference that did not exist.
- Delete option 0 and the >3 findings conditional
- Rename "Fix them automatically" -> "Apply every patch", with
explicit scope (patches only; defer/decision-needed untouched)
- Rename "Walk through each" -> "Walk through each patch" for the
same scope clarity
- Unify <Z> placeholder with the existing <P> patch count
- Strip stale (or "0" for batch) notes from HALT lines
* feat(installer): add plugin resolution strategies for custom URL installs
When installing from a custom GitHub URL, the installer now analyzes
marketplace.json plugin structures to determine how to locate module
registration files (module.yaml, module-help.csv). Five strategies
are tried in cascade:
1. Root module files at the common parent of listed skills
2. A -setup skill with registration files in its assets/
3. Single standalone skill with registration files in assets/
4. Multiple standalone skills, each with their own registration files
5. Fallback: synthesize registration from marketplace.json metadata
and SKILL.md frontmatter
Also changes the custom URL flow from confirm-all to multiselect,
letting users pick which plugins to install. Already-installed modules
are pre-checked for update; new modules are unchecked for opt-in.
New file: tools/installer/modules/plugin-resolver.js
Modified: custom-module-manager.js, official-modules.js, ui.js
* fix(installer): address PR review findings for plugin resolver
- Guard against path traversal in plugin-resolver.js: skill paths from
unverified marketplace.json are now constrained to the repo root using
path.resolve() + startsWith check
- Skip npm install during browsing phase: cloneRepo() accepts
skipInstall option, used in ui.js before user confirms selection,
preventing arbitrary lifecycle script execution from untrusted repos
- Add createModuleDirectories() call to installFromResolution() so
modules with declarative directory config are fully set up
- Fix ESLint: use replaceAll instead of replace with global regex
* fix(installer): pass version and repoUrl to manifest for custom plugins
installFromResolution was passing empty strings for version and repoUrl,
which the manifest stores as null. Now threads the repo URL from ui.js
through resolvePlugin into each ResolvedModule, and passes the plugin
version and URL to the manifest correctly.
* fix(installer): manifest-generator overwrites custom module version/repoUrl
ManifestGenerator rebuilds the entire manifest via getModuleVersionInfo
for every module. For custom modules, this returned null for version and
repoUrl because it only checked _readMarketplaceVersion (which searches
for marketplace.json on disk) and hardcoded repoUrl to null. Now checks
the resolution cache first to get the correct version and repo URL.
* fix(installer): resolve custom modules from disk cache on quick update
When the resolution cache is empty (fresh CLI process, e.g. quick
update), findModuleSourceByCode only matched plugin.name against the
module code. This failed for modules like "sam" and "dw" where the
code comes from module.yaml inside a setup/standalone skill, not from
the plugin name in marketplace.json.
Now runs the PluginResolver on cached repos when the direct name match
fails, finding the correct module source and re-populating the cache
for the install pipeline.
* feat(installer): universal source support for custom modules
Replace GitHub-only custom module installation with support for any Git
host (GitHub, GitLab, Bitbucket, self-hosted) and local file paths.
- Add parseSource() universal input parser (local paths, SSH, HTTPS with
deep path/subdir extraction for GitHub, GitLab, Gitea)
- Add resolveSource() coordinator: parse -> clone if URL -> detect
discovery vs direct mode (marketplace.json present or not)
- Clone-first approach eliminates host-specific raw URL fetching
- 3-level cache structure (host/owner/repo) with .bmad-source.json
metadata for URL reconstruction
- Local paths install directly without caching; localPath persisted in
manifest for quick-update source lookup
- Direct mode scans target directory for SKILL.md when no marketplace.json
- Fix version display bug where walk-up found parent repo marketplace.json
and reported wrong version for custom modules
* fix(installer): harden readMarketplaceJsonFromDisk and hoist require
- Add try/catch to readMarketplaceJsonFromDisk so malformed JSON returns
null instead of throwing an unhandled parse error
- Hoist CustomModuleManager require outside the per-module loop in
_installOfficialModules
* fix(installer): restore validateGitHubUrl strictness and fix prettier
- Restore original GitHub-only regex in deprecated validateGitHubUrl
wrapper so existing tests pass (rejects non-GitHub URLs, trailing
slashes)
- Run prettier to fix formatting in custom-module-manager.js
* feat(installer): add --custom-source CLI flag for non-interactive installs
Allows installing custom modules from Git URLs or local paths directly
from the command line without interactive prompts:
npx bmad-method install --custom-source /path/to/module
npx bmad-method install --custom-source https://gitlab.com/org/repo
npx bmad-method install --custom-source /path/one,https://host/org/repo
Works alongside --modules and --yes flags. All discovered modules from
each source are auto-selected.
* docs: add custom and community module installation guide
New how-to page covering community module browsing, custom sources (any
Git host, local paths), discovery vs direct mode, local development
workflow, and the --custom-source CLI flag. Clarifies that
.claude-plugin/ is a cross-tool convention, not Claude-specific.
Also updates non-interactive installation docs with the new flag and
examples, bumps sidebar ordering, and fixes --custom-source to install
only core + custom modules when --modules is not specified.
* feat(quick-dev): add epic context compilation to step-01
Fork step-01 context loading: epic stories get a sub-agent that
compiles planning docs into a cached epic-{N}-context.md, while
freeform intents keep the lightweight directory-listing path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(quick-dev): tighten epic context loading per PR review
- Validate cached epic-<N>-context.md is non-empty and starts with the
expected header before loading; treat invalid cache as missing.
- Replace inline {N} placeholders with <N> so the skill validator does
not flag them as unresolved workflow variables.
- Replace ambiguous "fall back to path B" with an explicit instruction
to scan/load planning artifacts using path B's procedure, with a note
not to re-evaluate path B's gating clause.
Addresses CodeRabbit and Augment review comments on PR #2218.
* refactor(quick-dev): tighten compile-epic-context prompt
- Restructure with Task/Steps opening and Exact Output Format section.
- Switch Stories template to bullet form for clarity.
- Add "no hallucination" and explicit "omit empty sections except Goal
and Stories" rules.
- Use <N> instead of {N} in the filename for consistency with step-01.
* refactor(quick-dev): restructure epic-story context loading
Reshape path A of step-01 into five explicit numbered steps and add an
inline-compilation fallback for runtimes that cannot spawn sub-agents
(Copilot, Codex, local Ollama, older Claude).
- Pull cache validity, compilation, verification, and continuity into
separate numbered steps instead of nested paragraphs.
- Define "valid cached context" upfront: non-empty and starts with
`# Epic <N> Context:`.
- Add inline-compilation fallback: runtimes without sub-agent support
read compile-epic-context.md and follow it directly.
- Make previous-story continuity run regardless of which context source
succeeded (cache hit, fresh compilation, or path-B raw fallback).
* fix(quick-dev): address review findings on epic context compilation
- Add freshness check to cached epic-N-context.md (invalidate when any
planning artifact is newer)
- Remove the silent fall-back-to-raw-planning-docs path on compile
failure; HALT and report instead
- Add explicit "ambiguous → freeform" tiebreakers for both the path A
header and the epic-number identification step
- Drop "verbatim" from compile-epic-context.md format header to resolve
the verbatim-vs-omit-empty contradiction
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(bmad-help): add _meta rows and llms.txt support for general questions
Register llms.txt URLs in module-help.csv via _meta rows so bmad-help
can fetch module documentation when users ask questions that don't map
to a specific skill.
* refactor(bmad-help): streamline llms.txt docs into existing skill sections
* feat(quick-dev): improve checkpoint 1 UX with clickable link, external editing note, and change detection
Display spec file path as clickable CWD-relative link alongside the
summary. Inform users they can open the spec in another session with
any tool before approving. On approval, re-read the spec from disk
and acknowledge any external edits before proceeding.
* fix(quick-dev): tighten checkpoint 1 [A] flow wording
- Remove stray 'and options' from the editing-note intro so the note's
position relative to the [A]/[E] menu is unambiguous.
- Restructure the [A] bullet into explicit missing/exists branches so
the missing-file HALT cannot fall through to status updates and
recreate a deleted spec.
Addresses augmentcode review comments on PR #2217.
* docs(quick-dev): rewrite checkpoint 1 editing-note
- Drop boilerplate opener about the spec being a regular file.
- Enumerate concrete options: editor, in-session Q&A, or bmad-advanced-elicitation / bmad-party-mode / bmad-code-review skills.
- Flag that skills should ideally run in another session to avoid context bloat.
- Change "add this note" to "display this note" for precision.
* feat(installer): add community module browser and custom URL support
Three-tier module selection: official, community (category drill-down
with featured/search), and custom GitHub URL.
- Add RegistryClient shared fetch utility
- Add CommunityModuleManager with SHA-pinned cloning (refuses install
if approved SHA cannot be reached; uses HEAD when no SHA set)
- Add CustomModuleManager for arbitrary GitHub repo installation
- Extend findModuleSource chain with community and custom fallthrough
- Extend manifest to detect community and custom source types
- Add Config.customModulesMeta for custom module metadata
* fix: resolve review findings for community/custom module support
- Remove redundant CommunityModuleManager instantiation in UI display
- Remove dead customModulesMeta field from Config (never populated)
- Add 35 unit tests for CustomModuleManager and CommunityModuleManager
pure functions: URL validation, normalization, search, featured, categories
* fix: preserve installed community/custom modules in modify flow
When a user does "Modify Installation" and declines to browse community
modules, previously installed community/custom modules are now auto-kept.
If the user does browse, their selections are trusted (they can deselect).
Also fix stale docs: class doc for SHA pinning, JSDoc return type.
* fix: include community and custom modules in quick update
Quick update now checks community registry and custom cache so installed
community/custom modules are updated instead of skipped.
* fix: use defaults for new config fields during quick update
When quick update encounters new config fields (e.g., from a newly
supported community module), use schema defaults silently instead of
prompting the user. Quick update should be non-interactive.
* test: add unit tests for SHA pinning, category filtering, and URL edge cases
Cover SHA normalization (set vs null/trusted), listByCategory,
getModuleByCode, and URL validation edge cases (HTTP, trailing slash,
SSH without .git). Total: 243 tests.
* refactor(installer): remove custom content installation feature
Remove the entire local filesystem custom content feature from the
installer to make way for marketplace-based plugin installation.
Deleted: custom-handler.js, custom-module-cache.js, custom-modules.js
Removed: --custom-content CLI flag, interactive custom content prompts,
custom module caching, manifest tracking, missing-source resolution,
and related test suites. Updated docs across all translations.
* fix: address review findings from Augment
Fix admonition syntax (remove accidental space in :::note) across 4
translated docs files, and update stale JSDoc on listAvailable().
* feat(installer): fetch module list from marketplace registry
Switch module list source of truth from bundled
external-official-modules.yaml to the remote marketplace registry
(registry/official.yaml) fetched via raw.githubusercontent.com.
- Rewrite ExternalModuleManager to fetch from GitHub with local fallback
- Simplify selectAllModules/getDefaultModules to use registry as single source
- Registry order controls display order; built_in flag prevents cloning
- Rename fallback file to registry-fallback.yaml in modules/
- Only show legacy migration message when legacy dirs actually exist
* refactor(installer): remove custom content installation feature
Remove the entire local filesystem custom content feature from the
installer to make way for marketplace-based plugin installation.
Deleted: custom-handler.js, custom-module-cache.js, custom-modules.js
Removed: --custom-content CLI flag, interactive custom content prompts,
custom module caching, manifest tracking, missing-source resolution,
and related test suites. Updated docs across all translations.
* fix: address review findings from Augment
Fix admonition syntax (remove accidental space in :::note) across 4
translated docs files, and update stale JSDoc on listAvailable().
* refactor(quick-dev): eliminate spec-wip.md singleton
Write directly to spec-{slug}.md with status: draft instead of using
a shared spec-wip.md file. Use draft status for resume detection in
step-01. Removes wipFile variable from all step frontmatter and
workflow initialization.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(quick-dev): address PR review findings
- step-02: preserve Intent block on draft resume instead of regenerating from template (F1)
- step-01: resume existing draft on slug collision rather than creating -2 duplicate (F3)
- step-01: recognize `done` status and ingest as context instead of silently re-implementing (F4)
- step-oneshot: remove unused spec_file frontmatter declaration (F6)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore(install): stop copying skill prompts to _bmad by default
Flip install_to_bmad default from true to false so skill directories
are cleaned from _bmad/ after IDE install. Skills are self-contained
in their IDE directories (.claude/skills/, etc.) and no longer need
duplicate copies in _bmad/.
Two skills (bmad-create-prd, bmad-validate-prd) opt back in via
explicit manifests because bmad-edit-prd cross-references their data
files. Also fixes broken bmm-skills/ path references and corrects
the file-ref validator module-to-source mapping.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(install): make edit-prd self-contained and remove install_to_bmad
Give bmad-edit-prd its own copy of prd-purpose.md and replace the
cross-skill validation workflow reference with a skill invocation, so
all three PRD skills are fully self-contained. With no remaining
consumers, remove the install_to_bmad flag from manifests, CSV output,
the post-install cleanup loop, and the dedicated test file.
* feat(install): clean up skill directories from _bmad after IDE install
Skills are self-contained in IDE directories, so _bmad/ only needs
module-level files (config.yaml, _config/). After all IDE setups
complete, remove skill directories from _bmad/ via skill-manifest.csv.
Also cleans up skill dirs left by older installer versions.
* test(install): drop stale install_to_bmad column from suite 27 CSV row
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(installer): overhaul branding, versioning, and skill cleanup
Logo and branding:
- Responsive logo: full "BMAD METHOD" at >=95 cols, "BMAD" for narrower terminals
- Color scheme updated from yellow to blue (matching bmadcode.com brand)
- Added copyright notice and tagline in white for contrast
- Removed version number from logo (individual module versions shown in summary)
- Added ™ to both wide and narrow logo variants
Installer start message:
- Replaced outdated V6 launch announcement with clean welcome
- Consolidated redundant module/platform messaging into single intro
- Tightened open source manifesto (same spirit, fewer words)
- Merged speaking/media into support section with contact email
- Added full social links: Website, Discord, YouTube, X, Facebook
- Replaced docs.bmad-method.org and changelog links with bmadcode.com hub
Install summary improvements:
- Module names now show full display names from module.yaml (not abbreviations)
- All module versions sourced from .claude-plugin/marketplace.json exclusively
- Summary shows version transitions: "v6.2.2 -> v6.3.0", "v6.3.0, no change",
or "v6.3.0, installed" for fresh installs
- Switched summary from clack note() to box() for full-brightness text
- Removed dim/gray styling that was hard to read on dark terminals
- Links styled with color.blue instead of color.dim
- Get started section leads with actionable steps (launch agent, run bmad-help)
- Removed redundant social links (already shown in start message)
Version source unification:
- All module versions now come from .claude-plugin/marketplace.json only
- Removed package.json as version source for core/bmm modules
- Updated manifest.js getModuleVersionInfo() to use marketplace.json
- Updated installer.js _getMarketplaceVersion() helper
- Updated ui.js getMarketplaceVersion() for module selection display
- Quick Update menu no longer shows misleading version (was using package.json)
- Module selection list now shows versions next to each module name
Skill cleanup overhaul:
- Replaced blunt-force bmad-* prefix deletion with surgical removal system
- Added removals.txt support: optional per-project file listing skills to remove
- Created initial removals.txt with all skills removed since v6.2.0
- Install/update: captures previously installed skill IDs from skill-manifest.csv
before manifest regeneration, then removes those + removals.txt entries
- Uninstall: removes all installed skills via skill-manifest.csv + removals.txt
- Deselecting modules now correctly removes their skills from IDE directories
- User-created bmad-* skills in IDE directories are no longer destroyed
- Legacy directory cleanup retains prefix matching (those dirs are abandoned)
Bug fixes:
- Fixed duplicate "CORE module already up to date" during quick update
- Fixed version display showing package.json version instead of actual module version
- Updated test fixture for bmad-os-* preservation test to use skill-manifest.csv
* fix(installer): address Augment review findings
- Fix plugins[0] fragility: extract highest version across all plugins
in marketplace.json instead of assuming first entry (ui.js, installer.js,
manifest.js)
- Fix _readMarketplaceVersion ignoring moduleSourcePath: custom modules
can now source their own marketplace.json by walking up from source path
- Hard-exclude bmad-os-* utility skills in both surgical and legacy cleanup
modes, preventing accidental deletion if tracked in manifests
- Distinguish missing file vs parse error in skill-manifest.csv reading:
warn on corrupt CSV instead of silently skipping cleanup
* fix(installer): resolve module source before reading marketplace version
Move _readMarketplaceVersion call after source type resolution so custom
modules use their own source path instead of falling back to the external
module cache, which could match a different module with the same code.