bmad-method 6.10.1-next.53 → 6.10.1-next.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/package.json +1 -1
  2. package/src/bmm-skills/agents/bmad-agent-analyst/SKILL.md +1 -1
  3. package/src/bmm-skills/agents/bmad-agent-architect/SKILL.md +1 -1
  4. package/src/bmm-skills/agents/bmad-agent-dev/SKILL.md +1 -1
  5. package/src/bmm-skills/agents/bmad-agent-pm/SKILL.md +1 -1
  6. package/src/bmm-skills/agents/bmad-agent-ux-designer/SKILL.md +1 -1
  7. package/src/bmm-skills/plan/bmad-create-epics-and-stories/SKILL.md +1 -1
  8. package/src/bmm-skills/plan/bmad-create-epics-and-stories/steps/step-04-final-validation.md +1 -1
  9. package/src/bmm-skills/plan/bmad-prd/references/validate.md +3 -3
  10. package/src/bmm-skills/plan/bmad-prfaq/SKILL.md +1 -1
  11. package/src/bmm-skills/plan/bmad-prfaq/references/verdict.md +1 -1
  12. package/src/bmm-skills/plan/bmad-project-context/SKILL.md +1 -1
  13. package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
  14. package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
  15. package/src/bmm-skills/plan/bmad-ux/assets/color-themes.md +1 -1
  16. package/src/bmm-skills/plan/bmad-ux/references/creative-tools.md +1 -1
  17. package/src/bmm-skills/plan/bmad-ux/references/validate.md +1 -1
  18. package/src/bmm-skills/ship/bmad-checkpoint-preview/SKILL.md +1 -1
  19. package/src/bmm-skills/ship/bmad-checkpoint-preview/step-05-wrapup.md +1 -1
  20. package/src/bmm-skills/ship/bmad-code-review/SKILL.md +1 -1
  21. package/src/bmm-skills/ship/bmad-code-review/steps/step-04-present.md +1 -1
  22. package/src/bmm-skills/ship/bmad-correct-course/SKILL.md +2 -2
  23. package/src/bmm-skills/ship/bmad-qa-generate-e2e-tests/SKILL.md +2 -2
  24. package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
  25. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
  26. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
  27. package/src/bmm-skills/v6-shims/bmad-create-architecture/SKILL.md +1 -1
  28. package/src/bmm-skills/v6-shims/bmad-create-prd/SKILL.md +1 -1
  29. package/src/bmm-skills/v6-shims/bmad-create-story/SKILL.md +2 -2
  30. package/src/bmm-skills/v6-shims/bmad-dev-story/SKILL.md +2 -2
  31. package/src/bmm-skills/v6-shims/bmad-edit-prd/SKILL.md +1 -1
  32. package/src/bmm-skills/v6-shims/bmad-validate-prd/SKILL.md +1 -1
  33. package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
  34. package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
  35. package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
  36. package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
  37. package/tools/installer/core/installer.js +17 -3
  38. package/tools/installer/core/uv-check.js +122 -24
  39. package/tools/installer/install-messages.yaml +3 -2
  40. package/tools/installer/ui.js +9 -7
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "bmad-method",
4
- "version": "6.10.1-next.53",
4
+ "version": "6.10.1-next.55",
5
5
  "description": "Breakthrough Method of Agile AI-driven Development",
6
6
  "keywords": [
7
7
  "agile",
@@ -20,7 +20,7 @@ You are Mary, the Business Analyst. You bring deep expertise in market research,
20
20
 
21
21
  ### Step 1: Resolve the Agent Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
24
24
 
25
25
  **If the script fails**, resolve the `agent` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -20,7 +20,7 @@ You are Winston, the System Architect. You turn product requirements and UX into
20
20
 
21
21
  ### Step 1: Resolve the Agent Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
24
24
 
25
25
  **If the script fails**, resolve the `agent` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -20,7 +20,7 @@ You are Amelia, the Senior Software Engineer. You execute approved stories with
20
20
 
21
21
  ### Step 1: Resolve the Agent Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
24
24
 
25
25
  **If the script fails**, resolve the `agent` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -20,7 +20,7 @@ You are John, the Product Manager. You drive PRD creation through user interview
20
20
 
21
21
  ### Step 1: Resolve the Agent Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
24
24
 
25
25
  **If the script fails**, resolve the `agent` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -20,7 +20,7 @@ You are Sally, the UX Designer. You translate user needs into interaction design
20
20
 
21
21
  ### Step 1: Resolve the Agent Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
24
24
 
25
25
  **If the script fails**, resolve the `agent` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -51,7 +51,7 @@ This uses **step-file architecture** for disciplined execution:
51
51
 
52
52
  ### Step 1: Resolve the Workflow Block
53
53
 
54
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
54
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
55
55
 
56
56
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
57
57
 
@@ -138,6 +138,6 @@ Upon Completion of task output: offer to answer any questions about the Epics an
138
138
 
139
139
  ## On Complete
140
140
 
141
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
141
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
142
142
 
143
143
  If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -41,11 +41,11 @@ Once every selected reviewer has returned, the parent synthesizes one consolidat
41
41
  - **Footer.** Rubric path, ISO timestamp.
42
42
  3. Write the filled HTML to `{doc_workspace}/validation-report.html`.
43
43
  4. Write the markdown twin to `{doc_workspace}/validation-report.md` (same content, grouped by severity rather than by dimension — see format below; this is the canonical form for downstream re-reading).
44
- 5. Open the HTML in the default browser:
44
+ 5. Open the HTML in the default browser with the platform opener — `open` on macOS, `xdg-open` on Linux, `start ""` on Windows — double-quoting the path:
45
45
  ```bash
46
- python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('{doc_workspace}/validation-report.html').resolve().as_uri())"
46
+ open "{doc_workspace}/validation-report.html"
47
47
  ```
48
- Skip the open step in headless mode (see `references/headless.md`).
48
+ If the command fails, don't retry with another opener: tell the user the file path and move on. Skip the open step in headless mode (see `references/headless.md`).
49
49
 
50
50
  ### Markdown twin format
51
51
 
@@ -30,7 +30,7 @@ The PRFAQ forces customer-first clarity: write the press release announcing the
30
30
 
31
31
  ### Step 1: Resolve the Workflow Block
32
32
 
33
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
33
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
34
34
 
35
35
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
36
36
 
@@ -78,6 +78,6 @@ purpose: "Token-efficient context for downstream PRD creation"
78
78
 
79
79
  This is the terminal stage. If the user wants to revise, loop back to the relevant stage. Otherwise, the workflow is done.
80
80
 
81
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
81
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
82
82
 
83
83
  If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: bmad-project-context
3
- description: 'Set up or refresh agent instructions so AI agents work well in it. Use when the user says "project context", "set up AGENTS.md", "document this project", "refresh context", "audit context", wants to apply coding standards or governance to a repo, or wants to record a mistake agents keep making'
3
+ description: 'Set up, refresh, or audit a repository''s agent instructions (the AGENTS.md block) so AI agents work well in that repo. Also records observed agent mistakes as pitfall lines. Must be invoked by name.'
4
4
  ---
5
5
 
6
6
  # Overview
@@ -6,4 +6,4 @@ Each variation: header (name + one-line emotional register), token chips for eve
6
6
 
7
7
  Inline CSS only, system font stack, no JS, no network. Document concrete hex values in `<style>` comments per variation so the user can lift them if they pick that theme. The spine itself stays semantic.
8
8
 
9
- Return to the parent: file path, one-line per variation, mode coverage. Do not dump HTML into the parent context. If interactive, open the file with `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`.
9
+ Return to the parent: file path, one-line per variation, mode coverage. Do not dump HTML into the parent context. If interactive, open the file with the platform opener — `open "PATH"` on macOS, `xdg-open` on Linux, `start ""` on Windows, path always double-quoted. On failure, give the user the path instead.
@@ -16,4 +16,4 @@ Every renderer writes to `{doc_workspace}/.working/` with a descriptive filename
16
16
 
17
17
  The parent passes the subagent: current `.memlog.md`, relevant prior `.working/` captures, the user's stated intent for this pass, the output path. The subagent writes its artifact under `.working/` and returns ONLY a compact summary (file path, one line per variant, mode coverage). Parent never holds the full payload.
18
18
 
19
- For HTML, open in browser when interactive: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`. Skip in headless.
19
+ For HTML, open in the browser when interactive with the platform opener — `open "PATH"` on macOS, `xdg-open` on Linux, `start ""` on Windows, path always double-quoted. On failure, give the user the path instead. Skip in headless.
@@ -69,7 +69,7 @@ Under Validate intent, after every reviewer returns, render one consolidated rep
69
69
  2. Fill `{workflow.validation_report_template}`. No overall grade — the per-category verdicts and severity counts already say what's true. Synthesis paragraph lifts the rubric's overall verdict; add a second if extra reviewers shift the picture. One section per rubric category (open if thin / broken), one per extra reviewer (closed, adversarial voice preserved).
70
70
  3. Write `{doc_workspace}/validation-report.html`.
71
71
  4. Write the Markdown twin `{doc_workspace}/validation-report.md` — same content grouped by severity.
72
- 5. Open HTML: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('{doc_workspace}/validation-report.html').resolve().as_uri())"`. Skip headless.
72
+ 5. Open HTML with the platform opener `open "{doc_workspace}/validation-report.html"` on macOS, `xdg-open` on Linux, `start ""` on Windows, path always double-quoted. On failure, give the user the path instead. Skip headless.
73
73
 
74
74
  Re-running overwrites the consolidated report; individual `review-*.md` files persist.
75
75
 
@@ -20,7 +20,7 @@ description: 'LLM-assisted human-in-the-loop review. Make sense of a change, foc
20
20
 
21
21
  ### Step 1: Resolve the Workflow Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
24
24
 
25
25
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -25,6 +25,6 @@ HALT — do not proceed until the user makes their choice.
25
25
 
26
26
  ## On Complete
27
27
 
28
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
28
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
29
29
 
30
30
  If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -21,7 +21,7 @@ If you need an explicit user instruction to run them, ask once now for the whole
21
21
 
22
22
  ### Step 1: Resolve the Workflow Block
23
23
 
24
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
24
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
25
25
 
26
26
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
27
27
 
@@ -127,6 +127,6 @@ Present the user with follow-up options:
127
127
 
128
128
  ## On Complete
129
129
 
130
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
130
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
131
131
 
132
132
  If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -20,7 +20,7 @@ description: 'Manage significant changes during sprint execution. Use when the u
20
20
 
21
21
  ### Step 1: Resolve the Workflow Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
24
24
 
25
25
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -294,7 +294,7 @@ Activation is complete. If `activation_steps_prepend` or `activation_steps_appen
294
294
 
295
295
  <action>Report workflow completion to user with personalized message: "Correct Course workflow complete, {user_name}!"</action>
296
296
  <action>Remind user of success criteria and next steps for Developer agent</action>
297
- <action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
297
+ <action>Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
298
298
  </step>
299
299
 
300
300
  </workflow>
@@ -20,7 +20,7 @@ description: 'Generate end to end automated tests for existing features. Use whe
20
20
 
21
21
  ### Step 1: Resolve the Workflow Block
22
22
 
23
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
23
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
24
24
 
25
25
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
26
26
 
@@ -171,6 +171,6 @@ Save summary to: `{default_output_file}`
171
171
 
172
172
  ## On Complete
173
173
 
174
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
174
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
175
175
 
176
176
  If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -9,7 +9,7 @@ This skill was consolidated into `bmad-architecture`. It is retained as a thin c
9
9
 
10
10
  ## On Activation
11
11
 
12
- 1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-create-architecture.toml` and `bmad-create-architecture.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
12
+ 1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-create-architecture.toml` and `bmad-create-architecture.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
13
13
 
14
14
  2. Load `{project-root}/_bmad/bmm/config.yaml` (and `config.user.yaml` if present) to resolve `{user_name}` and `{communication_language}`.
15
15
 
@@ -9,7 +9,7 @@ This skill was consolidated into `bmad-prd`. It is retained as a thin compatibil
9
9
 
10
10
  ## On Activation
11
11
 
12
- 1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-create-prd.toml` and `bmad-create-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
12
+ 1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-create-prd.toml` and `bmad-create-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
13
13
 
14
14
  2. Load `{project-root}/_bmad/bmm/config.yaml` (and `config.user.yaml` if present) to resolve `{user_name}` and `{communication_language}`.
15
15
 
@@ -30,7 +30,7 @@ If you need an explicit user instruction to run them, ask once now for the whole
30
30
 
31
31
  ### Step 1: Resolve the Workflow Block
32
32
 
33
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
33
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
34
34
 
35
35
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
36
36
 
@@ -428,7 +428,7 @@ Activation is complete. If `activation_steps_prepend` or `activation_steps_appen
428
428
 
429
429
  **The developer now has everything needed for flawless implementation!**
430
430
  </output>
431
- <action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
431
+ <action>Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
432
432
  </step>
433
433
 
434
434
  </workflow>
@@ -27,7 +27,7 @@ description: "Deprecated: `bmad-build` is now the official implementation method
27
27
 
28
28
  ### Step 1: Resolve the Workflow Block
29
29
 
30
- Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
30
+ Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
31
31
 
32
32
  **If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
33
33
 
@@ -496,7 +496,7 @@ Activation is complete. If `activation_steps_prepend` or `activation_steps_appen
496
496
  <action>Suggest checking {sprint_status} to see project progress</action>
497
497
  </check>
498
498
  <action>Remain flexible - allow user to choose their own path or ask for other assistance</action>
499
- <action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
499
+ <action>Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
500
500
  </step>
501
501
 
502
502
  </workflow>
@@ -9,7 +9,7 @@ This skill was consolidated into `bmad-prd`. It is retained as a thin compatibil
9
9
 
10
10
  ## On Activation
11
11
 
12
- 1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-edit-prd.toml` and `bmad-edit-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
12
+ 1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-edit-prd.toml` and `bmad-edit-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
13
13
 
14
14
  2. Load `{project-root}/_bmad/bmm/config.yaml` (and `config.user.yaml` if present) to resolve `{user_name}` and `{communication_language}`.
15
15
 
@@ -9,7 +9,7 @@ This skill was consolidated into `bmad-prd`. It is retained as a thin compatibil
9
9
 
10
10
  ## On Activation
11
11
 
12
- 1. Resolve customization: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-validate-prd.toml` and `bmad-validate-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
12
+ 1. Resolve customization: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`. This picks up any `{project-root}/_bmad/custom/bmad-validate-prd.toml` and `bmad-validate-prd.user.toml` overrides for the legacy fields (`activation_steps_prepend`, `activation_steps_append`, `persistent_facts`, `on_complete`).
13
13
 
14
14
  2. Load `{project-root}/_bmad/bmm/config.yaml` (and `config.user.yaml` if present) to resolve `{user_name}` and `{communication_language}`.
15
15
 
@@ -1245,9 +1245,23 @@ class Installer {
1245
1245
  ' Get started:',
1246
1246
  ` 1. Launch your AI agent from your project folder`,
1247
1247
  ` 2. Not sure what to do? Invoke the ${color.cyan('bmad-help')} skill and ask it what to do!`,
1248
- '',
1249
- ` ${color.cyan('Tip:')} BMAD workflows increasingly run Python scripts via ${color.cyan('uv run')} — uv is`,
1250
- ` becoming the de facto standard. If you don't have it yet, ask your agent to set it up.`,
1248
+ );
1249
+
1250
+ // Repeat the uv warning here when it applies. The pre-install probe fires
1251
+ // before every prompt in the run, so by now it is far up the scrollback —
1252
+ // and this box is titled "BMAD is ready to use!", which is only true if
1253
+ // the rendered skills can actually start.
1254
+ const { detectUv } = require('./uv-check');
1255
+ if (!detectUv()) {
1256
+ lines.push(
1257
+ '',
1258
+ ` ${color.yellow('⚠ uv is not installed.')} ${color.cyan('bmad-build')} and ${color.cyan('bmad-build-auto')} render through`,
1259
+ ` ${color.cyan('uv run')} and will halt on activation until you set it up — ask your agent to`,
1260
+ ` "install and set up uv for me", or see https://docs.astral.sh/uv/`,
1261
+ );
1262
+ }
1263
+
1264
+ lines.push(
1251
1265
  '',
1252
1266
  ` Blog, Docs and Guides: ${color.blue('https://bmadcode.com/')}`,
1253
1267
  ` Community: ${color.blue('https://discord.gg/gk8jAdXWmj')}`,
@@ -1,14 +1,30 @@
1
1
  const { spawnSync } = require('node:child_process');
2
2
  const prompts = require('../prompts');
3
3
 
4
- // `uv` (https://docs.astral.sh/uv/) is becoming the de facto standard for
5
- // running the Python scripts BMAD workflows shell out to: `uv run <script>`
6
- // resolves the interpreter and any dependencies on demand, so skills don't
7
- // have to assume a particular `python3` is on PATH. The ecosystem is mid-
8
- // migration — some skills still call `python3` directly — so a missing `uv`
9
- // is a warning, not a blocker: BMAD installs and runs either way.
4
+ // `uv` (https://docs.astral.sh/uv/) is how BMAD runs the Python scripts its
5
+ // skills shell out to: `uv run <script>` resolves the interpreter and any
6
+ // dependencies on demand from the script's own `requires-python` metadata, so
7
+ // skills don't have to assume a particular `python3` is on PATH.
8
+ //
9
+ // As of v6.11.0 this is a requirement, not a preference: the rendered skills
10
+ // (`bmad-build`, `bmad-build-auto`) render through `render_skill.py` and HALT
11
+ // on activation if `uv` is unavailable — there is no interpreter fallback.
12
+ //
13
+ // The check still never blocks the install. Core-only, docs-only, and CI
14
+ // installs are legitimate and never touch a rendered skill, so a missing `uv`
15
+ // must not fail the run. What it does is tell the truth about what will and
16
+ // will not work afterwards, here and again in the post-install summary.
10
17
  const RUNTIME_COMMAND = 'uv';
11
18
 
19
+ // Probed only when `uv` is absent. Some skills still invoke the interpreter
20
+ // directly (`python3 .../resolve_customization.py`), and those scripts declare
21
+ // `requires-python = ">=3.11"` — `resolve_config.py` hard-exits below it
22
+ // because `tomllib` is a 3.11 stdlib addition. When `uv` is present it
23
+ // provisions its own interpreter and whatever `python3` resolves to on PATH is
24
+ // irrelevant, so probing it then would report a problem that doesn't exist.
25
+ const PYTHON_COMMAND = 'python3';
26
+ const MIN_PYTHON = { major: 3, minor: 11 };
27
+
12
28
  /**
13
29
  * Parse `uv --version` output into version parts.
14
30
  * Example outputs: "uv 0.5.31", "uv 0.5.31 (Homebrew 2025-02-12)".
@@ -28,13 +44,44 @@ function parseUvVersion(output) {
28
44
  }
29
45
 
30
46
  /**
31
- * Probe the local environment for `uv`.
32
- * @returns {{version: {major: number, minor: number, patch: number, raw: string}}|null}
47
+ * Parse `python3 --version` output into version parts.
48
+ * Example outputs: "Python 3.11.7", "Python 3.13.0rc1".
49
+ * @param {string} output - stdout/stderr from `python3 --version`
50
+ * @returns {{major: number, minor: number, patch: number, raw: string}|null}
33
51
  */
34
- function detectUv() {
52
+ function parsePythonVersion(output) {
53
+ if (!output) return null;
54
+ const match = output.match(/Python\s+(\d+)\.(\d+)(?:\.(\d+))?/i);
55
+ if (!match) return null;
56
+ return {
57
+ major: Number(match[1]),
58
+ minor: Number(match[2]),
59
+ patch: Number(match[3] || 0),
60
+ raw: `${match[1]}.${match[2]}.${match[3] || 0}`,
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Whether a parsed Python version satisfies the 3.11+ floor the scripts declare.
66
+ * @param {{major: number, minor: number}|null} version
67
+ * @returns {boolean}
68
+ */
69
+ function pythonMeetsMinimum(version) {
70
+ if (!version) return false;
71
+ if (version.major !== MIN_PYTHON.major) return version.major > MIN_PYTHON.major;
72
+ return version.minor >= MIN_PYTHON.minor;
73
+ }
74
+
75
+ /**
76
+ * Run `<command> --version` and hand the combined output to a parser.
77
+ * @param {string} command
78
+ * @param {(output: string) => Object|null} parse
79
+ * @returns {{version: Object}|null}
80
+ */
81
+ function probeVersion(command, parse) {
35
82
  let result;
36
83
  try {
37
- result = spawnSync(RUNTIME_COMMAND, ['--version'], {
84
+ result = spawnSync(command, ['--version'], {
38
85
  encoding: 'utf8',
39
86
  timeout: 5000,
40
87
  windowsHide: true,
@@ -43,14 +90,30 @@ function detectUv() {
43
90
  return null;
44
91
  }
45
92
  if (!result || result.error) return null;
46
- const version = parseUvVersion(`${result.stdout || ''}\n${result.stderr || ''}`);
93
+ const version = parse(`${result.stdout || ''}\n${result.stderr || ''}`);
47
94
  return version ? { version } : null;
48
95
  }
49
96
 
97
+ /**
98
+ * Probe the local environment for `uv`.
99
+ * @returns {{version: {major: number, minor: number, patch: number, raw: string}}|null}
100
+ */
101
+ function detectUv() {
102
+ return probeVersion(RUNTIME_COMMAND, parseUvVersion);
103
+ }
104
+
105
+ /**
106
+ * Probe the local environment for `python3`.
107
+ * @returns {{version: {major: number, minor: number, patch: number, raw: string}}|null}
108
+ */
109
+ function detectPython3() {
110
+ return probeVersion(PYTHON_COMMAND, parsePythonVersion);
111
+ }
112
+
50
113
  function setupHints() {
51
114
  return [
52
- 'BMAD workflows increasingly run Python scripts via `uv run`, which manages',
53
- 'the interpreter and dependencies for you no manual venv or pip needed.',
115
+ '`uv run` provisions the interpreter and dependencies for you no manual',
116
+ 'venv or pip, and no need for a particular python3 on PATH.',
54
117
  '',
55
118
  'Easiest path: ask your AI agent to "install and set up uv for me".',
56
119
  '',
@@ -62,15 +125,42 @@ function setupHints() {
62
125
  ].join('\n');
63
126
  }
64
127
 
128
+ /**
129
+ * Describe what a missing `uv` leaves working, based on the `python3` fallback.
130
+ *
131
+ * With `uv` gone the rendered skills are lost either way; the only question is
132
+ * whether the skills that invoke the interpreter directly still run, and that
133
+ * turns on `python3` being 3.11+.
134
+ *
135
+ * @param {{version: Object}|null} python - result of detectPython3()
136
+ * @returns {string}
137
+ */
138
+ function pythonFallbackNote(python) {
139
+ if (!python) {
140
+ return 'No python3 on PATH either, so no Python-backed skill will run.';
141
+ }
142
+ if (pythonMeetsMinimum(python.version)) {
143
+ return (
144
+ `python3 ${python.version.raw} is present, so skills that call the interpreter ` +
145
+ 'directly still work — but the rendered skills above stay unavailable.'
146
+ );
147
+ }
148
+ return (
149
+ `python3 ${python.version.raw} is present but below the required ` +
150
+ `${MIN_PYTHON.major}.${MIN_PYTHON.minor}, so no Python-backed skill will run.`
151
+ );
152
+ }
153
+
65
154
  /**
66
155
  * Check whether `uv` is available and inform the user.
67
156
  *
68
- * Warn-don't-block, and no acknowledgement prompt: `uv` is on its way to being
69
- * the standard runner for BMAD's Python scripts, but the migration is still in
70
- * progress, so the install never stops on its account. The note tells the user
71
- * how to set it up (preferably by asking their agent).
157
+ * Warn-don't-block: a missing `uv` never stops or fails the install, because
158
+ * core-only and CI installs are legitimate and never render a skill. But the
159
+ * warning names the concrete consequence `bmad-build` and `bmad-build-auto`
160
+ * halt rather than describing `uv` as a nice-to-have, and `installer.js`
161
+ * repeats it in the post-install summary so it isn't lost in the scrollback.
72
162
  *
73
- * @returns {Promise<{status: 'found'|'missing', detected: Object|null}>}
163
+ * @returns {Promise<{status: 'found'|'missing', detected: Object|null, python: Object|null}>}
74
164
  */
75
165
  async function checkUvEnvironment() {
76
166
  // Called via module.exports so tests can stub detection.
@@ -78,20 +168,28 @@ async function checkUvEnvironment() {
78
168
 
79
169
  if (detected) {
80
170
  await prompts.log.success(`✅ Python UV check pass (uv ${detected.version.raw} detected).`);
81
- return { status: 'found', detected };
171
+ return { status: 'found', detected, python: null };
82
172
  }
83
173
 
174
+ const python = module.exports.detectPython3();
175
+
84
176
  await prompts.log.warn(
85
- "uv not found on PATH. uv is becoming the de facto standard for running BMAD's Python\n" +
86
- 'scripts (`uv run <script>`), and it provisions the interpreter for you. BMAD installs\n' +
87
- 'fine without it, but setting up uv now keeps you ahead as workflows adopt it.',
177
+ 'uv not found on PATH. BMAD requires it to run the Python scripts its skills\n' +
178
+ 'shell out to: bmad-build and bmad-build-auto render through `uv run` and will\n' +
179
+ 'HALT on activation without it there is no interpreter fallback.\n' +
180
+ `${pythonFallbackNote(python)}\n` +
181
+ 'The install itself completes either way.',
88
182
  );
89
- await prompts.note(setupHints(), 'uv recommended');
90
- return { status: 'missing', detected: null };
183
+ await prompts.note(setupHints(), 'uv required');
184
+ return { status: 'missing', detected: null, python };
91
185
  }
92
186
 
93
187
  module.exports = {
94
188
  checkUvEnvironment,
95
189
  detectUv,
190
+ detectPython3,
96
191
  parseUvVersion,
192
+ parsePythonVersion,
193
+ pythonMeetsMinimum,
194
+ MIN_PYTHON,
97
195
  };
@@ -12,8 +12,9 @@ startMessage: |
12
12
  🌟 100% free. 100% open source. Always.
13
13
  No paywalls. No gated content. Knowledge shared, not sold.
14
14
 
15
- 🐍 HEADS UP: uv (https://docs.astral.sh/uv/) is becoming the de facto standard
16
- for running the Python scripts BMAD workflows rely on (`uv run <script>`).
15
+ 🐍 REQUIRED: uv (https://docs.astral.sh/uv/) runs the Python scripts BMAD
16
+ skills rely on (`uv run <script>`) and provisions the interpreter itself.
17
+ Without it, bmad-build and bmad-build-auto halt on activation.
17
18
  If it's not set up yet, ask your AI agent to "install and set up uv for me".
18
19
 
19
20
  🌐 CONNECT:
@@ -204,13 +204,15 @@ class UI {
204
204
  const messageLoader = new MessageLoader();
205
205
  await messageLoader.displayStartMessage();
206
206
 
207
- // Probe for `uv` before any other prompts: it's becoming the de facto
208
- // runner for the Python scripts BMAD workflows shell out to
209
- // (`uv run <script>`), and uv provisions the interpreter itself, so it's
210
- // the single thing worth checking for. The migration is still in progress
211
- // (some skills still call `python3` directly), so this is informational —
212
- // warn-don't-block, no ack prompt and just points the user at setup
213
- // (ideally "ask your agent to set up uv"). The installer runs in the
207
+ // Probe for `uv` before any other prompts: it's the runner for the Python
208
+ // scripts BMAD skills shell out to (`uv run <script>`), and uv provisions
209
+ // the interpreter itself, so it's the single thing worth checking for.
210
+ // As of v6.11.0 `bmad-build` and `bmad-build-auto` HALT without it.
211
+ //
212
+ // Still warn-don't-block, with no ack prompt: core-only, docs-only, and
213
+ // CI installs never touch a rendered skill, so a missing `uv` must not
214
+ // fail the run. `installer.js` repeats the warning in the post-install
215
+ // summary so it survives the scrollback. The installer runs in the
214
216
  // destination environment, so probing PATH here tests the right machine.
215
217
  const { checkUvEnvironment } = require('./core/uv-check');
216
218
  await checkUvEnvironment();