observer-ggboy-bmad-method 6.0.0-alpha.23

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 (604) hide show
  1. package/.coderabbit.yaml +40 -0
  2. package/.github/CODE_OF_CONDUCT.md +128 -0
  3. package/.github/FUNDING.yaml +15 -0
  4. package/.github/ISSUE_TEMPLATE/config.yaml +8 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  6. package/.github/ISSUE_TEMPLATE/issue.md +32 -0
  7. package/.github/scripts/discord-helpers.sh +34 -0
  8. package/.github/workflows/bundle-latest.yaml +330 -0
  9. package/.github/workflows/discord.yaml +90 -0
  10. package/.github/workflows/docs.yaml +63 -0
  11. package/.github/workflows/manual-release.yaml +190 -0
  12. package/.github/workflows/quality.yaml +115 -0
  13. package/.health-status.json +7 -0
  14. package/.husky/pre-commit +20 -0
  15. package/.markdownlint-cli2.yaml +41 -0
  16. package/.nvmrc +1 -0
  17. package/.prettierignore +9 -0
  18. package/.vscode/settings.json +97 -0
  19. package/CHANGELOG.md +1394 -0
  20. package/CNAME +1 -0
  21. package/CONTRIBUTING.md +167 -0
  22. package/CONTRIBUTORS.md +32 -0
  23. package/LICENSE +30 -0
  24. package/README.md +100 -0
  25. package/SECURITY.md +85 -0
  26. package/TRADEMARK.md +55 -0
  27. package/Wordmark.png +0 -0
  28. package/banner-bmad-method.png +0 -0
  29. package/bmad-method-6.0.0-alpha.23.tgz +0 -0
  30. package/docs/404.md +9 -0
  31. package/docs/_README_WORKFLOW_DIAGRAMS.md +40 -0
  32. package/docs/_STYLE_GUIDE.md +367 -0
  33. package/docs/_archive/customize-workflows.md +30 -0
  34. package/docs/_archive/getting-started-bmadv4.md +247 -0
  35. package/docs/_archive/vendor-workflows.md +52 -0
  36. package/docs/downloads.md +72 -0
  37. package/docs/explanation/agents/barry-quick-flow.md +328 -0
  38. package/docs/explanation/agents/index.md +19 -0
  39. package/docs/explanation/architecture/four-phases.md +107 -0
  40. package/docs/explanation/architecture/preventing-agent-conflicts.md +111 -0
  41. package/docs/explanation/architecture/why-solutioning-matters.md +75 -0
  42. package/docs/explanation/bmm/index.md +131 -0
  43. package/docs/explanation/core/index.md +18 -0
  44. package/docs/explanation/core-concepts/agent-roles.md +179 -0
  45. package/docs/explanation/core-concepts/index.md +35 -0
  46. package/docs/explanation/core-concepts/what-are-agents.md +97 -0
  47. package/docs/explanation/core-concepts/what-are-modules.md +85 -0
  48. package/docs/explanation/core-concepts/what-are-workflows.md +204 -0
  49. package/docs/explanation/faq/brownfield-faq.md +73 -0
  50. package/docs/explanation/faq/getting-started-faq.md +67 -0
  51. package/docs/explanation/faq/implementation-faq.md +52 -0
  52. package/docs/explanation/faq/index.md +16 -0
  53. package/docs/explanation/faq/levels-and-tracks-faq.md +52 -0
  54. package/docs/explanation/faq/planning-faq.md +41 -0
  55. package/docs/explanation/faq/tools-faq.md +277 -0
  56. package/docs/explanation/faq/workflows-faq.md +61 -0
  57. package/docs/explanation/features/advanced-elicitation.md +95 -0
  58. package/docs/explanation/features/brainstorming-techniques.md +92 -0
  59. package/docs/explanation/features/party-mode.md +95 -0
  60. package/docs/explanation/features/quick-flow.md +149 -0
  61. package/docs/explanation/features/tea-overview.md +410 -0
  62. package/docs/explanation/features/web-bundles.md +34 -0
  63. package/docs/explanation/philosophy/facilitation-over-generation.md +333 -0
  64. package/docs/explanation/philosophy/testing-as-engineering.md +112 -0
  65. package/docs/explanation/tea/engagement-models.md +710 -0
  66. package/docs/explanation/tea/fixture-architecture.md +457 -0
  67. package/docs/explanation/tea/knowledge-base-system.md +554 -0
  68. package/docs/explanation/tea/network-first-patterns.md +853 -0
  69. package/docs/explanation/tea/risk-based-testing.md +586 -0
  70. package/docs/explanation/tea/test-quality-standards.md +907 -0
  71. package/docs/how-to/brownfield/add-feature-to-existing.md +74 -0
  72. package/docs/how-to/brownfield/document-existing-project.md +66 -0
  73. package/docs/how-to/brownfield/index.md +84 -0
  74. package/docs/how-to/brownfield/quick-fix-in-brownfield.md +77 -0
  75. package/docs/how-to/brownfield/use-tea-for-enterprise.md +525 -0
  76. package/docs/how-to/brownfield/use-tea-with-existing-tests.md +577 -0
  77. package/docs/how-to/customization/customize-agents.md +212 -0
  78. package/docs/how-to/customization/enable-tea-mcp-enhancements.md +424 -0
  79. package/docs/how-to/customization/index.md +23 -0
  80. package/docs/how-to/customization/integrate-playwright-utils.md +813 -0
  81. package/docs/how-to/customization/shard-large-documents.md +101 -0
  82. package/docs/how-to/get-answers-about-bmad.md +102 -0
  83. package/docs/how-to/installation/index.md +12 -0
  84. package/docs/how-to/installation/install-bmad.md +111 -0
  85. package/docs/how-to/installation/install-custom-modules.md +118 -0
  86. package/docs/how-to/installation/upgrade-to-v6.md +131 -0
  87. package/docs/how-to/workflows/bmgd-quick-flow.md +156 -0
  88. package/docs/how-to/workflows/conduct-research.md +97 -0
  89. package/docs/how-to/workflows/create-architecture.md +119 -0
  90. package/docs/how-to/workflows/create-epics-and-stories.md +109 -0
  91. package/docs/how-to/workflows/create-prd.md +91 -0
  92. package/docs/how-to/workflows/create-product-brief.md +94 -0
  93. package/docs/how-to/workflows/create-story.md +102 -0
  94. package/docs/how-to/workflows/create-ux-design.md +100 -0
  95. package/docs/how-to/workflows/implement-story.md +97 -0
  96. package/docs/how-to/workflows/quick-spec.md +122 -0
  97. package/docs/how-to/workflows/run-atdd.md +436 -0
  98. package/docs/how-to/workflows/run-automate.md +653 -0
  99. package/docs/how-to/workflows/run-brainstorming-session.md +73 -0
  100. package/docs/how-to/workflows/run-code-review.md +89 -0
  101. package/docs/how-to/workflows/run-implementation-readiness.md +125 -0
  102. package/docs/how-to/workflows/run-nfr-assess.md +679 -0
  103. package/docs/how-to/workflows/run-sprint-planning.md +94 -0
  104. package/docs/how-to/workflows/run-test-design.md +135 -0
  105. package/docs/how-to/workflows/run-test-review.md +605 -0
  106. package/docs/how-to/workflows/run-trace.md +883 -0
  107. package/docs/how-to/workflows/setup-ci.md +712 -0
  108. package/docs/how-to/workflows/setup-party-mode.md +89 -0
  109. package/docs/how-to/workflows/setup-test-framework.md +98 -0
  110. package/docs/index.md +63 -0
  111. package/docs/reference/agents/index.md +109 -0
  112. package/docs/reference/configuration/core-tasks.md +67 -0
  113. package/docs/reference/configuration/global-config.md +28 -0
  114. package/docs/reference/glossary/index.md +159 -0
  115. package/docs/reference/tea/commands.md +276 -0
  116. package/docs/reference/tea/configuration.md +678 -0
  117. package/docs/reference/tea/knowledge-base.md +340 -0
  118. package/docs/reference/workflows/core-workflows.md +32 -0
  119. package/docs/reference/workflows/document-project.md +73 -0
  120. package/docs/reference/workflows/index.md +12 -0
  121. package/docs/tutorials/getting-started/getting-started-bmadv6.md +246 -0
  122. package/docs/tutorials/getting-started/images/workflow-method-greenfield.excalidraw +5034 -0
  123. package/docs/tutorials/getting-started/images/workflow-method-greenfield.svg +4 -0
  124. package/docs/tutorials/getting-started/images/workflow-overview.jpg +0 -0
  125. package/docs/tutorials/getting-started/tea-lite-quickstart.md +444 -0
  126. package/docs/tutorials/getting-started/workflow-overview.jpg +0 -0
  127. package/eslint.config.mjs +152 -0
  128. package/package.json +117 -0
  129. package/prettier.config.mjs +32 -0
  130. package/src/bmm/_module-installer/installer.js +48 -0
  131. package/src/bmm/_module-installer/platform-specifics/claude-code.js +35 -0
  132. package/src/bmm/_module-installer/platform-specifics/windsurf.js +32 -0
  133. package/src/bmm/agents/analyst.agent.yaml +36 -0
  134. package/src/bmm/agents/architect.agent.yaml +28 -0
  135. package/src/bmm/agents/dev.agent.yaml +38 -0
  136. package/src/bmm/agents/pm.agent.yaml +46 -0
  137. package/src/bmm/agents/quick-flow-solo-dev.agent.yaml +32 -0
  138. package/src/bmm/agents/sm.agent.yaml +36 -0
  139. package/src/bmm/agents/tea.agent.yaml +63 -0
  140. package/src/bmm/agents/tech-writer/tech-writer-sidecar/documentation-standards.md +224 -0
  141. package/src/bmm/agents/tech-writer/tech-writer.agent.yaml +45 -0
  142. package/src/bmm/agents/ux-designer.agent.yaml +26 -0
  143. package/src/bmm/data/project-context-template.md +26 -0
  144. package/src/bmm/module-help.csv +32 -0
  145. package/src/bmm/module.yaml +44 -0
  146. package/src/bmm/sub-modules/claude-code/config.yaml +4 -0
  147. package/src/bmm/sub-modules/claude-code/injections.yaml +242 -0
  148. package/src/bmm/sub-modules/claude-code/readme.md +87 -0
  149. package/src/bmm/teams/default-party.csv +21 -0
  150. package/src/bmm/teams/team-fullstack.yaml +12 -0
  151. package/src/bmm/testarch/knowledge/adr-quality-readiness-checklist.md +350 -0
  152. package/src/bmm/testarch/knowledge/api-request.md +442 -0
  153. package/src/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
  154. package/src/bmm/testarch/knowledge/auth-session.md +552 -0
  155. package/src/bmm/testarch/knowledge/burn-in.md +273 -0
  156. package/src/bmm/testarch/knowledge/ci-burn-in.md +675 -0
  157. package/src/bmm/testarch/knowledge/component-tdd.md +486 -0
  158. package/src/bmm/testarch/knowledge/contract-testing.md +957 -0
  159. package/src/bmm/testarch/knowledge/data-factories.md +500 -0
  160. package/src/bmm/testarch/knowledge/email-auth.md +721 -0
  161. package/src/bmm/testarch/knowledge/error-handling.md +725 -0
  162. package/src/bmm/testarch/knowledge/feature-flags.md +750 -0
  163. package/src/bmm/testarch/knowledge/file-utils.md +463 -0
  164. package/src/bmm/testarch/knowledge/fixture-architecture.md +401 -0
  165. package/src/bmm/testarch/knowledge/fixtures-composition.md +382 -0
  166. package/src/bmm/testarch/knowledge/intercept-network-call.md +430 -0
  167. package/src/bmm/testarch/knowledge/log.md +429 -0
  168. package/src/bmm/testarch/knowledge/network-error-monitor.md +405 -0
  169. package/src/bmm/testarch/knowledge/network-first.md +486 -0
  170. package/src/bmm/testarch/knowledge/network-recorder.md +527 -0
  171. package/src/bmm/testarch/knowledge/nfr-criteria.md +670 -0
  172. package/src/bmm/testarch/knowledge/overview.md +286 -0
  173. package/src/bmm/testarch/knowledge/playwright-config.md +730 -0
  174. package/src/bmm/testarch/knowledge/probability-impact.md +601 -0
  175. package/src/bmm/testarch/knowledge/recurse.md +421 -0
  176. package/src/bmm/testarch/knowledge/risk-governance.md +615 -0
  177. package/src/bmm/testarch/knowledge/selective-testing.md +732 -0
  178. package/src/bmm/testarch/knowledge/selector-resilience.md +527 -0
  179. package/src/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
  180. package/src/bmm/testarch/knowledge/test-levels-framework.md +473 -0
  181. package/src/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
  182. package/src/bmm/testarch/knowledge/test-quality.md +664 -0
  183. package/src/bmm/testarch/knowledge/timing-debugging.md +372 -0
  184. package/src/bmm/testarch/knowledge/visual-debugging.md +524 -0
  185. package/src/bmm/testarch/tea-index.csv +35 -0
  186. package/src/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
  187. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
  188. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
  189. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
  190. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
  191. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
  192. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
  193. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
  194. package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
  195. package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
  196. package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
  197. package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
  198. package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
  199. package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
  200. package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
  201. package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
  202. package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
  203. package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
  204. package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
  205. package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
  206. package/src/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
  207. package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
  208. package/src/bmm/workflows/1-analysis/research/research.template.md +29 -0
  209. package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
  210. package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
  211. package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
  212. package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
  213. package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
  214. package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
  215. package/src/bmm/workflows/1-analysis/research/workflow.md +173 -0
  216. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
  217. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
  218. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
  219. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
  220. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
  221. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
  222. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
  223. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
  224. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
  225. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
  226. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
  227. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
  228. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
  229. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
  230. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
  231. package/src/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
  232. package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
  233. package/src/bmm/workflows/2-plan-workflows/prd/data/domain-complexity.csv +13 -0
  234. package/src/bmm/workflows/2-plan-workflows/prd/data/prd-purpose.md +197 -0
  235. package/src/bmm/workflows/2-plan-workflows/prd/data/project-types.csv +11 -0
  236. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-01-init.md +191 -0
  237. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-01b-continue.md +153 -0
  238. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-02-discovery.md +224 -0
  239. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-03-success.md +226 -0
  240. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-04-journeys.md +213 -0
  241. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-05-domain.md +207 -0
  242. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-06-innovation.md +226 -0
  243. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-07-project-type.md +237 -0
  244. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-08-scoping.md +228 -0
  245. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-09-functional.md +231 -0
  246. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-10-nonfunctional.md +242 -0
  247. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-11-polish.md +217 -0
  248. package/src/bmm/workflows/2-plan-workflows/prd/steps-c/step-12-complete.md +124 -0
  249. package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01-discovery.md +247 -0
  250. package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
  251. package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-02-review.md +249 -0
  252. package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-03-edit.md +253 -0
  253. package/src/bmm/workflows/2-plan-workflows/prd/steps-e/step-e-04-complete.md +168 -0
  254. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-01-discovery.md +218 -0
  255. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02-format-detection.md +191 -0
  256. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-02b-parity-check.md +209 -0
  257. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-03-density-validation.md +174 -0
  258. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
  259. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-05-measurability-validation.md +228 -0
  260. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-06-traceability-validation.md +217 -0
  261. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
  262. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
  263. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-09-project-type-validation.md +263 -0
  264. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-10-smart-validation.md +209 -0
  265. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
  266. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-12-completeness-validation.md +242 -0
  267. package/src/bmm/workflows/2-plan-workflows/prd/steps-v/step-v-13-report-complete.md +231 -0
  268. package/src/bmm/workflows/2-plan-workflows/prd/templates/prd-template.md +10 -0
  269. package/src/bmm/workflows/2-plan-workflows/prd/validation-report-prd-workflow.md +433 -0
  270. package/src/bmm/workflows/2-plan-workflows/prd/workflow.md +150 -0
  271. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
  272. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
  273. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
  274. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
  275. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
  276. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +135 -0
  277. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
  278. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
  279. package/src/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
  280. package/src/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
  281. package/src/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
  282. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
  283. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
  284. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
  285. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
  286. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
  287. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
  288. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
  289. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
  290. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
  291. package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
  292. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
  293. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
  294. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
  295. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
  296. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
  297. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
  298. package/src/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
  299. package/src/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
  300. package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +51 -0
  301. package/src/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
  302. package/src/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
  303. package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +60 -0
  304. package/src/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
  305. package/src/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
  306. package/src/bmm/workflows/4-implementation/create-story/template.md +49 -0
  307. package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +61 -0
  308. package/src/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
  309. package/src/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
  310. package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +27 -0
  311. package/src/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
  312. package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +58 -0
  313. package/src/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
  314. package/src/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
  315. package/src/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
  316. package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +54 -0
  317. package/src/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
  318. package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +36 -0
  319. package/src/bmm/workflows/bmad-quick-flow/quick-dev/data/project-levels.yaml +59 -0
  320. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +156 -0
  321. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
  322. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
  323. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
  324. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
  325. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +140 -0
  326. package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -0
  327. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +189 -0
  328. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +144 -0
  329. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
  330. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +191 -0
  331. package/src/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
  332. package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
  333. package/src/bmm/workflows/document-project/checklist.md +245 -0
  334. package/src/bmm/workflows/document-project/documentation-requirements.csv +12 -0
  335. package/src/bmm/workflows/document-project/instructions.md +221 -0
  336. package/src/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
  337. package/src/bmm/workflows/document-project/templates/index-template.md +169 -0
  338. package/src/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
  339. package/src/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
  340. package/src/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
  341. package/src/bmm/workflows/document-project/workflow.yaml +30 -0
  342. package/src/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
  343. package/src/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
  344. package/src/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
  345. package/src/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
  346. package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
  347. package/src/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
  348. package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
  349. package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
  350. package/src/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +27 -0
  351. package/src/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
  352. package/src/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
  353. package/src/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +27 -0
  354. package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
  355. package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
  356. package/src/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +27 -0
  357. package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
  358. package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
  359. package/src/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +27 -0
  360. package/src/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
  361. package/src/bmm/workflows/testarch/atdd/checklist.md +374 -0
  362. package/src/bmm/workflows/testarch/atdd/instructions.md +806 -0
  363. package/src/bmm/workflows/testarch/atdd/workflow.yaml +47 -0
  364. package/src/bmm/workflows/testarch/automate/checklist.md +582 -0
  365. package/src/bmm/workflows/testarch/automate/instructions.md +1324 -0
  366. package/src/bmm/workflows/testarch/automate/workflow.yaml +54 -0
  367. package/src/bmm/workflows/testarch/ci/checklist.md +247 -0
  368. package/src/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
  369. package/src/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
  370. package/src/bmm/workflows/testarch/ci/instructions.md +536 -0
  371. package/src/bmm/workflows/testarch/ci/workflow.yaml +47 -0
  372. package/src/bmm/workflows/testarch/framework/checklist.md +320 -0
  373. package/src/bmm/workflows/testarch/framework/instructions.md +481 -0
  374. package/src/bmm/workflows/testarch/framework/workflow.yaml +49 -0
  375. package/src/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
  376. package/src/bmm/workflows/testarch/nfr-assess/instructions.md +726 -0
  377. package/src/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +461 -0
  378. package/src/bmm/workflows/testarch/nfr-assess/workflow.yaml +49 -0
  379. package/src/bmm/workflows/testarch/test-design/checklist.md +407 -0
  380. package/src/bmm/workflows/testarch/test-design/instructions.md +1158 -0
  381. package/src/bmm/workflows/testarch/test-design/test-design-architecture-template.md +213 -0
  382. package/src/bmm/workflows/testarch/test-design/test-design-qa-template.md +286 -0
  383. package/src/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
  384. package/src/bmm/workflows/testarch/test-design/workflow.yaml +71 -0
  385. package/src/bmm/workflows/testarch/test-review/checklist.md +472 -0
  386. package/src/bmm/workflows/testarch/test-review/instructions.md +628 -0
  387. package/src/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
  388. package/src/bmm/workflows/testarch/test-review/workflow.yaml +48 -0
  389. package/src/bmm/workflows/testarch/trace/checklist.md +642 -0
  390. package/src/bmm/workflows/testarch/trace/instructions.md +1030 -0
  391. package/src/bmm/workflows/testarch/trace/trace-template.md +675 -0
  392. package/src/bmm/workflows/testarch/trace/workflow.yaml +57 -0
  393. package/src/core/_module-installer/installer.js +60 -0
  394. package/src/core/agents/bmad-master.agent.yaml +29 -0
  395. package/src/core/module-help.csv +9 -0
  396. package/src/core/module.yaml +25 -0
  397. package/src/core/resources/excalidraw/README.md +160 -0
  398. package/src/core/resources/excalidraw/excalidraw-helpers.md +127 -0
  399. package/src/core/resources/excalidraw/library-loader.md +50 -0
  400. package/src/core/resources/excalidraw/validate-json-instructions.md +79 -0
  401. package/src/core/tasks/editorial-review-prose.xml +100 -0
  402. package/src/core/tasks/editorial-review-structure.xml +209 -0
  403. package/src/core/tasks/help.md +62 -0
  404. package/src/core/tasks/index-docs.xml +65 -0
  405. package/src/core/tasks/review-adversarial-general.xml +48 -0
  406. package/src/core/tasks/shard-doc.xml +109 -0
  407. package/src/core/tasks/workflow.xml +235 -0
  408. package/src/core/workflows/advanced-elicitation/methods.csv +51 -0
  409. package/src/core/workflows/advanced-elicitation/workflow.xml +117 -0
  410. package/src/core/workflows/brainstorming/brain-methods.csv +62 -0
  411. package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
  412. package/src/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
  413. package/src/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
  414. package/src/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
  415. package/src/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
  416. package/src/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
  417. package/src/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
  418. package/src/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
  419. package/src/core/workflows/brainstorming/template.md +15 -0
  420. package/src/core/workflows/brainstorming/workflow.md +58 -0
  421. package/src/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
  422. package/src/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
  423. package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
  424. package/src/core/workflows/party-mode/workflow.md +194 -0
  425. package/src/utility/agent-components/activation-rules.txt +6 -0
  426. package/src/utility/agent-components/activation-steps.txt +14 -0
  427. package/src/utility/agent-components/agent-command-header.md +1 -0
  428. package/src/utility/agent-components/agent.customize.template.yaml +41 -0
  429. package/src/utility/agent-components/handler-action.txt +4 -0
  430. package/src/utility/agent-components/handler-data.txt +5 -0
  431. package/src/utility/agent-components/handler-exec.txt +6 -0
  432. package/src/utility/agent-components/handler-multi.txt +14 -0
  433. package/src/utility/agent-components/handler-tmpl.txt +5 -0
  434. package/src/utility/agent-components/handler-validate-workflow.txt +7 -0
  435. package/src/utility/agent-components/handler-workflow.txt +10 -0
  436. package/src/utility/agent-components/menu-handlers.txt +6 -0
  437. package/test/README.md +295 -0
  438. package/test/adversarial-review-tests/README.md +56 -0
  439. package/test/adversarial-review-tests/sample-content.md +46 -0
  440. package/test/adversarial-review-tests/test-cases.yaml +103 -0
  441. package/test/fixtures/agent-schema/invalid/critical-actions/actions-as-string.agent.yaml +27 -0
  442. package/test/fixtures/agent-schema/invalid/critical-actions/empty-string-in-actions.agent.yaml +30 -0
  443. package/test/fixtures/agent-schema/invalid/menu/empty-menu.agent.yaml +22 -0
  444. package/test/fixtures/agent-schema/invalid/menu/missing-menu.agent.yaml +20 -0
  445. package/test/fixtures/agent-schema/invalid/menu-commands/empty-command-target.agent.yaml +25 -0
  446. package/test/fixtures/agent-schema/invalid/menu-commands/no-command-target.agent.yaml +24 -0
  447. package/test/fixtures/agent-schema/invalid/menu-triggers/camel-case.agent.yaml +25 -0
  448. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-invalid-format.agent.yaml +25 -0
  449. package/test/fixtures/agent-schema/invalid/menu-triggers/compound-mismatched-kebab.agent.yaml +25 -0
  450. package/test/fixtures/agent-schema/invalid/menu-triggers/duplicate-triggers.agent.yaml +31 -0
  451. package/test/fixtures/agent-schema/invalid/menu-triggers/empty-trigger.agent.yaml +25 -0
  452. package/test/fixtures/agent-schema/invalid/menu-triggers/leading-asterisk.agent.yaml +25 -0
  453. package/test/fixtures/agent-schema/invalid/menu-triggers/snake-case.agent.yaml +25 -0
  454. package/test/fixtures/agent-schema/invalid/menu-triggers/trigger-with-spaces.agent.yaml +25 -0
  455. package/test/fixtures/agent-schema/invalid/metadata/empty-module-string.agent.yaml +26 -0
  456. package/test/fixtures/agent-schema/invalid/metadata/empty-name.agent.yaml +24 -0
  457. package/test/fixtures/agent-schema/invalid/metadata/extra-metadata-fields.agent.yaml +27 -0
  458. package/test/fixtures/agent-schema/invalid/metadata/missing-id.agent.yaml +23 -0
  459. package/test/fixtures/agent-schema/invalid/persona/empty-principles-array.agent.yaml +24 -0
  460. package/test/fixtures/agent-schema/invalid/persona/empty-string-in-principles.agent.yaml +27 -0
  461. package/test/fixtures/agent-schema/invalid/persona/extra-persona-fields.agent.yaml +27 -0
  462. package/test/fixtures/agent-schema/invalid/persona/missing-role.agent.yaml +24 -0
  463. package/test/fixtures/agent-schema/invalid/prompts/empty-content.agent.yaml +29 -0
  464. package/test/fixtures/agent-schema/invalid/prompts/extra-prompt-fields.agent.yaml +31 -0
  465. package/test/fixtures/agent-schema/invalid/prompts/missing-content.agent.yaml +28 -0
  466. package/test/fixtures/agent-schema/invalid/prompts/missing-id.agent.yaml +28 -0
  467. package/test/fixtures/agent-schema/invalid/top-level/empty-file.agent.yaml +5 -0
  468. package/test/fixtures/agent-schema/invalid/top-level/extra-top-level-keys.agent.yaml +28 -0
  469. package/test/fixtures/agent-schema/invalid/top-level/missing-agent-key.agent.yaml +11 -0
  470. package/test/fixtures/agent-schema/invalid/yaml-errors/invalid-indentation.agent.yaml +19 -0
  471. package/test/fixtures/agent-schema/invalid/yaml-errors/malformed-yaml.agent.yaml +18 -0
  472. package/test/fixtures/agent-schema/valid/critical-actions/empty-critical-actions.agent.yaml +24 -0
  473. package/test/fixtures/agent-schema/valid/critical-actions/no-critical-actions.agent.yaml +22 -0
  474. package/test/fixtures/agent-schema/valid/critical-actions/valid-critical-actions.agent.yaml +27 -0
  475. package/test/fixtures/agent-schema/valid/menu/multiple-menu-items.agent.yaml +31 -0
  476. package/test/fixtures/agent-schema/valid/menu/single-menu-item.agent.yaml +22 -0
  477. package/test/fixtures/agent-schema/valid/menu-commands/all-command-types.agent.yaml +38 -0
  478. package/test/fixtures/agent-schema/valid/menu-commands/multiple-commands.agent.yaml +24 -0
  479. package/test/fixtures/agent-schema/valid/menu-triggers/compound-triggers.agent.yaml +31 -0
  480. package/test/fixtures/agent-schema/valid/menu-triggers/kebab-case-triggers.agent.yaml +34 -0
  481. package/test/fixtures/agent-schema/valid/metadata/core-agent-with-module.agent.yaml +24 -0
  482. package/test/fixtures/agent-schema/valid/metadata/empty-module-name-in-path.agent.yaml +24 -0
  483. package/test/fixtures/agent-schema/valid/metadata/malformed-path-treated-as-core.agent.yaml +24 -0
  484. package/test/fixtures/agent-schema/valid/metadata/module-agent-correct.agent.yaml +24 -0
  485. package/test/fixtures/agent-schema/valid/metadata/module-agent-missing-module.agent.yaml +23 -0
  486. package/test/fixtures/agent-schema/valid/metadata/wrong-module-value.agent.yaml +24 -0
  487. package/test/fixtures/agent-schema/valid/persona/complete-persona.agent.yaml +24 -0
  488. package/test/fixtures/agent-schema/valid/prompts/empty-prompts.agent.yaml +24 -0
  489. package/test/fixtures/agent-schema/valid/prompts/no-prompts.agent.yaml +22 -0
  490. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-minimal.agent.yaml +28 -0
  491. package/test/fixtures/agent-schema/valid/prompts/valid-prompts-with-description.agent.yaml +30 -0
  492. package/test/fixtures/agent-schema/valid/top-level/minimal-core-agent.agent.yaml +24 -0
  493. package/test/test-agent-schema.js +387 -0
  494. package/test/test-cli-integration.sh +159 -0
  495. package/test/test-installation-components.js +214 -0
  496. package/test/unit-test-schema.js +133 -0
  497. package/tools/bmad-npx-wrapper.js +38 -0
  498. package/tools/build-docs.js +577 -0
  499. package/tools/cli/README.md +7 -0
  500. package/tools/cli/bmad-cli.js +58 -0
  501. package/tools/cli/commands/install.js +87 -0
  502. package/tools/cli/commands/status.js +65 -0
  503. package/tools/cli/external-official-modules.yaml +56 -0
  504. package/tools/cli/installers/install-messages.yaml +58 -0
  505. package/tools/cli/installers/lib/core/config-collector.js +1079 -0
  506. package/tools/cli/installers/lib/core/custom-module-cache.js +259 -0
  507. package/tools/cli/installers/lib/core/dependency-resolver.js +739 -0
  508. package/tools/cli/installers/lib/core/detector.js +223 -0
  509. package/tools/cli/installers/lib/core/ide-config-manager.js +156 -0
  510. package/tools/cli/installers/lib/core/installer.js +2826 -0
  511. package/tools/cli/installers/lib/core/manifest-generator.js +1054 -0
  512. package/tools/cli/installers/lib/core/manifest.js +1036 -0
  513. package/tools/cli/installers/lib/custom/handler.js +363 -0
  514. package/tools/cli/installers/lib/ide/STANDARDIZATION_PLAN.md +208 -0
  515. package/tools/cli/installers/lib/ide/_base-ide.js +655 -0
  516. package/tools/cli/installers/lib/ide/antigravity.js +474 -0
  517. package/tools/cli/installers/lib/ide/auggie.js +244 -0
  518. package/tools/cli/installers/lib/ide/claude-code.js +506 -0
  519. package/tools/cli/installers/lib/ide/cline.js +272 -0
  520. package/tools/cli/installers/lib/ide/codex.js +412 -0
  521. package/tools/cli/installers/lib/ide/crush.js +149 -0
  522. package/tools/cli/installers/lib/ide/cursor.js +160 -0
  523. package/tools/cli/installers/lib/ide/gemini.js +301 -0
  524. package/tools/cli/installers/lib/ide/github-copilot.js +383 -0
  525. package/tools/cli/installers/lib/ide/iflow.js +191 -0
  526. package/tools/cli/installers/lib/ide/kilo.js +250 -0
  527. package/tools/cli/installers/lib/ide/kiro-cli.js +326 -0
  528. package/tools/cli/installers/lib/ide/manager.js +244 -0
  529. package/tools/cli/installers/lib/ide/opencode.js +257 -0
  530. package/tools/cli/installers/lib/ide/qwen.js +372 -0
  531. package/tools/cli/installers/lib/ide/roo.js +273 -0
  532. package/tools/cli/installers/lib/ide/rovo-dev.js +290 -0
  533. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +165 -0
  534. package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +158 -0
  535. package/tools/cli/installers/lib/ide/shared/module-injections.js +136 -0
  536. package/tools/cli/installers/lib/ide/shared/path-utils.js +165 -0
  537. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +268 -0
  538. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +293 -0
  539. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +14 -0
  540. package/tools/cli/installers/lib/ide/templates/gemini-agent-command.toml +14 -0
  541. package/tools/cli/installers/lib/ide/templates/gemini-task-command.toml +12 -0
  542. package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +13 -0
  543. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
  544. package/tools/cli/installers/lib/ide/trae.js +313 -0
  545. package/tools/cli/installers/lib/ide/windsurf.js +258 -0
  546. package/tools/cli/installers/lib/message-loader.js +85 -0
  547. package/tools/cli/installers/lib/modules/external-manager.js +135 -0
  548. package/tools/cli/installers/lib/modules/manager.js +1375 -0
  549. package/tools/cli/lib/activation-builder.js +163 -0
  550. package/tools/cli/lib/agent/compiler.js +522 -0
  551. package/tools/cli/lib/agent/installer.js +716 -0
  552. package/tools/cli/lib/agent/template-engine.js +152 -0
  553. package/tools/cli/lib/agent-analyzer.js +109 -0
  554. package/tools/cli/lib/agent-party-generator.js +194 -0
  555. package/tools/cli/lib/cli-utils.js +227 -0
  556. package/tools/cli/lib/config.js +213 -0
  557. package/tools/cli/lib/file-ops.js +204 -0
  558. package/tools/cli/lib/platform-codes.js +116 -0
  559. package/tools/cli/lib/project-root.js +77 -0
  560. package/tools/cli/lib/prompts.js +433 -0
  561. package/tools/cli/lib/ui.js +1716 -0
  562. package/tools/cli/lib/xml-handler.js +177 -0
  563. package/tools/cli/lib/xml-to-markdown.js +82 -0
  564. package/tools/cli/lib/yaml-format.js +245 -0
  565. package/tools/cli/lib/yaml-xml-builder.js +587 -0
  566. package/tools/docs/BUNDLE_DISTRIBUTION_SETUP.md +95 -0
  567. package/tools/docs/index.md +2 -0
  568. package/tools/fix-doc-links.js +288 -0
  569. package/tools/flattener/aggregate.js +76 -0
  570. package/tools/flattener/binary.js +80 -0
  571. package/tools/flattener/discovery.js +71 -0
  572. package/tools/flattener/files.js +35 -0
  573. package/tools/flattener/ignoreRules.js +172 -0
  574. package/tools/flattener/main.js +483 -0
  575. package/tools/flattener/projectRoot.js +201 -0
  576. package/tools/flattener/prompts.js +44 -0
  577. package/tools/flattener/stats.helpers.js +368 -0
  578. package/tools/flattener/stats.js +75 -0
  579. package/tools/flattener/test-matrix.js +409 -0
  580. package/tools/flattener/xml.js +82 -0
  581. package/tools/format-workflow-md.js +263 -0
  582. package/tools/lib/xml-utils.js +13 -0
  583. package/tools/maintainer/review-pr-README.md +55 -0
  584. package/tools/maintainer/review-pr.md +242 -0
  585. package/tools/migrate-custom-module-paths.js +124 -0
  586. package/tools/platform-codes.yaml +157 -0
  587. package/tools/schema/agent.js +491 -0
  588. package/tools/validate-agent-schema.js +110 -0
  589. package/tools/validate-doc-links.js +363 -0
  590. package/tools/validate-svg-changes.sh +356 -0
  591. package/website/README.md +76 -0
  592. package/website/astro.config.mjs +228 -0
  593. package/website/public/favicon.ico +0 -0
  594. package/website/public/img/bmad-dark.png +0 -0
  595. package/website/public/img/bmad-light.png +0 -0
  596. package/website/public/img/logo.svg +4 -0
  597. package/website/public/robots.txt +37 -0
  598. package/website/src/components/Banner.astro +59 -0
  599. package/website/src/components/Header.astro +121 -0
  600. package/website/src/components/MobileMenuFooter.astro +53 -0
  601. package/website/src/content/config.ts +6 -0
  602. package/website/src/lib/site-url.js +25 -0
  603. package/website/src/rehype-markdown-links.js +102 -0
  604. package/website/src/styles/custom.css +485 -0
@@ -0,0 +1,1054 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const yaml = require('yaml');
4
+ const crypto = require('node:crypto');
5
+ const { getSourcePath, getModulePath } = require('../../../lib/project-root');
6
+
7
+ // Load package.json for version info
8
+ const packageJson = require('../../../../../package.json');
9
+
10
+ /**
11
+ * Generates manifest files for installed workflows, agents, and tasks
12
+ */
13
+ class ManifestGenerator {
14
+ constructor() {
15
+ this.workflows = [];
16
+ this.agents = [];
17
+ this.tasks = [];
18
+ this.tools = [];
19
+ this.modules = [];
20
+ this.files = [];
21
+ this.selectedIdes = [];
22
+ }
23
+
24
+ /**
25
+ * Generate all manifests for the installation
26
+ * @param {string} bmadDir - _bmad
27
+ * @param {Array} selectedModules - Selected modules for installation
28
+ * @param {Array} installedFiles - All installed files (optional, for hash tracking)
29
+ */
30
+ async generateManifests(bmadDir, selectedModules, installedFiles = [], options = {}) {
31
+ // Create _config directory if it doesn't exist
32
+ const cfgDir = path.join(bmadDir, '_config');
33
+ await fs.ensureDir(cfgDir);
34
+
35
+ // Store modules list (all modules including preserved ones)
36
+ const preservedModules = options.preservedModules || [];
37
+
38
+ // Scan the bmad directory to find all actually installed modules
39
+ const installedModules = await this.scanInstalledModules(bmadDir);
40
+
41
+ // Since custom modules are now installed the same way as regular modules,
42
+ // we don't need to exclude them from manifest generation
43
+ const allModules = [...new Set(['core', ...selectedModules, ...preservedModules, ...installedModules])];
44
+
45
+ this.modules = allModules;
46
+ this.updatedModules = allModules; // Include ALL modules (including custom) for scanning
47
+
48
+ // For CSV manifests, we need to include ALL modules that are installed
49
+ // preservedModules controls which modules stay as-is in the CSV (don't get rescanned)
50
+ // But all modules should be included in the final manifest
51
+ this.preservedModules = allModules; // Include ALL modules (including custom)
52
+ this.bmadDir = bmadDir;
53
+ this.bmadFolderName = path.basename(bmadDir); // Get the actual folder name (e.g., '_bmad' or 'bmad')
54
+ this.allInstalledFiles = installedFiles;
55
+
56
+ if (!Object.prototype.hasOwnProperty.call(options, 'ides')) {
57
+ throw new Error('ManifestGenerator requires `options.ides` to be provided – installer should supply the selected IDEs array.');
58
+ }
59
+
60
+ const resolvedIdes = options.ides ?? [];
61
+ if (!Array.isArray(resolvedIdes)) {
62
+ throw new TypeError('ManifestGenerator expected `options.ides` to be an array.');
63
+ }
64
+
65
+ // Filter out any undefined/null values from IDE list
66
+ this.selectedIdes = resolvedIdes.filter((ide) => ide && typeof ide === 'string');
67
+
68
+ // Collect workflow data
69
+ await this.collectWorkflows(selectedModules);
70
+
71
+ // Collect agent data - use updatedModules which includes all installed modules
72
+ await this.collectAgents(this.updatedModules);
73
+
74
+ // Collect task data
75
+ await this.collectTasks(this.updatedModules);
76
+
77
+ // Collect tool data
78
+ await this.collectTools(this.updatedModules);
79
+
80
+ // Write manifest files and collect their paths
81
+ const manifestFiles = [
82
+ await this.writeMainManifest(cfgDir),
83
+ await this.writeWorkflowManifest(cfgDir),
84
+ await this.writeAgentManifest(cfgDir),
85
+ await this.writeTaskManifest(cfgDir),
86
+ await this.writeToolManifest(cfgDir),
87
+ await this.writeFilesManifest(cfgDir),
88
+ ];
89
+
90
+ return {
91
+ workflows: this.workflows.length,
92
+ agents: this.agents.length,
93
+ tasks: this.tasks.length,
94
+ tools: this.tools.length,
95
+ files: this.files.length,
96
+ manifestFiles: manifestFiles,
97
+ };
98
+ }
99
+
100
+ /**
101
+ * Collect all workflows from core and selected modules
102
+ * Scans the INSTALLED bmad directory, not the source
103
+ */
104
+ async collectWorkflows(selectedModules) {
105
+ this.workflows = [];
106
+
107
+ // Use updatedModules which already includes deduplicated 'core' + selectedModules
108
+ for (const moduleName of this.updatedModules) {
109
+ const modulePath = path.join(this.bmadDir, moduleName);
110
+
111
+ if (await fs.pathExists(modulePath)) {
112
+ const moduleWorkflows = await this.getWorkflowsFromPath(modulePath, moduleName);
113
+ this.workflows.push(...moduleWorkflows);
114
+ }
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Recursively find and parse workflow.yaml and workflow.md files
120
+ */
121
+ async getWorkflowsFromPath(basePath, moduleName) {
122
+ const workflows = [];
123
+ const workflowsPath = path.join(basePath, 'workflows');
124
+ const debug = process.env.BMAD_DEBUG_MANIFEST === 'true';
125
+
126
+ if (debug) {
127
+ console.log(`[DEBUG] Scanning workflows in: ${workflowsPath}`);
128
+ }
129
+
130
+ if (!(await fs.pathExists(workflowsPath))) {
131
+ if (debug) {
132
+ console.log(`[DEBUG] Workflows path does not exist: ${workflowsPath}`);
133
+ }
134
+ return workflows;
135
+ }
136
+
137
+ // Recursively find workflow.yaml files
138
+ const findWorkflows = async (dir, relativePath = '') => {
139
+ const entries = await fs.readdir(dir, { withFileTypes: true });
140
+
141
+ for (const entry of entries) {
142
+ const fullPath = path.join(dir, entry.name);
143
+
144
+ if (entry.isDirectory()) {
145
+ // Recurse into subdirectories
146
+ const newRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
147
+ await findWorkflows(fullPath, newRelativePath);
148
+ } else if (entry.name === 'workflow.yaml' || entry.name === 'workflow.md') {
149
+ // Parse workflow file (both YAML and MD formats)
150
+ if (debug) {
151
+ console.log(`[DEBUG] Found workflow file: ${fullPath}`);
152
+ }
153
+ try {
154
+ // Read and normalize line endings (fix Windows CRLF issues)
155
+ const rawContent = await fs.readFile(fullPath, 'utf8');
156
+ const content = rawContent.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
157
+
158
+ let workflow;
159
+ if (entry.name === 'workflow.yaml') {
160
+ // Parse YAML workflow
161
+ workflow = yaml.parse(content);
162
+ } else {
163
+ // Parse MD workflow with YAML frontmatter
164
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
165
+ if (!frontmatterMatch) {
166
+ if (debug) {
167
+ console.log(`[DEBUG] Skipped (no frontmatter): ${fullPath}`);
168
+ }
169
+ continue; // Skip MD files without frontmatter
170
+ }
171
+ workflow = yaml.parse(frontmatterMatch[1]);
172
+ }
173
+
174
+ if (debug) {
175
+ console.log(`[DEBUG] Parsed: name="${workflow.name}", description=${workflow.description ? 'OK' : 'MISSING'}`);
176
+ }
177
+
178
+ // Skip template workflows (those with placeholder values)
179
+ if (workflow.name && workflow.name.includes('{') && workflow.name.includes('}')) {
180
+ if (debug) {
181
+ console.log(`[DEBUG] Skipped (template placeholder): ${workflow.name}`);
182
+ }
183
+ continue;
184
+ }
185
+
186
+ // Skip workflows marked as non-standalone (reference/example workflows)
187
+ if (workflow.standalone === false) {
188
+ if (debug) {
189
+ console.log(`[DEBUG] Skipped (standalone=false): ${workflow.name}`);
190
+ }
191
+ continue;
192
+ }
193
+
194
+ if (workflow.name && workflow.description) {
195
+ // Build relative path for installation
196
+ const installPath =
197
+ moduleName === 'core'
198
+ ? `${this.bmadFolderName}/core/workflows/${relativePath}/${entry.name}`
199
+ : `${this.bmadFolderName}/${moduleName}/workflows/${relativePath}/${entry.name}`;
200
+
201
+ // Workflows with standalone: false are filtered out above
202
+ workflows.push({
203
+ name: workflow.name,
204
+ description: workflow.description.replaceAll('"', '""'), // Escape quotes for CSV
205
+ module: moduleName,
206
+ path: installPath,
207
+ });
208
+
209
+ // Add to files list
210
+ this.files.push({
211
+ type: 'workflow',
212
+ name: workflow.name,
213
+ module: moduleName,
214
+ path: installPath,
215
+ });
216
+
217
+ if (debug) {
218
+ console.log(`[DEBUG] ✓ Added workflow: ${workflow.name} (${moduleName})`);
219
+ }
220
+ } else {
221
+ if (debug) {
222
+ console.log(`[DEBUG] Skipped (missing name or description): ${fullPath}`);
223
+ }
224
+ }
225
+ } catch (error) {
226
+ console.warn(`Warning: Failed to parse workflow at ${fullPath}: ${error.message}`);
227
+ }
228
+ }
229
+ }
230
+ };
231
+
232
+ await findWorkflows(workflowsPath);
233
+
234
+ if (debug) {
235
+ console.log(`[DEBUG] Total workflows found in ${moduleName}: ${workflows.length}`);
236
+ }
237
+
238
+ return workflows;
239
+ }
240
+
241
+ /**
242
+ * Collect all agents from core and selected modules
243
+ * Scans the INSTALLED bmad directory, not the source
244
+ */
245
+ async collectAgents(selectedModules) {
246
+ this.agents = [];
247
+
248
+ // Use updatedModules which already includes deduplicated 'core' + selectedModules
249
+ for (const moduleName of this.updatedModules) {
250
+ const agentsPath = path.join(this.bmadDir, moduleName, 'agents');
251
+
252
+ if (await fs.pathExists(agentsPath)) {
253
+ const moduleAgents = await this.getAgentsFromDir(agentsPath, moduleName);
254
+ this.agents.push(...moduleAgents);
255
+ }
256
+ }
257
+
258
+ // Get standalone agents from bmad/agents/ directory
259
+ const standaloneAgentsDir = path.join(this.bmadDir, 'agents');
260
+ if (await fs.pathExists(standaloneAgentsDir)) {
261
+ const agentDirs = await fs.readdir(standaloneAgentsDir, { withFileTypes: true });
262
+
263
+ for (const agentDir of agentDirs) {
264
+ if (!agentDir.isDirectory()) continue;
265
+
266
+ const agentDirPath = path.join(standaloneAgentsDir, agentDir.name);
267
+ const standaloneAgents = await this.getAgentsFromDir(agentDirPath, 'standalone');
268
+ this.agents.push(...standaloneAgents);
269
+ }
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Get agents from a directory recursively
275
+ * Only includes compiled .md files (not .agent.yaml source files)
276
+ */
277
+ async getAgentsFromDir(dirPath, moduleName, relativePath = '') {
278
+ const agents = [];
279
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
280
+
281
+ for (const entry of entries) {
282
+ const fullPath = path.join(dirPath, entry.name);
283
+
284
+ if (entry.isDirectory()) {
285
+ // Recurse into subdirectories
286
+ const newRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
287
+ const subDirAgents = await this.getAgentsFromDir(fullPath, moduleName, newRelativePath);
288
+ agents.push(...subDirAgents);
289
+ } else if (entry.name.endsWith('.md') && !entry.name.endsWith('.agent.yaml') && entry.name.toLowerCase() !== 'readme.md') {
290
+ const content = await fs.readFile(fullPath, 'utf8');
291
+
292
+ // Skip files that don't contain <agent> tag (e.g., README files)
293
+ if (!content.includes('<agent')) {
294
+ continue;
295
+ }
296
+
297
+ // Skip web-only agents
298
+ if (content.includes('localskip="true"')) {
299
+ continue;
300
+ }
301
+
302
+ // Extract agent metadata from the XML structure
303
+ const nameMatch = content.match(/name="([^"]+)"/);
304
+ const titleMatch = content.match(/title="([^"]+)"/);
305
+ const iconMatch = content.match(/icon="([^"]+)"/);
306
+
307
+ // Extract persona fields
308
+ const roleMatch = content.match(/<role>([^<]+)<\/role>/);
309
+ const identityMatch = content.match(/<identity>([\s\S]*?)<\/identity>/);
310
+ const styleMatch = content.match(/<communication_style>([\s\S]*?)<\/communication_style>/);
311
+ const principlesMatch = content.match(/<principles>([\s\S]*?)<\/principles>/);
312
+
313
+ // Build relative path for installation
314
+ const fileRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
315
+ const installPath =
316
+ moduleName === 'core'
317
+ ? `${this.bmadFolderName}/core/agents/${fileRelativePath}`
318
+ : `${this.bmadFolderName}/${moduleName}/agents/${fileRelativePath}`;
319
+
320
+ const agentName = entry.name.replace('.md', '');
321
+
322
+ // Helper function to clean and escape CSV content
323
+ const cleanForCSV = (text) => {
324
+ if (!text) return '';
325
+ return text
326
+ .trim()
327
+ .replaceAll(/\s+/g, ' ') // Normalize whitespace
328
+ .replaceAll('"', '""'); // Escape quotes for CSV
329
+ };
330
+
331
+ agents.push({
332
+ name: agentName,
333
+ displayName: nameMatch ? nameMatch[1] : agentName,
334
+ title: titleMatch ? titleMatch[1] : '',
335
+ icon: iconMatch ? iconMatch[1] : '',
336
+ role: roleMatch ? cleanForCSV(roleMatch[1]) : '',
337
+ identity: identityMatch ? cleanForCSV(identityMatch[1]) : '',
338
+ communicationStyle: styleMatch ? cleanForCSV(styleMatch[1]) : '',
339
+ principles: principlesMatch ? cleanForCSV(principlesMatch[1]) : '',
340
+ module: moduleName,
341
+ path: installPath,
342
+ });
343
+
344
+ // Add to files list
345
+ this.files.push({
346
+ type: 'agent',
347
+ name: agentName,
348
+ module: moduleName,
349
+ path: installPath,
350
+ });
351
+ }
352
+ }
353
+
354
+ return agents;
355
+ }
356
+
357
+ /**
358
+ * Collect all tasks from core and selected modules
359
+ * Scans the INSTALLED bmad directory, not the source
360
+ */
361
+ async collectTasks(selectedModules) {
362
+ this.tasks = [];
363
+
364
+ // Use updatedModules which already includes deduplicated 'core' + selectedModules
365
+ for (const moduleName of this.updatedModules) {
366
+ const tasksPath = path.join(this.bmadDir, moduleName, 'tasks');
367
+
368
+ if (await fs.pathExists(tasksPath)) {
369
+ const moduleTasks = await this.getTasksFromDir(tasksPath, moduleName);
370
+ this.tasks.push(...moduleTasks);
371
+ }
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Get tasks from a directory
377
+ */
378
+ async getTasksFromDir(dirPath, moduleName) {
379
+ const tasks = [];
380
+ const files = await fs.readdir(dirPath);
381
+
382
+ for (const file of files) {
383
+ // Check for both .xml and .md files
384
+ if (file.endsWith('.xml') || file.endsWith('.md')) {
385
+ const filePath = path.join(dirPath, file);
386
+ const content = await fs.readFile(filePath, 'utf8');
387
+
388
+ let name = file.replace(/\.(xml|md)$/, '');
389
+ let displayName = name;
390
+ let description = '';
391
+ let standalone = false;
392
+
393
+ if (file.endsWith('.md')) {
394
+ // Parse YAML frontmatter for .md tasks
395
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
396
+ if (frontmatterMatch) {
397
+ try {
398
+ const frontmatter = yaml.parse(frontmatterMatch[1]);
399
+ name = frontmatter.name || name;
400
+ displayName = frontmatter.displayName || frontmatter.name || name;
401
+ description = frontmatter.description || '';
402
+ standalone = frontmatter.standalone === true || frontmatter.standalone === 'true';
403
+ } catch {
404
+ // If YAML parsing fails, use defaults
405
+ }
406
+ }
407
+ } else {
408
+ // For .xml tasks, extract from tag attributes
409
+ const nameMatch = content.match(/name="([^"]+)"/);
410
+ displayName = nameMatch ? nameMatch[1] : name;
411
+
412
+ const descMatch = content.match(/description="([^"]+)"/);
413
+ const objMatch = content.match(/<objective>([^<]+)<\/objective>/);
414
+ description = descMatch ? descMatch[1] : objMatch ? objMatch[1].trim() : '';
415
+
416
+ const standaloneMatch = content.match(/<task[^>]+standalone="true"/);
417
+ standalone = !!standaloneMatch;
418
+ }
419
+
420
+ // Build relative path for installation
421
+ const installPath =
422
+ moduleName === 'core' ? `${this.bmadFolderName}/core/tasks/${file}` : `${this.bmadFolderName}/${moduleName}/tasks/${file}`;
423
+
424
+ tasks.push({
425
+ name: name,
426
+ displayName: displayName,
427
+ description: description.replaceAll('"', '""'),
428
+ module: moduleName,
429
+ path: installPath,
430
+ standalone: standalone,
431
+ });
432
+
433
+ // Add to files list
434
+ this.files.push({
435
+ type: 'task',
436
+ name: name,
437
+ module: moduleName,
438
+ path: installPath,
439
+ });
440
+ }
441
+ }
442
+
443
+ return tasks;
444
+ }
445
+
446
+ /**
447
+ * Collect all tools from core and selected modules
448
+ * Scans the INSTALLED bmad directory, not the source
449
+ */
450
+ async collectTools(selectedModules) {
451
+ this.tools = [];
452
+
453
+ // Use updatedModules which already includes deduplicated 'core' + selectedModules
454
+ for (const moduleName of this.updatedModules) {
455
+ const toolsPath = path.join(this.bmadDir, moduleName, 'tools');
456
+
457
+ if (await fs.pathExists(toolsPath)) {
458
+ const moduleTools = await this.getToolsFromDir(toolsPath, moduleName);
459
+ this.tools.push(...moduleTools);
460
+ }
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Get tools from a directory
466
+ */
467
+ async getToolsFromDir(dirPath, moduleName) {
468
+ const tools = [];
469
+ const files = await fs.readdir(dirPath);
470
+
471
+ for (const file of files) {
472
+ // Check for both .xml and .md files
473
+ if (file.endsWith('.xml') || file.endsWith('.md')) {
474
+ const filePath = path.join(dirPath, file);
475
+ const content = await fs.readFile(filePath, 'utf8');
476
+
477
+ let name = file.replace(/\.(xml|md)$/, '');
478
+ let displayName = name;
479
+ let description = '';
480
+ let standalone = false;
481
+
482
+ if (file.endsWith('.md')) {
483
+ // Parse YAML frontmatter for .md tools
484
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
485
+ if (frontmatterMatch) {
486
+ try {
487
+ const frontmatter = yaml.parse(frontmatterMatch[1]);
488
+ name = frontmatter.name || name;
489
+ displayName = frontmatter.displayName || frontmatter.name || name;
490
+ description = frontmatter.description || '';
491
+ standalone = frontmatter.standalone === true || frontmatter.standalone === 'true';
492
+ } catch {
493
+ // If YAML parsing fails, use defaults
494
+ }
495
+ }
496
+ } else {
497
+ // For .xml tools, extract from tag attributes
498
+ const nameMatch = content.match(/name="([^"]+)"/);
499
+ displayName = nameMatch ? nameMatch[1] : name;
500
+
501
+ const descMatch = content.match(/description="([^"]+)"/);
502
+ const objMatch = content.match(/<objective>([^<]+)<\/objective>/);
503
+ description = descMatch ? descMatch[1] : objMatch ? objMatch[1].trim() : '';
504
+
505
+ const standaloneMatch = content.match(/<tool[^>]+standalone="true"/);
506
+ standalone = !!standaloneMatch;
507
+ }
508
+
509
+ // Build relative path for installation
510
+ const installPath =
511
+ moduleName === 'core' ? `${this.bmadFolderName}/core/tools/${file}` : `${this.bmadFolderName}/${moduleName}/tools/${file}`;
512
+
513
+ tools.push({
514
+ name: name,
515
+ displayName: displayName,
516
+ description: description.replaceAll('"', '""'),
517
+ module: moduleName,
518
+ path: installPath,
519
+ standalone: standalone,
520
+ });
521
+
522
+ // Add to files list
523
+ this.files.push({
524
+ type: 'tool',
525
+ name: name,
526
+ module: moduleName,
527
+ path: installPath,
528
+ });
529
+ }
530
+ }
531
+
532
+ return tools;
533
+ }
534
+
535
+ /**
536
+ * Write main manifest as YAML with installation info only
537
+ * Fetches fresh version info for all modules
538
+ * @returns {string} Path to the manifest file
539
+ */
540
+ async writeMainManifest(cfgDir) {
541
+ const manifestPath = path.join(cfgDir, 'manifest.yaml');
542
+
543
+ // Read existing manifest to preserve install date
544
+ let existingInstallDate = null;
545
+ const existingModulesMap = new Map();
546
+
547
+ if (await fs.pathExists(manifestPath)) {
548
+ try {
549
+ const existingContent = await fs.readFile(manifestPath, 'utf8');
550
+ const existingManifest = yaml.parse(existingContent);
551
+
552
+ // Preserve original install date
553
+ if (existingManifest.installation?.installDate) {
554
+ existingInstallDate = existingManifest.installation.installDate;
555
+ }
556
+
557
+ // Build map of existing modules for quick lookup
558
+ if (existingManifest.modules && Array.isArray(existingManifest.modules)) {
559
+ for (const m of existingManifest.modules) {
560
+ if (typeof m === 'object' && m.name) {
561
+ existingModulesMap.set(m.name, m);
562
+ } else if (typeof m === 'string') {
563
+ existingModulesMap.set(m, { installDate: existingInstallDate });
564
+ }
565
+ }
566
+ }
567
+ } catch {
568
+ // If we can't read existing manifest, continue with defaults
569
+ }
570
+ }
571
+
572
+ // Fetch fresh version info for all modules
573
+ const { Manifest } = require('./manifest');
574
+ const manifestObj = new Manifest();
575
+ const updatedModules = [];
576
+
577
+ for (const moduleName of this.modules) {
578
+ // Get fresh version info from source
579
+ const versionInfo = await manifestObj.getModuleVersionInfo(moduleName, this.bmadDir);
580
+
581
+ // Get existing install date if available
582
+ const existing = existingModulesMap.get(moduleName);
583
+
584
+ updatedModules.push({
585
+ name: moduleName,
586
+ version: versionInfo.version,
587
+ installDate: existing?.installDate || new Date().toISOString(),
588
+ lastUpdated: new Date().toISOString(),
589
+ source: versionInfo.source,
590
+ npmPackage: versionInfo.npmPackage,
591
+ repoUrl: versionInfo.repoUrl,
592
+ });
593
+ }
594
+
595
+ const manifest = {
596
+ installation: {
597
+ version: packageJson.version,
598
+ installDate: existingInstallDate || new Date().toISOString(),
599
+ lastUpdated: new Date().toISOString(),
600
+ },
601
+ modules: updatedModules,
602
+ ides: this.selectedIdes,
603
+ };
604
+
605
+ // Clean the manifest to remove any non-serializable values
606
+ const cleanManifest = structuredClone(manifest);
607
+
608
+ const yamlStr = yaml.stringify(cleanManifest, {
609
+ indent: 2,
610
+ lineWidth: 0,
611
+ sortKeys: false,
612
+ });
613
+
614
+ // Ensure POSIX-compliant final newline
615
+ const content = yamlStr.endsWith('\n') ? yamlStr : yamlStr + '\n';
616
+ await fs.writeFile(manifestPath, content);
617
+ return manifestPath;
618
+ }
619
+
620
+ /**
621
+ * Read existing CSV and preserve rows for modules NOT being updated
622
+ * @param {string} csvPath - Path to existing CSV file
623
+ * @param {number} moduleColumnIndex - Which column contains the module name (0-indexed)
624
+ * @param {Array<string>} expectedColumns - Expected column names in order
625
+ * @param {Object} defaultValues - Default values for missing columns
626
+ * @returns {Array} Preserved CSV rows (without header), upgraded to match expected columns
627
+ */
628
+ async getPreservedCsvRows(csvPath, moduleColumnIndex, expectedColumns, defaultValues = {}) {
629
+ if (!(await fs.pathExists(csvPath)) || this.preservedModules.length === 0) {
630
+ return [];
631
+ }
632
+
633
+ try {
634
+ const content = await fs.readFile(csvPath, 'utf8');
635
+ const lines = content.trim().split('\n');
636
+
637
+ if (lines.length < 2) {
638
+ return []; // No data rows
639
+ }
640
+
641
+ // Parse header to understand old schema
642
+ const header = lines[0];
643
+ const headerColumns = header.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
644
+ const oldColumns = headerColumns.map((c) => c.replaceAll(/^"|"$/g, ''));
645
+
646
+ // Skip header row for data
647
+ const dataRows = lines.slice(1);
648
+ const preservedRows = [];
649
+
650
+ for (const row of dataRows) {
651
+ // Simple CSV parsing (handles quoted values)
652
+ const columns = row.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
653
+ const cleanColumns = columns.map((c) => c.replaceAll(/^"|"$/g, ''));
654
+
655
+ const moduleValue = cleanColumns[moduleColumnIndex];
656
+
657
+ // Keep this row if it belongs to a preserved module
658
+ if (this.preservedModules.includes(moduleValue)) {
659
+ // Upgrade row to match expected schema
660
+ const upgradedRow = this.upgradeRowToSchema(cleanColumns, oldColumns, expectedColumns, defaultValues);
661
+ preservedRows.push(upgradedRow);
662
+ }
663
+ }
664
+
665
+ return preservedRows;
666
+ } catch (error) {
667
+ console.warn(`Warning: Failed to read existing CSV ${csvPath}:`, error.message);
668
+ return [];
669
+ }
670
+ }
671
+
672
+ /**
673
+ * Upgrade a CSV row from old schema to new schema
674
+ * @param {Array<string>} rowValues - Values from old row
675
+ * @param {Array<string>} oldColumns - Old column names
676
+ * @param {Array<string>} newColumns - New column names
677
+ * @param {Object} defaultValues - Default values for missing columns
678
+ * @returns {string} Upgraded CSV row
679
+ */
680
+ upgradeRowToSchema(rowValues, oldColumns, newColumns, defaultValues) {
681
+ const upgradedValues = [];
682
+
683
+ for (const newCol of newColumns) {
684
+ const oldIndex = oldColumns.indexOf(newCol);
685
+
686
+ if (oldIndex !== -1 && oldIndex < rowValues.length) {
687
+ // Column exists in old schema, use its value
688
+ upgradedValues.push(rowValues[oldIndex]);
689
+ } else if (defaultValues[newCol] === undefined) {
690
+ // Column missing, no default provided
691
+ upgradedValues.push('');
692
+ } else {
693
+ // Column missing, use default value
694
+ upgradedValues.push(defaultValues[newCol]);
695
+ }
696
+ }
697
+
698
+ // Properly quote values and join
699
+ return upgradedValues.map((v) => `"${v}"`).join(',');
700
+ }
701
+
702
+ /**
703
+ * Write workflow manifest CSV
704
+ * @returns {string} Path to the manifest file
705
+ */
706
+ async writeWorkflowManifest(cfgDir) {
707
+ const csvPath = path.join(cfgDir, 'workflow-manifest.csv');
708
+ const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
709
+ const parseCsvLine = (line) => {
710
+ const columns = line.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g) || [];
711
+ return columns.map((c) => c.replaceAll(/^"|"$/g, ''));
712
+ };
713
+
714
+ // Read existing manifest to preserve entries
715
+ const existingEntries = new Map();
716
+ if (await fs.pathExists(csvPath)) {
717
+ const content = await fs.readFile(csvPath, 'utf8');
718
+ const lines = content.split('\n').filter((line) => line.trim());
719
+
720
+ // Skip header
721
+ for (let i = 1; i < lines.length; i++) {
722
+ const line = lines[i];
723
+ if (line) {
724
+ const parts = parseCsvLine(line);
725
+ if (parts.length >= 4) {
726
+ const [name, description, module, workflowPath] = parts;
727
+ existingEntries.set(`${module}:${name}`, {
728
+ name,
729
+ description,
730
+ module,
731
+ path: workflowPath,
732
+ });
733
+ }
734
+ }
735
+ }
736
+ }
737
+
738
+ // Create CSV header - standalone column removed, everything is canonicalized to 4 columns
739
+ let csv = 'name,description,module,path\n';
740
+
741
+ // Combine existing and new workflows
742
+ const allWorkflows = new Map();
743
+
744
+ // Add existing entries
745
+ for (const [key, value] of existingEntries) {
746
+ allWorkflows.set(key, value);
747
+ }
748
+
749
+ // Add/update new workflows
750
+ for (const workflow of this.workflows) {
751
+ const key = `${workflow.module}:${workflow.name}`;
752
+ allWorkflows.set(key, {
753
+ name: workflow.name,
754
+ description: workflow.description,
755
+ module: workflow.module,
756
+ path: workflow.path,
757
+ });
758
+ }
759
+
760
+ // Write all workflows
761
+ for (const [, value] of allWorkflows) {
762
+ const row = [escapeCsv(value.name), escapeCsv(value.description), escapeCsv(value.module), escapeCsv(value.path)].join(',');
763
+ csv += row + '\n';
764
+ }
765
+
766
+ await fs.writeFile(csvPath, csv);
767
+ return csvPath;
768
+ }
769
+
770
+ /**
771
+ * Write agent manifest CSV
772
+ * @returns {string} Path to the manifest file
773
+ */
774
+ async writeAgentManifest(cfgDir) {
775
+ const csvPath = path.join(cfgDir, 'agent-manifest.csv');
776
+
777
+ // Read existing manifest to preserve entries
778
+ const existingEntries = new Map();
779
+ if (await fs.pathExists(csvPath)) {
780
+ const content = await fs.readFile(csvPath, 'utf8');
781
+ const lines = content.split('\n').filter((line) => line.trim());
782
+
783
+ // Skip header
784
+ for (let i = 1; i < lines.length; i++) {
785
+ const line = lines[i];
786
+ if (line) {
787
+ // Parse CSV (simple parsing assuming no commas in quoted fields)
788
+ const parts = line.split('","');
789
+ if (parts.length >= 11) {
790
+ const name = parts[0].replace(/^"/, '');
791
+ const module = parts[8];
792
+ existingEntries.set(`${module}:${name}`, line);
793
+ }
794
+ }
795
+ }
796
+ }
797
+
798
+ // Create CSV header with persona fields
799
+ let csv = 'name,displayName,title,icon,role,identity,communicationStyle,principles,module,path\n';
800
+
801
+ // Combine existing and new agents, preferring new data for duplicates
802
+ const allAgents = new Map();
803
+
804
+ // Add existing entries
805
+ for (const [key, value] of existingEntries) {
806
+ allAgents.set(key, value);
807
+ }
808
+
809
+ // Add/update new agents
810
+ for (const agent of this.agents) {
811
+ const key = `${agent.module}:${agent.name}`;
812
+ allAgents.set(
813
+ key,
814
+ `"${agent.name}","${agent.displayName}","${agent.title}","${agent.icon}","${agent.role}","${agent.identity}","${agent.communicationStyle}","${agent.principles}","${agent.module}","${agent.path}"`,
815
+ );
816
+ }
817
+
818
+ // Write all agents
819
+ for (const [, value] of allAgents) {
820
+ csv += value + '\n';
821
+ }
822
+
823
+ await fs.writeFile(csvPath, csv);
824
+ return csvPath;
825
+ }
826
+
827
+ /**
828
+ * Write task manifest CSV
829
+ * @returns {string} Path to the manifest file
830
+ */
831
+ async writeTaskManifest(cfgDir) {
832
+ const csvPath = path.join(cfgDir, 'task-manifest.csv');
833
+
834
+ // Read existing manifest to preserve entries
835
+ const existingEntries = new Map();
836
+ if (await fs.pathExists(csvPath)) {
837
+ const content = await fs.readFile(csvPath, 'utf8');
838
+ const lines = content.split('\n').filter((line) => line.trim());
839
+
840
+ // Skip header
841
+ for (let i = 1; i < lines.length; i++) {
842
+ const line = lines[i];
843
+ if (line) {
844
+ // Parse CSV (simple parsing assuming no commas in quoted fields)
845
+ const parts = line.split('","');
846
+ if (parts.length >= 6) {
847
+ const name = parts[0].replace(/^"/, '');
848
+ const module = parts[3];
849
+ existingEntries.set(`${module}:${name}`, line);
850
+ }
851
+ }
852
+ }
853
+ }
854
+
855
+ // Create CSV header with standalone column
856
+ let csv = 'name,displayName,description,module,path,standalone\n';
857
+
858
+ // Combine existing and new tasks
859
+ const allTasks = new Map();
860
+
861
+ // Add existing entries
862
+ for (const [key, value] of existingEntries) {
863
+ allTasks.set(key, value);
864
+ }
865
+
866
+ // Add/update new tasks
867
+ for (const task of this.tasks) {
868
+ const key = `${task.module}:${task.name}`;
869
+ allTasks.set(key, `"${task.name}","${task.displayName}","${task.description}","${task.module}","${task.path}","${task.standalone}"`);
870
+ }
871
+
872
+ // Write all tasks
873
+ for (const [, value] of allTasks) {
874
+ csv += value + '\n';
875
+ }
876
+
877
+ await fs.writeFile(csvPath, csv);
878
+ return csvPath;
879
+ }
880
+
881
+ /**
882
+ * Write tool manifest CSV
883
+ * @returns {string} Path to the manifest file
884
+ */
885
+ async writeToolManifest(cfgDir) {
886
+ const csvPath = path.join(cfgDir, 'tool-manifest.csv');
887
+
888
+ // Read existing manifest to preserve entries
889
+ const existingEntries = new Map();
890
+ if (await fs.pathExists(csvPath)) {
891
+ const content = await fs.readFile(csvPath, 'utf8');
892
+ const lines = content.split('\n').filter((line) => line.trim());
893
+
894
+ // Skip header
895
+ for (let i = 1; i < lines.length; i++) {
896
+ const line = lines[i];
897
+ if (line) {
898
+ // Parse CSV (simple parsing assuming no commas in quoted fields)
899
+ const parts = line.split('","');
900
+ if (parts.length >= 6) {
901
+ const name = parts[0].replace(/^"/, '');
902
+ const module = parts[3];
903
+ existingEntries.set(`${module}:${name}`, line);
904
+ }
905
+ }
906
+ }
907
+ }
908
+
909
+ // Create CSV header with standalone column
910
+ let csv = 'name,displayName,description,module,path,standalone\n';
911
+
912
+ // Combine existing and new tools
913
+ const allTools = new Map();
914
+
915
+ // Add existing entries
916
+ for (const [key, value] of existingEntries) {
917
+ allTools.set(key, value);
918
+ }
919
+
920
+ // Add/update new tools
921
+ for (const tool of this.tools) {
922
+ const key = `${tool.module}:${tool.name}`;
923
+ allTools.set(key, `"${tool.name}","${tool.displayName}","${tool.description}","${tool.module}","${tool.path}","${tool.standalone}"`);
924
+ }
925
+
926
+ // Write all tools
927
+ for (const [, value] of allTools) {
928
+ csv += value + '\n';
929
+ }
930
+
931
+ await fs.writeFile(csvPath, csv);
932
+ return csvPath;
933
+ }
934
+
935
+ /**
936
+ * Write files manifest CSV
937
+ */
938
+ /**
939
+ * Calculate SHA256 hash of a file
940
+ * @param {string} filePath - Path to file
941
+ * @returns {string} SHA256 hash
942
+ */
943
+ async calculateFileHash(filePath) {
944
+ try {
945
+ const content = await fs.readFile(filePath);
946
+ return crypto.createHash('sha256').update(content).digest('hex');
947
+ } catch {
948
+ return '';
949
+ }
950
+ }
951
+
952
+ /**
953
+ * @returns {string} Path to the manifest file
954
+ */
955
+ async writeFilesManifest(cfgDir) {
956
+ const csvPath = path.join(cfgDir, 'files-manifest.csv');
957
+
958
+ // Create CSV header with hash column
959
+ let csv = 'type,name,module,path,hash\n';
960
+
961
+ // If we have ALL installed files, use those instead of just workflows/agents/tasks
962
+ const allFiles = [];
963
+ if (this.allInstalledFiles && this.allInstalledFiles.length > 0) {
964
+ // Process all installed files
965
+ for (const filePath of this.allInstalledFiles) {
966
+ // Store paths relative to bmadDir (no folder prefix)
967
+ const relativePath = filePath.replace(this.bmadDir, '').replaceAll('\\', '/').replace(/^\//, '');
968
+ const ext = path.extname(filePath).toLowerCase();
969
+ const fileName = path.basename(filePath, ext);
970
+
971
+ // Determine module from path (first directory component)
972
+ const pathParts = relativePath.split('/');
973
+ const module = pathParts.length > 0 ? pathParts[0] : 'unknown';
974
+
975
+ // Calculate hash
976
+ const hash = await this.calculateFileHash(filePath);
977
+
978
+ allFiles.push({
979
+ type: ext.slice(1) || 'file',
980
+ name: fileName,
981
+ module: module,
982
+ path: relativePath,
983
+ hash: hash,
984
+ });
985
+ }
986
+ } else {
987
+ // Fallback: use the collected workflows/agents/tasks
988
+ for (const file of this.files) {
989
+ // Strip the folder prefix if present (for consistency)
990
+ const relPath = file.path.replace(this.bmadFolderName + '/', '');
991
+ const filePath = path.join(this.bmadDir, relPath);
992
+ const hash = await this.calculateFileHash(filePath);
993
+ allFiles.push({
994
+ ...file,
995
+ path: relPath,
996
+ hash: hash,
997
+ });
998
+ }
999
+ }
1000
+
1001
+ // Sort files by module, then type, then name
1002
+ allFiles.sort((a, b) => {
1003
+ if (a.module !== b.module) return a.module.localeCompare(b.module);
1004
+ if (a.type !== b.type) return a.type.localeCompare(b.type);
1005
+ return a.name.localeCompare(b.name);
1006
+ });
1007
+
1008
+ // Add all files
1009
+ for (const file of allFiles) {
1010
+ csv += `"${file.type}","${file.name}","${file.module}","${file.path}","${file.hash}"\n`;
1011
+ }
1012
+
1013
+ await fs.writeFile(csvPath, csv);
1014
+ return csvPath;
1015
+ }
1016
+
1017
+ /**
1018
+ * Scan the bmad directory to find all installed modules
1019
+ * @param {string} bmadDir - Path to bmad directory
1020
+ * @returns {Array} List of module names
1021
+ */
1022
+ async scanInstalledModules(bmadDir) {
1023
+ const modules = [];
1024
+
1025
+ try {
1026
+ const entries = await fs.readdir(bmadDir, { withFileTypes: true });
1027
+
1028
+ for (const entry of entries) {
1029
+ // Skip if not a directory or is a special directory
1030
+ if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === '_config') {
1031
+ continue;
1032
+ }
1033
+
1034
+ // Check if this looks like a module (has agents, workflows, or tasks directory)
1035
+ const modulePath = path.join(bmadDir, entry.name);
1036
+ const hasAgents = await fs.pathExists(path.join(modulePath, 'agents'));
1037
+ const hasWorkflows = await fs.pathExists(path.join(modulePath, 'workflows'));
1038
+ const hasTasks = await fs.pathExists(path.join(modulePath, 'tasks'));
1039
+ const hasTools = await fs.pathExists(path.join(modulePath, 'tools'));
1040
+
1041
+ // If it has any of these directories, it's likely a module
1042
+ if (hasAgents || hasWorkflows || hasTasks || hasTools) {
1043
+ modules.push(entry.name);
1044
+ }
1045
+ }
1046
+ } catch (error) {
1047
+ console.warn(`Warning: Could not scan for installed modules: ${error.message}`);
1048
+ }
1049
+
1050
+ return modules;
1051
+ }
1052
+ }
1053
+
1054
+ module.exports = { ManifestGenerator };