bmad-method 5.1.3 → 6.0.0-Beta.0

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 (739) hide show
  1. package/.coderabbit.yaml +40 -0
  2. package/.github/CODE_OF_CONDUCT.md +128 -0
  3. package/.github/FUNDING.yaml +2 -2
  4. package/.github/ISSUE_TEMPLATE/config.yaml +8 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +11 -11
  6. package/.github/ISSUE_TEMPLATE/issue.md +32 -0
  7. package/.github/scripts/discord-helpers.sh +34 -0
  8. package/.github/workflows/discord.yaml +82 -17
  9. package/.github/workflows/docs.yaml +63 -0
  10. package/.github/workflows/manual-release.yaml +40 -20
  11. package/.github/workflows/quality.yaml +115 -0
  12. package/.husky/pre-commit +17 -0
  13. package/.markdownlint-cli2.yaml +41 -0
  14. package/.nvmrc +1 -0
  15. package/.prettierignore +9 -0
  16. package/.vscode/settings.json +38 -10
  17. package/CHANGELOG.md +1167 -372
  18. package/CNAME +1 -0
  19. package/CONTRIBUTING.md +100 -142
  20. package/CONTRIBUTORS.md +32 -0
  21. package/LICENSE +10 -1
  22. package/README.md +67 -170
  23. package/SECURITY.md +85 -0
  24. package/TRADEMARK.md +55 -0
  25. package/Wordmark.png +0 -0
  26. package/banner-bmad-method.png +0 -0
  27. package/docs/404.md +9 -0
  28. package/docs/_STYLE_GUIDE.md +367 -0
  29. package/docs/downloads.md +74 -0
  30. package/docs/explanation/advanced-elicitation.md +24 -0
  31. package/docs/explanation/adversarial-review.md +57 -0
  32. package/docs/explanation/brainstorming.md +31 -0
  33. package/docs/explanation/brownfield-faq.md +55 -0
  34. package/docs/explanation/party-mode.md +57 -0
  35. package/docs/explanation/preventing-agent-conflicts.md +110 -0
  36. package/docs/explanation/quick-flow.md +27 -0
  37. package/docs/explanation/why-solutioning-matters.md +75 -0
  38. package/docs/how-to/brownfield/index.md +84 -0
  39. package/docs/how-to/brownfield/quick-fix-in-brownfield.md +76 -0
  40. package/docs/how-to/customize-bmad.md +158 -0
  41. package/docs/how-to/get-answers-about-bmad.md +102 -0
  42. package/docs/how-to/install-bmad.md +82 -0
  43. package/docs/how-to/shard-large-documents.md +101 -0
  44. package/docs/how-to/upgrade-to-v6.md +131 -0
  45. package/docs/index.md +56 -0
  46. package/docs/reference/workflow-map.md +83 -0
  47. package/docs/tea/explanation/engagement-models.md +710 -0
  48. package/docs/tea/explanation/fixture-architecture.md +457 -0
  49. package/docs/tea/explanation/knowledge-base-system.md +554 -0
  50. package/docs/tea/explanation/network-first-patterns.md +853 -0
  51. package/docs/tea/explanation/risk-based-testing.md +586 -0
  52. package/docs/tea/explanation/tea-overview.md +410 -0
  53. package/docs/tea/explanation/test-quality-standards.md +907 -0
  54. package/docs/tea/explanation/testing-as-engineering.md +112 -0
  55. package/docs/tea/glossary/index.md +159 -0
  56. package/docs/tea/how-to/brownfield/use-tea-for-enterprise.md +525 -0
  57. package/docs/tea/how-to/brownfield/use-tea-with-existing-tests.md +577 -0
  58. package/docs/tea/how-to/customization/enable-tea-mcp-enhancements.md +424 -0
  59. package/docs/tea/how-to/customization/integrate-playwright-utils.md +813 -0
  60. package/docs/tea/how-to/workflows/run-atdd.md +436 -0
  61. package/docs/tea/how-to/workflows/run-automate.md +653 -0
  62. package/docs/tea/how-to/workflows/run-nfr-assess.md +679 -0
  63. package/docs/tea/how-to/workflows/run-test-design.md +135 -0
  64. package/docs/tea/how-to/workflows/run-test-review.md +605 -0
  65. package/docs/tea/how-to/workflows/run-trace.md +883 -0
  66. package/docs/tea/how-to/workflows/setup-ci.md +712 -0
  67. package/docs/tea/how-to/workflows/setup-test-framework.md +98 -0
  68. package/docs/tea/reference/commands.md +276 -0
  69. package/docs/tea/reference/configuration.md +678 -0
  70. package/docs/tea/reference/knowledge-base.md +340 -0
  71. package/docs/tea/tutorials/tea-lite-quickstart.md +444 -0
  72. package/docs/tutorials/getting-started.md +205 -0
  73. package/eslint.config.mjs +42 -9
  74. package/package.json +50 -38
  75. package/prettier.config.mjs +1 -1
  76. package/src/bmm/_module-installer/installer.js +48 -0
  77. package/src/bmm/agents/analyst.agent.yaml +36 -0
  78. package/src/bmm/agents/architect.agent.yaml +28 -0
  79. package/src/bmm/agents/dev.agent.yaml +38 -0
  80. package/src/bmm/agents/pm.agent.yaml +46 -0
  81. package/src/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -0
  82. package/src/bmm/agents/sm.agent.yaml +36 -0
  83. package/src/bmm/agents/tea.agent.yaml +63 -0
  84. package/src/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
  85. package/src/bmm/agents/tech-writer/tech-writer.agent.yaml +45 -0
  86. package/src/bmm/agents/ux-designer.agent.yaml +26 -0
  87. package/src/bmm/data/project-context-template.md +26 -0
  88. package/src/bmm/module-help.csv +32 -0
  89. package/src/bmm/module.yaml +44 -0
  90. package/src/bmm/teams/default-party.csv +21 -0
  91. package/src/bmm/teams/team-fullstack.yaml +12 -0
  92. package/src/bmm/testarch/knowledge/adr-quality-readiness-checklist.md +350 -0
  93. package/src/bmm/testarch/knowledge/api-request.md +442 -0
  94. package/src/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
  95. package/src/bmm/testarch/knowledge/auth-session.md +552 -0
  96. package/src/bmm/testarch/knowledge/burn-in.md +273 -0
  97. package/src/bmm/testarch/knowledge/ci-burn-in.md +675 -0
  98. package/src/bmm/testarch/knowledge/component-tdd.md +486 -0
  99. package/src/bmm/testarch/knowledge/contract-testing.md +957 -0
  100. package/src/bmm/testarch/knowledge/data-factories.md +500 -0
  101. package/src/bmm/testarch/knowledge/email-auth.md +721 -0
  102. package/src/bmm/testarch/knowledge/error-handling.md +725 -0
  103. package/src/bmm/testarch/knowledge/feature-flags.md +750 -0
  104. package/src/bmm/testarch/knowledge/file-utils.md +463 -0
  105. package/src/bmm/testarch/knowledge/fixture-architecture.md +401 -0
  106. package/src/bmm/testarch/knowledge/fixtures-composition.md +382 -0
  107. package/src/bmm/testarch/knowledge/intercept-network-call.md +430 -0
  108. package/src/bmm/testarch/knowledge/log.md +429 -0
  109. package/src/bmm/testarch/knowledge/network-error-monitor.md +405 -0
  110. package/src/bmm/testarch/knowledge/network-first.md +486 -0
  111. package/src/bmm/testarch/knowledge/network-recorder.md +527 -0
  112. package/src/bmm/testarch/knowledge/nfr-criteria.md +670 -0
  113. package/src/bmm/testarch/knowledge/overview.md +286 -0
  114. package/src/bmm/testarch/knowledge/playwright-config.md +730 -0
  115. package/src/bmm/testarch/knowledge/probability-impact.md +601 -0
  116. package/src/bmm/testarch/knowledge/recurse.md +421 -0
  117. package/src/bmm/testarch/knowledge/risk-governance.md +615 -0
  118. package/src/bmm/testarch/knowledge/selective-testing.md +732 -0
  119. package/src/bmm/testarch/knowledge/selector-resilience.md +527 -0
  120. package/src/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
  121. package/src/bmm/testarch/knowledge/test-levels-framework.md +473 -0
  122. package/src/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
  123. package/src/bmm/testarch/knowledge/test-quality.md +664 -0
  124. package/src/bmm/testarch/knowledge/timing-debugging.md +372 -0
  125. package/src/bmm/testarch/knowledge/visual-debugging.md +524 -0
  126. package/src/bmm/testarch/tea-index.csv +35 -0
  127. package/src/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
  128. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
  129. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
  130. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
  131. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
  132. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
  133. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
  134. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
  135. package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
  136. package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
  137. package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
  138. package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
  139. package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
  140. package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
  141. package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
  142. package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
  143. package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
  144. package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
  145. package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
  146. package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
  147. package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
  148. package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
  149. package/src/bmm/workflows/1-analysis/research/research.template.md +29 -0
  150. package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
  151. package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
  152. package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
  153. package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
  154. package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
  155. package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
  156. package/src/bmm/workflows/1-analysis/research/workflow.md +173 -0
  157. package/src/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +13 -0
  158. package/src/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
  159. package/src/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
  160. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +191 -0
  161. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +153 -0
  162. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +224 -0
  163. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +226 -0
  164. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +213 -0
  165. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +207 -0
  166. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +226 -0
  167. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +237 -0
  168. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +228 -0
  169. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +231 -0
  170. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +242 -0
  171. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +217 -0
  172. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +124 -0
  173. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +247 -0
  174. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
  175. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +249 -0
  176. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +253 -0
  177. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +168 -0
  178. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +218 -0
  179. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
  180. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
  181. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
  182. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
  183. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
  184. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
  185. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
  186. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
  187. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
  188. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
  189. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
  190. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
  191. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +231 -0
  192. package/src/bmm/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -0
  193. package/src/bmm/workflows/2-plan-workflows/create-prd/validation-report-prd-workflow.md +433 -0
  194. package/src/bmm/workflows/2-plan-workflows/create-prd/workflow.md +150 -0
  195. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
  196. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
  197. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
  198. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
  199. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
  200. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
  201. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
  202. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
  203. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
  204. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
  205. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
  206. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
  207. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
  208. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
  209. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
  210. package/src/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
  211. package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
  212. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
  213. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
  214. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
  215. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
  216. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
  217. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +135 -0
  218. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
  219. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
  220. package/src/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
  221. package/src/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
  222. package/src/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
  223. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
  224. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
  225. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
  226. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
  227. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
  228. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
  229. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
  230. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
  231. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
  232. package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
  233. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
  234. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
  235. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
  236. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
  237. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
  238. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
  239. package/src/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
  240. package/src/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
  241. package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +51 -0
  242. package/src/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
  243. package/src/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
  244. package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +60 -0
  245. package/src/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
  246. package/src/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
  247. package/src/bmm/workflows/4-implementation/create-story/template.md +49 -0
  248. package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +61 -0
  249. package/src/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
  250. package/src/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
  251. package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +27 -0
  252. package/src/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
  253. package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +58 -0
  254. package/src/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
  255. package/src/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
  256. package/src/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
  257. package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +54 -0
  258. package/src/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
  259. package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
  260. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +176 -0
  261. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
  262. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
  263. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
  264. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
  265. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +149 -0
  266. package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -0
  267. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +192 -0
  268. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +145 -0
  269. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
  270. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -0
  271. package/src/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
  272. package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
  273. package/src/bmm/workflows/document-project/checklist.md +245 -0
  274. package/src/bmm/workflows/document-project/documentation-requirements.csv +12 -0
  275. package/src/bmm/workflows/document-project/instructions.md +221 -0
  276. package/src/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
  277. package/src/bmm/workflows/document-project/templates/index-template.md +169 -0
  278. package/src/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
  279. package/src/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
  280. package/src/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
  281. package/src/bmm/workflows/document-project/workflow.yaml +30 -0
  282. package/src/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
  283. package/src/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
  284. package/src/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
  285. package/src/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
  286. package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
  287. package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
  288. package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
  289. package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
  290. package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
  291. package/src/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
  292. package/src/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
  293. package/src/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
  294. package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
  295. package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
  296. package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
  297. package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
  298. package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
  299. package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
  300. package/src/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
  301. package/src/bmm/workflows/testarch/atdd/checklist.md +374 -0
  302. package/src/bmm/workflows/testarch/atdd/instructions.md +806 -0
  303. package/src/bmm/workflows/testarch/atdd/workflow.yaml +47 -0
  304. package/src/bmm/workflows/testarch/automate/checklist.md +582 -0
  305. package/src/bmm/workflows/testarch/automate/instructions.md +1324 -0
  306. package/src/bmm/workflows/testarch/automate/workflow.yaml +54 -0
  307. package/src/bmm/workflows/testarch/ci/checklist.md +247 -0
  308. package/src/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
  309. package/src/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
  310. package/src/bmm/workflows/testarch/ci/instructions.md +536 -0
  311. package/src/bmm/workflows/testarch/ci/workflow.yaml +47 -0
  312. package/src/bmm/workflows/testarch/framework/checklist.md +320 -0
  313. package/src/bmm/workflows/testarch/framework/instructions.md +481 -0
  314. package/src/bmm/workflows/testarch/framework/workflow.yaml +49 -0
  315. package/src/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
  316. package/src/bmm/workflows/testarch/nfr-assess/instructions.md +726 -0
  317. package/src/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +461 -0
  318. package/src/bmm/workflows/testarch/nfr-assess/workflow.yaml +49 -0
  319. package/src/bmm/workflows/testarch/test-design/checklist.md +407 -0
  320. package/src/bmm/workflows/testarch/test-design/instructions.md +1158 -0
  321. package/src/bmm/workflows/testarch/test-design/test-design-architecture-template.md +213 -0
  322. package/src/bmm/workflows/testarch/test-design/test-design-qa-template.md +286 -0
  323. package/src/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
  324. package/src/bmm/workflows/testarch/test-design/workflow.yaml +71 -0
  325. package/src/bmm/workflows/testarch/test-review/checklist.md +472 -0
  326. package/src/bmm/workflows/testarch/test-review/instructions.md +628 -0
  327. package/src/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
  328. package/src/bmm/workflows/testarch/test-review/workflow.yaml +48 -0
  329. package/src/bmm/workflows/testarch/trace/checklist.md +642 -0
  330. package/src/bmm/workflows/testarch/trace/instructions.md +1030 -0
  331. package/src/bmm/workflows/testarch/trace/trace-template.md +675 -0
  332. package/src/bmm/workflows/testarch/trace/workflow.yaml +57 -0
  333. package/src/core/_module-installer/installer.js +60 -0
  334. package/src/core/agents/bmad-master.agent.yaml +29 -0
  335. package/src/core/module-help.csv +9 -0
  336. package/src/core/module.yaml +25 -0
  337. package/src/core/resources/excalidraw/README.md +160 -0
  338. package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
  339. package/src/core/resources/excalidraw/library-loader.md +50 -0
  340. package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
  341. package/src/core/tasks/editorial-review-prose.xml +100 -0
  342. package/src/core/tasks/editorial-review-structure.xml +209 -0
  343. package/src/core/tasks/help.md +62 -0
  344. package/src/core/tasks/index-docs.xml +65 -0
  345. package/src/core/tasks/review-adversarial-general.xml +48 -0
  346. package/src/core/tasks/shard-doc.xml +109 -0
  347. package/src/core/tasks/workflow.xml +235 -0
  348. package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
  349. package/src/core/workflows/advanced-elicitation/workflow.xml +117 -0
  350. package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
  351. package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
  352. package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
  353. package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
  354. package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
  355. package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
  356. package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
  357. package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
  358. package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
  359. package/src/core/workflows/brainstorming/template.md +15 -0
  360. package/src/core/workflows/brainstorming/workflow.md +58 -0
  361. package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
  362. package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
  363. package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
  364. package/src/core/workflows/party-mode/workflow.md +194 -0
  365. package/src/utility/agent-components/activation-rules.txt +6 -0
  366. package/src/utility/agent-components/activation-steps.txt +14 -0
  367. package/src/utility/agent-components/agent-command-header.md +1 -0
  368. package/src/utility/agent-components/agent.customize.template.yaml +41 -0
  369. package/src/utility/agent-components/handler-action.txt +4 -0
  370. package/src/utility/agent-components/handler-data.txt +5 -0
  371. package/src/utility/agent-components/handler-exec.txt +6 -0
  372. package/src/utility/agent-components/handler-multi.txt +14 -0
  373. package/src/utility/agent-components/handler-tmpl.txt +5 -0
  374. package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
  375. package/src/utility/agent-components/handler-workflow.txt +10 -0
  376. package/src/utility/agent-components/menu-handlers.txt +6 -0
  377. package/test/README.md +295 -0
  378. package/test/adversarial-review-tests/README.md +56 -0
  379. package/test/adversarial-review-tests/sample-content.md +46 -0
  380. package/test/adversarial-review-tests/test-cases.yaml +103 -0
  381. package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
  382. package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
  383. package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
  384. package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
  385. package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
  386. package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
  387. package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
  388. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
  389. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
  390. package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
  391. package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
  392. package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
  393. package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
  394. package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
  395. package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
  396. package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
  397. package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
  398. package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
  399. package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
  400. package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
  401. package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
  402. package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
  403. package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
  404. package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
  405. package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
  406. package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
  407. package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
  408. package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
  409. package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
  410. package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
  411. package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
  412. package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
  413. package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
  414. package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
  415. package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
  416. package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
  417. package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
  418. package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +24 -0
  419. package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
  420. package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
  421. package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
  422. package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
  423. package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
  424. package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
  425. package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
  426. package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
  427. package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
  428. package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
  429. package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
  430. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
  431. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
  432. package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
  433. package/test/test-agent-schema.js +387 -0
  434. package/test/test-cli-integration.sh +159 -0
  435. package/test/test-installation-components.js +214 -0
  436. package/test/unit-test-schema.js +133 -0
  437. package/tools/bmad-npx-wrapper.js +11 -12
  438. package/tools/build-docs.js +577 -0
  439. package/tools/cli/README.md +7 -0
  440. package/tools/cli/bmad-cli.js +58 -0
  441. package/tools/cli/commands/install.js +87 -0
  442. package/tools/cli/commands/status.js +65 -0
  443. package/tools/cli/external-official-modules.yaml +44 -0
  444. package/tools/cli/installers/install-messages.yaml +58 -0
  445. package/tools/cli/installers/lib/core/config-collector.js +1079 -0
  446. package/tools/cli/installers/lib/core/custom-module-cache.js +259 -0
  447. package/tools/cli/installers/lib/core/dependency-resolver.js +739 -0
  448. package/tools/cli/installers/lib/core/detector.js +223 -0
  449. package/tools/cli/installers/lib/core/ide-config-manager.js +156 -0
  450. package/tools/cli/installers/lib/core/installer.js +2826 -0
  451. package/tools/cli/installers/lib/core/manifest-generator.js +1054 -0
  452. package/tools/cli/installers/lib/core/manifest.js +1036 -0
  453. package/tools/cli/installers/lib/custom/handler.js +363 -0
  454. package/tools/cli/installers/lib/ide/STANDARDIZATION_PLAN.md +208 -0
  455. package/tools/cli/installers/lib/ide/_base-ide.js +655 -0
  456. package/tools/cli/installers/lib/ide/antigravity.js +474 -0
  457. package/tools/cli/installers/lib/ide/auggie.js +244 -0
  458. package/tools/cli/installers/lib/ide/claude-code.js +506 -0
  459. package/tools/cli/installers/lib/ide/cline.js +272 -0
  460. package/tools/cli/installers/lib/ide/codex.js +412 -0
  461. package/tools/cli/installers/lib/ide/crush.js +149 -0
  462. package/tools/cli/installers/lib/ide/cursor.js +160 -0
  463. package/tools/cli/installers/lib/ide/gemini.js +301 -0
  464. package/tools/cli/installers/lib/ide/github-copilot.js +383 -0
  465. package/tools/cli/installers/lib/ide/iflow.js +191 -0
  466. package/tools/cli/installers/lib/ide/kilo.js +250 -0
  467. package/tools/cli/installers/lib/ide/kiro-cli.js +326 -0
  468. package/tools/cli/installers/lib/ide/manager.js +244 -0
  469. package/tools/cli/installers/lib/ide/opencode.js +257 -0
  470. package/tools/cli/installers/lib/ide/qwen.js +372 -0
  471. package/tools/cli/installers/lib/ide/roo.js +273 -0
  472. package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
  473. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +165 -0
  474. package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +158 -0
  475. package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
  476. package/tools/cli/installers/lib/ide/shared/path-utils.js +165 -0
  477. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +268 -0
  478. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +293 -0
  479. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
  480. package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
  481. package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
  482. package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
  483. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
  484. package/tools/cli/installers/lib/ide/trae.js +313 -0
  485. package/tools/cli/installers/lib/ide/windsurf.js +258 -0
  486. package/tools/cli/installers/lib/message-loader.js +85 -0
  487. package/tools/cli/installers/lib/modules/external-manager.js +135 -0
  488. package/tools/cli/installers/lib/modules/manager.js +1375 -0
  489. package/tools/cli/lib/activation-builder.js +163 -0
  490. package/tools/cli/lib/agent/compiler.js +522 -0
  491. package/tools/cli/lib/agent/installer.js +716 -0
  492. package/tools/cli/lib/agent/template-engine.js +152 -0
  493. package/tools/cli/lib/agent-analyzer.js +109 -0
  494. package/tools/cli/lib/agent-party-generator.js +194 -0
  495. package/tools/cli/lib/cli-utils.js +227 -0
  496. package/tools/cli/lib/config.js +213 -0
  497. package/tools/cli/lib/file-ops.js +204 -0
  498. package/tools/cli/lib/platform-codes.js +116 -0
  499. package/tools/cli/lib/project-root.js +77 -0
  500. package/tools/cli/lib/prompts.js +433 -0
  501. package/tools/cli/lib/ui.js +1716 -0
  502. package/tools/cli/lib/xml-handler.js +177 -0
  503. package/tools/cli/lib/xml-to-markdown.js +82 -0
  504. package/tools/{yaml-format.js → cli/lib/yaml-format.js} +9 -17
  505. package/tools/cli/lib/yaml-xml-builder.js +587 -0
  506. package/tools/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
  507. package/tools/docs/fix-refs.md +91 -0
  508. package/tools/docs/index.md +2 -0
  509. package/tools/fix-doc-links.js +288 -0
  510. package/tools/flattener/ignoreRules.js +2 -6
  511. package/tools/flattener/main.js +31 -121
  512. package/tools/flattener/projectRoot.js +3 -8
  513. package/tools/flattener/stats.helpers.js +8 -35
  514. package/tools/flattener/stats.js +1 -6
  515. package/tools/flattener/test-matrix.js +1 -5
  516. package/tools/flattener/xml.js +1 -7
  517. package/tools/format-workflow-md.js +263 -0
  518. package/tools/lib/xml-utils.js +13 -0
  519. package/tools/maintainer/review-pr-README.md +55 -0
  520. package/tools/maintainer/review-pr.md +242 -0
  521. package/tools/migrate-custom-module-paths.js +124 -0
  522. package/tools/platform-codes.yaml +157 -0
  523. package/tools/schema/agent.js +491 -0
  524. package/tools/validate-agent-schema.js +110 -0
  525. package/tools/validate-doc-links.js +371 -0
  526. package/tools/validate-svg-changes.sh +356 -0
  527. package/website/README.md +76 -0
  528. package/website/_basement/components/WorkflowGuide.astro +444 -0
  529. package/website/_basement/pages/workflow-guide.astro +17 -0
  530. package/website/astro.config.mjs +169 -0
  531. package/website/public/favicon.ico +0 -0
  532. package/website/public/img/bmad-dark.png +0 -0
  533. package/website/public/img/bmad-light.png +0 -0
  534. package/website/public/img/logo.svg +4 -0
  535. package/website/public/img/workflow-map.png +0 -0
  536. package/website/public/robots.txt +37 -0
  537. package/website/public/workflow-map-diagram.html +361 -0
  538. package/website/src/components/Banner.astro +59 -0
  539. package/website/src/components/Header.astro +121 -0
  540. package/website/src/components/MobileMenuFooter.astro +53 -0
  541. package/website/src/content/config.ts +6 -0
  542. package/website/src/lib/site-url.js +25 -0
  543. package/website/src/pages/404.astro +11 -0
  544. package/website/src/rehype-base-paths.js +89 -0
  545. package/website/src/rehype-markdown-links.js +117 -0
  546. package/website/src/styles/custom.css +500 -0
  547. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
  548. package/.github/workflows/format-check.yaml +0 -42
  549. package/bmad-core/agent-teams/team-all.yaml +0 -14
  550. package/bmad-core/agent-teams/team-fullstack.yaml +0 -18
  551. package/bmad-core/agent-teams/team-ide-minimal.yaml +0 -10
  552. package/bmad-core/agent-teams/team-no-ui.yaml +0 -13
  553. package/bmad-core/agents/analyst.md +0 -81
  554. package/bmad-core/agents/architect.md +0 -83
  555. package/bmad-core/agents/bmad-master.md +0 -107
  556. package/bmad-core/agents/bmad-orchestrator.md +0 -149
  557. package/bmad-core/agents/dev.md +0 -75
  558. package/bmad-core/agents/pm.md +0 -81
  559. package/bmad-core/agents/po.md +0 -76
  560. package/bmad-core/agents/qa.md +0 -88
  561. package/bmad-core/agents/sm.md +0 -62
  562. package/bmad-core/agents/ux-expert.md +0 -66
  563. package/bmad-core/checklists/architect-checklist.md +0 -438
  564. package/bmad-core/checklists/change-checklist.md +0 -182
  565. package/bmad-core/checklists/pm-checklist.md +0 -370
  566. package/bmad-core/checklists/po-master-checklist.md +0 -432
  567. package/bmad-core/checklists/story-dod-checklist.md +0 -94
  568. package/bmad-core/checklists/story-draft-checklist.md +0 -153
  569. package/bmad-core/core-config.yaml +0 -20
  570. package/bmad-core/data/bmad-kb.md +0 -806
  571. package/bmad-core/data/brainstorming-techniques.md +0 -36
  572. package/bmad-core/data/elicitation-methods.md +0 -154
  573. package/bmad-core/data/technical-preferences.md +0 -3
  574. package/bmad-core/data/test-levels-framework.md +0 -146
  575. package/bmad-core/data/test-priorities-matrix.md +0 -172
  576. package/bmad-core/tasks/advanced-elicitation.md +0 -117
  577. package/bmad-core/tasks/brownfield-create-epic.md +0 -160
  578. package/bmad-core/tasks/brownfield-create-story.md +0 -147
  579. package/bmad-core/tasks/correct-course.md +0 -70
  580. package/bmad-core/tasks/create-brownfield-story.md +0 -312
  581. package/bmad-core/tasks/create-deep-research-prompt.md +0 -278
  582. package/bmad-core/tasks/create-next-story.md +0 -112
  583. package/bmad-core/tasks/document-project.md +0 -343
  584. package/bmad-core/tasks/facilitate-brainstorming-session.md +0 -136
  585. package/bmad-core/tasks/generate-ai-frontend-prompt.md +0 -51
  586. package/bmad-core/tasks/index-docs.md +0 -173
  587. package/bmad-core/tasks/kb-mode-interaction.md +0 -75
  588. package/bmad-core/tasks/nfr-assess.md +0 -343
  589. package/bmad-core/tasks/qa-gate.md +0 -159
  590. package/bmad-core/tasks/review-story.md +0 -314
  591. package/bmad-core/tasks/risk-profile.md +0 -353
  592. package/bmad-core/tasks/shard-doc.md +0 -185
  593. package/bmad-core/tasks/test-design.md +0 -174
  594. package/bmad-core/tasks/trace-requirements.md +0 -264
  595. package/bmad-core/tasks/validate-next-story.md +0 -134
  596. package/bmad-core/templates/architecture-tmpl.yaml +0 -650
  597. package/bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
  598. package/bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -476
  599. package/bmad-core/templates/brownfield-prd-tmpl.yaml +0 -280
  600. package/bmad-core/templates/competitor-analysis-tmpl.yaml +0 -306
  601. package/bmad-core/templates/front-end-architecture-tmpl.yaml +0 -218
  602. package/bmad-core/templates/front-end-spec-tmpl.yaml +0 -349
  603. package/bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -823
  604. package/bmad-core/templates/market-research-tmpl.yaml +0 -252
  605. package/bmad-core/templates/prd-tmpl.yaml +0 -202
  606. package/bmad-core/templates/project-brief-tmpl.yaml +0 -221
  607. package/bmad-core/templates/qa-gate-tmpl.yaml +0 -102
  608. package/bmad-core/templates/story-tmpl.yaml +0 -137
  609. package/bmad-core/workflows/brownfield-fullstack.yaml +0 -297
  610. package/bmad-core/workflows/brownfield-service.yaml +0 -187
  611. package/bmad-core/workflows/brownfield-ui.yaml +0 -197
  612. package/bmad-core/workflows/greenfield-fullstack.yaml +0 -240
  613. package/bmad-core/workflows/greenfield-service.yaml +0 -206
  614. package/bmad-core/workflows/greenfield-ui.yaml +0 -235
  615. package/common/tasks/create-doc.md +0 -101
  616. package/common/tasks/execute-checklist.md +0 -86
  617. package/common/utils/bmad-doc-template.md +0 -325
  618. package/common/utils/workflow-management.md +0 -69
  619. package/dist/agents/analyst.txt +0 -2889
  620. package/dist/agents/architect.txt +0 -3552
  621. package/dist/agents/bmad-master.txt +0 -8769
  622. package/dist/agents/bmad-orchestrator.txt +0 -1513
  623. package/dist/agents/dev.txt +0 -414
  624. package/dist/agents/pm.txt +0 -2204
  625. package/dist/agents/po.txt +0 -1346
  626. package/dist/agents/qa.txt +0 -1987
  627. package/dist/agents/sm.txt +0 -658
  628. package/dist/agents/ux-expert.txt +0 -694
  629. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +0 -2371
  630. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +0 -1620
  631. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +0 -815
  632. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +0 -10952
  633. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +0 -4012
  634. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +0 -3698
  635. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +0 -450
  636. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +0 -973
  637. package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +0 -15376
  638. package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +0 -2075
  639. package/dist/teams/team-all.txt +0 -12682
  640. package/dist/teams/team-fullstack.txt +0 -10421
  641. package/dist/teams/team-ide-minimal.txt +0 -5103
  642. package/dist/teams/team-no-ui.txt +0 -8980
  643. package/docs/GUIDING-PRINCIPLES.md +0 -91
  644. package/docs/core-architecture.md +0 -219
  645. package/docs/enhanced-ide-development-workflow.md +0 -248
  646. package/docs/expansion-packs.md +0 -280
  647. package/docs/how-to-contribute-with-pull-requests.md +0 -158
  648. package/docs/user-guide.md +0 -504
  649. package/docs/versioning-and-releases.md +0 -147
  650. package/docs/versions.md +0 -48
  651. package/docs/working-in-the-brownfield.md +0 -597
  652. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/Complete AI Agent System - Flowchart.svg +0 -102
  653. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash copy.txt +0 -13
  654. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash.txt +0 -13
  655. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.2 Agent Development Kit Installation/1.2.2 - Basic Project Structure - txt.txt +0 -25
  656. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.1 - settings.py +0 -34
  657. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.2 - main.py - Base Application.py +0 -70
  658. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.4 Deployment Configuration/1.4.2 - cloudbuild.yaml +0 -26
  659. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +0 -109
  660. package/expansion-packs/README.md +0 -3
  661. package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/phaser-2d-nodejs-game-team.yaml +0 -13
  662. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +0 -71
  663. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +0 -78
  664. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +0 -64
  665. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +0 -201
  666. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +0 -160
  667. package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +0 -8
  668. package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +0 -250
  669. package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +0 -647
  670. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +0 -110
  671. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +0 -216
  672. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +0 -290
  673. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +0 -613
  674. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +0 -356
  675. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +0 -343
  676. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +0 -253
  677. package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +0 -484
  678. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +0 -183
  679. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +0 -175
  680. package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +0 -14
  681. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.md +0 -80
  682. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +0 -77
  683. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +0 -78
  684. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.md +0 -65
  685. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-architect-checklist.md +0 -391
  686. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-change-checklist.md +0 -203
  687. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +0 -201
  688. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +0 -124
  689. package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +0 -6
  690. package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +0 -769
  691. package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +0 -586
  692. package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +0 -110
  693. package/expansion-packs/bmad-2d-unity-game-dev/tasks/correct-course-game.md +0 -141
  694. package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +0 -184
  695. package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +0 -290
  696. package/expansion-packs/bmad-2d-unity-game-dev/tasks/validate-game-story.md +0 -200
  697. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +0 -1030
  698. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +0 -356
  699. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +0 -705
  700. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +0 -256
  701. package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +0 -484
  702. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +0 -183
  703. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +0 -175
  704. package/expansion-packs/bmad-infrastructure-devops/README.md +0 -147
  705. package/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.md +0 -71
  706. package/expansion-packs/bmad-infrastructure-devops/checklists/infrastructure-checklist.md +0 -484
  707. package/expansion-packs/bmad-infrastructure-devops/config.yaml +0 -9
  708. package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +0 -305
  709. package/expansion-packs/bmad-infrastructure-devops/tasks/review-infrastructure.md +0 -159
  710. package/expansion-packs/bmad-infrastructure-devops/tasks/validate-infrastructure.md +0 -153
  711. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +0 -424
  712. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +0 -629
  713. package/release_notes.md +0 -33
  714. package/tools/builders/web-builder.js +0 -675
  715. package/tools/bump-all-versions.js +0 -115
  716. package/tools/bump-expansion-version.js +0 -90
  717. package/tools/cli.js +0 -152
  718. package/tools/installer/README.md +0 -8
  719. package/tools/installer/bin/bmad.js +0 -585
  720. package/tools/installer/config/ide-agent-config.yaml +0 -58
  721. package/tools/installer/config/install.config.yaml +0 -123
  722. package/tools/installer/lib/config-loader.js +0 -257
  723. package/tools/installer/lib/file-manager.js +0 -389
  724. package/tools/installer/lib/ide-base-setup.js +0 -228
  725. package/tools/installer/lib/ide-setup.js +0 -1441
  726. package/tools/installer/lib/installer.js +0 -1995
  727. package/tools/installer/lib/memory-profiler.js +0 -225
  728. package/tools/installer/lib/module-manager.js +0 -114
  729. package/tools/installer/lib/resource-locator.js +0 -308
  730. package/tools/installer/package.json +0 -44
  731. package/tools/lib/dependency-resolver.js +0 -175
  732. package/tools/lib/yaml-utils.js +0 -29
  733. package/tools/md-assets/web-agent-startup-instructions.md +0 -39
  734. package/tools/preview-release-notes.js +0 -66
  735. package/tools/shared/bannerArt.js +0 -105
  736. package/tools/sync-installer-version.js +0 -32
  737. package/tools/update-expansion-version.js +0 -53
  738. package/tools/upgraders/v3-to-v4-upgrader.js +0 -672
  739. package/tools/version-bump.js +0 -94
@@ -0,0 +1,1079 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const yaml = require('yaml');
4
+ const chalk = require('chalk');
5
+ const { getProjectRoot, getModulePath } = require('../../../lib/project-root');
6
+ const { CLIUtils } = require('../../../lib/cli-utils');
7
+ const prompts = require('../../../lib/prompts');
8
+
9
+ class ConfigCollector {
10
+ constructor() {
11
+ this.collectedConfig = {};
12
+ this.existingConfig = null;
13
+ this.currentProjectDir = null;
14
+ }
15
+
16
+ /**
17
+ * Find the bmad installation directory in a project
18
+ * V6+ installations can use ANY folder name but ALWAYS have _config/manifest.yaml
19
+ * @param {string} projectDir - Project directory
20
+ * @returns {Promise<string>} Path to bmad directory
21
+ */
22
+ async findBmadDir(projectDir) {
23
+ // Check if project directory exists
24
+ if (!(await fs.pathExists(projectDir))) {
25
+ // Project doesn't exist yet, return default
26
+ return path.join(projectDir, 'bmad');
27
+ }
28
+
29
+ // V6+ strategy: Look for ANY directory with _config/manifest.yaml
30
+ // This is the definitive marker of a V6+ installation
31
+ try {
32
+ const entries = await fs.readdir(projectDir, { withFileTypes: true });
33
+ for (const entry of entries) {
34
+ if (entry.isDirectory()) {
35
+ const manifestPath = path.join(projectDir, entry.name, '_config', 'manifest.yaml');
36
+ if (await fs.pathExists(manifestPath)) {
37
+ // Found a V6+ installation
38
+ return path.join(projectDir, entry.name);
39
+ }
40
+ }
41
+ }
42
+ } catch {
43
+ // Ignore errors, fall through to default
44
+ }
45
+
46
+ // No V6+ installation found, return default
47
+ // This will be used for new installations
48
+ return path.join(projectDir, 'bmad');
49
+ }
50
+
51
+ /**
52
+ * Detect the existing BMAD folder name in a project
53
+ * @param {string} projectDir - Project directory
54
+ * @returns {Promise<string|null>} Folder name (just the name, not full path) or null if not found
55
+ */
56
+ async detectExistingBmadFolder(projectDir) {
57
+ // Check if project directory exists
58
+ if (!(await fs.pathExists(projectDir))) {
59
+ return null;
60
+ }
61
+
62
+ // Look for ANY directory with _config/manifest.yaml
63
+ try {
64
+ const entries = await fs.readdir(projectDir, { withFileTypes: true });
65
+ for (const entry of entries) {
66
+ if (entry.isDirectory()) {
67
+ const manifestPath = path.join(projectDir, entry.name, '_config', 'manifest.yaml');
68
+ if (await fs.pathExists(manifestPath)) {
69
+ // Found a V6+ installation, return just the folder name
70
+ return entry.name;
71
+ }
72
+ }
73
+ }
74
+ } catch {
75
+ // Ignore errors
76
+ }
77
+
78
+ return null;
79
+ }
80
+
81
+ /**
82
+ * Load existing config if it exists from module config files
83
+ * @param {string} projectDir - Target project directory
84
+ */
85
+ async loadExistingConfig(projectDir) {
86
+ this.existingConfig = {};
87
+
88
+ // Check if project directory exists first
89
+ if (!(await fs.pathExists(projectDir))) {
90
+ return false;
91
+ }
92
+
93
+ // Find the actual bmad directory (handles custom folder names)
94
+ const bmadDir = await this.findBmadDir(projectDir);
95
+
96
+ // Check if bmad directory exists
97
+ if (!(await fs.pathExists(bmadDir))) {
98
+ return false;
99
+ }
100
+
101
+ // Dynamically discover all installed modules by scanning bmad directory
102
+ // A directory is a module ONLY if it contains a config.yaml file
103
+ let foundAny = false;
104
+ const entries = await fs.readdir(bmadDir, { withFileTypes: true });
105
+
106
+ for (const entry of entries) {
107
+ if (entry.isDirectory()) {
108
+ // Skip the _config directory - it's for system use
109
+ if (entry.name === '_config' || entry.name === '_memory') {
110
+ continue;
111
+ }
112
+
113
+ const moduleConfigPath = path.join(bmadDir, entry.name, 'config.yaml');
114
+
115
+ if (await fs.pathExists(moduleConfigPath)) {
116
+ try {
117
+ const content = await fs.readFile(moduleConfigPath, 'utf8');
118
+ const moduleConfig = yaml.parse(content);
119
+ if (moduleConfig) {
120
+ this.existingConfig[entry.name] = moduleConfig;
121
+ foundAny = true;
122
+ }
123
+ } catch {
124
+ // Ignore parse errors for individual modules
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ return foundAny;
131
+ }
132
+
133
+ /**
134
+ * Collect configuration for all modules
135
+ * @param {Array} modules - List of modules to configure (including 'core')
136
+ * @param {string} projectDir - Target project directory
137
+ * @param {Object} options - Additional options
138
+ * @param {Map} options.customModulePaths - Map of module ID to source path for custom modules
139
+ */
140
+ async collectAllConfigurations(modules, projectDir, options = {}) {
141
+ // Store custom module paths for use in collectModuleConfig
142
+ this.customModulePaths = options.customModulePaths || new Map();
143
+ await this.loadExistingConfig(projectDir);
144
+
145
+ // Check if core was already collected (e.g., in early collection phase)
146
+ const coreAlreadyCollected = this.collectedConfig.core && Object.keys(this.collectedConfig.core).length > 0;
147
+
148
+ // If core wasn't already collected, include it
149
+ const allModules = coreAlreadyCollected ? modules.filter((m) => m !== 'core') : ['core', ...modules.filter((m) => m !== 'core')];
150
+
151
+ // Store all answers across modules for cross-referencing
152
+ if (!this.allAnswers) {
153
+ this.allAnswers = {};
154
+ }
155
+
156
+ for (const moduleName of allModules) {
157
+ await this.collectModuleConfig(moduleName, projectDir);
158
+ }
159
+
160
+ // Add metadata
161
+ this.collectedConfig._meta = {
162
+ version: require(path.join(getProjectRoot(), 'package.json')).version,
163
+ installDate: new Date().toISOString(),
164
+ lastModified: new Date().toISOString(),
165
+ };
166
+
167
+ return this.collectedConfig;
168
+ }
169
+
170
+ /**
171
+ * Collect configuration for a single module (Quick Update mode - only new fields)
172
+ * @param {string} moduleName - Module name
173
+ * @param {string} projectDir - Target project directory
174
+ * @param {boolean} silentMode - If true, only prompt for new/missing fields
175
+ * @returns {boolean} True if new fields were prompted, false if all fields existed
176
+ */
177
+ async collectModuleConfigQuick(moduleName, projectDir, silentMode = true) {
178
+ this.currentProjectDir = projectDir;
179
+
180
+ // Load existing config if not already loaded
181
+ if (!this.existingConfig) {
182
+ await this.loadExistingConfig(projectDir);
183
+ }
184
+
185
+ // Initialize allAnswers if not already initialized
186
+ if (!this.allAnswers) {
187
+ this.allAnswers = {};
188
+ }
189
+
190
+ // Load module's install config schema
191
+ // First, try the standard src/modules location
192
+ let installerConfigPath = path.join(getModulePath(moduleName), '_module-installer', 'module.yaml');
193
+ let moduleConfigPath = path.join(getModulePath(moduleName), 'module.yaml');
194
+
195
+ // If not found in src/modules, we need to find it by searching the project
196
+ if (!(await fs.pathExists(installerConfigPath)) && !(await fs.pathExists(moduleConfigPath))) {
197
+ // Use the module manager to find the module source
198
+ const { ModuleManager } = require('../modules/manager');
199
+ const moduleManager = new ModuleManager();
200
+ const moduleSourcePath = await moduleManager.findModuleSource(moduleName);
201
+
202
+ if (moduleSourcePath) {
203
+ installerConfigPath = path.join(moduleSourcePath, '_module-installer', 'module.yaml');
204
+ moduleConfigPath = path.join(moduleSourcePath, 'module.yaml');
205
+ }
206
+ }
207
+
208
+ let configPath = null;
209
+ let isCustomModule = false;
210
+
211
+ if (await fs.pathExists(moduleConfigPath)) {
212
+ configPath = moduleConfigPath;
213
+ } else if (await fs.pathExists(installerConfigPath)) {
214
+ configPath = installerConfigPath;
215
+ } else {
216
+ // Check if this is a custom module with custom.yaml
217
+ const { ModuleManager } = require('../modules/manager');
218
+ const moduleManager = new ModuleManager();
219
+ const moduleSourcePath = await moduleManager.findModuleSource(moduleName);
220
+
221
+ if (moduleSourcePath) {
222
+ const rootCustomConfigPath = path.join(moduleSourcePath, 'custom.yaml');
223
+ const moduleInstallerCustomPath = path.join(moduleSourcePath, '_module-installer', 'custom.yaml');
224
+
225
+ if ((await fs.pathExists(rootCustomConfigPath)) || (await fs.pathExists(moduleInstallerCustomPath))) {
226
+ isCustomModule = true;
227
+ // For custom modules, we don't have an install-config schema, so just use existing values
228
+ // The custom.yaml values will be loaded and merged during installation
229
+ }
230
+ }
231
+
232
+ // No config schema for this module - use existing values
233
+ if (this.existingConfig && this.existingConfig[moduleName]) {
234
+ if (!this.collectedConfig[moduleName]) {
235
+ this.collectedConfig[moduleName] = {};
236
+ }
237
+ this.collectedConfig[moduleName] = { ...this.existingConfig[moduleName] };
238
+ }
239
+ return false;
240
+ }
241
+
242
+ const configContent = await fs.readFile(configPath, 'utf8');
243
+ const moduleConfig = yaml.parse(configContent);
244
+
245
+ if (!moduleConfig) {
246
+ return false;
247
+ }
248
+
249
+ // Compare schema with existing config to find new/missing fields
250
+ const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt');
251
+ const existingKeys = this.existingConfig && this.existingConfig[moduleName] ? Object.keys(this.existingConfig[moduleName]) : [];
252
+
253
+ // Check if this module has no configuration keys at all (like CIS)
254
+ // Filter out metadata fields and only count actual config objects
255
+ const metadataFields = new Set(['code', 'name', 'header', 'subheader', 'default_selected']);
256
+ const actualConfigKeys = configKeys.filter((key) => !metadataFields.has(key));
257
+ const hasNoConfig = actualConfigKeys.length === 0;
258
+
259
+ // If module has no config keys at all, handle it specially
260
+ if (hasNoConfig && moduleConfig.subheader) {
261
+ // Add blank line for better readability (matches other modules)
262
+ console.log();
263
+ const moduleDisplayName = moduleConfig.header || `${moduleName.toUpperCase()} Module`;
264
+
265
+ // Display the module name in color first (matches other modules)
266
+ console.log(chalk.cyan('?') + ' ' + chalk.magenta(moduleDisplayName));
267
+
268
+ // Show the subheader since there's no configuration to ask about
269
+ console.log(chalk.dim(` ✓ ${moduleConfig.subheader}`));
270
+ return false; // No new fields
271
+ }
272
+
273
+ // Find new interactive fields (with prompt)
274
+ const newKeys = configKeys.filter((key) => {
275
+ const item = moduleConfig[key];
276
+ // Check if it's a config item and doesn't exist in existing config
277
+ return item && typeof item === 'object' && item.prompt && !existingKeys.includes(key);
278
+ });
279
+
280
+ // Find new static fields (without prompt, just result)
281
+ const newStaticKeys = configKeys.filter((key) => {
282
+ const item = moduleConfig[key];
283
+ return item && typeof item === 'object' && !item.prompt && item.result && !existingKeys.includes(key);
284
+ });
285
+
286
+ // If in silent mode and no new keys (neither interactive nor static), use existing config and skip prompts
287
+ if (silentMode && newKeys.length === 0 && newStaticKeys.length === 0) {
288
+ if (this.existingConfig && this.existingConfig[moduleName]) {
289
+ if (!this.collectedConfig[moduleName]) {
290
+ this.collectedConfig[moduleName] = {};
291
+ }
292
+ this.collectedConfig[moduleName] = { ...this.existingConfig[moduleName] };
293
+
294
+ // Special handling for user_name: ensure it has a value
295
+ if (
296
+ moduleName === 'core' &&
297
+ (!this.collectedConfig[moduleName].user_name || this.collectedConfig[moduleName].user_name === '[USER_NAME]')
298
+ ) {
299
+ this.collectedConfig[moduleName].user_name = this.getDefaultUsername();
300
+ }
301
+
302
+ // Also populate allAnswers for cross-referencing
303
+ for (const [key, value] of Object.entries(this.existingConfig[moduleName])) {
304
+ // Ensure user_name is properly set in allAnswers too
305
+ let finalValue = value;
306
+ if (moduleName === 'core' && key === 'user_name' && (!value || value === '[USER_NAME]')) {
307
+ finalValue = this.getDefaultUsername();
308
+ }
309
+ this.allAnswers[`${moduleName}_${key}`] = finalValue;
310
+ }
311
+ } else if (moduleName === 'core') {
312
+ // No existing core config - ensure we at least have user_name
313
+ if (!this.collectedConfig[moduleName]) {
314
+ this.collectedConfig[moduleName] = {};
315
+ }
316
+ if (!this.collectedConfig[moduleName].user_name) {
317
+ this.collectedConfig[moduleName].user_name = this.getDefaultUsername();
318
+ this.allAnswers[`${moduleName}_user_name`] = this.getDefaultUsername();
319
+ }
320
+ }
321
+
322
+ // Show "no config" message for modules with no new questions (that have config keys)
323
+ console.log(chalk.dim(` ✓ ${moduleName.toUpperCase()} module already up to date`));
324
+ return false; // No new fields
325
+ }
326
+
327
+ // If we have new fields (interactive or static), process them
328
+ if (newKeys.length > 0 || newStaticKeys.length > 0) {
329
+ const questions = [];
330
+ const staticAnswers = {};
331
+
332
+ // Build questions for interactive fields
333
+ for (const key of newKeys) {
334
+ const item = moduleConfig[key];
335
+ const question = await this.buildQuestion(moduleName, key, item, moduleConfig);
336
+ if (question) {
337
+ questions.push(question);
338
+ }
339
+ }
340
+
341
+ // Prepare static answers (no prompt, just result)
342
+ for (const key of newStaticKeys) {
343
+ staticAnswers[`${moduleName}_${key}`] = undefined;
344
+ }
345
+
346
+ // Collect all answers (static + prompted)
347
+ let allAnswers = { ...staticAnswers };
348
+
349
+ if (questions.length > 0) {
350
+ // Only show header if we actually have questions
351
+ CLIUtils.displayModuleConfigHeader(moduleName, moduleConfig.header, moduleConfig.subheader);
352
+ console.log(); // Line break before questions
353
+ const promptedAnswers = await prompts.prompt(questions);
354
+
355
+ // Merge prompted answers with static answers
356
+ Object.assign(allAnswers, promptedAnswers);
357
+ } else if (newStaticKeys.length > 0) {
358
+ // Only static fields, no questions - show no config message
359
+ console.log(chalk.dim(` ✓ ${moduleName.toUpperCase()} module configuration updated`));
360
+ }
361
+
362
+ // Store all answers for cross-referencing
363
+ Object.assign(this.allAnswers, allAnswers);
364
+
365
+ // Process all answers (both static and prompted)
366
+ // First, copy existing config to preserve values that aren't being updated
367
+ if (this.existingConfig && this.existingConfig[moduleName]) {
368
+ this.collectedConfig[moduleName] = { ...this.existingConfig[moduleName] };
369
+ } else {
370
+ this.collectedConfig[moduleName] = {};
371
+ }
372
+
373
+ for (const key of Object.keys(allAnswers)) {
374
+ const originalKey = key.replace(`${moduleName}_`, '');
375
+ const item = moduleConfig[originalKey];
376
+ const value = allAnswers[key];
377
+
378
+ let result;
379
+ if (Array.isArray(value)) {
380
+ result = value;
381
+ } else if (item.result) {
382
+ result = this.processResultTemplate(item.result, value);
383
+ } else {
384
+ result = value;
385
+ }
386
+
387
+ // Update the collected config with new/updated values
388
+ this.collectedConfig[moduleName][originalKey] = result;
389
+ }
390
+ }
391
+
392
+ // Copy over existing values for fields that weren't prompted
393
+ if (this.existingConfig && this.existingConfig[moduleName]) {
394
+ if (!this.collectedConfig[moduleName]) {
395
+ this.collectedConfig[moduleName] = {};
396
+ }
397
+ for (const [key, value] of Object.entries(this.existingConfig[moduleName])) {
398
+ if (!this.collectedConfig[moduleName][key]) {
399
+ this.collectedConfig[moduleName][key] = value;
400
+ this.allAnswers[`${moduleName}_${key}`] = value;
401
+ }
402
+ }
403
+ }
404
+
405
+ return newKeys.length > 0 || newStaticKeys.length > 0; // Return true if we had any new fields (interactive or static)
406
+ }
407
+
408
+ /**
409
+ * Process a result template with value substitution
410
+ * @param {*} resultTemplate - The result template
411
+ * @param {*} value - The value to substitute
412
+ * @returns {*} Processed result
413
+ */
414
+ processResultTemplate(resultTemplate, value) {
415
+ let result = resultTemplate;
416
+
417
+ if (typeof result === 'string' && value !== undefined) {
418
+ if (typeof value === 'string') {
419
+ result = result.replace('{value}', value);
420
+ } else if (typeof value === 'boolean' || typeof value === 'number') {
421
+ if (result === '{value}') {
422
+ result = value;
423
+ } else {
424
+ result = result.replace('{value}', value);
425
+ }
426
+ } else {
427
+ result = value;
428
+ }
429
+
430
+ if (typeof result === 'string') {
431
+ result = result.replaceAll(/{([^}]+)}/g, (match, configKey) => {
432
+ if (configKey === 'project-root') {
433
+ return '{project-root}';
434
+ }
435
+ if (configKey === 'value') {
436
+ return match;
437
+ }
438
+
439
+ let configValue = this.allAnswers[configKey] || this.allAnswers[`${configKey}`];
440
+ if (!configValue) {
441
+ for (const [answerKey, answerValue] of Object.entries(this.allAnswers)) {
442
+ if (answerKey.endsWith(`_${configKey}`)) {
443
+ configValue = answerValue;
444
+ break;
445
+ }
446
+ }
447
+ }
448
+
449
+ if (!configValue) {
450
+ for (const mod of Object.keys(this.collectedConfig)) {
451
+ if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) {
452
+ configValue = this.collectedConfig[mod][configKey];
453
+ if (typeof configValue === 'string' && configValue.includes('{project-root}/')) {
454
+ configValue = configValue.replace('{project-root}/', '');
455
+ }
456
+ break;
457
+ }
458
+ }
459
+ }
460
+
461
+ return configValue || match;
462
+ });
463
+ }
464
+ }
465
+
466
+ return result;
467
+ }
468
+
469
+ /**
470
+ * Get the default username from the system
471
+ * @returns {string} Capitalized username\
472
+ */
473
+ getDefaultUsername() {
474
+ let result = 'BMad';
475
+ try {
476
+ const os = require('node:os');
477
+ const userInfo = os.userInfo();
478
+ if (userInfo && userInfo.username) {
479
+ const username = userInfo.username;
480
+ result = username.charAt(0).toUpperCase() + username.slice(1);
481
+ }
482
+ } catch {
483
+ // Do nothing, just return 'BMad'
484
+ }
485
+ return result;
486
+ }
487
+
488
+ /**
489
+ * Collect configuration for a single module
490
+ * @param {string} moduleName - Module name
491
+ * @param {string} projectDir - Target project directory
492
+ * @param {boolean} skipLoadExisting - Skip loading existing config (for early core collection)
493
+ * @param {boolean} skipCompletion - Skip showing completion message (for early core collection)
494
+ */
495
+ async collectModuleConfig(moduleName, projectDir, skipLoadExisting = false, skipCompletion = false) {
496
+ this.currentProjectDir = projectDir;
497
+ // Load existing config if needed and not already loaded
498
+ if (!skipLoadExisting && !this.existingConfig) {
499
+ await this.loadExistingConfig(projectDir);
500
+ }
501
+
502
+ // Initialize allAnswers if not already initialized
503
+ if (!this.allAnswers) {
504
+ this.allAnswers = {};
505
+ }
506
+ // Load module's config
507
+ // First, check if we have a custom module path for this module
508
+ let installerConfigPath = null;
509
+ let moduleConfigPath = null;
510
+
511
+ if (this.customModulePaths && this.customModulePaths.has(moduleName)) {
512
+ const customPath = this.customModulePaths.get(moduleName);
513
+ installerConfigPath = path.join(customPath, '_module-installer', 'module.yaml');
514
+ moduleConfigPath = path.join(customPath, 'module.yaml');
515
+ } else {
516
+ // Try the standard src/modules location
517
+ installerConfigPath = path.join(getModulePath(moduleName), '_module-installer', 'module.yaml');
518
+ moduleConfigPath = path.join(getModulePath(moduleName), 'module.yaml');
519
+ }
520
+
521
+ // If not found in src/modules or custom paths, search the project
522
+ if (!(await fs.pathExists(installerConfigPath)) && !(await fs.pathExists(moduleConfigPath))) {
523
+ // Use the module manager to find the module source
524
+ const { ModuleManager } = require('../modules/manager');
525
+ const moduleManager = new ModuleManager();
526
+ const moduleSourcePath = await moduleManager.findModuleSource(moduleName);
527
+
528
+ if (moduleSourcePath) {
529
+ installerConfigPath = path.join(moduleSourcePath, '_module-installer', 'module.yaml');
530
+ moduleConfigPath = path.join(moduleSourcePath, 'module.yaml');
531
+ }
532
+ }
533
+
534
+ let configPath = null;
535
+ if (await fs.pathExists(moduleConfigPath)) {
536
+ configPath = moduleConfigPath;
537
+ } else if (await fs.pathExists(installerConfigPath)) {
538
+ configPath = installerConfigPath;
539
+ } else {
540
+ // No config for this module
541
+ return;
542
+ }
543
+
544
+ const configContent = await fs.readFile(configPath, 'utf8');
545
+ const moduleConfig = yaml.parse(configContent);
546
+
547
+ if (!moduleConfig) {
548
+ return;
549
+ }
550
+
551
+ // Process each config item
552
+ const questions = [];
553
+ const staticAnswers = {};
554
+ const configKeys = Object.keys(moduleConfig).filter((key) => key !== 'prompt');
555
+
556
+ for (const key of configKeys) {
557
+ const item = moduleConfig[key];
558
+
559
+ // Skip if not a config object
560
+ if (!item || typeof item !== 'object') {
561
+ continue;
562
+ }
563
+
564
+ // Handle static values (no prompt, just result)
565
+ if (!item.prompt && item.result) {
566
+ // Add to static answers with a marker value
567
+ staticAnswers[`${moduleName}_${key}`] = undefined;
568
+ continue;
569
+ }
570
+
571
+ // Handle interactive values (with prompt)
572
+ if (item.prompt) {
573
+ const question = await this.buildQuestion(moduleName, key, item, moduleConfig);
574
+ if (question) {
575
+ questions.push(question);
576
+ }
577
+ }
578
+ }
579
+
580
+ // Collect all answers (static + prompted)
581
+ let allAnswers = { ...staticAnswers };
582
+
583
+ // If there are questions to ask, prompt for accepting defaults vs customizing
584
+ if (questions.length > 0) {
585
+ const moduleDisplayName = moduleConfig.header || `${moduleName.toUpperCase()} Module`;
586
+ console.log();
587
+ console.log(chalk.cyan('?') + ' ' + chalk.magenta(moduleDisplayName));
588
+ let customize = true;
589
+ if (moduleName !== 'core') {
590
+ const customizeAnswer = await prompts.prompt([
591
+ {
592
+ type: 'confirm',
593
+ name: 'customize',
594
+ message: 'Accept Defaults (no to customize)?',
595
+ default: true,
596
+ },
597
+ ]);
598
+ customize = customizeAnswer.customize;
599
+ }
600
+
601
+ if (customize && moduleName !== 'core') {
602
+ // Accept defaults - only ask questions that have NO default value
603
+ const questionsWithoutDefaults = questions.filter((q) => q.default === undefined || q.default === null || q.default === '');
604
+
605
+ if (questionsWithoutDefaults.length > 0) {
606
+ console.log(chalk.dim(`\n Asking required questions for ${moduleName.toUpperCase()}...`));
607
+ const promptedAnswers = await prompts.prompt(questionsWithoutDefaults);
608
+ Object.assign(allAnswers, promptedAnswers);
609
+ }
610
+
611
+ // For questions with defaults that weren't asked, we need to process them with their default values
612
+ const questionsWithDefaults = questions.filter((q) => q.default !== undefined && q.default !== null && q.default !== '');
613
+ for (const question of questionsWithDefaults) {
614
+ // Skip function defaults - these are dynamic and will be evaluated later
615
+ if (typeof question.default === 'function') {
616
+ continue;
617
+ }
618
+ allAnswers[question.name] = question.default;
619
+ }
620
+ } else {
621
+ const promptedAnswers = await prompts.prompt(questions);
622
+ Object.assign(allAnswers, promptedAnswers);
623
+ }
624
+ }
625
+
626
+ // Store all answers for cross-referencing
627
+ Object.assign(this.allAnswers, allAnswers);
628
+
629
+ // Process all answers (both static and prompted)
630
+ // Always process if we have any answers or static answers
631
+ if (Object.keys(allAnswers).length > 0 || Object.keys(staticAnswers).length > 0) {
632
+ const answers = allAnswers;
633
+
634
+ // Process answers and build result values
635
+ for (const key of Object.keys(answers)) {
636
+ const originalKey = key.replace(`${moduleName}_`, '');
637
+ const item = moduleConfig[originalKey];
638
+ const value = answers[key];
639
+
640
+ // Build the result using the template
641
+ let result;
642
+
643
+ // For arrays (multi-select), handle differently
644
+ if (Array.isArray(value)) {
645
+ result = value;
646
+ } else if (item.result) {
647
+ result = item.result;
648
+
649
+ // Replace placeholders only for strings
650
+ if (typeof result === 'string' && value !== undefined) {
651
+ // Replace {value} with the actual value
652
+ if (typeof value === 'string') {
653
+ result = result.replace('{value}', value);
654
+ } else if (typeof value === 'boolean' || typeof value === 'number') {
655
+ // For boolean and number values, if result is just "{value}", use the raw value
656
+ if (result === '{value}') {
657
+ result = value;
658
+ } else {
659
+ result = result.replace('{value}', value);
660
+ }
661
+ } else {
662
+ result = value;
663
+ }
664
+
665
+ // Only do further replacements if result is still a string
666
+ if (typeof result === 'string') {
667
+ // Replace references to other config values
668
+ result = result.replaceAll(/{([^}]+)}/g, (match, configKey) => {
669
+ // Check if it's a special placeholder
670
+ if (configKey === 'project-root') {
671
+ return '{project-root}';
672
+ }
673
+
674
+ // Skip if it's the 'value' placeholder we already handled
675
+ if (configKey === 'value') {
676
+ return match;
677
+ }
678
+
679
+ // Look for the config value across all modules
680
+ // First check if it's in the current module's answers
681
+ let configValue = answers[`${moduleName}_${configKey}`];
682
+
683
+ // Then check all answers (for cross-module references like outputFolder)
684
+ if (!configValue) {
685
+ // Try with various module prefixes
686
+ for (const [answerKey, answerValue] of Object.entries(this.allAnswers)) {
687
+ if (answerKey.endsWith(`_${configKey}`)) {
688
+ configValue = answerValue;
689
+ break;
690
+ }
691
+ }
692
+ }
693
+
694
+ // Check in already collected config
695
+ if (!configValue) {
696
+ for (const mod of Object.keys(this.collectedConfig)) {
697
+ if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) {
698
+ configValue = this.collectedConfig[mod][configKey];
699
+ break;
700
+ }
701
+ }
702
+ }
703
+
704
+ return configValue || match;
705
+ });
706
+ }
707
+ }
708
+ } else {
709
+ result = value;
710
+ }
711
+
712
+ // Store only the result value (no prompts, defaults, examples, etc.)
713
+ if (!this.collectedConfig[moduleName]) {
714
+ this.collectedConfig[moduleName] = {};
715
+ }
716
+ this.collectedConfig[moduleName][originalKey] = result;
717
+ }
718
+
719
+ // No longer display completion boxes - keep output clean
720
+ } else {
721
+ // No questions for this module - show completion message with header if available
722
+ const moduleDisplayName = moduleConfig.header || `${moduleName.toUpperCase()} Module`;
723
+
724
+ // Check if this module has NO configuration keys at all (like CIS)
725
+ // Filter out metadata fields and only count actual config objects
726
+ const metadataFields = new Set(['code', 'name', 'header', 'subheader', 'default_selected']);
727
+ const actualConfigKeys = configKeys.filter((key) => !metadataFields.has(key));
728
+ const hasNoConfig = actualConfigKeys.length === 0;
729
+
730
+ if (hasNoConfig && (moduleConfig.subheader || moduleConfig.header)) {
731
+ // Module explicitly has no configuration - show with special styling
732
+ // Add blank line for better readability (matches other modules)
733
+ console.log();
734
+
735
+ // Display the module name in color first (matches other modules)
736
+ console.log(chalk.cyan('?') + ' ' + chalk.magenta(moduleDisplayName));
737
+
738
+ // Ask user if they want to accept defaults or customize on the next line
739
+ const { customize } = await prompts.prompt([
740
+ {
741
+ type: 'confirm',
742
+ name: 'customize',
743
+ message: 'Accept Defaults (no to customize)?',
744
+ default: true,
745
+ },
746
+ ]);
747
+
748
+ // Show the subheader if available, otherwise show a default message
749
+ if (moduleConfig.subheader) {
750
+ console.log(chalk.dim(` ✓ ${moduleConfig.subheader}`));
751
+ } else {
752
+ console.log(chalk.dim(` ✓ No custom configuration required`));
753
+ }
754
+ } else {
755
+ // Module has config but just no questions to ask
756
+ console.log(chalk.dim(` ✓ ${moduleName.toUpperCase()} module configured`));
757
+ }
758
+ }
759
+
760
+ // If we have no collected config for this module, but we have a module schema,
761
+ // ensure we have at least an empty object
762
+ if (!this.collectedConfig[moduleName]) {
763
+ this.collectedConfig[moduleName] = {};
764
+
765
+ // If we accepted defaults and have no answers, we still need to check
766
+ // if there are any static values in the schema that should be applied
767
+ if (moduleConfig) {
768
+ for (const key of Object.keys(moduleConfig)) {
769
+ if (key !== 'prompt' && moduleConfig[key] && typeof moduleConfig[key] === 'object') {
770
+ const item = moduleConfig[key];
771
+ // For static items (no prompt, just result), apply the result
772
+ if (!item.prompt && item.result) {
773
+ // Apply any placeholder replacements to the result
774
+ let result = item.result;
775
+ if (typeof result === 'string') {
776
+ result = this.replacePlaceholders(result, moduleName, moduleConfig);
777
+ }
778
+ this.collectedConfig[moduleName][key] = result;
779
+ }
780
+ }
781
+ }
782
+ }
783
+ }
784
+ }
785
+
786
+ /**
787
+ * Replace placeholders in a string with collected config values
788
+ * @param {string} str - String with placeholders
789
+ * @param {string} currentModule - Current module name (to look up defaults in same module)
790
+ * @param {Object} moduleConfig - Current module's config schema (to look up defaults)
791
+ * @returns {string} String with placeholders replaced
792
+ */
793
+ replacePlaceholders(str, currentModule = null, moduleConfig = null) {
794
+ if (typeof str !== 'string') {
795
+ return str;
796
+ }
797
+
798
+ return str.replaceAll(/{([^}]+)}/g, (match, configKey) => {
799
+ // Preserve special placeholders
800
+ if (configKey === 'project-root' || configKey === 'value' || configKey === 'directory_name') {
801
+ return match;
802
+ }
803
+
804
+ // Look for the config value in allAnswers (already answered questions)
805
+ let configValue = this.allAnswers[configKey] || this.allAnswers[`core_${configKey}`];
806
+
807
+ // Check in already collected config
808
+ if (!configValue) {
809
+ for (const mod of Object.keys(this.collectedConfig)) {
810
+ if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) {
811
+ configValue = this.collectedConfig[mod][configKey];
812
+ break;
813
+ }
814
+ }
815
+ }
816
+
817
+ // If still not found and we're in the same module, use the default from the config schema
818
+ if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) {
819
+ const referencedItem = moduleConfig[configKey];
820
+ if (referencedItem && referencedItem.default !== undefined) {
821
+ configValue = referencedItem.default;
822
+ }
823
+ }
824
+
825
+ return configValue || match;
826
+ });
827
+ }
828
+
829
+ /**
830
+ * Build a prompt question from a config item
831
+ * @param {string} moduleName - Module name
832
+ * @param {string} key - Config key
833
+ * @param {Object} item - Config item definition
834
+ * @param {Object} moduleConfig - Full module config schema (for resolving defaults)
835
+ */
836
+ async buildQuestion(moduleName, key, item, moduleConfig = null) {
837
+ const questionName = `${moduleName}_${key}`;
838
+
839
+ // Check for existing value
840
+ let existingValue = null;
841
+ if (this.existingConfig && this.existingConfig[moduleName]) {
842
+ existingValue = this.existingConfig[moduleName][key];
843
+
844
+ // Clean up existing value - remove {project-root}/ prefix if present
845
+ // This prevents duplication when the result template adds it back
846
+ if (typeof existingValue === 'string' && existingValue.startsWith('{project-root}/')) {
847
+ existingValue = existingValue.replace('{project-root}/', '');
848
+ }
849
+ }
850
+
851
+ // Special handling for user_name: default to system user
852
+ if (moduleName === 'core' && key === 'user_name' && !existingValue) {
853
+ item.default = this.getDefaultUsername();
854
+ }
855
+
856
+ // Determine question type and default value
857
+ let questionType = 'input';
858
+ let defaultValue = item.default;
859
+ let choices = null;
860
+
861
+ // Check if default contains references to other fields in the same module
862
+ const hasSameModuleReference = typeof defaultValue === 'string' && defaultValue.match(/{([^}]+)}/);
863
+ let dynamicDefault = false;
864
+
865
+ // Replace placeholders in default value with collected config values
866
+ if (typeof defaultValue === 'string') {
867
+ if (defaultValue.includes('{directory_name}') && this.currentProjectDir) {
868
+ const dirName = path.basename(this.currentProjectDir);
869
+ defaultValue = defaultValue.replaceAll('{directory_name}', dirName);
870
+ }
871
+
872
+ // Check if this references another field in the same module (for dynamic defaults)
873
+ if (hasSameModuleReference && moduleConfig) {
874
+ const matches = defaultValue.match(/{([^}]+)}/g);
875
+ if (matches) {
876
+ for (const match of matches) {
877
+ const fieldName = match.slice(1, -1); // Remove { }
878
+ // Check if this field exists in the same module config
879
+ if (moduleConfig[fieldName]) {
880
+ dynamicDefault = true;
881
+ break;
882
+ }
883
+ }
884
+ }
885
+ }
886
+
887
+ // If not dynamic, replace placeholders now
888
+ if (!dynamicDefault) {
889
+ defaultValue = this.replacePlaceholders(defaultValue, moduleName, moduleConfig);
890
+ }
891
+
892
+ // Strip {project-root}/ from defaults since it will be added back by result template
893
+ // This makes the display cleaner and user input simpler
894
+ if (defaultValue.includes('{project-root}/')) {
895
+ defaultValue = defaultValue.replace('{project-root}/', '');
896
+ }
897
+ }
898
+
899
+ // Handle different question types
900
+ if (item['single-select']) {
901
+ questionType = 'list';
902
+ choices = item['single-select'].map((choice) => {
903
+ // If choice is an object with label and value
904
+ if (typeof choice === 'object' && choice.label && choice.value !== undefined) {
905
+ return {
906
+ name: choice.label,
907
+ value: choice.value,
908
+ };
909
+ }
910
+ // Otherwise it's a simple string choice
911
+ return {
912
+ name: choice,
913
+ value: choice,
914
+ };
915
+ });
916
+ if (existingValue) {
917
+ defaultValue = existingValue;
918
+ }
919
+ } else if (item['multi-select']) {
920
+ questionType = 'checkbox';
921
+ choices = item['multi-select'].map((choice) => {
922
+ // If choice is an object with label and value
923
+ if (typeof choice === 'object' && choice.label && choice.value !== undefined) {
924
+ return {
925
+ name: choice.label,
926
+ value: choice.value,
927
+ checked: existingValue
928
+ ? existingValue.includes(choice.value)
929
+ : item.default && Array.isArray(item.default)
930
+ ? item.default.includes(choice.value)
931
+ : false,
932
+ };
933
+ }
934
+ // Otherwise it's a simple string choice
935
+ return {
936
+ name: choice,
937
+ value: choice,
938
+ checked: existingValue
939
+ ? existingValue.includes(choice)
940
+ : item.default && Array.isArray(item.default)
941
+ ? item.default.includes(choice)
942
+ : false,
943
+ };
944
+ });
945
+ } else if (typeof defaultValue === 'boolean') {
946
+ questionType = 'confirm';
947
+ }
948
+
949
+ // Build the prompt message
950
+ let message = '';
951
+
952
+ // Handle array prompts for multi-line messages
953
+ if (Array.isArray(item.prompt)) {
954
+ message = item.prompt.join('\n');
955
+ } else {
956
+ message = item.prompt;
957
+ }
958
+
959
+ // Replace placeholders in prompt message with collected config values
960
+ if (typeof message === 'string') {
961
+ message = this.replacePlaceholders(message, moduleName, moduleConfig);
962
+ }
963
+
964
+ // Add current value indicator for existing configs
965
+ if (existingValue !== null && existingValue !== undefined) {
966
+ if (typeof existingValue === 'boolean') {
967
+ message += chalk.dim(` (current: ${existingValue ? 'true' : 'false'})`);
968
+ } else if (Array.isArray(existingValue)) {
969
+ message += chalk.dim(` (current: ${existingValue.join(', ')})`);
970
+ } else if (questionType !== 'list') {
971
+ // Show the cleaned value (without {project-root}/) for display
972
+ message += chalk.dim(` (current: ${existingValue})`);
973
+ }
974
+ } else if (item.example && questionType === 'input') {
975
+ // Show example for input fields
976
+ let exampleText = typeof item.example === 'string' ? item.example : JSON.stringify(item.example);
977
+ // Replace placeholders in example
978
+ if (typeof exampleText === 'string') {
979
+ exampleText = this.replacePlaceholders(exampleText, moduleName, moduleConfig);
980
+ exampleText = exampleText.replace('{project-root}/', '');
981
+ }
982
+ message += chalk.dim(` (e.g., ${exampleText})`);
983
+ }
984
+
985
+ // Build the question object
986
+ const question = {
987
+ type: questionType,
988
+ name: questionName,
989
+ message: message,
990
+ };
991
+
992
+ // Set default - if it's dynamic, use a function that the prompt will evaluate with current answers
993
+ // But if we have an existing value, always use that instead
994
+ if (existingValue !== null && existingValue !== undefined && questionType !== 'list') {
995
+ question.default = existingValue;
996
+ } else if (dynamicDefault && typeof item.default === 'string') {
997
+ const originalDefault = item.default;
998
+ question.default = (answers) => {
999
+ // Replace placeholders using answers from previous questions in the same batch
1000
+ let resolved = originalDefault;
1001
+ resolved = resolved.replaceAll(/{([^}]+)}/g, (match, fieldName) => {
1002
+ // Look for the answer in the current batch (prefixed with module name)
1003
+ const answerKey = `${moduleName}_${fieldName}`;
1004
+ if (answers[answerKey] !== undefined) {
1005
+ return answers[answerKey];
1006
+ }
1007
+ // Fall back to collected config
1008
+ return this.collectedConfig[moduleName]?.[fieldName] || match;
1009
+ });
1010
+ // Strip {project-root}/ for cleaner display
1011
+ if (resolved.includes('{project-root}/')) {
1012
+ resolved = resolved.replace('{project-root}/', '');
1013
+ }
1014
+ return resolved;
1015
+ };
1016
+ } else {
1017
+ question.default = defaultValue;
1018
+ }
1019
+
1020
+ // Add choices for select types
1021
+ if (choices) {
1022
+ question.choices = choices;
1023
+ }
1024
+
1025
+ // Add validation for input fields
1026
+ if (questionType === 'input') {
1027
+ question.validate = (input) => {
1028
+ if (!input && item.required) {
1029
+ return 'This field is required';
1030
+ }
1031
+ // Validate against regex pattern if provided
1032
+ if (input && item.regex) {
1033
+ const regex = new RegExp(item.regex);
1034
+ if (!regex.test(input)) {
1035
+ return `Invalid format. Must match pattern: ${item.regex}`;
1036
+ }
1037
+ }
1038
+ return true;
1039
+ };
1040
+ }
1041
+
1042
+ // Add validation for checkbox (multi-select) fields
1043
+ if (questionType === 'checkbox' && item.required) {
1044
+ question.validate = (answers) => {
1045
+ if (!answers || answers.length === 0) {
1046
+ return 'At least one option must be selected';
1047
+ }
1048
+ return true;
1049
+ };
1050
+ }
1051
+
1052
+ return question;
1053
+ }
1054
+
1055
+ /**
1056
+ * Deep merge two objects
1057
+ * @param {Object} target - Target object
1058
+ * @param {Object} source - Source object
1059
+ */
1060
+ deepMerge(target, source) {
1061
+ const result = { ...target };
1062
+
1063
+ for (const key in source) {
1064
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
1065
+ if (result[key] && typeof result[key] === 'object' && !Array.isArray(result[key])) {
1066
+ result[key] = this.deepMerge(result[key], source[key]);
1067
+ } else {
1068
+ result[key] = source[key];
1069
+ }
1070
+ } else {
1071
+ result[key] = source[key];
1072
+ }
1073
+ }
1074
+
1075
+ return result;
1076
+ }
1077
+ }
1078
+
1079
+ module.exports = { ConfigCollector };