writeGlobalUserCore now line-surgery upserts only the [core] keys it owns into the existing file content — no read-parse-merge-emit round-trip. Hand edits in shapes the minimal parseSimpleToml dropped (arrays, single-quoted strings, dotted/quoted keys, \uXXXX escapes, custom sections) survive byte-for-byte. Dead emitTomlSections helper removed. writeModuleTomls emits core's shipped defaults under top-level [core], not nested [modules.core] — matches where writeCentralConfig writes core deltas and where resolve_config.py consumers read core.* from. tomlString auto-infers TOML type from --set values: true/false → bool, integer pattern → int, decimal pattern → float, otherwise quoted string. Explicit-string escape hatch: --set k='"true"' writes "true" as a string. Previously every --set value was wrapped in quotes, so --set bmm.workers=4 wrote "4" and downstream numeric comparisons broke. upsertTomlKey's inline-comment detector now tracks double-quoted string state via findInlineCommentStart, so a # inside a basic-string value (legal per the TOML spec, contrary to the previous defending comment) is no longer truncated. tomlHasKey and upsertTomlKey both use a new isSectionHeader matcher that tolerates trailing inline comments on the header line and walks every section occurrence — fixes mis-routing on hand-edited files with [core] # comment headers or duplicate sections. Python test harnesses (test_resolve_config.py, test_resolve_customization_cascade.py) now force BMAD_HOME to the synthetic isolation path unconditionally instead of env.get(BMAD_HOME, default), which was a no-op when the developer had BMAD_HOME set in their shell. Adds 21 JS assertions covering the new behaviors directly: tomlString type inference, # inside string values, inline-comment headers, and writeGlobalUserCore round-trip preservation of hand-edited shapes. Tests: 405 JS + 21 Python pass. Lint, markdownlint, prettier green.
BMad CLI Tool
Installing external repo BMad official modules
For external official modules to be discoverable during install, ensure an entry for the external repo is added to external-official-modules.yaml.
For community modules - this will be handled in a different way. This file is only for registration of modules under the bmad-code-org.
Post-Install Notes
Modules can display setup guidance to users after configuration is collected during npx bmad-method install. Notes are defined in the module's own module.yaml — no changes to the installer are needed.
Simple Format
Always displayed after the module is configured:
post-install-notes: |
Thank you for choosing the XYZ Cool Module
For Support about this Module call 555-1212
Conditional Format
Display different messages based on a config question's answer:
post-install-notes:
config_key_name:
value1: |
Instructions for value1...
value2: |
Instructions for value2...
Values without an entry (e.g., none) display nothing. Multiple config keys can each have their own conditional notes.
Example: TEA Module
The TEA module uses the conditional format keyed on tea_browser_automation:
post-install-notes:
tea_browser_automation:
cli: |
Playwright CLI Setup:
npm install -g @playwright/cli@latest
playwright-cli install --skills
mcp: |
Playwright MCP Setup (two servers):
1. playwright — npx @playwright/mcp@latest
2. playwright-test — npx playwright run-test-mcp-server
auto: |
Playwright CLI Setup:
...
Playwright MCP Setup (two servers):
...
When a user selects auto, they see both CLI and MCP instructions. When they select none, nothing is shown.