Compare commits

..

No commits in common. "6a56d2eb11b520be48bd67a6162c4678301cd2bc" and "2ae3ddfee408ecc92fa24af9553b758b2fa32253" have entirely different histories.

3 changed files with 9 additions and 20 deletions

View File

@ -1,11 +1,11 @@
---
title: 'How to Expand BMad for Your Organization'
description: Six customization patterns that reshape BMad without forking — agent-wide rules, workflow conventions, external publishing, template swaps, agent roster changes, and advanced integration patterns
description: Five customization patterns that reshape BMad without forking — agent-wide rules, workflow conventions, external publishing, template swaps, and agent roster changes
sidebar:
order: 9
---
BMad's customization surface lets an organization reshape behavior without editing installed files or forking skills. This guide walks through six recipes that cover most enterprise needs.
BMad's customization surface lets an organization reshape behavior without editing installed files or forking skills. This guide walks through five recipes that cover most enterprise needs.
:::note[Prerequisites]
@ -299,7 +299,7 @@ The agent adapts to whatever structure the template defines. Keep templates unde
## Combining Recipes
All six recipes compose. A realistic enterprise override for `bmad-product-brief` might set `persistent_facts` (Recipe 2), `on_complete` (Recipe 3), and `brief_template` (Recipe 4) in one file. The agent-level rule (Recipe 1) lives in a separate file under the agent's name, central config (Recipe 5) pins the shared roster and team settings, advanced integration patterns (Recipe 6) configure external sources and handoffs, and all layers apply in parallel.
All five recipes compose. A realistic enterprise override for `bmad-product-brief` might set `persistent_facts` (Recipe 2), `on_complete` (Recipe 3), and `brief_template` (Recipe 4) in one file. The agent-level rule (Recipe 1) lives in a separate file under the agent's name, central config (Recipe 5) pins the shared roster and team settings, and all four apply in parallel.
```toml
# _bmad/custom/bmad-product-brief.toml (workflow-level)

View File

@ -46,7 +46,7 @@ Define what to build and for whom.
| Workflow | Purpose | Produces |
|-------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------|
| `bmad-prd` | Create, update, or validate a PRD — facilitated discovery, three intents in one skill | Create/Update: `prd.md`, `addendum.md`, `decision-log.md`; Validate: `validation-report.html` + `.md` |
| `bmad-prd` | Create, update, or validate a PRD — facilitated discovery, three intents in one skill | `prd.md`, `addendum.md`, `decision-log.md` |
| `bmad-create-ux-design` | Design user experience (when UX matters) | `ux-spec.md` |
:::tip[Three intents in one skill]

View File

@ -46,7 +46,7 @@ def compute_stats(findings: list[dict]) -> dict:
failed_critical = 0
failed_high = 0
for f in findings:
status = (f.get("status") or "n/a").lower()
status = f.get("status", "n/a")
if status in by_status:
by_status[status] += 1
if status == "fail":
@ -219,19 +219,8 @@ def main(argv: list[str]) -> int:
template_path = Path(args.template)
output_path = Path(args.output)
try:
data = json.loads(findings_path.read_text(encoding="utf-8"))
except FileNotFoundError:
print(f"error: findings file not found: {findings_path}", file=sys.stderr)
return 1
except json.JSONDecodeError as e:
print(f"error: findings file is not valid JSON ({findings_path}): {e}", file=sys.stderr)
return 1
try:
template = template_path.read_text(encoding="utf-8")
except FileNotFoundError:
print(f"error: template file not found: {template_path}", file=sys.stderr)
return 1
data = json.loads(findings_path.read_text())
template = template_path.read_text()
findings = data.get("findings", []) or []
@ -268,10 +257,10 @@ def main(argv: list[str]) -> int:
}
rendered = string.Template(template).safe_substitute(substitutions)
output_path.write_text(rendered, encoding="utf-8")
output_path.write_text(rendered)
md_path = output_path.with_suffix(".md")
md_path.write_text(render_markdown_report(data, findings, stats, grade), encoding="utf-8")
md_path.write_text(render_markdown_report(data, findings, stats, grade))
print(json.dumps({
"output": str(output_path),