fix(bmad-customize): address PR #2289 review findings
- SKILL.md preflight: load root config from _bmad/config.toml and config.user.toml (not .yaml) — the installer emits TOML; the YAML references would have made the skill silently miss real user config - SKILL.md resolver fallback (Step 6.4): read all three merge layers when present (base / team / user) and describe the merge in base → team → user order; the prior wording could describe the wrong effective merge when the user wrote .user.toml on top of an existing team .toml - SKILL.md: replace bare 'docs/how-to/customize-bmad.md' references (3 locations) with the public docs URL so users installing the skill aren't pointed at a path they don't have locally - list_customizable_skills.py: catch UnicodeDecodeError in read_frontmatter_description so a non-UTF-8 SKILL.md can't abort the whole scan - list_customizable_skills.py: clarify exit-code contract in the module docstring — errors[] is non-fatal by design, exit 2 is reserved for invocation errors - customize-bmad.md: tighten the tip to scope bmad-customize to the per-skill surface; central-config is out of scope v1 - expand-bmad-for-your-org.md: same scoping — Recipes 1-4 can be applied by the skill; Recipe 5 (central config) stays hand-authored
This commit is contained in:
parent
2d804fdad7
commit
da8d5d6b6d
|
|
@ -8,7 +8,7 @@ sidebar:
|
||||||
Tailor agent personas, inject domain context, add capabilities, and configure workflow behavior -- all without modifying installed files. Your customizations survive every update.
|
Tailor agent personas, inject domain context, add capabilities, and configure workflow behavior -- all without modifying installed files. Your customizations survive every update.
|
||||||
|
|
||||||
:::tip[Don't want to hand-author TOML? Use `bmad-customize`]
|
:::tip[Don't want to hand-author TOML? Use `bmad-customize`]
|
||||||
The `bmad-customize` skill is a guided authoring helper for the customization surface described in this doc. It scans what's customizable in your installation, helps you choose the right surface (agent vs workflow) for your intent, writes the override file for you, and verifies the merge landed. Run it whenever you want to make a change; this doc is the reference for *what* the surface exposes and how merging works.
|
The `bmad-customize` skill is a guided authoring helper for the **per-skill agent/workflow override surface** described in this doc. It scans what's customizable in your installation, helps you choose the right surface (agent vs workflow) for your intent, writes the override file for you, and verifies the merge landed. Central-config overrides (`_bmad/custom/config.toml`) are out of scope for v1 — hand-author those per the Central Configuration section below. Run the skill whenever you want to make a per-skill change; this doc is the reference for *what* each surface exposes and how merging works.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## When to Use This
|
## When to Use This
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ BMad's customization surface lets an organization reshape behavior without editi
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::tip[Applying these recipes]
|
:::tip[Applying these recipes]
|
||||||
Every recipe below can be applied by running the `bmad-customize` skill and describing the intent — it will pick the right surface, author the override file, and verify the merge. The recipes here are the source of truth for *what* to override; `bmad-customize` handles the *how*. Hand-authoring still works the same way if you prefer it or need a pattern the skill doesn't cover yet (currently: central-config overrides).
|
The **per-skill recipes** below (Recipes 1–4) can be applied by running the `bmad-customize` skill and describing the intent — it will pick the right surface, author the override file, and verify the merge. Recipe 5 (central-config overrides to the agent roster) is out of scope for v1 of the skill and remains hand-authored. The recipes here are the source of truth for *what* to override; `bmad-customize` handles the *how* for the agent/workflow surface.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## The Three-Layer Mental Model
|
## The Three-Layer Mental Model
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ Translate a user's intent ("I want X to behave differently") into a correctly-pl
|
||||||
|
|
||||||
**What customization means in BMad.** Every customizable skill ships a `customize.toml` that declares the knobs it exposes — scalars, arrays, and keyed tables under `[agent]` or `[workflow]`. Users never edit that file. Instead, they write sparse override files to `{project-root}/_bmad/custom/`, and the resolver merges base → team → user at activation. This skill's job is to help users author those override files correctly. Users typically arrive either with a specific skill and change in mind ("make bmad-create-prd require a brief first") or with a broader want ("the PM agent should speak more formally"); you handle both.
|
**What customization means in BMad.** Every customizable skill ships a `customize.toml` that declares the knobs it exposes — scalars, arrays, and keyed tables under `[agent]` or `[workflow]`. Users never edit that file. Instead, they write sparse override files to `{project-root}/_bmad/custom/`, and the resolver merges base → team → user at activation. This skill's job is to help users author those override files correctly. Users typically arrive either with a specific skill and change in mind ("make bmad-create-prd require a brief first") or with a broader want ("the PM agent should speak more formally"); you handle both.
|
||||||
|
|
||||||
Scope for this version: per-skill **agent** overrides (`bmad-agent-<role>.toml` / `.user.toml`) and per-skill **workflow** overrides (`bmad-<workflow>.toml` / `.user.toml`). Central config (`{project-root}/_bmad/custom/config.toml`) is out of scope — flag it and point the user at `docs/how-to/customize-bmad.md` if their ask lives there.
|
Scope for this version: per-skill **agent** overrides (`bmad-agent-<role>.toml` / `.user.toml`) and per-skill **workflow** overrides (`bmad-<workflow>.toml` / `.user.toml`). Central config (`{project-root}/_bmad/custom/config.toml`) is out of scope — flag it and point the user at the **How to Customize BMad** guide (https://docs.bmad-method.org/how-to/customize-bmad/) if their ask lives there.
|
||||||
|
|
||||||
## Desired Outcomes
|
## Desired Outcomes
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ Before any other work, verify the project environment supports this skill:
|
||||||
|
|
||||||
### Config and greet
|
### Config and greet
|
||||||
|
|
||||||
Load available config from `{project-root}/_bmad/config.yaml` and `{project-root}/_bmad/config.user.yaml` (root level). Defaults if missing: `user_name` (BMad), `communication_language` (English). Greet the user and acknowledge the topic.
|
Load available config from `{project-root}/_bmad/config.toml` and `{project-root}/_bmad/config.user.toml` (root level, installer-owned). Defaults if missing: `user_name` (BMad), `communication_language` (English). Greet the user and acknowledge the topic.
|
||||||
|
|
||||||
Treat the user's invoking message as initial intent. Skip discovery if they already named a target skill AND a specific change — go straight to Step 3.
|
Treat the user's invoking message as initial intent. Skip discovery if they already named a target skill AND a specific change — go straight to Step 3.
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ Default the choice based on the change's character (policy → team, personal
|
||||||
|
|
||||||
Display the merged output and point out the fields that changed so the user sees their override took effect.
|
Display the merged output and point out the fields that changed so the user sees their override took effect.
|
||||||
|
|
||||||
**If the resolver is missing or fails**, fall back: read the three files (`<install-path>/customize.toml`, the written override, and any sibling `.user.toml`) directly, describe how the merge resolves for the fields the user just changed, and tell them the normal verify path is unavailable in this environment.
|
**If the resolver is missing or fails**, fall back: read whichever of the three merge layers exist — `<install-path>/customize.toml` (base), `{project-root}/_bmad/custom/{skill-name}.toml` (team), and `{project-root}/_bmad/custom/{skill-name}.user.toml` (user). Apply base → team → user in order using the same merge rules as the resolver (scalars override, tables deep-merge, `code`/`id`-keyed arrays of tables merge by key, all other arrays append). Describe how the fields the user just changed resolve, and tell them the normal verify path is unavailable in this environment.
|
||||||
|
|
||||||
**If verification shows the override did not take effect** (field unchanged, resolver reports merge conflict, override file not picked up), do not declare success. Explain what the resolver showed, re-enter Step 4 with the verify output as new context — usually the fix is a field name, merge-mode mismatch (e.g. wrote a scalar where the base expects an array), or wrong placement scope.
|
**If verification shows the override did not take effect** (field unchanged, resolver reports merge conflict, override file not picked up), do not declare success. Explain what the resolver showed, re-enter Step 4 with the verify output as new context — usually the fix is a field name, merge-mode mismatch (e.g. wrote a scalar where the base expects an array), or wrong placement scope.
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ If any of these is missing, the skill is not done — either finish the remainin
|
||||||
|
|
||||||
Say so clearly:
|
Say so clearly:
|
||||||
|
|
||||||
- **Central config** (`{project-root}/_bmad/custom/config.toml` — agent roster, install answers) is not covered by this version. Point the user at `docs/how-to/customize-bmad.md`.
|
- **Central config** (`{project-root}/_bmad/custom/config.toml` — agent roster, install answers) is not covered by this version. Point the user at the **How to Customize BMad** guide (https://docs.bmad-method.org/how-to/customize-bmad/).
|
||||||
- **Changes to step logic, step ordering, or behavior not exposed in `customize.toml`** require a customization feature request or using bmad builder to create a custom skill. Offer to help with either path.
|
- **Changes to step logic, step ordering, or behavior not exposed in `customize.toml`** require a customization feature request or using bmad builder to create a custom skill. Offer to help with either path.
|
||||||
- **Skills without a `customize.toml`** are not customizable — fork is the only path.
|
- **Skills without a `customize.toml`** are not customizable — fork is the only path.
|
||||||
|
|
||||||
|
|
@ -172,4 +172,4 @@ Say so clearly:
|
||||||
|
|
||||||
- Override files are sparse. Everything omitted inherits from the layer below (base → team → user).
|
- Override files are sparse. Everything omitted inherits from the layer below (base → team → user).
|
||||||
- The scanner does not hardcode IDE paths. It scans whichever directory this skill itself was loaded from — that's the same place the user's other skills live in this session. For mixed project-local + user-global setups, use `--extra-root`.
|
- The scanner does not hardcode IDE paths. It scans whichever directory this skill itself was loaded from — that's the same place the user's other skills live in this session. For mixed project-local + user-global setups, use `--extra-root`.
|
||||||
- Full reference on the customization surface, merge rules, and central config lives in `docs/how-to/customize-bmad.md`.
|
- Full reference on the customization surface, merge rules, and central config lives in the **How to Customize BMad** guide: https://docs.bmad-method.org/how-to/customize-bmad/.
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,12 @@ running skill's own location is the source of truth for sibling discovery.
|
||||||
`--extra-root` is available for the rare case where skills live in multiple
|
`--extra-root` is available for the rare case where skills live in multiple
|
||||||
locations on the same machine.
|
locations on the same machine.
|
||||||
|
|
||||||
Output: JSON to stdout. Exit 0 on success (including empty result), 2 on error.
|
Output: JSON to stdout. Non-empty `errors[]` in the payload is non-fatal
|
||||||
|
by contract — the scanner surfaces malformed TOML, missing roots, and
|
||||||
|
skills with no customization block as data for the caller to display,
|
||||||
|
and still exits 0. Exit 2 is reserved for invocation errors (e.g.
|
||||||
|
missing or unreadable `--project-root`) where no useful payload can be
|
||||||
|
produced.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
@ -56,7 +61,7 @@ def read_frontmatter_description(skill_md: Path) -> str:
|
||||||
return ""
|
return ""
|
||||||
try:
|
try:
|
||||||
text = skill_md.read_text(encoding="utf-8")
|
text = skill_md.read_text(encoding="utf-8")
|
||||||
except OSError:
|
except (OSError, UnicodeDecodeError):
|
||||||
return ""
|
return ""
|
||||||
m = FRONTMATTER_RE.match(text)
|
m = FRONTMATTER_RE.match(text)
|
||||||
if not m:
|
if not m:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue