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

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