Skip to content

Commit bd1c005

Browse files
authored
feat(skills): YAML-based agent customization with Python resolver (#2282)
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.
1 parent d09363b commit bd1c005

28 files changed

Lines changed: 1041 additions & 379 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ z*/
5050

5151
_bmad
5252
_bmad-output
53+
54+
# Personal customization files (team files are committed, personal files are not)
55+
_bmad/custom/*.user.yaml
5356
.clinerules
5457
# .augment/ is gitignored except tracked config files — add exceptions explicitly
5558
.augment/*

docs/how-to/customize-bmad.md

Lines changed: 162 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,240 @@
11
---
22
title: 'How to Customize BMad'
3-
description: Customize agents, workflows, and modules while preserving update compatibility
3+
description: Customize agents and workflows while preserving update compatibility
44
sidebar:
55
order: 8
66
---
77

8-
Use the `.customize.yaml` files to tailor agent behavior, personas, and menus while preserving your changes across updates.
8+
Tailor agent personas, inject domain context, add capabilities, and configure workflow behavior -- all without modifying installed files. Your customizations survive every update.
99

1010
## When to Use This
1111

1212
- You want to change an agent's name, personality, or communication style
13-
- You need agents to remember project-specific context
14-
- You want to add custom menu items that trigger your own workflows or prompts
15-
- You want agents to perform specific actions every time they start up
13+
- You need to give an agent persistent facts to recall (e.g. "our org is AWS-only")
14+
- You want to add procedural startup steps the agent must run every session
15+
- You want to add custom menu items that trigger your own skills or prompts
16+
- Your team needs shared customizations committed to git, with personal preferences layered on top
1617

1718
:::note[Prerequisites]
1819

1920
- BMad installed in your project (see [How to Install BMad](./install-bmad.md))
2021
- A text editor for YAML files
21-
:::
22-
23-
:::caution[Keep Your Customizations Safe]
24-
Always use the `.customize.yaml` files described here rather than editing agent files directly. The installer overwrites agent files during updates, but preserves your `.customize.yaml` changes.
2522
:::
2623

24+
## How It Works
25+
26+
Every agent skill ships a `customize.yaml` file with its defaults. This file defines the skill's complete customization surface -- read it to see what's customizable. You never edit this file. Instead, you create sparse override files containing only the fields you want to change.
27+
28+
### Three-Layer Override Model
29+
30+
```text
31+
Priority 1 (wins): _bmad/custom/{skill-name}.user.yaml (personal, gitignored)
32+
Priority 2: _bmad/custom/{skill-name}.yaml (team/org, committed)
33+
Priority 3 (last): skill's own customize.yaml (defaults)
34+
```
35+
36+
The `_bmad/custom/` folder starts empty. Files only appear when someone actively customizes.
37+
38+
### Merge Rules (per field)
39+
40+
| Field | Rule |
41+
|---|---|
42+
| `agent.metadata` | shallow merge -- scalar fields override |
43+
| `agent.persona` | full replace -- if present in override, it replaces wholesale |
44+
| `agent.critical_actions` | append -- override items are added after defaults |
45+
| `agent.memories` | append |
46+
| `agent.menu` | merge by `code` -- matching codes replace, new codes append |
47+
| other tables | deep merge |
48+
| other arrays | atomic replace |
49+
| scalars | override wins |
50+
2751
## Steps
2852

29-
### 1. Locate Customization Files
53+
### 1. Find the Skill's Customization Surface
3054

31-
After installation, find one `.customize.yaml` file per agent in:
55+
Look at the skill's `customize.yaml` in its installed directory. For example, the PM agent:
3256

3357
```text
34-
_bmad/_config/agents/
35-
├── core-bmad-master.customize.yaml
36-
├── bmm-dev.customize.yaml
37-
├── bmm-pm.customize.yaml
38-
└── ... (one file per installed agent)
58+
.claude/skills/bmad-agent-pm/customize.yaml
3959
```
4060

41-
### 2. Edit the Customization File
61+
(Path varies by IDE -- Cursor uses `.cursor/skills/`, Cline uses `.cline/skills/`, and so on.)
4262

43-
Open the `.customize.yaml` file for the agent you want to modify. Every section is optional -- customize only what you need.
63+
This file is the canonical schema. Every field you see is customizable.
4464

45-
| Section | Behavior | Purpose |
46-
| ------------------ | -------- | ----------------------------------------------- |
47-
| `agent.metadata` | Replaces | Override the agent's display name |
48-
| `persona` | Replaces | Set role, identity, style, and principles |
49-
| `memories` | Appends | Add persistent context the agent always recalls |
50-
| `menu` | Appends | Add custom menu items for workflows or prompts |
51-
| `critical_actions` | Appends | Define startup instructions for the agent |
52-
| `prompts` | Appends | Create reusable prompts for menu actions |
65+
### 2. Create Your Override File
5366

54-
Sections marked **Replaces** overwrite the agent's defaults entirely. Sections marked **Appends** add to the existing configuration.
67+
Create the `_bmad/custom/` directory in your project root if it doesn't exist. Then create a file named after the skill:
5568

56-
**Agent Name**
69+
```text
70+
_bmad/custom/
71+
bmad-agent-pm.yaml # team overrides (committed to git)
72+
bmad-agent-pm.user.yaml # personal preferences (gitignored)
73+
```
74+
75+
Only include the fields you want to change. Unmentioned fields inherit from the layer below.
76+
77+
### 3. Customize What You Need
78+
79+
#### Agent Persona
5780

58-
Change how the agent introduces itself:
81+
Change any combination of title, icon, role, identity, communication style, and principles. Anything under `agent.metadata` merges field-by-field; anything under `agent.persona` replaces the persona wholesale if you include it.
82+
83+
:::note[Agent names are fixed]
84+
The built-in BMad agents (Mary, John, Winston, Sally, Amelia, Paige) have hardcoded names. This is a deliberate design choice so every skill can be reliably invoked by role *or* default name — "hey Mary" always activates the analyst, no matter how the team has customized her behavior. If you genuinely need a differently-named agent, copy the skill folder, rename it, and ship it as a custom skill (a few-minute task).
85+
:::
86+
87+
Team override (shallow merge on metadata):
5988

6089
```yaml
90+
# _bmad/custom/bmad-agent-pm.yaml
91+
6192
agent:
6293
metadata:
63-
name: 'Spongebob' # Default: "Amelia"
94+
title: Senior Product Lead
95+
icon: "🏥"
6496
```
6597
66-
**Persona**
67-
68-
Replace the agent's personality, role, and communication style:
98+
Team override (full persona replacement):
6999
70100
```yaml
71-
persona:
72-
role: 'Senior Full-Stack Engineer'
73-
identity: 'Lives in a pineapple (under the sea)'
74-
communication_style: 'Spongebob annoying'
75-
principles:
76-
- 'Never Nester, Spongebob Devs hate nesting more than 2 levels deep'
77-
- 'Favor composition over inheritance'
101+
agent:
102+
persona:
103+
role: "Senior Product Lead specializing in healthcare technology"
104+
identity: |
105+
15-year product leader in healthcare technology and digital health
106+
platforms. Deep expertise in EHR integrations and navigating
107+
FDA/HIPAA regulatory landscapes.
108+
communication_style: |
109+
Precise, regulatory-aware, asks compliance-shaped questions early.
110+
principles: |
111+
- Ship nothing that can't pass an FDA audit.
112+
- User value first, compliance always.
78113
```
79114
80-
The `persona` section replaces the entire default persona, so include all four fields if you set it.
115+
Because `agent.persona` is replace-wholesale, include every persona field you want the agent to have -- anything omitted will be blank.
81116

82-
**Memories**
117+
#### Memories
83118

84-
Add persistent context the agent will always remember:
119+
Persistent facts the agent always recalls during the session:
85120

86121
```yaml
87-
memories:
88-
- 'Works at Krusty Krab'
89-
- 'Favorite Celebrity: David Hasselhoff'
90-
- 'Learned in Epic 1 that it is not cool to just pretend that tests have passed'
122+
agent:
123+
memories:
124+
- "Our org is AWS-only -- do not propose GCP or Azure."
125+
- "All PRDs require legal sign-off before engineering kickoff."
126+
- "Target users are clinicians, not patients -- frame examples accordingly."
91127
```
92128

93-
**Menu Items**
129+
Memories append: your items are added after defaults.
130+
131+
#### Critical Actions
94132

95-
Add custom entries to the agent's display menu. Each item needs a `trigger`, a target (`workflow` path or `action` reference), and a `description`:
133+
Procedural startup steps the agent must execute before presenting its menu:
96134

97135
```yaml
98-
menu:
99-
- trigger: my-workflow
100-
workflow: 'my-custom/workflows/my-workflow.yaml'
101-
description: My custom workflow
102-
- trigger: deploy
103-
action: '#deploy-prompt'
104-
description: Deploy to production
136+
agent:
137+
critical_actions:
138+
- "Scan {project-root}/docs/compliance/ and load any HIPAA-related documents as context."
139+
- "Read {project-root}/_bmad/custom/company-glossary.md if it exists."
105140
```
106141

107-
**Critical Actions**
142+
Critical actions append too. They run top-to-bottom on every activation.
143+
144+
#### Menu Customization
108145

109-
Define instructions that run when the agent starts up:
146+
Add new capabilities or replace existing ones using `code` as the merge key. Each menu item has exactly one of `skill` (invokes a registered skill) or `prompt` (executes the text directly).
110147

111148
```yaml
112-
critical_actions:
113-
- 'Check the CI Pipelines with the XYZ Skill and alert user on wake if anything is urgently needing attention'
149+
agent:
150+
menu:
151+
# Replace the existing CE item with a custom skill
152+
- code: CE
153+
description: "Create Epics using our delivery framework"
154+
skill: custom-create-epics
155+
156+
# Add a new item (code RC doesn't exist in defaults)
157+
- code: RC
158+
description: "Run compliance pre-check"
159+
prompt: |
160+
Read {project-root}/_bmad/custom/compliance-checklist.md
161+
and scan all documents in {planning_artifacts} against it.
162+
Report any gaps and cite the relevant regulatory section.
114163
```
115164

116-
**Custom Prompts**
165+
Items not listed in your override keep their defaults.
166+
167+
#### Referencing Files
168+
169+
When a field's text needs to point at a file (in `memories`, `critical_actions`, or a menu item's `prompt`), use a full path rooted at `{project-root}`. Even if the file sits next to your override in `_bmad/custom/`, spell out the full path: `{project-root}/_bmad/custom/info.md`. The agent resolves `{project-root}` at runtime.
170+
171+
### 4. Personal vs Team
172+
173+
**Team file** (`bmad-agent-pm.yaml`): Committed to git. Shared across the org. Use for compliance rules, company persona, custom capabilities.
117174

118-
Create reusable prompts that menu items can reference with `action="#id"`:
175+
**Personal file** (`bmad-agent-pm.user.yaml`): Gitignored automatically. Use for tone adjustments, personal workflow preferences, and private memories.
119176

120177
```yaml
121-
prompts:
122-
- id: deploy-prompt
123-
content: |
124-
Deploy the current branch to production:
125-
1. Run all tests
126-
2. Build the project
127-
3. Execute deployment script
178+
# _bmad/custom/bmad-agent-pm.user.yaml
179+
180+
agent:
181+
memories:
182+
- "Always include a rough complexity estimate (low/medium/high) when presenting options."
128183
```
129184

130-
### 3. Apply Your Changes
185+
## How Resolution Works
131186

132-
After editing, reinstall to apply changes:
187+
On activation, the agent's SKILL.md runs a shared Python script that does the three-layer merge and returns the resolved `agent` block as JSON. The script uses [PEP 723 inline script metadata](https://peps.python.org/pep-0723/) to declare its dependency on PyYAML, and is designed to be invoked via [`uv`](https://docs.astral.sh/uv/):
133188

134189
```bash
135-
npx bmad-method install
190+
uv run {project-root}/_bmad/scripts/resolve_customization.py \
191+
--skill {skill-root} \
192+
--key agent
136193
```
137194

138-
The installer detects the existing installation and offers these options:
195+
`uv run` reads the inline metadata, creates a cached isolated environment with PyYAML installed, and runs the script. First run takes a few seconds while the env is built; subsequent runs reuse the cache and are instant.
139196

140-
| Option | What It Does |
141-
| ---------------------------- | -------------------------------------------------------------------- |
142-
| **Quick Update** | Updates all modules to the latest version and applies customizations |
143-
| **Modify BMad Installation** | Full installation flow for adding or removing modules |
197+
**Requirements**: Python 3.10+ and `uv` (install via `brew install uv`, `pip install uv`, or [the official installer](https://docs.astral.sh/uv/getting-started/installation/)). If `uv` isn't available, the script can be run with plain `python3` provided PyYAML is already installed (`pip install PyYAML`).
144198

145-
For customization-only changes, **Quick Update** is the fastest option.
199+
`--skill` points at the skill's installed directory (where `customize.yaml` lives). The skill name is derived from the directory's basename, and the script looks up `_bmad/custom/{skill-name}.yaml` and `{skill-name}.user.yaml` automatically.
146200

147-
## Troubleshooting
201+
Useful invocations:
148202

149-
**Changes not appearing?**
203+
```bash
204+
# Resolve the full agent block
205+
uv run {project-root}/_bmad/scripts/resolve_customization.py \
206+
--skill /abs/path/to/bmad-agent-pm \
207+
--key agent
208+
209+
# Resolve a single field
210+
uv run {project-root}/_bmad/scripts/resolve_customization.py \
211+
--skill /abs/path/to/bmad-agent-pm \
212+
--key agent.metadata.title
213+
214+
# Full dump (everything under agent plus any other top-level keys)
215+
uv run {project-root}/_bmad/scripts/resolve_customization.py \
216+
--skill /abs/path/to/bmad-agent-pm
217+
```
150218

151-
- Run `npx bmad-method install` and select **Quick Update** to apply changes
152-
- Check that your YAML syntax is valid (indentation matters)
153-
- Verify you edited the correct `.customize.yaml` file for the agent
219+
Output is always JSON. If the script is unavailable on a given platform, the SKILL.md tells the agent to read the three YAML files directly and apply the same merge rules.
154220

155-
**Agent not loading?**
221+
## Workflow Customization
222+
223+
Some workflows expose their own customization surface (output paths, review settings, section toggles, etc.) via the same `customize.yaml` + override mechanism. The merge rules above apply to any top-level key, not just `agent` -- so a workflow might use `workflow`, `config`, or other keys to organize its fields. Check the workflow's `customize.yaml` for its specific shape.
156224

157-
- Check for YAML syntax errors using an online YAML validator
158-
- Ensure you did not leave fields empty after uncommenting them
159-
- Try reverting to the original template and rebuilding
225+
## Troubleshooting
160226

161-
**Need to reset an agent?**
227+
**Customization not appearing?**
162228

163-
- Clear or delete the agent's `.customize.yaml` file
164-
- Run `npx bmad-method install` and select **Quick Update** to restore defaults
229+
- Verify your file is in `_bmad/custom/` with the correct skill name
230+
- Check YAML indentation (spaces only, no tabs) and make sure block scalars (`|`) are correctly indented
231+
- For agents, customization lives under `agent:` -- keys written below it belong to that key until another top-level key begins
232+
- Remember `agent.persona` is replace-wholesale: include every persona field you want, not just the ones you're changing
165233

166-
## Workflow Customization
234+
**Need to see what's customizable?**
167235

168-
Customization of existing BMad Method workflows and skills is coming soon.
236+
- Read the skill's `customize.yaml` -- every field there is customizable
169237

170-
## Module Customization
238+
**Need to reset?**
171239

172-
Guidance on building expansion modules and customizing existing modules is coming soon.
240+
- Delete your override file from `_bmad/custom/` -- the skill falls back to its built-in defaults

eslint.config.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ export default [
8484
},
8585
},
8686

87-
// CLI scripts under tools/** and test/**
87+
// CLI scripts under tools/**, test/**, and src/scripts/**
8888
{
89-
files: ['tools/**/*.js', 'tools/**/*.mjs', 'test/**/*.js', 'test/**/*.mjs'],
89+
files: ['tools/**/*.js', 'tools/**/*.mjs', 'test/**/*.js', 'test/**/*.mjs', 'src/scripts/**/*.js', 'src/scripts/**/*.mjs'],
9090
rules: {
9191
// Allow CommonJS patterns for Node CLI scripts
9292
'unicorn/prefer-module': 'off',

0 commit comments

Comments
 (0)