bmad-method 6.3.1-next.17 → 6.3.1-next.19

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 (37) hide show
  1. package/package.json +1 -1
  2. package/src/bmm-skills/1-analysis/bmad-document-project/workflows/deep-dive-instructions.md +1 -0
  3. package/src/bmm-skills/1-analysis/bmad-document-project/workflows/full-scan-instructions.md +1 -0
  4. package/src/bmm-skills/1-analysis/bmad-prfaq/customize.toml +22 -0
  5. package/src/bmm-skills/1-analysis/bmad-prfaq/references/verdict.md +4 -0
  6. package/src/bmm-skills/1-analysis/research/bmad-domain-research/customize.toml +22 -0
  7. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +6 -0
  8. package/src/bmm-skills/1-analysis/research/bmad-market-research/customize.toml +26 -0
  9. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +6 -0
  10. package/src/bmm-skills/1-analysis/research/bmad-technical-research/customize.toml +26 -0
  11. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +6 -0
  12. package/src/bmm-skills/2-plan-workflows/bmad-create-prd/customize.toml +28 -1
  13. package/src/bmm-skills/2-plan-workflows/bmad-create-prd/steps-c/step-12-complete.md +6 -0
  14. package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/customize.toml +28 -1
  15. package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-14-complete.md +6 -0
  16. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/customize.toml +29 -1
  17. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +2 -0
  18. package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/customize.toml +29 -1
  19. package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/steps-v/step-v-13-report-complete.md +1 -0
  20. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/customize.toml +28 -1
  21. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +6 -0
  22. package/src/bmm-skills/3-solutioning/bmad-create-architecture/customize.toml +28 -1
  23. package/src/bmm-skills/3-solutioning/bmad-create-architecture/steps/step-08-complete.md +6 -0
  24. package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/customize.toml +28 -1
  25. package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/steps/step-04-final-validation.md +6 -0
  26. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/customize.toml +28 -1
  27. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-03-complete.md +6 -0
  28. package/src/bmm-skills/4-implementation/bmad-correct-course/SKILL.md +1 -0
  29. package/src/bmm-skills/4-implementation/bmad-correct-course/customize.toml +28 -1
  30. package/src/bmm-skills/4-implementation/bmad-create-story/SKILL.md +1 -0
  31. package/src/bmm-skills/4-implementation/bmad-create-story/customize.toml +28 -1
  32. package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/SKILL.md +6 -0
  33. package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/customize.toml +28 -1
  34. package/src/bmm-skills/4-implementation/bmad-retrospective/SKILL.md +1 -1
  35. package/src/bmm-skills/4-implementation/bmad-retrospective/customize.toml +28 -1
  36. package/tools/installer/core/manifest-generator.js +23 -6
  37. package/tools/installer/project-root.js +54 -0
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.3.1-next.17",
4
+ "version": "6.3.1-next.19",
5
5
  "description": "Breakthrough Method of Agile AI-driven Development",
6
6
  "keywords": [
7
7
  "agile",
@@ -291,6 +291,7 @@ These comprehensive docs are now ready for:
291
291
 
292
292
  Thank you for using the document-project workflow!
293
293
  </action>
294
+ <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>
294
295
  <action>Exit workflow</action>
295
296
  </action>
296
297
  </step>
@@ -1103,5 +1103,6 @@ When ready to plan new features, run the PRD workflow and provide this index as
1103
1103
  </action>
1104
1104
 
1105
1105
  <action>Display: "State file saved: {{project_knowledge}}/project-scan-report.json"</action>
1106
+ <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>
1106
1107
 
1107
1108
  </workflow>
@@ -9,11 +9,33 @@
9
9
  # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
10
  # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
11
 
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
12
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
13
21
  activation_steps_append = []
14
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All briefs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
15
33
  persistent_facts = [
16
34
  "file:{project-root}/**/project-context.md",
17
35
  ]
18
36
 
37
+ # Scalar: executed when the workflow reaches its terminal stage (Stage 5: The Verdict),
38
+ # after the PRFAQ and distillate have been delivered. Override wins. Leave empty for
39
+ # no custom post-completion behavior.
40
+
19
41
  on_complete = ""
@@ -77,3 +77,7 @@ purpose: "Token-efficient context for downstream PRD creation"
77
77
  ## Stage Complete
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
+
81
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
82
+
83
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -9,11 +9,33 @@
9
9
  # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
10
  # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
11
 
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
12
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
13
21
  activation_steps_append = []
14
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All briefs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
15
33
  persistent_facts = [
16
34
  "file:{project-root}/**/project-context.md",
17
35
  ]
18
36
 
37
+ # Scalar: executed when the workflow reaches its terminal stage (Step 6: Research Synthesis),
38
+ # after the domain research document has been saved and the user selects [C] Complete.
39
+ # Override wins. Leave empty for no custom post-completion behavior.
40
+
19
41
  on_complete = ""
@@ -441,4 +441,10 @@ Complete authoritative research document on {{research_topic}} that:
441
441
  - Serves as reference document for continued use
442
442
  - Maintains highest research quality standards
443
443
 
444
+ ## On Complete
445
+
446
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
447
+
448
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
449
+
444
450
  Congratulations on completing comprehensive domain research! 🎉
@@ -5,11 +5,37 @@
5
5
 
6
6
  [workflow]
7
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
8
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
9
21
  activation_steps_append = []
10
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All briefs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
11
33
  persistent_facts = [
12
34
  "file:{project-root}/**/project-context.md",
13
35
  ]
14
36
 
37
+ # Scalar: executed when the workflow reaches its terminal stage (Step 6: Research Completion),
38
+ # after the market research document has been saved and the user selects [C] Complete.
39
+ # Override wins. Leave empty for no custom post-completion behavior.
40
+
15
41
  on_complete = ""
@@ -475,4 +475,10 @@ Comprehensive market research workflow complete. User may:
475
475
  - Combine market research with other research types for comprehensive insights
476
476
  - Move forward with implementation based on strategic market recommendations
477
477
 
478
+ ## On Complete
479
+
480
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
481
+
482
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
483
+
478
484
  Congratulations on completing comprehensive market research with professional documentation! 🎉
@@ -5,11 +5,37 @@
5
5
 
6
6
  [workflow]
7
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
8
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
9
21
  activation_steps_append = []
10
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All briefs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
11
33
  persistent_facts = [
12
34
  "file:{project-root}/**/project-context.md",
13
35
  ]
14
36
 
37
+ # Scalar: executed when the workflow reaches its terminal stage (Step 6: Technical Synthesis),
38
+ # after the technical research document has been saved and the user selects [C] Complete.
39
+ # Override wins. Leave empty for no custom post-completion behavior.
40
+
15
41
  on_complete = ""
@@ -484,4 +484,10 @@ Complete authoritative technical research document on {{research_topic}} that:
484
484
  - Serves as technical reference document for continued use
485
485
  - Maintains highest technical research quality standards with current verification
486
486
 
487
+ ## On Complete
488
+
489
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
490
+
491
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
492
+
487
493
  Congratulations on completing comprehensive technical research with professional documentation! 🎉
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-create-prd.
3
+ # Workflow customization surface for bmad-create-prd. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All PRDs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 12 (Workflow Completion),
38
+ # after the PRD is finalized and workflow status is updated. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -113,3 +113,9 @@ PRD complete. Invoke the `bmad-help` skill.
113
113
  The polished PRD serves as the foundation for all subsequent product development activities. All design, architecture, and development work should trace back to the requirements and vision documented in this PRD - update it also as needed as you continue planning.
114
114
 
115
115
  **Congratulations on completing the Product Requirements Document for {{project_name}}!** 🎉
116
+
117
+ ## On Complete
118
+
119
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
120
+
121
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-create-ux-design.
3
+ # Workflow customization surface for bmad-create-ux-design. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All designs must meet WCAG 2.1 AA accessibility standards."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 14 (Workflow Completion),
38
+ # after the UX design specification is finalized and status is updated. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -169,3 +169,9 @@ This UX design workflow is now complete. The specification serves as the foundat
169
169
  - ✅ UX Design Specification: `{planning_artifacts}/ux-design-specification.md`
170
170
  - ✅ Color Themes Visualizer: `{planning_artifacts}/ux-color-themes.html`
171
171
  - ✅ Design Directions: `{planning_artifacts}/ux-design-directions.html`
172
+
173
+ ## On Complete
174
+
175
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
176
+
177
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,14 +1,42 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-edit-prd.
3
+ # Workflow customization surface for bmad-edit-prd. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All PRDs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step E-4 (Complete & Validate) and the
38
+ # user exits via [S] Summary or [X] Exit — not on [V] Validate (which chains to
39
+ # bmad-validate-prd) or [E] Edit More (which loops back). Override wins.
40
+ # Leave empty for no custom post-completion behavior.
41
+
14
42
  on_complete = ""
@@ -130,11 +130,13 @@ Display:
130
130
  - Before/after comparison (key improvements)
131
131
  - Recommendations for next steps
132
132
  - Display: "**Edit Workflow Complete**"
133
+ - 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.
133
134
  - Exit
134
135
 
135
136
  - **IF X (Exit):**
136
137
  - Display summary
137
138
  - Display: "**Edit Workflow Complete**"
139
+ - 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.
138
140
  - Exit
139
141
 
140
142
  - **IF Any other:** Help user, then redisplay menu
@@ -1,14 +1,42 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-validate-prd.
3
+ # Workflow customization surface for bmad-validate-prd. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All PRDs must include a regulatory-risk section."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 13 (Validation Report Complete) and
38
+ # the user exits via [X] Exit — not on [E] Use Edit Workflow (which chains to
39
+ # bmad-edit-prd), [R] Review (which loops within), or [F] Fix (which loops within).
40
+ # Override wins. Leave empty for no custom post-completion behavior.
41
+
14
42
  on_complete = ""
@@ -196,6 +196,7 @@ Display:
196
196
  - Display: "**Validation Report Saved:** {validationReportPath}"
197
197
  - Display: "**Summary:** {overall status} - {recommendation}"
198
198
  - PRD Validation complete. Invoke the `bmad-help` skill.
199
+ - 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.
199
200
 
200
201
  - **IF Any other:** Help user, then redisplay menu
201
202
 
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-check-implementation-readiness.
3
+ # Workflow customization surface for bmad-check-implementation-readiness. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All artifacts must follow org naming conventions."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 6 (Final Assessment),
38
+ # after the readiness report has been saved and presented. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -124,3 +124,9 @@ Implementation Readiness complete. Invoke the `bmad-help` skill.
124
124
  - Not reviewing previous findings
125
125
  - Incomplete summary
126
126
  - No clear recommendations
127
+
128
+ ## On Complete
129
+
130
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
131
+
132
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-create-architecture.
3
+ # Workflow customization surface for bmad-create-architecture. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "Our org is AWS-only -- do not propose GCP or Azure."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 8 (Architecture Completion & Handoff),
38
+ # after the architecture document frontmatter is updated and next-steps guidance is given.
39
+ # Override wins. Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -74,3 +74,9 @@ Upon Completion of task output: offer to answer any questions about the Architec
74
74
  This is the final step of the Architecture workflow. The user now has a complete, validated architecture document ready for AI agent implementation.
75
75
 
76
76
  The architecture will serve as the single source of truth for all technical decisions, ensuring consistent implementation across the entire project development lifecycle.
77
+
78
+ ## On Complete
79
+
80
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
81
+
82
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-create-epics-and-stories.
3
+ # Workflow customization surface for bmad-create-epics-and-stories. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All epics must deliver complete end-to-end user value."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 4 (Final Validation) and the
38
+ # user confirms [C] Complete — after the epics.md is saved and bmad-help is invoked.
39
+ # Override wins. Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -129,3 +129,9 @@ When C is selected, the workflow is complete and the epics.md is ready for devel
129
129
  Epics and Stories complete. Invoke the `bmad-help` skill.
130
130
 
131
131
  Upon Completion of task output: offer to answer any questions about the Epics and Stories.
132
+
133
+ ## On Complete
134
+
135
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
136
+
137
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-generate-project-context.
3
+ # Workflow customization surface for bmad-generate-project-context. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All artifacts must follow org naming conventions."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 3 (Context Completion & Finalization),
38
+ # after the project-context.md file is optimized and saved. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -276,3 +276,9 @@ Your project context will help ensure high-quality, consistent implementation ac
276
276
  This is the final step of the Generate Project Context workflow. The user now has a comprehensive, optimized project context file that will ensure consistent, high-quality implementation across all AI agents working on the project.
277
277
 
278
278
  The project context file serves as the critical "rules of the road" that agents need to implement code consistently with the project's standards and patterns.
279
+
280
+ ## On Complete
281
+
282
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
283
+
284
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -295,6 +295,7 @@ Activation is complete. Begin the workflow below.
295
295
 
296
296
  <action>Report workflow completion to user with personalized message: "Correct Course workflow complete, {user_name}!"</action>
297
297
  <action>Remind user of success criteria and next steps for Developer agent</action>
298
+ <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>
298
299
  </step>
299
300
 
300
301
  </workflow>
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-correct-course.
3
+ # Workflow customization surface for bmad-correct-course. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All sprint changes require PO sign-off before execution."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 6 (Workflow Completion),
38
+ # after the Sprint Change Proposal is finalized and handoff is confirmed. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -411,6 +411,7 @@ Activation is complete. Begin the workflow below.
411
411
 
412
412
  **The developer now has everything needed for flawless implementation!**
413
413
  </output>
414
+ <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>
414
415
  </step>
415
416
 
416
417
  </workflow>
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-create-story.
3
+ # Workflow customization surface for bmad-create-story. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All stories must include testable acceptance criteria."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 6 (Update sprint status and finalize),
38
+ # after the story file is saved and sprint-status.yaml is updated. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -168,3 +168,9 @@ If the project needs:
168
168
  Save summary to: `{default_output_file}`
169
169
 
170
170
  **Done!** Tests generated and verified. Validate against `./checklist.md`.
171
+
172
+ ## On Complete
173
+
174
+ Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
175
+
176
+ If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-qa-generate-e2e-tests.
3
+ # Workflow customization surface for bmad-qa-generate-e2e-tests. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All tests must follow the project's existing test framework patterns."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 5 (Create Summary),
38
+ # after all tests pass and the summary document is saved. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -1486,7 +1486,7 @@ Alice (Product Owner): "See you at epic planning!"
1486
1486
  Charlie (Senior Dev): "Time to knock out that prep work."
1487
1487
 
1488
1488
  </output>
1489
-
1489
+ <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>
1490
1490
  </step>
1491
1491
 
1492
1492
  </workflow>
@@ -1,14 +1,41 @@
1
1
  # DO NOT EDIT -- overwritten on every update.
2
2
  #
3
- # Workflow customization surface for bmad-retrospective.
3
+ # Workflow customization surface for bmad-retrospective. Mirrors the
4
+ # agent customization shape under the [workflow] namespace.
4
5
 
5
6
  [workflow]
6
7
 
8
+ # --- Configurable below. Overrides merge per BMad structural rules: ---
9
+ # scalars: override wins • arrays (persistent_facts, activation_steps_*): append
10
+ # arrays-of-tables with `code`/`id`: replace matching items, append new ones.
11
+
12
+ # Steps to run before the standard activation (config load, greet).
13
+ # Overrides append. Use for pre-flight loads, compliance checks, etc.
14
+
7
15
  activation_steps_prepend = []
16
+
17
+ # Steps to run after greet but before the workflow begins.
18
+ # Overrides append. Use for context-heavy setup that should happen
19
+ # once the user has been acknowledged.
20
+
8
21
  activation_steps_append = []
9
22
 
23
+ # Persistent facts the workflow keeps in mind for the whole run
24
+ # (standards, compliance constraints, stylistic guardrails).
25
+ # Distinct from the runtime memory sidecar — these are static context
26
+ # loaded on activation. Overrides append.
27
+ #
28
+ # Each entry is either:
29
+ # - a literal sentence, e.g. "All retrospectives must produce SMART action items with named owners."
30
+ # - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
31
+ # (glob patterns are supported; the file's contents are loaded and treated as facts).
32
+
10
33
  persistent_facts = [
11
34
  "file:{project-root}/**/project-context.md",
12
35
  ]
13
36
 
37
+ # Scalar: executed when the workflow reaches Step 12 (Final Summary and Handoff),
38
+ # after the retrospective document is saved and sprint-status is updated. Override wins.
39
+ # Leave empty for no custom post-completion behavior.
40
+
14
41
  on_complete = ""
@@ -2,7 +2,7 @@ const path = require('node:path');
2
2
  const fs = require('../fs-native');
3
3
  const yaml = require('yaml');
4
4
  const crypto = require('node:crypto');
5
- const { getModulePath } = require('../project-root');
5
+ const { resolveInstalledModuleYaml } = require('../project-root');
6
6
  const prompts = require('../prompts');
7
7
 
8
8
  // Load package.json for version info
@@ -244,8 +244,17 @@ class ManifestGenerator {
244
244
  const debug = process.env.BMAD_DEBUG_MANIFEST === 'true';
245
245
 
246
246
  for (const moduleName of this.updatedModules) {
247
- const moduleYamlPath = path.join(getModulePath(moduleName), 'module.yaml');
248
- if (!(await fs.pathExists(moduleYamlPath))) continue;
247
+ const moduleYamlPath = await resolveInstalledModuleYaml(moduleName);
248
+ if (!moduleYamlPath) {
249
+ // External modules live in ~/.bmad/cache/external-modules, not src/modules.
250
+ // Warn rather than silently skip so missing agent rosters don't vanish
251
+ // from config.toml without notice.
252
+ console.warn(
253
+ `[warn] collectAgentsFromModuleYaml: could not locate module.yaml for '${moduleName}'. ` +
254
+ `Agents declared by this module will not be written to config.toml.`,
255
+ );
256
+ continue;
257
+ }
249
258
 
250
259
  let moduleDef;
251
260
  try {
@@ -271,7 +280,9 @@ class ManifestGenerator {
271
280
  }
272
281
 
273
282
  if (debug) {
274
- console.log(`[DEBUG] collectAgentsFromModuleYaml: ${moduleName} contributed ${moduleDef.agents.length} agents`);
283
+ console.log(
284
+ `[DEBUG] collectAgentsFromModuleYaml: ${moduleName} contributed ${moduleDef.agents.length} agents from ${moduleYamlPath}`,
285
+ );
275
286
  }
276
287
  }
277
288
 
@@ -410,8 +421,14 @@ class ManifestGenerator {
410
421
  // team config, so the operator should notice.
411
422
  const scopeByModuleKey = {};
412
423
  for (const moduleName of this.updatedModules) {
413
- const moduleYamlPath = path.join(getModulePath(moduleName), 'module.yaml');
414
- if (!(await fs.pathExists(moduleYamlPath))) continue;
424
+ const moduleYamlPath = await resolveInstalledModuleYaml(moduleName);
425
+ if (!moduleYamlPath) {
426
+ console.warn(
427
+ `[warn] writeCentralConfig: could not locate module.yaml for '${moduleName}'. ` +
428
+ `Answers from this module will default to team scope — user-scoped keys may mis-file into config.toml.`,
429
+ );
430
+ continue;
431
+ }
415
432
  try {
416
433
  const parsed = yaml.parse(await fs.readFile(moduleYamlPath, 'utf8'));
417
434
  if (!parsed || typeof parsed !== 'object') continue;
@@ -1,4 +1,5 @@
1
1
  const path = require('node:path');
2
+ const os = require('node:os');
2
3
  const fs = require('./fs-native');
3
4
 
4
5
  /**
@@ -69,9 +70,62 @@ function getModulePath(moduleName, ...segments) {
69
70
  return getSourcePath('modules', moduleName, ...segments);
70
71
  }
71
72
 
73
+ /**
74
+ * Path to the local external-module clone cache.
75
+ * External official modules (bmb, cis, gds, tea, wds, etc.) are cloned here
76
+ * by ExternalModuleManager during install and are not copied into <src>/modules/.
77
+ */
78
+ function getExternalModuleCachePath(moduleName, ...segments) {
79
+ const base = process.env.BMAD_EXTERNAL_MODULES_CACHE || path.join(os.homedir(), '.bmad', 'cache', 'external-modules');
80
+ return path.join(base, moduleName, ...segments);
81
+ }
82
+
83
+ /**
84
+ * Locate an installed module's `module.yaml` by filesystem lookup only.
85
+ *
86
+ * Built-in modules (core, bmm) live under <src>. External official modules are
87
+ * cloned into ~/.bmad/cache/external-modules/<name>/ with varying internal
88
+ * layouts (some at src/module.yaml, some at skills/module.yaml, some nested).
89
+ * This mirrors the candidate-path search in
90
+ * ExternalModuleManager.findExternalModuleSource but performs no git/network
91
+ * work, which keeps it safe to call during manifest writing.
92
+ *
93
+ * @param {string} moduleName
94
+ * @returns {Promise<string|null>} Absolute path to module.yaml, or null if not found.
95
+ */
96
+ async function resolveInstalledModuleYaml(moduleName) {
97
+ const builtIn = path.join(getModulePath(moduleName), 'module.yaml');
98
+ if (await fs.pathExists(builtIn)) return builtIn;
99
+
100
+ const cacheRoot = getExternalModuleCachePath(moduleName);
101
+ if (!(await fs.pathExists(cacheRoot))) return null;
102
+
103
+ for (const dir of ['skills', 'src']) {
104
+ const direct = path.join(cacheRoot, dir, 'module.yaml');
105
+ if (await fs.pathExists(direct)) return direct;
106
+
107
+ const dirPath = path.join(cacheRoot, dir);
108
+ if (await fs.pathExists(dirPath)) {
109
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
110
+ for (const entry of entries) {
111
+ if (!entry.isDirectory()) continue;
112
+ const nested = path.join(dirPath, entry.name, 'module.yaml');
113
+ if (await fs.pathExists(nested)) return nested;
114
+ }
115
+ }
116
+ }
117
+
118
+ const atRoot = path.join(cacheRoot, 'module.yaml');
119
+ if (await fs.pathExists(atRoot)) return atRoot;
120
+
121
+ return null;
122
+ }
123
+
72
124
  module.exports = {
73
125
  getProjectRoot,
74
126
  getSourcePath,
75
127
  getModulePath,
128
+ getExternalModuleCachePath,
129
+ resolveInstalledModuleYaml,
76
130
  findProjectRoot,
77
131
  };