bmad-method 6.0.0-alpha.13 → 6.0.0-alpha.15

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 (355) hide show
  1. package/.coderabbit.yaml +36 -0
  2. package/.github/CODE_OF_CONDUCT.md +128 -0
  3. package/.github/ISSUE_TEMPLATE/idea_submission.md +1 -1
  4. package/.github/scripts/discord-helpers.sh +15 -0
  5. package/.github/workflows/discord.yaml +278 -8
  6. package/.github/workflows/quality.yaml +19 -0
  7. package/.markdownlint-cli2.yaml +42 -0
  8. package/.prettierignore +3 -0
  9. package/CHANGELOG.md +183 -360
  10. package/README.md +4 -1
  11. package/docs/agent-customization-guide.md +2 -2
  12. package/docs/custom-content-installation.md +245 -0
  13. package/docs/document-sharding-guide.md +1 -1
  14. package/docs/index.md +2 -2
  15. package/docs/installers-bundlers/installers-modules-platforms-reference.md +6 -5
  16. package/docs/web-bundles-gemini-gpt-guide.md +1 -1
  17. package/eslint.config.mjs +14 -0
  18. package/example-custom-content/README.md +8 -0
  19. package/{custom/src → example-custom-content}/agents/commit-poet/commit-poet.agent.yaml +1 -1
  20. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/instructions.md +5 -5
  21. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +1 -1
  22. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +1 -1
  23. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +2 -2
  24. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/memories.md +1 -1
  25. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith.agent.yaml +18 -17
  26. package/example-custom-content/module.yaml +4 -0
  27. package/example-custom-content/workflows/quiz-master/steps/step-01-init.md +168 -0
  28. package/example-custom-content/workflows/quiz-master/steps/step-02-q1.md +155 -0
  29. package/example-custom-content/workflows/quiz-master/steps/step-03-q2.md +89 -0
  30. package/example-custom-content/workflows/quiz-master/steps/step-04-q3.md +36 -0
  31. package/example-custom-content/workflows/quiz-master/steps/step-05-q4.md +36 -0
  32. package/example-custom-content/workflows/quiz-master/steps/step-06-q5.md +36 -0
  33. package/example-custom-content/workflows/quiz-master/steps/step-07-q6.md +36 -0
  34. package/example-custom-content/workflows/quiz-master/steps/step-08-q7.md +36 -0
  35. package/example-custom-content/workflows/quiz-master/steps/step-09-q8.md +36 -0
  36. package/example-custom-content/workflows/quiz-master/steps/step-10-q9.md +36 -0
  37. package/example-custom-content/workflows/quiz-master/steps/step-11-q10.md +36 -0
  38. package/example-custom-content/workflows/quiz-master/steps/step-12-results.md +150 -0
  39. package/example-custom-content/workflows/quiz-master/templates/csv-headers.template +1 -0
  40. package/example-custom-content/workflows/quiz-master/workflow.md +54 -0
  41. package/example-custom-content/workflows/wassup/workflow.md +26 -0
  42. package/example-custom-module/mwm/README.md +9 -0
  43. package/example-custom-module/mwm/agents/cbt-coach/cbt-coach-sidecar/cognitive-distortions.md +47 -0
  44. package/example-custom-module/mwm/agents/cbt-coach/cbt-coach-sidecar/thought-records.md +17 -0
  45. package/example-custom-module/mwm/agents/cbt-coach/cbt-coach.agent.yaml +151 -0
  46. package/example-custom-module/mwm/agents/crisis-navigator.agent.yaml +138 -0
  47. package/example-custom-module/mwm/agents/meditation-guide.agent.yaml +138 -0
  48. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/insights.md +13 -0
  49. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/instructions.md +30 -0
  50. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/memories.md +13 -0
  51. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/patterns.md +17 -0
  52. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion.agent.yaml +125 -0
  53. package/example-custom-module/mwm/module.yaml +28 -0
  54. package/example-custom-module/mwm/workflows/cbt-thought-record/README.md +31 -0
  55. package/example-custom-module/mwm/workflows/cbt-thought-record/workflow.md +45 -0
  56. package/example-custom-module/mwm/workflows/crisis-support/README.md +31 -0
  57. package/example-custom-module/mwm/workflows/crisis-support/workflow.md +45 -0
  58. package/example-custom-module/mwm/workflows/daily-checkin/README.md +32 -0
  59. package/example-custom-module/mwm/workflows/daily-checkin/workflow.md +45 -0
  60. package/example-custom-module/mwm/workflows/guided-meditation/README.md +31 -0
  61. package/example-custom-module/mwm/workflows/guided-meditation/workflow.md +45 -0
  62. package/example-custom-module/mwm/workflows/wellness-journal/README.md +31 -0
  63. package/example-custom-module/mwm/workflows/wellness-journal/workflow.md +45 -0
  64. package/package.json +9 -4
  65. package/src/core/_module-installer/installer.js +1 -1
  66. package/src/core/{_module-installer/install-config.yaml → module.yaml} +5 -1
  67. package/src/core/resources/excalidraw/library-loader.md +2 -2
  68. package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +1 -1
  69. package/src/core/workflows/brainstorming/workflow.md +1 -1
  70. package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +0 -1
  71. package/src/core/workflows/party-mode/workflow.md +2 -3
  72. package/src/modules/bmb/README.md +1 -1
  73. package/src/modules/bmb/_module-installer/installer.js +76 -0
  74. package/src/modules/bmb/agents/bmad-builder.agent.yaml +32 -9
  75. package/src/modules/bmb/docs/agents/agent-menu-patterns.md +5 -5
  76. package/src/modules/bmb/docs/agents/expert-agent-architecture.md +20 -20
  77. package/src/modules/bmb/docs/agents/index.md +1 -1
  78. package/src/modules/bmb/docs/agents/module-agent-architecture.md +45 -45
  79. package/src/modules/bmb/docs/agents/simple-agent-architecture.md +7 -3
  80. package/src/modules/bmb/docs/workflows/architecture.md +1 -1
  81. package/src/modules/bmb/docs/workflows/templates/step-01-init-continuable-template.md +241 -0
  82. package/src/modules/bmb/docs/workflows/templates/step-1b-template.md +223 -0
  83. package/src/modules/bmb/{workflows/create-workflow → docs/workflows}/templates/step-file.md +4 -4
  84. package/src/modules/bmb/docs/workflows/{step-template.md → templates/step-template.md} +40 -33
  85. package/src/modules/bmb/docs/workflows/templates/workflow-template.md +104 -0
  86. package/src/modules/bmb/{workflows/create-workflow → docs/workflows}/templates/workflow.md +1 -1
  87. package/src/modules/bmb/{_module-installer/install-config.yaml → module.yaml} +4 -9
  88. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/README.md +4 -4
  89. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +8 -8
  90. package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +6 -6
  91. package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +7 -7
  92. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +2 -3
  93. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +10 -40
  94. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +1 -1
  95. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +1 -0
  96. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +2 -2
  97. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +2 -2
  98. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +2 -2
  99. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/workflow.md +2 -2
  100. package/src/modules/bmb/workflows/create-agent/data/info-and-installation-guide.md +16 -4
  101. package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/README.md +4 -4
  102. package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +7 -7
  103. package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +1 -1
  104. package/src/modules/bmb/workflows/create-agent/data/validation-complete.md +3 -3
  105. package/src/modules/bmb/workflows/create-agent/steps/step-01-brainstorm.md +3 -3
  106. package/src/modules/bmb/workflows/create-agent/steps/step-02-discover.md +3 -3
  107. package/src/modules/bmb/workflows/create-agent/steps/step-03-persona.md +3 -3
  108. package/src/modules/bmb/workflows/create-agent/steps/step-04-commands.md +6 -6
  109. package/src/modules/bmb/workflows/create-agent/steps/step-05-name.md +2 -2
  110. package/src/modules/bmb/workflows/create-agent/steps/step-06-build.md +3 -3
  111. package/src/modules/bmb/workflows/create-agent/steps/step-07-validate.md +3 -3
  112. package/src/modules/bmb/workflows/create-agent/steps/step-08-setup.md +2 -2
  113. package/src/modules/bmb/workflows/create-agent/steps/step-09-customize.md +3 -3
  114. package/src/modules/bmb/workflows/create-agent/steps/step-10-build-tools.md +2 -2
  115. package/src/modules/bmb/workflows/create-agent/steps/step-11-celebrate.md +2 -2
  116. package/src/modules/bmb/workflows/create-agent/workflow.md +11 -11
  117. package/src/modules/bmb/workflows/create-module/steps/step-01-init.md +155 -0
  118. package/src/modules/bmb/workflows/create-module/steps/step-01b-continue.md +169 -0
  119. package/src/modules/bmb/workflows/create-module/steps/step-02-concept.md +217 -0
  120. package/src/modules/bmb/workflows/create-module/steps/step-03-components.md +267 -0
  121. package/src/modules/bmb/workflows/create-module/steps/step-04-structure.md +228 -0
  122. package/src/modules/bmb/workflows/create-module/steps/step-05-config.md +233 -0
  123. package/src/modules/bmb/workflows/create-module/steps/step-06-agents.md +296 -0
  124. package/src/modules/bmb/workflows/create-module/steps/step-07-workflows.md +228 -0
  125. package/src/modules/bmb/workflows/create-module/steps/step-08-installer.md +186 -0
  126. package/src/modules/bmb/workflows/create-module/steps/step-09-documentation.md +309 -0
  127. package/src/modules/bmb/workflows/create-module/steps/step-10-roadmap.md +337 -0
  128. package/src/modules/bmb/workflows/create-module/steps/step-11-validate.md +335 -0
  129. package/src/modules/bmb/workflows/create-module/templates/agent.template.md +317 -0
  130. package/src/modules/bmb/workflows/create-module/templates/installer.template.js +47 -0
  131. package/src/modules/bmb/workflows/create-module/templates/module-plan.template.md +5 -0
  132. package/src/modules/bmb/workflows/create-module/templates/module.template.yaml +53 -0
  133. package/src/modules/bmb/workflows/create-module/templates/workflow-plan-template.md +23 -0
  134. package/src/modules/bmb/workflows/create-module/validation.md +126 -0
  135. package/src/modules/bmb/workflows/create-module/workflow.md +55 -0
  136. package/src/modules/bmb/workflows/create-workflow/steps/step-01-init.md +45 -56
  137. package/src/modules/bmb/workflows/create-workflow/steps/step-02-gather.md +9 -31
  138. package/src/modules/bmb/workflows/create-workflow/steps/step-03-tools-configuration.md +250 -0
  139. package/src/modules/bmb/workflows/create-workflow/steps/step-04-plan-review.md +216 -0
  140. package/src/modules/bmb/workflows/create-workflow/steps/step-05-output-format-design.md +289 -0
  141. package/src/modules/bmb/workflows/create-workflow/steps/{step-09-design.md → step-06-design.md} +76 -44
  142. package/src/modules/bmb/workflows/create-workflow/steps/{step-11-build.md → step-07-build.md} +71 -25
  143. package/src/modules/bmb/workflows/create-workflow/steps/{step-12-review.md → step-08-review.md} +30 -16
  144. package/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md +187 -0
  145. package/src/modules/bmb/workflows/create-workflow/workflow.md +2 -2
  146. package/src/modules/bmb/workflows/edit-agent/steps/step-01-discover-intent.md +2 -2
  147. package/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md +14 -14
  148. package/src/modules/bmb/workflows/edit-agent/steps/step-03-propose-changes.md +4 -4
  149. package/src/modules/bmb/workflows/edit-agent/steps/step-04-apply-changes.md +2 -2
  150. package/src/modules/bmb/workflows/edit-agent/steps/step-05-validate.md +4 -4
  151. package/src/modules/bmb/workflows/edit-agent/workflow.md +1 -1
  152. package/src/modules/bmb/workflows/edit-workflow/steps/step-01-analyze.md +2 -6
  153. package/src/modules/bmb/workflows/edit-workflow/steps/step-03-improve.md +2 -2
  154. package/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md +1 -1
  155. package/src/modules/bmb/workflows/edit-workflow/workflow.md +1 -1
  156. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-01-validate-goal.md +2 -2
  157. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-02-workflow-validation.md +5 -5
  158. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-03-step-validation.md +7 -7
  159. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-04-file-validation.md +3 -3
  160. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-05-intent-spectrum-validation.md +3 -3
  161. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-06-web-subprocess-validation.md +3 -3
  162. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-07-holistic-analysis.md +3 -3
  163. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-08-generate-report.md +2 -2
  164. package/src/modules/bmb/workflows/workflow-compliance-check/workflow.md +1 -1
  165. package/src/modules/bmb/workflows-legacy/edit-module/checklist.md +0 -1
  166. package/src/modules/bmgd/README.md +2 -1
  167. package/src/modules/bmgd/workflows/3-technical/game-architecture/instructions.md +8 -8
  168. package/src/modules/bmm/_module-installer/installer.js +1 -1
  169. package/src/modules/bmm/_module-installer/platform-specifics/claude-code.js +1 -1
  170. package/src/modules/bmm/_module-installer/platform-specifics/windsurf.js +1 -1
  171. package/src/modules/bmm/agents/analyst.agent.yaml +11 -8
  172. package/src/modules/bmm/agents/architect.agent.yaml +1 -5
  173. package/src/modules/bmm/agents/pm.agent.yaml +5 -5
  174. package/src/modules/bmm/docs/README.md +23 -1
  175. package/src/modules/bmm/docs/agents-guide.md +16 -35
  176. package/src/modules/bmm/docs/brownfield-guide.md +17 -30
  177. package/src/modules/bmm/docs/enterprise-agentic-development.md +2 -2
  178. package/src/modules/bmm/docs/faq.md +6 -39
  179. package/src/modules/bmm/docs/glossary.md +11 -24
  180. package/src/modules/bmm/docs/images/README.md +37 -0
  181. package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +62 -202
  182. package/src/modules/bmm/docs/images/workflow-method-greenfield.svg +3 -1
  183. package/src/modules/bmm/docs/quick-spec-flow.md +652 -0
  184. package/src/modules/bmm/docs/quick-start.md +9 -25
  185. package/src/modules/bmm/docs/test-architecture.md +6 -6
  186. package/src/modules/bmm/docs/troubleshooting.md +680 -0
  187. package/src/modules/bmm/docs/workflow-document-project-reference.md +1 -1
  188. package/src/modules/bmm/docs/workflows-implementation.md +143 -3
  189. package/src/modules/bmm/docs/workflows-solutioning.md +2 -2
  190. package/src/modules/bmm/{_module-installer/install-config.yaml → module.yaml} +1 -1
  191. package/src/modules/bmm/tasks/daily-standup.xml +85 -0
  192. package/src/modules/bmm/testarch/knowledge/ci-burn-in.md +1 -1
  193. package/src/modules/bmm/testarch/knowledge/overview.md +1 -1
  194. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-02-vision.md +2 -2
  195. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-03-users.md +2 -2
  196. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-04-metrics.md +2 -2
  197. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-05-scope.md +2 -2
  198. package/src/modules/bmm/workflows/1-analysis/product-brief/workflow.md +1 -1
  199. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +8 -8
  200. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +18 -18
  201. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +18 -18
  202. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +18 -18
  203. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +17 -17
  204. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +35 -36
  205. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +5 -6
  206. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +20 -19
  207. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +21 -20
  208. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +20 -19
  209. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +21 -20
  210. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +16 -15
  211. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +36 -37
  212. package/src/modules/bmm/workflows/1-analysis/research/research.template.md +0 -1
  213. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +8 -8
  214. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +19 -18
  215. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +20 -19
  216. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +21 -20
  217. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +19 -18
  218. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +38 -39
  219. package/src/modules/bmm/workflows/1-analysis/research/workflow.md +14 -8
  220. package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +6 -0
  221. package/src/modules/bmm/workflows/2-plan-workflows/prd/prd-template.md +7 -0
  222. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01-init.md +138 -56
  223. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01b-continue.md +93 -51
  224. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-02-discovery.md +223 -78
  225. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-03-success.md +20 -2
  226. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-04-journeys.md +18 -0
  227. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-05-domain.md +21 -0
  228. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-06-innovation.md +21 -0
  229. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-07-project-type.md +21 -0
  230. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-08-scoping.md +18 -0
  231. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-09-functional.md +18 -0
  232. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-10-nonfunctional.md +18 -0
  233. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-11-complete.md +13 -0
  234. package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.md +2 -2
  235. package/src/modules/bmm/workflows/3-solutioning/architecture/steps/step-03-starter.md +14 -14
  236. package/src/modules/bmm/workflows/3-solutioning/architecture/steps/step-04-decisions.md +7 -7
  237. package/src/modules/bmm/workflows/3-solutioning/architecture/workflow.md +2 -1
  238. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +258 -0
  239. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +232 -0
  240. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +271 -0
  241. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +144 -0
  242. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
  243. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -0
  244. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-01-document-discovery.md +189 -0
  245. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-02-prd-analysis.md +177 -0
  246. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-03-epic-coverage-validation.md +178 -0
  247. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-04-ux-alignment.md +138 -0
  248. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-05-epic-quality-review.md +251 -0
  249. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-06-final-assessment.md +132 -0
  250. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/templates/readiness-report-template.md +4 -0
  251. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/workflow.md +54 -0
  252. package/src/modules/{bmgd/workflows/4-production → bmm/workflows/4-implementation}/code-review/checklist.md +2 -1
  253. package/src/modules/bmm/workflows/4-implementation/code-review/instructions.xml +51 -3
  254. package/src/modules/bmm/workflows/4-implementation/code-review/workflow.yaml +1 -1
  255. package/src/modules/bmm/workflows/4-implementation/create-story/instructions.xml +32 -2
  256. package/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md +3 -3
  257. package/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md +19 -21
  258. package/src/modules/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +10 -10
  259. package/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md +174 -0
  260. package/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml +35 -0
  261. package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/instructions.md +104 -7
  262. package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/workflow.yaml +4 -0
  263. package/src/modules/bmm/workflows/document-project/instructions.md +1 -1
  264. package/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md +2 -2
  265. package/src/modules/bmm/workflows/generate-project-context/workflow.md +1 -1
  266. package/src/modules/bmm/workflows/testarch/atdd/atdd-checklist-template.md +1 -1
  267. package/src/modules/bmm/workflows/testarch/ci/checklist.md +1 -1
  268. package/src/modules/bmm/workflows/testarch/ci/github-actions-template.yaml +36 -3
  269. package/src/modules/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +25 -4
  270. package/src/modules/bmm/workflows/testarch/ci/instructions.md +2 -2
  271. package/src/modules/bmm/workflows/testarch/test-review/instructions.md +1 -1
  272. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +1 -6
  273. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +1 -6
  274. package/src/modules/bmm/workflows/workflow-status/paths/method-brownfield.yaml +1 -6
  275. package/src/modules/bmm/workflows/workflow-status/paths/method-greenfield.yaml +1 -7
  276. package/src/modules/cis/_module-installer/installer.js +1 -1
  277. package/tools/cli/README.md +7 -7
  278. package/tools/cli/commands/build.js +9 -184
  279. package/tools/cli/commands/install.js +1 -6
  280. package/tools/cli/installers/lib/core/config-collector.js +80 -12
  281. package/tools/cli/installers/lib/core/custom-module-cache.js +239 -0
  282. package/tools/cli/installers/lib/core/detector.js +8 -4
  283. package/tools/cli/installers/lib/core/installer.js +933 -376
  284. package/tools/cli/installers/lib/core/manifest-generator.js +265 -41
  285. package/tools/cli/installers/lib/core/manifest.js +47 -0
  286. package/tools/cli/installers/lib/core/post-install-sidecar-replacement.js +79 -0
  287. package/tools/cli/installers/lib/custom/handler.js +396 -0
  288. package/tools/cli/installers/lib/ide/_base-ide.js +10 -0
  289. package/tools/cli/installers/lib/ide/auggie.js +19 -7
  290. package/tools/cli/installers/lib/ide/crush.js +19 -6
  291. package/tools/cli/installers/lib/ide/cursor.js +29 -13
  292. package/tools/cli/installers/lib/ide/gemini.js +49 -1
  293. package/tools/cli/installers/lib/ide/iflow.js +20 -1
  294. package/tools/cli/installers/lib/ide/kiro-cli.js +327 -0
  295. package/tools/cli/installers/lib/ide/opencode.js +3 -3
  296. package/tools/cli/installers/lib/ide/roo.js +120 -184
  297. package/tools/cli/installers/lib/ide/rovo-dev.js +1 -1
  298. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +8 -2
  299. package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +34 -19
  300. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +18 -14
  301. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +1 -1
  302. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
  303. package/tools/cli/installers/lib/modules/manager.js +535 -56
  304. package/tools/cli/lib/agent/compiler.js +57 -16
  305. package/tools/cli/lib/agent/installer.js +129 -28
  306. package/tools/cli/lib/cli-utils.js +21 -4
  307. package/tools/cli/lib/config.js +2 -1
  308. package/tools/cli/lib/ui.js +561 -12
  309. package/tools/cli/lib/yaml-xml-builder.js +0 -15
  310. package/tools/maintainer/review-pr-README.md +55 -0
  311. package/tools/maintainer/review-pr.md +242 -0
  312. package/tools/migrate-custom-module-paths.js +124 -0
  313. package/tools/schema/agent.js +149 -89
  314. package/tools/validate-svg-changes.sh +356 -0
  315. package/custom/src/agents/commit-poet/installation-guide.md +0 -36
  316. package/custom/src/agents/toolsmith/installation-guide.md +0 -36
  317. package/docs/custom-agent-installation.md +0 -183
  318. package/src/modules/bmb/docs/workflows/workflow-template.md +0 -152
  319. package/src/modules/bmb/workflows/create-workflow/steps/step-03-tools-overview.md +0 -127
  320. package/src/modules/bmb/workflows/create-workflow/steps/step-04-core-tools.md +0 -145
  321. package/src/modules/bmb/workflows/create-workflow/steps/step-05-memory-requirements.md +0 -136
  322. package/src/modules/bmb/workflows/create-workflow/steps/step-06-external-tools.md +0 -154
  323. package/src/modules/bmb/workflows/create-workflow/steps/step-07-installation-guidance.md +0 -159
  324. package/src/modules/bmb/workflows/create-workflow/steps/step-08-tools-summary.md +0 -167
  325. package/src/modules/bmb/workflows/create-workflow/steps/step-10-plan-review.md +0 -215
  326. package/src/modules/bmb/workflows/create-workflow/templates/build-summary.md +0 -36
  327. package/src/modules/bmb/workflows/create-workflow/templates/completion-section.md +0 -39
  328. package/src/modules/bmb/workflows/create-workflow/templates/content-template.md +0 -21
  329. package/src/modules/bmb/workflows/create-workflow/templates/design-section.md +0 -53
  330. package/src/modules/bmb/workflows/create-workflow/templates/project-info.md +0 -18
  331. package/src/modules/bmb/workflows/create-workflow/templates/requirements-section.md +0 -47
  332. package/src/modules/bmb/workflows/create-workflow/templates/review-section.md +0 -56
  333. package/src/modules/bmb/workflows/create-workflow/templates/workflow-plan.md +0 -54
  334. package/src/modules/bmb/workflows-legacy/create-module/README.md +0 -229
  335. package/src/modules/bmb/workflows-legacy/create-module/brainstorm-context.md +0 -137
  336. package/src/modules/bmb/workflows-legacy/create-module/checklist.md +0 -235
  337. package/src/modules/bmb/workflows-legacy/create-module/installer-templates/install-config.yaml +0 -92
  338. package/src/modules/bmb/workflows-legacy/create-module/installer-templates/installer.js +0 -231
  339. package/src/modules/bmb/workflows-legacy/create-module/instructions.md +0 -577
  340. package/src/modules/bmb/workflows-legacy/create-module/module-structure.md +0 -400
  341. package/src/modules/bmb/workflows-legacy/create-module/workflow.yaml +0 -52
  342. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/epics-template.md +0 -80
  343. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/instructions.md +0 -387
  344. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.yaml +0 -53
  345. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +0 -169
  346. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +0 -332
  347. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/template.md +0 -146
  348. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -64
  349. package/tools/cli/commands/agent-install.js +0 -409
  350. package/tools/cli/commands/cleanup.js +0 -141
  351. /package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +0 -0
  352. /package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +0 -0
  353. /package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +0 -0
  354. /package/src/modules/bmgd/{_module-installer/install-config.yaml → module.yaml} +0 -0
  355. /package/src/modules/cis/{_module-installer/install-config.yaml → module.yaml} +0 -0
@@ -22,11 +22,12 @@ const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/p
22
22
  * await manager.install('core-module', '/path/to/bmad');
23
23
  */
24
24
  class ModuleManager {
25
- constructor() {
25
+ constructor(options = {}) {
26
26
  // Path to source modules directory
27
27
  this.modulesSourcePath = getSourcePath('modules');
28
28
  this.xmlHandler = new XmlHandler();
29
29
  this.bmadFolderName = 'bmad'; // Default, can be overridden
30
+ this.scanProjectForModules = options.scanProjectForModules !== false; // Default to true for backward compatibility
30
31
  }
31
32
 
32
33
  /**
@@ -37,6 +38,14 @@ class ModuleManager {
37
38
  this.bmadFolderName = bmadFolderName;
38
39
  }
39
40
 
41
+ /**
42
+ * Set the core configuration for access during module installation
43
+ * @param {Object} coreConfig - Core configuration object
44
+ */
45
+ setCoreConfig(coreConfig) {
46
+ this.coreConfig = coreConfig;
47
+ }
48
+
40
49
  /**
41
50
  * Copy a file and replace {bmad_folder} placeholder with actual folder name
42
51
  * @param {string} sourcePath - Source file path
@@ -53,6 +62,11 @@ class ModuleManager {
53
62
  // Read the file content
54
63
  let content = await fs.readFile(sourcePath, 'utf8');
55
64
 
65
+ // Replace escape sequence {*bmad_folder*} with literal {bmad_folder}
66
+ if (content.includes('{*bmad_folder*}')) {
67
+ content = content.replaceAll('{*bmad_folder*}', '{bmad_folder}');
68
+ }
69
+
56
70
  // Replace {bmad_folder} placeholder with actual folder name
57
71
  if (content.includes('{bmad_folder}')) {
58
72
  content = content.replaceAll('{bmad_folder}', this.bmadFolderName);
@@ -93,62 +107,297 @@ class ModuleManager {
93
107
  }
94
108
 
95
109
  /**
96
- * List all available modules
97
- * @returns {Array} List of available modules with metadata
110
+ * Find all modules in the project by searching for module.yaml files
111
+ * @returns {Array} List of module paths
112
+ */
113
+ async findModulesInProject() {
114
+ const projectRoot = getProjectRoot();
115
+ const modulePaths = new Set();
116
+
117
+ // Helper function to recursively scan directories
118
+ async function scanDirectory(dir, excludePaths = []) {
119
+ try {
120
+ const entries = await fs.readdir(dir, { withFileTypes: true });
121
+
122
+ for (const entry of entries) {
123
+ const fullPath = path.join(dir, entry.name);
124
+
125
+ // Skip hidden directories, node_modules, and literal placeholder directories
126
+ if (
127
+ entry.name.startsWith('.') ||
128
+ entry.name === 'node_modules' ||
129
+ entry.name === 'dist' ||
130
+ entry.name === 'build' ||
131
+ entry.name === '{project-root}'
132
+ ) {
133
+ continue;
134
+ }
135
+
136
+ // Skip excluded paths
137
+ if (excludePaths.some((exclude) => fullPath.startsWith(exclude))) {
138
+ continue;
139
+ }
140
+
141
+ if (entry.isDirectory()) {
142
+ // Skip core module - it's always installed first and not selectable
143
+ if (entry.name === 'core') {
144
+ continue;
145
+ }
146
+
147
+ // Check if this directory contains a module (module.yaml OR custom.yaml)
148
+ const moduleConfigPath = path.join(fullPath, 'module.yaml');
149
+ const installerConfigPath = path.join(fullPath, '_module-installer', 'module.yaml');
150
+ const customConfigPath = path.join(fullPath, '_module-installer', 'custom.yaml');
151
+ const rootCustomConfigPath = path.join(fullPath, 'custom.yaml');
152
+
153
+ if (
154
+ (await fs.pathExists(moduleConfigPath)) ||
155
+ (await fs.pathExists(installerConfigPath)) ||
156
+ (await fs.pathExists(customConfigPath)) ||
157
+ (await fs.pathExists(rootCustomConfigPath))
158
+ ) {
159
+ modulePaths.add(fullPath);
160
+ // Don't scan inside modules - they might have their own nested structures
161
+ continue;
162
+ }
163
+
164
+ // Recursively scan subdirectories
165
+ await scanDirectory(fullPath, excludePaths);
166
+ }
167
+ }
168
+ } catch {
169
+ // Ignore errors (e.g., permission denied)
170
+ }
171
+ }
172
+
173
+ // Scan the entire project, but exclude src/modules since we handle it separately
174
+ await scanDirectory(projectRoot, [this.modulesSourcePath]);
175
+
176
+ return [...modulePaths];
177
+ }
178
+
179
+ /**
180
+ * List all available modules (excluding core which is always installed)
181
+ * @returns {Object} Object with modules array and customModules array
98
182
  */
99
183
  async listAvailable() {
100
184
  const modules = [];
185
+ const customModules = [];
186
+
187
+ // First, scan src/modules (the standard location)
188
+ if (await fs.pathExists(this.modulesSourcePath)) {
189
+ const entries = await fs.readdir(this.modulesSourcePath, { withFileTypes: true });
190
+
191
+ for (const entry of entries) {
192
+ if (entry.isDirectory()) {
193
+ const modulePath = path.join(this.modulesSourcePath, entry.name);
194
+ // Check for module structure (module.yaml OR custom.yaml)
195
+ const moduleConfigPath = path.join(modulePath, 'module.yaml');
196
+ const installerConfigPath = path.join(modulePath, '_module-installer', 'module.yaml');
197
+ const customConfigPath = path.join(modulePath, '_module-installer', 'custom.yaml');
198
+
199
+ // Skip if this doesn't look like a module
200
+ if (
201
+ !(await fs.pathExists(moduleConfigPath)) &&
202
+ !(await fs.pathExists(installerConfigPath)) &&
203
+ !(await fs.pathExists(customConfigPath))
204
+ ) {
205
+ continue;
206
+ }
101
207
 
102
- if (!(await fs.pathExists(this.modulesSourcePath))) {
103
- console.warn(chalk.yellow('Warning: src/modules directory not found'));
104
- return modules;
208
+ // Skip core module - it's always installed first and not selectable
209
+ if (entry.name === 'core') {
210
+ continue;
211
+ }
212
+
213
+ const moduleInfo = await this.getModuleInfo(modulePath, entry.name, 'src/modules');
214
+ if (moduleInfo) {
215
+ modules.push(moduleInfo);
216
+ }
217
+ }
218
+ }
105
219
  }
106
220
 
107
- const entries = await fs.readdir(this.modulesSourcePath, { withFileTypes: true });
221
+ // Then, find all other modules in the project (only if scanning is enabled)
222
+ if (this.scanProjectForModules) {
223
+ const otherModulePaths = await this.findModulesInProject();
224
+ for (const modulePath of otherModulePaths) {
225
+ const moduleName = path.basename(modulePath);
226
+ const relativePath = path.relative(getProjectRoot(), modulePath);
108
227
 
109
- for (const entry of entries) {
110
- if (entry.isDirectory()) {
111
- const modulePath = path.join(this.modulesSourcePath, entry.name);
112
- // Check for new structure first
113
- const installerConfigPath = path.join(modulePath, '_module-installer', 'install-config.yaml');
114
- // Fallback to old structure
115
- const configPath = path.join(modulePath, 'config.yaml');
116
-
117
- const moduleInfo = {
118
- id: entry.name,
119
- path: modulePath,
120
- name: entry.name.toUpperCase(),
121
- description: 'BMAD Module',
122
- version: '5.0.0',
123
- };
228
+ // Skip core module - it's always installed first and not selectable
229
+ if (moduleName === 'core') {
230
+ continue;
231
+ }
124
232
 
125
- // Try to read module config for metadata (prefer new location)
126
- const configToRead = (await fs.pathExists(installerConfigPath)) ? installerConfigPath : configPath;
127
- if (await fs.pathExists(configToRead)) {
128
- try {
129
- const configContent = await fs.readFile(configToRead, 'utf8');
130
- const config = yaml.load(configContent);
233
+ const moduleInfo = await this.getModuleInfo(modulePath, moduleName, relativePath);
234
+ if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) {
235
+ // Avoid duplicates - skip if we already have this module ID
236
+ if (moduleInfo.isCustom) {
237
+ customModules.push(moduleInfo);
238
+ } else {
239
+ modules.push(moduleInfo);
240
+ }
241
+ }
242
+ }
131
243
 
132
- // Use the code property as the id if available
133
- if (config.code) {
134
- moduleInfo.id = config.code;
244
+ // Also check for cached custom modules in _cfg/custom/
245
+ if (this.bmadDir) {
246
+ const customCacheDir = path.join(this.bmadDir, '_cfg', 'custom');
247
+ if (await fs.pathExists(customCacheDir)) {
248
+ const cacheEntries = await fs.readdir(customCacheDir, { withFileTypes: true });
249
+ for (const entry of cacheEntries) {
250
+ if (entry.isDirectory()) {
251
+ const cachePath = path.join(customCacheDir, entry.name);
252
+ const moduleInfo = await this.getModuleInfo(cachePath, entry.name, '_cfg/custom');
253
+ if (moduleInfo && !modules.some((m) => m.id === moduleInfo.id) && !customModules.some((m) => m.id === moduleInfo.id)) {
254
+ moduleInfo.isCustom = true;
255
+ moduleInfo.fromCache = true;
256
+ customModules.push(moduleInfo);
257
+ }
135
258
  }
136
-
137
- moduleInfo.name = config.name || moduleInfo.name;
138
- moduleInfo.description = config.description || moduleInfo.description;
139
- moduleInfo.version = config.version || moduleInfo.version;
140
- moduleInfo.dependencies = config.dependencies || [];
141
- moduleInfo.defaultSelected = config.default_selected === undefined ? false : config.default_selected;
142
- } catch (error) {
143
- console.warn(`Failed to read config for ${entry.name}:`, error.message);
144
259
  }
145
260
  }
261
+ }
262
+ }
263
+
264
+ return { modules, customModules };
265
+ }
266
+
267
+ /**
268
+ * Get module information from a module path
269
+ * @param {string} modulePath - Path to the module directory
270
+ * @param {string} defaultName - Default name for the module
271
+ * @param {string} sourceDescription - Description of where the module was found
272
+ * @returns {Object|null} Module info or null if not a valid module
273
+ */
274
+ async getModuleInfo(modulePath, defaultName, sourceDescription) {
275
+ // Check for module structure (module.yaml OR custom.yaml)
276
+ const moduleConfigPath = path.join(modulePath, 'module.yaml');
277
+ const installerConfigPath = path.join(modulePath, '_module-installer', 'module.yaml');
278
+ const customConfigPath = path.join(modulePath, '_module-installer', 'custom.yaml');
279
+ const rootCustomConfigPath = path.join(modulePath, 'custom.yaml');
280
+ let configPath = null;
281
+
282
+ if (await fs.pathExists(moduleConfigPath)) {
283
+ configPath = moduleConfigPath;
284
+ } else if (await fs.pathExists(installerConfigPath)) {
285
+ configPath = installerConfigPath;
286
+ } else if (await fs.pathExists(customConfigPath)) {
287
+ configPath = customConfigPath;
288
+ } else if (await fs.pathExists(rootCustomConfigPath)) {
289
+ configPath = rootCustomConfigPath;
290
+ }
291
+
292
+ // Skip if this doesn't look like a module
293
+ if (!configPath) {
294
+ return null;
295
+ }
296
+
297
+ // Mark as custom if it's using custom.yaml OR if it's outside src/modules
298
+ const isCustomSource = sourceDescription !== 'src/modules';
299
+ const moduleInfo = {
300
+ id: defaultName,
301
+ path: modulePath,
302
+ name: defaultName
303
+ .split('-')
304
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
305
+ .join(' '),
306
+ description: 'BMAD Module',
307
+ version: '5.0.0',
308
+ source: sourceDescription,
309
+ isCustom: configPath === customConfigPath || configPath === rootCustomConfigPath || isCustomSource,
310
+ };
311
+
312
+ // Read module config for metadata
313
+ try {
314
+ const configContent = await fs.readFile(configPath, 'utf8');
315
+ const config = yaml.load(configContent);
316
+
317
+ // Use the code property as the id if available
318
+ if (config.code) {
319
+ moduleInfo.id = config.code;
320
+ }
321
+
322
+ moduleInfo.name = config.name || moduleInfo.name;
323
+ moduleInfo.description = config.description || moduleInfo.description;
324
+ moduleInfo.version = config.version || moduleInfo.version;
325
+ moduleInfo.dependencies = config.dependencies || [];
326
+ moduleInfo.defaultSelected = config.default_selected === undefined ? false : config.default_selected;
327
+ } catch (error) {
328
+ console.warn(`Failed to read config for ${defaultName}:`, error.message);
329
+ }
330
+
331
+ return moduleInfo;
332
+ }
333
+
334
+ /**
335
+ * Find the source path for a module by searching all possible locations
336
+ * @param {string} moduleName - Name of the module to find
337
+ * @returns {string|null} Path to the module source or null if not found
338
+ */
339
+ async findModuleSource(moduleName) {
340
+ const projectRoot = getProjectRoot();
341
+
342
+ // First, check src/modules
343
+ const srcModulePath = path.join(this.modulesSourcePath, moduleName);
344
+ if (await fs.pathExists(srcModulePath)) {
345
+ // Check if this looks like a module (has module.yaml)
346
+ const moduleConfigPath = path.join(srcModulePath, 'module.yaml');
347
+ const installerConfigPath = path.join(srcModulePath, '_module-installer', 'module.yaml');
348
+
349
+ if ((await fs.pathExists(moduleConfigPath)) || (await fs.pathExists(installerConfigPath))) {
350
+ return srcModulePath;
351
+ }
146
352
 
147
- modules.push(moduleInfo);
353
+ // Also check for custom.yaml in src/modules/_module-installer
354
+ const customConfigPath = path.join(srcModulePath, '_module-installer', 'custom.yaml');
355
+ if (await fs.pathExists(customConfigPath)) {
356
+ return srcModulePath;
148
357
  }
149
358
  }
150
359
 
151
- return modules;
360
+ // If not found in src/modules, search the entire project
361
+ const allModulePaths = await this.findModulesInProject();
362
+ for (const modulePath of allModulePaths) {
363
+ if (path.basename(modulePath) === moduleName) {
364
+ return modulePath;
365
+ }
366
+ }
367
+
368
+ // Also check by module ID (not just folder name)
369
+ // Need to read configs to match by ID
370
+ for (const modulePath of allModulePaths) {
371
+ const moduleConfigPath = path.join(modulePath, 'module.yaml');
372
+ const installerConfigPath = path.join(modulePath, '_module-installer', 'module.yaml');
373
+ const customConfigPath = path.join(modulePath, '_module-installer', 'custom.yaml');
374
+ const rootCustomConfigPath = path.join(modulePath, 'custom.yaml');
375
+
376
+ let configPath = null;
377
+ if (await fs.pathExists(moduleConfigPath)) {
378
+ configPath = moduleConfigPath;
379
+ } else if (await fs.pathExists(installerConfigPath)) {
380
+ configPath = installerConfigPath;
381
+ } else if (await fs.pathExists(customConfigPath)) {
382
+ configPath = customConfigPath;
383
+ } else if (await fs.pathExists(rootCustomConfigPath)) {
384
+ configPath = rootCustomConfigPath;
385
+ }
386
+
387
+ if (configPath) {
388
+ try {
389
+ const configContent = await fs.readFile(configPath, 'utf8');
390
+ const config = yaml.load(configContent);
391
+ if (config.code === moduleName) {
392
+ return modulePath;
393
+ }
394
+ } catch {
395
+ // Skip if can't read config
396
+ }
397
+ }
398
+ }
399
+
400
+ return null;
152
401
  }
153
402
 
154
403
  /**
@@ -162,12 +411,41 @@ class ModuleManager {
162
411
  * @param {Object} options.logger - Logger instance for output
163
412
  */
164
413
  async install(moduleName, bmadDir, fileTrackingCallback = null, options = {}) {
165
- const sourcePath = path.join(this.modulesSourcePath, moduleName);
414
+ const sourcePath = await this.findModuleSource(moduleName);
166
415
  const targetPath = path.join(bmadDir, moduleName);
167
416
 
168
417
  // Check if source module exists
169
- if (!(await fs.pathExists(sourcePath))) {
170
- throw new Error(`Module '${moduleName}' not found in ${this.modulesSourcePath}`);
418
+ if (!sourcePath) {
419
+ throw new Error(`Module '${moduleName}' not found in any source location`);
420
+ }
421
+
422
+ // Check if this is a custom module and read its custom.yaml values
423
+ let customConfig = null;
424
+ const rootCustomConfigPath = path.join(sourcePath, 'custom.yaml');
425
+ const moduleInstallerCustomPath = path.join(sourcePath, '_module-installer', 'custom.yaml');
426
+
427
+ if (await fs.pathExists(rootCustomConfigPath)) {
428
+ try {
429
+ const customContent = await fs.readFile(rootCustomConfigPath, 'utf8');
430
+ customConfig = yaml.load(customContent);
431
+ } catch (error) {
432
+ console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
433
+ }
434
+ } else if (await fs.pathExists(moduleInstallerCustomPath)) {
435
+ try {
436
+ const customContent = await fs.readFile(moduleInstallerCustomPath, 'utf8');
437
+ customConfig = yaml.load(customContent);
438
+ } catch (error) {
439
+ console.warn(chalk.yellow(`Warning: Failed to read custom.yaml for ${moduleName}:`, error.message));
440
+ }
441
+ }
442
+
443
+ // If this is a custom module, merge its values into the module config
444
+ if (customConfig) {
445
+ options.moduleConfig = { ...options.moduleConfig, ...customConfig };
446
+ if (options.logger) {
447
+ options.logger.log(chalk.cyan(` Merged custom configuration for ${moduleName}`));
448
+ }
171
449
  }
172
450
 
173
451
  // Check if already installed
@@ -183,6 +461,9 @@ class ModuleManager {
183
461
  // Copy module files with filtering
184
462
  await this.copyModuleWithFiltering(sourcePath, targetPath, fileTrackingCallback, options.moduleConfig);
185
463
 
464
+ // Compile any .agent.yaml files to .md format
465
+ await this.compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir);
466
+
186
467
  // Process agent files to inject activation block
187
468
  await this.processAgentFiles(targetPath, moduleName);
188
469
 
@@ -205,12 +486,12 @@ class ModuleManager {
205
486
  * @param {boolean} force - Force update (overwrite modifications)
206
487
  */
207
488
  async update(moduleName, bmadDir, force = false) {
208
- const sourcePath = path.join(this.modulesSourcePath, moduleName);
489
+ const sourcePath = await this.findModuleSource(moduleName);
209
490
  const targetPath = path.join(bmadDir, moduleName);
210
491
 
211
492
  // Check if source module exists
212
- if (!(await fs.pathExists(sourcePath))) {
213
- throw new Error(`Module '${moduleName}' not found in source`);
493
+ if (!sourcePath) {
494
+ throw new Error(`Module '${moduleName}' not found in any source location`);
214
495
  }
215
496
 
216
497
  // Check if module is installed
@@ -325,13 +606,29 @@ class ModuleManager {
325
606
  continue;
326
607
  }
327
608
 
609
+ // Skip sidecar directories - they are handled separately during agent compilation
610
+ if (
611
+ path
612
+ .dirname(file)
613
+ .split('/')
614
+ .some((dir) => dir.toLowerCase().includes('sidecar'))
615
+ ) {
616
+ continue;
617
+ }
618
+
328
619
  // Skip _module-installer directory - it's only needed at install time
329
- if (file.startsWith('_module-installer/')) {
620
+ if (file.startsWith('_module-installer/') || file === 'module.yaml') {
330
621
  continue;
331
622
  }
332
623
 
333
624
  // Skip config.yaml templates - we'll generate clean ones with actual values
334
- if (file === 'config.yaml' || file.endsWith('/config.yaml')) {
625
+ // Also skip custom.yaml files - their values will be merged into core config
626
+ if (file === 'config.yaml' || file.endsWith('/config.yaml') || file === 'custom.yaml' || file.endsWith('/custom.yaml')) {
627
+ continue;
628
+ }
629
+
630
+ // Skip .agent.yaml files - they will be compiled separately
631
+ if (file.endsWith('.agent.yaml')) {
335
632
  continue;
336
633
  }
337
634
 
@@ -396,8 +693,9 @@ class ModuleManager {
396
693
  // Read the source YAML file
397
694
  let yamlContent = await fs.readFile(sourceFile, 'utf8');
398
695
 
399
- // IMPORTANT: Replace {bmad_folder} BEFORE parsing YAML
696
+ // IMPORTANT: Replace escape sequence and placeholder BEFORE parsing YAML
400
697
  // Otherwise parsing will fail on the placeholder
698
+ yamlContent = yamlContent.replaceAll('{*bmad_folder*}', '{bmad_folder}');
401
699
  yamlContent = yamlContent.replaceAll('{bmad_folder}', this.bmadFolderName);
402
700
 
403
701
  try {
@@ -476,6 +774,157 @@ class ModuleManager {
476
774
  }
477
775
  }
478
776
 
777
+ /**
778
+ * Compile .agent.yaml files to .md format in modules
779
+ * @param {string} sourcePath - Source module path
780
+ * @param {string} targetPath - Target module path
781
+ * @param {string} moduleName - Module name
782
+ * @param {string} bmadDir - BMAD installation directory
783
+ */
784
+ async compileModuleAgents(sourcePath, targetPath, moduleName, bmadDir) {
785
+ const sourceAgentsPath = path.join(sourcePath, 'agents');
786
+ const targetAgentsPath = path.join(targetPath, 'agents');
787
+ const cfgAgentsDir = path.join(bmadDir, '_cfg', 'agents');
788
+
789
+ // Check if agents directory exists in source
790
+ if (!(await fs.pathExists(sourceAgentsPath))) {
791
+ return; // No agents to compile
792
+ }
793
+
794
+ // Get all agent YAML files recursively
795
+ const agentFiles = await this.findAgentFiles(sourceAgentsPath);
796
+
797
+ for (const agentFile of agentFiles) {
798
+ if (!agentFile.endsWith('.agent.yaml')) continue;
799
+
800
+ const relativePath = path.relative(sourceAgentsPath, agentFile);
801
+ const targetDir = path.join(targetAgentsPath, path.dirname(relativePath));
802
+
803
+ await fs.ensureDir(targetDir);
804
+
805
+ const agentName = path.basename(agentFile, '.agent.yaml');
806
+ const sourceYamlPath = agentFile;
807
+ const targetMdPath = path.join(targetDir, `${agentName}.md`);
808
+ const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
809
+
810
+ // Read and compile the YAML
811
+ try {
812
+ const yamlContent = await fs.readFile(sourceYamlPath, 'utf8');
813
+ const { compileAgent } = require('../../../lib/agent/compiler');
814
+
815
+ // Create customize template if it doesn't exist
816
+ if (!(await fs.pathExists(customizePath))) {
817
+ const { getSourcePath } = require('../../../lib/project-root');
818
+ const genericTemplatePath = getSourcePath('utility', 'templates', 'agent.customize.template.yaml');
819
+ if (await fs.pathExists(genericTemplatePath)) {
820
+ await this.copyFileWithPlaceholderReplacement(genericTemplatePath, customizePath);
821
+ console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`));
822
+ }
823
+ }
824
+
825
+ // Check for customizations
826
+ let customizedFields = [];
827
+ if (await fs.pathExists(customizePath)) {
828
+ const customizeContent = await fs.readFile(customizePath, 'utf8');
829
+ const customizeData = yaml.load(customizeContent);
830
+ customizedFields = customizeData.customized_fields || [];
831
+ }
832
+
833
+ // Load core config to get agent_sidecar_folder
834
+ const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml');
835
+ let coreConfig = {};
836
+
837
+ if (await fs.pathExists(coreConfigPath)) {
838
+ const yamlLib = require('yaml');
839
+ const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
840
+ coreConfig = yamlLib.parse(coreConfigContent);
841
+ }
842
+
843
+ // Check if agent has sidecar
844
+ let hasSidecar = false;
845
+ try {
846
+ const yamlLib = require('yaml');
847
+ const agentYaml = yamlLib.parse(yamlContent);
848
+ hasSidecar = agentYaml?.agent?.metadata?.hasSidecar === true;
849
+ } catch {
850
+ // Continue without sidecar processing
851
+ }
852
+
853
+ // Compile with customizations if any
854
+ const { xml } = compileAgent(yamlContent, {}, agentName, relativePath, { config: this.coreConfig });
855
+
856
+ // Replace {bmad_folder} placeholder if needed
857
+ if (xml.includes('{bmad_folder}') && this.bmadFolderName) {
858
+ const processedXml = xml.replaceAll('{bmad_folder}', this.bmadFolderName);
859
+ await fs.writeFile(targetMdPath, processedXml, 'utf8');
860
+ } else {
861
+ await fs.writeFile(targetMdPath, xml, 'utf8');
862
+ }
863
+
864
+ // Copy sidecar files if agent has hasSidecar flag
865
+ if (hasSidecar) {
866
+ const { copyAgentSidecarFiles } = require('../../../lib/agent/installer');
867
+
868
+ // Get agent sidecar folder from core config (should always be set)
869
+ const agentSidecarFolder = this.coreConfig?.agent_sidecar_folder;
870
+
871
+ // Resolve path variables
872
+ const projectDir = path.dirname(bmadDir);
873
+ const resolvedSidecarFolder = agentSidecarFolder
874
+ .replaceAll('{project-root}', projectDir)
875
+ .replaceAll('{bmad_folder}', path.basename(bmadDir));
876
+
877
+ // Create sidecar directory for this agent
878
+ const agentSidecarDir = path.join(resolvedSidecarFolder, agentName);
879
+ await fs.ensureDir(agentSidecarDir);
880
+
881
+ // Copy sidecar files (preserve existing, add new)
882
+ const sidecarResult = copyAgentSidecarFiles(path.dirname(sourceYamlPath), agentSidecarDir, sourceYamlPath);
883
+ const totalFiles = sidecarResult.copied.length + sidecarResult.preserved.length;
884
+
885
+ if (sidecarResult.copied.length > 0) {
886
+ console.log(chalk.dim(` Copied ${sidecarResult.copied.length} new sidecar file(s) to: ${agentSidecarDir}`));
887
+ }
888
+ if (sidecarResult.preserved.length > 0) {
889
+ console.log(chalk.dim(` Preserved ${sidecarResult.preserved.length} existing sidecar file(s)`));
890
+ }
891
+ }
892
+
893
+ console.log(
894
+ chalk.dim(` Compiled agent: ${agentName} -> ${path.relative(targetPath, targetMdPath)}${hasSidecar ? ' (with sidecar)' : ''}`),
895
+ );
896
+ } catch (error) {
897
+ console.warn(chalk.yellow(` Failed to compile agent ${agentName}:`, error.message));
898
+ }
899
+ }
900
+ }
901
+
902
+ /**
903
+ * Find all .agent.yaml files recursively in a directory
904
+ * @param {string} dir - Directory to search
905
+ * @returns {Array} List of .agent.yaml file paths
906
+ */
907
+ async findAgentFiles(dir) {
908
+ const agentFiles = [];
909
+
910
+ async function searchDirectory(searchDir) {
911
+ const entries = await fs.readdir(searchDir, { withFileTypes: true });
912
+
913
+ for (const entry of entries) {
914
+ const fullPath = path.join(searchDir, entry.name);
915
+
916
+ if (entry.isFile() && entry.name.endsWith('.agent.yaml')) {
917
+ agentFiles.push(fullPath);
918
+ } else if (entry.isDirectory()) {
919
+ await searchDirectory(fullPath);
920
+ }
921
+ }
922
+ }
923
+
924
+ await searchDirectory(dir);
925
+ return agentFiles;
926
+ }
927
+
479
928
  /**
480
929
  * Process agent files to inject activation block
481
930
  * @param {string} modulePath - Path to installed module
@@ -489,24 +938,49 @@ class ModuleManager {
489
938
  return; // No agents to process
490
939
  }
491
940
 
492
- // Get all agent files
493
- const agentFiles = await fs.readdir(agentsPath);
941
+ // Get all agent MD files recursively
942
+ const agentFiles = await this.findAgentMdFiles(agentsPath);
494
943
 
495
944
  for (const agentFile of agentFiles) {
496
945
  if (!agentFile.endsWith('.md')) continue;
497
946
 
498
- const agentPath = path.join(agentsPath, agentFile);
499
- let content = await fs.readFile(agentPath, 'utf8');
947
+ let content = await fs.readFile(agentFile, 'utf8');
500
948
 
501
949
  // Check if content has agent XML and no activation block
502
950
  if (content.includes('<agent') && !content.includes('<activation')) {
503
951
  // Inject the activation block using XML handler
504
952
  content = this.xmlHandler.injectActivationSimple(content);
505
- await fs.writeFile(agentPath, content, 'utf8');
953
+ await fs.writeFile(agentFile, content, 'utf8');
506
954
  }
507
955
  }
508
956
  }
509
957
 
958
+ /**
959
+ * Find all .md agent files recursively in a directory
960
+ * @param {string} dir - Directory to search
961
+ * @returns {Array} List of .md agent file paths
962
+ */
963
+ async findAgentMdFiles(dir) {
964
+ const agentFiles = [];
965
+
966
+ async function searchDirectory(searchDir) {
967
+ const entries = await fs.readdir(searchDir, { withFileTypes: true });
968
+
969
+ for (const entry of entries) {
970
+ const fullPath = path.join(searchDir, entry.name);
971
+
972
+ if (entry.isFile() && entry.name.endsWith('.md')) {
973
+ agentFiles.push(fullPath);
974
+ } else if (entry.isDirectory()) {
975
+ await searchDirectory(fullPath);
976
+ }
977
+ }
978
+ }
979
+
980
+ await searchDirectory(dir);
981
+ return agentFiles;
982
+ }
983
+
510
984
  /**
511
985
  * Vendor cross-module workflows referenced in agent files
512
986
  * Scans SOURCE agent.yaml files for workflow-install and copies workflows to destination
@@ -648,7 +1122,11 @@ class ModuleManager {
648
1122
  if (moduleName === 'core') {
649
1123
  sourcePath = getSourcePath('core');
650
1124
  } else {
651
- sourcePath = path.join(this.modulesSourcePath, moduleName);
1125
+ sourcePath = await this.findModuleSource(moduleName);
1126
+ if (!sourcePath) {
1127
+ // No source found, skip module installer
1128
+ return;
1129
+ }
652
1130
  }
653
1131
 
654
1132
  const installerPath = path.join(sourcePath, '_module-installer', 'installer.js');
@@ -677,6 +1155,7 @@ class ModuleManager {
677
1155
  const result = await moduleInstaller.install({
678
1156
  projectRoot,
679
1157
  config: options.moduleConfig || {},
1158
+ coreConfig: options.coreConfig || {},
680
1159
  installedIDEs: options.installedIDEs || [],
681
1160
  logger,
682
1161
  });