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,1036 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const crypto = require('node:crypto');
4
+ const { getProjectRoot } = require('../../../lib/project-root');
5
+
6
+ class Manifest {
7
+ /**
8
+ * Create a new manifest
9
+ * @param {string} bmadDir - Path to bmad directory
10
+ * @param {Object} data - Manifest data
11
+ * @param {Array} installedFiles - List of installed files (no longer used, files tracked in files-manifest.csv)
12
+ */
13
+ async create(bmadDir, data, installedFiles = []) {
14
+ const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
15
+ const yaml = require('yaml');
16
+
17
+ // Ensure _config directory exists
18
+ await fs.ensureDir(path.dirname(manifestPath));
19
+
20
+ // Get the BMad version from package.json
21
+ const bmadVersion = data.version || require(path.join(process.cwd(), 'package.json')).version;
22
+
23
+ // Convert module list to new detailed format
24
+ const moduleDetails = [];
25
+ if (data.modules && Array.isArray(data.modules)) {
26
+ for (const moduleName of data.modules) {
27
+ // Core and BMM modules use the BMad version
28
+ const moduleVersion = moduleName === 'core' || moduleName === 'bmm' ? bmadVersion : null;
29
+ const now = data.installDate || new Date().toISOString();
30
+
31
+ moduleDetails.push({
32
+ name: moduleName,
33
+ version: moduleVersion,
34
+ installDate: now,
35
+ lastUpdated: now,
36
+ source: moduleName === 'core' || moduleName === 'bmm' ? 'built-in' : 'unknown',
37
+ });
38
+ }
39
+ }
40
+
41
+ // Structure the manifest data
42
+ const manifestData = {
43
+ installation: {
44
+ version: bmadVersion,
45
+ installDate: data.installDate || new Date().toISOString(),
46
+ lastUpdated: data.lastUpdated || new Date().toISOString(),
47
+ },
48
+ modules: moduleDetails,
49
+ ides: data.ides || [],
50
+ };
51
+
52
+ // Write YAML manifest
53
+ // Clean the manifest data to remove any non-serializable values
54
+ const cleanManifestData = structuredClone(manifestData);
55
+
56
+ const yamlContent = yaml.stringify(cleanManifestData, {
57
+ indent: 2,
58
+ lineWidth: 0,
59
+ sortKeys: false,
60
+ });
61
+
62
+ // Ensure POSIX-compliant final newline
63
+ const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
64
+ await fs.writeFile(manifestPath, content, 'utf8');
65
+ return { success: true, path: manifestPath, filesTracked: 0 };
66
+ }
67
+
68
+ /**
69
+ * Read existing manifest
70
+ * @param {string} bmadDir - Path to bmad directory
71
+ * @returns {Object|null} Manifest data or null if not found
72
+ */
73
+ async read(bmadDir) {
74
+ const yamlPath = path.join(bmadDir, '_config', 'manifest.yaml');
75
+ const yaml = require('yaml');
76
+
77
+ if (await fs.pathExists(yamlPath)) {
78
+ try {
79
+ const content = await fs.readFile(yamlPath, 'utf8');
80
+ const manifestData = yaml.parse(content);
81
+
82
+ // Handle new detailed module format
83
+ const modules = manifestData.modules || [];
84
+
85
+ // For backward compatibility: if modules is an array of strings (old format),
86
+ // the calling code may need the array of names
87
+ const moduleNames = modules.map((m) => (typeof m === 'string' ? m : m.name));
88
+
89
+ // Check if we have the new detailed format
90
+ const hasDetailedModules = modules.length > 0 && typeof modules[0] === 'object';
91
+
92
+ // Flatten the structure for compatibility with existing code
93
+ return {
94
+ version: manifestData.installation?.version,
95
+ installDate: manifestData.installation?.installDate,
96
+ lastUpdated: manifestData.installation?.lastUpdated,
97
+ modules: moduleNames, // Simple array of module names for backward compatibility
98
+ modulesDetailed: hasDetailedModules ? modules : null, // New detailed format
99
+ customModules: manifestData.customModules || [], // Keep for backward compatibility
100
+ ides: manifestData.ides || [],
101
+ };
102
+ } catch (error) {
103
+ console.error('Failed to read YAML manifest:', error.message);
104
+ }
105
+ }
106
+
107
+ return null;
108
+ }
109
+
110
+ /**
111
+ * Update existing manifest
112
+ * @param {string} bmadDir - Path to bmad directory
113
+ * @param {Object} updates - Fields to update
114
+ * @param {Array} installedFiles - Updated list of installed files
115
+ */
116
+ async update(bmadDir, updates, installedFiles = null) {
117
+ const yaml = require('yaml');
118
+ const manifest = (await this._readRaw(bmadDir)) || {
119
+ installation: {},
120
+ modules: [],
121
+ ides: [],
122
+ };
123
+
124
+ // Handle module updates
125
+ if (updates.modules) {
126
+ // If modules is being updated, we need to preserve detailed module info
127
+ const existingDetailed = manifest.modules || [];
128
+ const incomingNames = updates.modules;
129
+
130
+ // Build updated modules array
131
+ const updatedModules = [];
132
+ for (const name of incomingNames) {
133
+ const existing = existingDetailed.find((m) => m.name === name);
134
+ if (existing) {
135
+ // Preserve existing details, update lastUpdated if this module is being updated
136
+ updatedModules.push({
137
+ ...existing,
138
+ lastUpdated: new Date().toISOString(),
139
+ });
140
+ } else {
141
+ // New module - add with minimal details
142
+ updatedModules.push({
143
+ name,
144
+ version: null,
145
+ installDate: new Date().toISOString(),
146
+ lastUpdated: new Date().toISOString(),
147
+ source: 'unknown',
148
+ });
149
+ }
150
+ }
151
+
152
+ manifest.modules = updatedModules;
153
+ }
154
+
155
+ // Merge other updates
156
+ if (updates.version) {
157
+ manifest.installation.version = updates.version;
158
+ }
159
+ if (updates.installDate) {
160
+ manifest.installation.installDate = updates.installDate;
161
+ }
162
+ manifest.installation.lastUpdated = new Date().toISOString();
163
+
164
+ if (updates.ides) {
165
+ manifest.ides = updates.ides;
166
+ }
167
+
168
+ // Handle per-module version updates
169
+ if (updates.moduleVersions) {
170
+ for (const [moduleName, versionInfo] of Object.entries(updates.moduleVersions)) {
171
+ const moduleIndex = manifest.modules.findIndex((m) => m.name === moduleName);
172
+ if (moduleIndex !== -1) {
173
+ manifest.modules[moduleIndex] = {
174
+ ...manifest.modules[moduleIndex],
175
+ ...versionInfo,
176
+ lastUpdated: new Date().toISOString(),
177
+ };
178
+ }
179
+ }
180
+ }
181
+
182
+ // Handle adding a new module with version info
183
+ if (updates.addModule) {
184
+ const { name, version, source, npmPackage, repoUrl } = updates.addModule;
185
+ const existing = manifest.modules.find((m) => m.name === name);
186
+ if (!existing) {
187
+ manifest.modules.push({
188
+ name,
189
+ version: version || null,
190
+ installDate: new Date().toISOString(),
191
+ lastUpdated: new Date().toISOString(),
192
+ source: source || 'external',
193
+ npmPackage: npmPackage || null,
194
+ repoUrl: repoUrl || null,
195
+ });
196
+ }
197
+ }
198
+
199
+ const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
200
+ await fs.ensureDir(path.dirname(manifestPath));
201
+
202
+ // Clean the manifest data to remove any non-serializable values
203
+ const cleanManifestData = structuredClone(manifest);
204
+
205
+ const yamlContent = yaml.stringify(cleanManifestData, {
206
+ indent: 2,
207
+ lineWidth: 0,
208
+ sortKeys: false,
209
+ });
210
+
211
+ // Ensure POSIX-compliant final newline
212
+ const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
213
+ await fs.writeFile(manifestPath, content, 'utf8');
214
+
215
+ // Return the flattened format for compatibility
216
+ return this._flattenManifest(manifest);
217
+ }
218
+
219
+ /**
220
+ * Read raw manifest data without flattening
221
+ * @param {string} bmadDir - Path to bmad directory
222
+ * @returns {Object|null} Raw manifest data or null if not found
223
+ */
224
+ async _readRaw(bmadDir) {
225
+ const yamlPath = path.join(bmadDir, '_config', 'manifest.yaml');
226
+ const yaml = require('yaml');
227
+
228
+ if (await fs.pathExists(yamlPath)) {
229
+ try {
230
+ const content = await fs.readFile(yamlPath, 'utf8');
231
+ return yaml.parse(content);
232
+ } catch (error) {
233
+ console.error('Failed to read YAML manifest:', error.message);
234
+ }
235
+ }
236
+
237
+ return null;
238
+ }
239
+
240
+ /**
241
+ * Flatten manifest for backward compatibility
242
+ * @param {Object} manifest - Raw manifest data
243
+ * @returns {Object} Flattened manifest
244
+ */
245
+ _flattenManifest(manifest) {
246
+ const modules = manifest.modules || [];
247
+ const moduleNames = modules.map((m) => (typeof m === 'string' ? m : m.name));
248
+ const hasDetailedModules = modules.length > 0 && typeof modules[0] === 'object';
249
+
250
+ return {
251
+ version: manifest.installation?.version,
252
+ installDate: manifest.installation?.installDate,
253
+ lastUpdated: manifest.installation?.lastUpdated,
254
+ modules: moduleNames,
255
+ modulesDetailed: hasDetailedModules ? modules : null,
256
+ customModules: manifest.customModules || [],
257
+ ides: manifest.ides || [],
258
+ };
259
+ }
260
+
261
+ /**
262
+ * Add a module to the manifest with optional version info
263
+ * If module already exists, update its version info
264
+ * @param {string} bmadDir - Path to bmad directory
265
+ * @param {string} moduleName - Module name to add
266
+ * @param {Object} options - Optional version info
267
+ */
268
+ async addModule(bmadDir, moduleName, options = {}) {
269
+ const manifest = await this._readRaw(bmadDir);
270
+ if (!manifest) {
271
+ throw new Error('No manifest found');
272
+ }
273
+
274
+ if (!manifest.modules) {
275
+ manifest.modules = [];
276
+ }
277
+
278
+ const existingIndex = manifest.modules.findIndex((m) => m.name === moduleName);
279
+
280
+ if (existingIndex === -1) {
281
+ // Module doesn't exist, add it
282
+ manifest.modules.push({
283
+ name: moduleName,
284
+ version: options.version || null,
285
+ installDate: new Date().toISOString(),
286
+ lastUpdated: new Date().toISOString(),
287
+ source: options.source || 'unknown',
288
+ npmPackage: options.npmPackage || null,
289
+ repoUrl: options.repoUrl || null,
290
+ });
291
+ } else {
292
+ // Module exists, update its version info
293
+ const existing = manifest.modules[existingIndex];
294
+ manifest.modules[existingIndex] = {
295
+ ...existing,
296
+ version: options.version === undefined ? existing.version : options.version,
297
+ source: options.source || existing.source,
298
+ npmPackage: options.npmPackage === undefined ? existing.npmPackage : options.npmPackage,
299
+ repoUrl: options.repoUrl === undefined ? existing.repoUrl : options.repoUrl,
300
+ lastUpdated: new Date().toISOString(),
301
+ };
302
+ }
303
+
304
+ await this._writeRaw(bmadDir, manifest);
305
+ }
306
+
307
+ /**
308
+ * Remove a module from the manifest
309
+ * @param {string} bmadDir - Path to bmad directory
310
+ * @param {string} moduleName - Module name to remove
311
+ */
312
+ async removeModule(bmadDir, moduleName) {
313
+ const manifest = await this._readRaw(bmadDir);
314
+ if (!manifest || !manifest.modules) {
315
+ return;
316
+ }
317
+
318
+ const index = manifest.modules.findIndex((m) => m.name === moduleName);
319
+ if (index !== -1) {
320
+ manifest.modules.splice(index, 1);
321
+ await this._writeRaw(bmadDir, manifest);
322
+ }
323
+ }
324
+
325
+ /**
326
+ * Update a single module's version info
327
+ * @param {string} bmadDir - Path to bmad directory
328
+ * @param {string} moduleName - Module name
329
+ * @param {Object} versionInfo - Version info to update
330
+ */
331
+ async updateModuleVersion(bmadDir, moduleName, versionInfo) {
332
+ const manifest = await this._readRaw(bmadDir);
333
+ if (!manifest || !manifest.modules) {
334
+ return;
335
+ }
336
+
337
+ const index = manifest.modules.findIndex((m) => m.name === moduleName);
338
+ if (index !== -1) {
339
+ manifest.modules[index] = {
340
+ ...manifest.modules[index],
341
+ ...versionInfo,
342
+ lastUpdated: new Date().toISOString(),
343
+ };
344
+ await this._writeRaw(bmadDir, manifest);
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Get version info for a specific module
350
+ * @param {string} bmadDir - Path to bmad directory
351
+ * @param {string} moduleName - Module name
352
+ * @returns {Object|null} Module version info or null
353
+ */
354
+ async getModuleVersion(bmadDir, moduleName) {
355
+ const manifest = await this._readRaw(bmadDir);
356
+ if (!manifest || !manifest.modules) {
357
+ return null;
358
+ }
359
+
360
+ return manifest.modules.find((m) => m.name === moduleName) || null;
361
+ }
362
+
363
+ /**
364
+ * Get all modules with their version info
365
+ * @param {string} bmadDir - Path to bmad directory
366
+ * @returns {Array} Array of module info objects
367
+ */
368
+ async getAllModuleVersions(bmadDir) {
369
+ const manifest = await this._readRaw(bmadDir);
370
+ if (!manifest || !manifest.modules) {
371
+ return [];
372
+ }
373
+
374
+ return manifest.modules;
375
+ }
376
+
377
+ /**
378
+ * Write raw manifest data to file
379
+ * @param {string} bmadDir - Path to bmad directory
380
+ * @param {Object} manifestData - Raw manifest data to write
381
+ */
382
+ async _writeRaw(bmadDir, manifestData) {
383
+ const yaml = require('yaml');
384
+ const manifestPath = path.join(bmadDir, '_config', 'manifest.yaml');
385
+
386
+ await fs.ensureDir(path.dirname(manifestPath));
387
+
388
+ const cleanManifestData = structuredClone(manifestData);
389
+
390
+ const yamlContent = yaml.stringify(cleanManifestData, {
391
+ indent: 2,
392
+ lineWidth: 0,
393
+ sortKeys: false,
394
+ });
395
+
396
+ const content = yamlContent.endsWith('\n') ? yamlContent : yamlContent + '\n';
397
+ await fs.writeFile(manifestPath, content, 'utf8');
398
+ }
399
+
400
+ /**
401
+ * Add an IDE configuration to the manifest
402
+ * @param {string} bmadDir - Path to bmad directory
403
+ * @param {string} ideName - IDE name to add
404
+ */
405
+ async addIde(bmadDir, ideName) {
406
+ const manifest = await this.read(bmadDir);
407
+ if (!manifest) {
408
+ throw new Error('No manifest found');
409
+ }
410
+
411
+ if (!manifest.ides) {
412
+ manifest.ides = [];
413
+ }
414
+
415
+ if (!manifest.ides.includes(ideName)) {
416
+ manifest.ides.push(ideName);
417
+ await this.update(bmadDir, { ides: manifest.ides });
418
+ }
419
+ }
420
+
421
+ /**
422
+ * Calculate SHA256 hash of a file
423
+ * @param {string} filePath - Path to file
424
+ * @returns {string} SHA256 hash
425
+ */
426
+ async calculateFileHash(filePath) {
427
+ try {
428
+ const content = await fs.readFile(filePath);
429
+ return crypto.createHash('sha256').update(content).digest('hex');
430
+ } catch {
431
+ return null;
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Parse installed files to extract metadata
437
+ * @param {Array} installedFiles - List of installed file paths
438
+ * @param {string} bmadDir - Path to bmad directory for relative paths
439
+ * @returns {Array} Array of file metadata objects
440
+ */
441
+ async parseInstalledFiles(installedFiles, bmadDir) {
442
+ const fileMetadata = [];
443
+
444
+ for (const filePath of installedFiles) {
445
+ const fileExt = path.extname(filePath).toLowerCase();
446
+ // Make path relative to parent of bmad directory, starting with 'bmad/'
447
+ const relativePath = 'bmad' + filePath.replace(bmadDir, '').replaceAll('\\', '/');
448
+
449
+ // Calculate file hash
450
+ const hash = await this.calculateFileHash(filePath);
451
+
452
+ // Handle markdown files - extract XML metadata if present
453
+ if (fileExt === '.md') {
454
+ try {
455
+ if (await fs.pathExists(filePath)) {
456
+ const content = await fs.readFile(filePath, 'utf8');
457
+ const metadata = this.extractXmlNodeAttributes(content, filePath, relativePath);
458
+
459
+ if (metadata) {
460
+ // Has XML metadata
461
+ metadata.hash = hash;
462
+ fileMetadata.push(metadata);
463
+ } else {
464
+ // No XML metadata - still track the file
465
+ fileMetadata.push({
466
+ file: relativePath,
467
+ type: 'md',
468
+ name: path.basename(filePath, fileExt),
469
+ title: null,
470
+ hash: hash,
471
+ });
472
+ }
473
+ }
474
+ } catch (error) {
475
+ console.warn(`Warning: Could not parse ${filePath}:`, error.message);
476
+ }
477
+ }
478
+ // Handle other file types (CSV, JSON, YAML, etc.)
479
+ else {
480
+ fileMetadata.push({
481
+ file: relativePath,
482
+ type: fileExt.slice(1), // Remove the dot
483
+ name: path.basename(filePath, fileExt),
484
+ title: null,
485
+ hash: hash,
486
+ });
487
+ }
488
+ }
489
+
490
+ return fileMetadata;
491
+ }
492
+
493
+ /**
494
+ * Extract XML node attributes from MD file content
495
+ * @param {string} content - File content
496
+ * @param {string} filePath - File path for context
497
+ * @param {string} relativePath - Relative path starting with 'bmad/'
498
+ * @returns {Object|null} Extracted metadata or null
499
+ */
500
+ extractXmlNodeAttributes(content, filePath, relativePath) {
501
+ // Look for XML blocks in code fences
502
+ const xmlBlockMatch = content.match(/```xml\s*([\s\S]*?)```/);
503
+ if (!xmlBlockMatch) {
504
+ return null;
505
+ }
506
+
507
+ const xmlContent = xmlBlockMatch[1];
508
+
509
+ // Extract root XML node (agent, task, template, etc.)
510
+ const rootNodeMatch = xmlContent.match(/<(\w+)([^>]*)>/);
511
+ if (!rootNodeMatch) {
512
+ return null;
513
+ }
514
+
515
+ const nodeType = rootNodeMatch[1];
516
+ const attributes = rootNodeMatch[2];
517
+
518
+ // Extract name and title attributes (id not needed since we have path)
519
+ const nameMatch = attributes.match(/name="([^"]*)"/);
520
+ const titleMatch = attributes.match(/title="([^"]*)"/);
521
+
522
+ return {
523
+ file: relativePath,
524
+ type: nodeType,
525
+ name: nameMatch ? nameMatch[1] : null,
526
+ title: titleMatch ? titleMatch[1] : null,
527
+ };
528
+ }
529
+
530
+ /**
531
+ * Generate CSV manifest content
532
+ * @param {Object} data - Manifest data
533
+ * @param {Array} fileMetadata - File metadata array
534
+ * @param {Object} moduleConfigs - Module configuration data
535
+ * @returns {string} CSV content
536
+ */
537
+ generateManifestCsv(data, fileMetadata, moduleConfigs = {}) {
538
+ const timestamp = new Date().toISOString();
539
+ let csv = [];
540
+
541
+ // Header section
542
+ csv.push(
543
+ '# BMAD Manifest',
544
+ `# Generated: ${timestamp}`,
545
+ '',
546
+ '## Installation Info',
547
+ 'Property,Value',
548
+ `Version,${data.version}`,
549
+ `InstallDate,${data.installDate || timestamp}`,
550
+ `LastUpdated,${data.lastUpdated || timestamp}`,
551
+ );
552
+ if (data.language) {
553
+ csv.push(`Language,${data.language}`);
554
+ }
555
+ csv.push('');
556
+
557
+ // Modules section
558
+ if (data.modules && data.modules.length > 0) {
559
+ csv.push('## Modules', 'Name,Version,ShortTitle');
560
+ for (const moduleName of data.modules) {
561
+ const config = moduleConfigs[moduleName] || {};
562
+ csv.push([moduleName, config.version || '', config['short-title'] || ''].map((v) => this.escapeCsv(v)).join(','));
563
+ }
564
+ csv.push('');
565
+ }
566
+
567
+ // IDEs section
568
+ if (data.ides && data.ides.length > 0) {
569
+ csv.push('## IDEs', 'IDE');
570
+ for (const ide of data.ides) {
571
+ csv.push(this.escapeCsv(ide));
572
+ }
573
+ csv.push('');
574
+ }
575
+
576
+ // Files section - NO LONGER USED
577
+ // Files are now tracked in files-manifest.csv by ManifestGenerator
578
+
579
+ return csv.join('\n');
580
+ }
581
+
582
+ /**
583
+ * Parse CSV manifest content back to object
584
+ * @param {string} csvContent - CSV content to parse
585
+ * @returns {Object} Parsed manifest data
586
+ */
587
+ parseManifestCsv(csvContent) {
588
+ const result = {
589
+ modules: [],
590
+ ides: [],
591
+ files: [],
592
+ };
593
+
594
+ const lines = csvContent.split('\n');
595
+ let section = '';
596
+
597
+ for (const line_ of lines) {
598
+ const line = line_.trim();
599
+
600
+ // Skip empty lines and comments
601
+ if (!line || line.startsWith('#')) {
602
+ // Check for section headers
603
+ if (line.startsWith('## ')) {
604
+ section = line.slice(3).toLowerCase();
605
+ }
606
+ continue;
607
+ }
608
+
609
+ // Parse based on current section
610
+ switch (section) {
611
+ case 'installation info': {
612
+ // Skip header row
613
+ if (line === 'Property,Value') continue;
614
+
615
+ const [property, ...valueParts] = line.split(',');
616
+ const value = this.unescapeCsv(valueParts.join(','));
617
+
618
+ switch (property) {
619
+ // Path no longer stored in manifest
620
+ case 'Version': {
621
+ result.version = value;
622
+ break;
623
+ }
624
+ case 'InstallDate': {
625
+ result.installDate = value;
626
+ break;
627
+ }
628
+ case 'LastUpdated': {
629
+ result.lastUpdated = value;
630
+ break;
631
+ }
632
+ case 'Language': {
633
+ result.language = value;
634
+ break;
635
+ }
636
+ }
637
+
638
+ break;
639
+ }
640
+ case 'modules': {
641
+ // Skip header row
642
+ if (line === 'Name,Version,ShortTitle') continue;
643
+
644
+ const parts = this.parseCsvLine(line);
645
+ if (parts[0]) {
646
+ result.modules.push(parts[0]);
647
+ }
648
+
649
+ break;
650
+ }
651
+ case 'ides': {
652
+ // Skip header row
653
+ if (line === 'IDE') continue;
654
+
655
+ result.ides.push(this.unescapeCsv(line));
656
+
657
+ break;
658
+ }
659
+ case 'files': {
660
+ // Skip header rows (support both old and new format)
661
+ if (line === 'Type,Path,Name,Title' || line === 'Type,Path,Name,Title,Hash') continue;
662
+
663
+ const parts = this.parseCsvLine(line);
664
+ if (parts.length >= 2) {
665
+ result.files.push({
666
+ type: parts[0] || '',
667
+ file: parts[1] || '',
668
+ name: parts[2] || null,
669
+ title: parts[3] || null,
670
+ hash: parts[4] || null, // Hash column (may not exist in old manifests)
671
+ });
672
+ }
673
+
674
+ break;
675
+ }
676
+ // No default
677
+ }
678
+ }
679
+
680
+ return result;
681
+ }
682
+
683
+ /**
684
+ * Parse a CSV line handling quotes and commas
685
+ * @param {string} line - CSV line to parse
686
+ * @returns {Array} Array of values
687
+ */
688
+ parseCsvLine(line) {
689
+ const result = [];
690
+ let current = '';
691
+ let inQuotes = false;
692
+
693
+ for (let i = 0; i < line.length; i++) {
694
+ const char = line[i];
695
+
696
+ if (char === '"') {
697
+ if (inQuotes && line[i + 1] === '"') {
698
+ // Escaped quote
699
+ current += '"';
700
+ i++;
701
+ } else {
702
+ // Toggle quote state
703
+ inQuotes = !inQuotes;
704
+ }
705
+ } else if (char === ',' && !inQuotes) {
706
+ // Field separator
707
+ result.push(this.unescapeCsv(current));
708
+ current = '';
709
+ } else {
710
+ current += char;
711
+ }
712
+ }
713
+
714
+ // Add the last field
715
+ result.push(this.unescapeCsv(current));
716
+
717
+ return result;
718
+ }
719
+
720
+ /**
721
+ * Escape CSV special characters
722
+ * @param {string} text - Text to escape
723
+ * @returns {string} Escaped text
724
+ */
725
+ escapeCsv(text) {
726
+ if (!text) return '';
727
+ const str = String(text);
728
+
729
+ // If contains comma, newline, or quote, wrap in quotes and escape quotes
730
+ if (str.includes(',') || str.includes('\n') || str.includes('"')) {
731
+ return '"' + str.replaceAll('"', '""') + '"';
732
+ }
733
+
734
+ return str;
735
+ }
736
+
737
+ /**
738
+ * Unescape CSV field
739
+ * @param {string} text - Text to unescape
740
+ * @returns {string} Unescaped text
741
+ */
742
+ unescapeCsv(text) {
743
+ if (!text) return '';
744
+
745
+ // Remove surrounding quotes if present
746
+ if (text.startsWith('"') && text.endsWith('"')) {
747
+ text = text.slice(1, -1);
748
+ // Unescape doubled quotes
749
+ text = text.replaceAll('""', '"');
750
+ }
751
+
752
+ return text;
753
+ }
754
+
755
+ /**
756
+ * Load module configuration files
757
+ * @param {Array} modules - List of module names
758
+ * @returns {Object} Module configurations indexed by name
759
+ */
760
+ async loadModuleConfigs(modules) {
761
+ const configs = {};
762
+
763
+ for (const moduleName of modules) {
764
+ // Handle core module differently - it's in src/core not src/modules/core
765
+ const configPath =
766
+ moduleName === 'core'
767
+ ? path.join(process.cwd(), 'src', 'core', 'config.yaml')
768
+ : path.join(process.cwd(), 'src', 'modules', moduleName, 'config.yaml');
769
+
770
+ try {
771
+ if (await fs.pathExists(configPath)) {
772
+ const yaml = require('yaml');
773
+ const content = await fs.readFile(configPath, 'utf8');
774
+ configs[moduleName] = yaml.parse(content);
775
+ }
776
+ } catch (error) {
777
+ console.warn(`Could not load config for module ${moduleName}:`, error.message);
778
+ }
779
+ }
780
+
781
+ return configs;
782
+ }
783
+ /**
784
+ * Add a custom module to the manifest with its source path
785
+ * @param {string} bmadDir - Path to bmad directory
786
+ * @param {Object} customModule - Custom module info
787
+ */
788
+ async addCustomModule(bmadDir, customModule) {
789
+ const manifest = await this.read(bmadDir);
790
+ if (!manifest) {
791
+ throw new Error('No manifest found');
792
+ }
793
+
794
+ if (!manifest.customModules) {
795
+ manifest.customModules = [];
796
+ }
797
+
798
+ // Check if custom module already exists
799
+ const existingIndex = manifest.customModules.findIndex((m) => m.id === customModule.id);
800
+ if (existingIndex === -1) {
801
+ // Add new entry
802
+ manifest.customModules.push(customModule);
803
+ } else {
804
+ // Update existing entry
805
+ manifest.customModules[existingIndex] = customModule;
806
+ }
807
+
808
+ await this.update(bmadDir, { customModules: manifest.customModules });
809
+ }
810
+
811
+ /**
812
+ * Remove a custom module from the manifest
813
+ * @param {string} bmadDir - Path to bmad directory
814
+ * @param {string} moduleId - Module ID to remove
815
+ */
816
+ async removeCustomModule(bmadDir, moduleId) {
817
+ const manifest = await this.read(bmadDir);
818
+ if (!manifest || !manifest.customModules) {
819
+ return;
820
+ }
821
+
822
+ const index = manifest.customModules.findIndex((m) => m.id === moduleId);
823
+ if (index !== -1) {
824
+ manifest.customModules.splice(index, 1);
825
+ await this.update(bmadDir, { customModules: manifest.customModules });
826
+ }
827
+ }
828
+
829
+ /**
830
+ * Get module version info from source
831
+ * @param {string} moduleName - Module name/code
832
+ * @param {string} bmadDir - Path to bmad directory
833
+ * @param {string} moduleSourcePath - Optional source path for custom modules
834
+ * @returns {Object} Version info object with version, source, npmPackage, repoUrl
835
+ */
836
+ async getModuleVersionInfo(moduleName, bmadDir, moduleSourcePath = null) {
837
+ const os = require('node:os');
838
+
839
+ // Built-in modules use BMad version (only core and bmm are in BMAD-METHOD repo)
840
+ if (['core', 'bmm'].includes(moduleName)) {
841
+ const bmadVersion = require(path.join(getProjectRoot(), 'package.json')).version;
842
+ return {
843
+ version: bmadVersion,
844
+ source: 'built-in',
845
+ npmPackage: null,
846
+ repoUrl: null,
847
+ };
848
+ }
849
+
850
+ // Check if this is an external official module
851
+ const { ExternalModuleManager } = require('../modules/external-manager');
852
+ const extMgr = new ExternalModuleManager();
853
+ const moduleInfo = await extMgr.getModuleByCode(moduleName);
854
+
855
+ if (moduleInfo) {
856
+ // External module - try to get version from npm registry first, then fall back to cache
857
+ let version = null;
858
+
859
+ if (moduleInfo.npmPackage) {
860
+ // Fetch version from npm registry
861
+ try {
862
+ version = await this.fetchNpmVersion(moduleInfo.npmPackage);
863
+ } catch {
864
+ // npm fetch failed, try cache as fallback
865
+ }
866
+ }
867
+
868
+ // If npm didn't work, try reading from cached repo's package.json
869
+ if (!version) {
870
+ const cacheDir = path.join(os.homedir(), '.bmad', 'cache', 'external-modules', moduleName);
871
+ const packageJsonPath = path.join(cacheDir, 'package.json');
872
+
873
+ if (await fs.pathExists(packageJsonPath)) {
874
+ try {
875
+ const pkg = require(packageJsonPath);
876
+ version = pkg.version;
877
+ } catch (error) {
878
+ console.warn(`Failed to read package.json for ${moduleName}: ${error.message}`);
879
+ }
880
+ }
881
+ }
882
+
883
+ return {
884
+ version: version,
885
+ source: 'external',
886
+ npmPackage: moduleInfo.npmPackage || null,
887
+ repoUrl: moduleInfo.url || null,
888
+ };
889
+ }
890
+
891
+ // Custom module - check cache directory
892
+ const cacheDir = path.join(bmadDir, '_config', 'custom', moduleName);
893
+ const moduleYamlPath = path.join(cacheDir, 'module.yaml');
894
+
895
+ if (await fs.pathExists(moduleYamlPath)) {
896
+ try {
897
+ const yamlContent = await fs.readFile(moduleYamlPath, 'utf8');
898
+ const moduleConfig = yaml.parse(yamlContent);
899
+ return {
900
+ version: moduleConfig.version || null,
901
+ source: 'custom',
902
+ npmPackage: moduleConfig.npmPackage || null,
903
+ repoUrl: moduleConfig.repoUrl || null,
904
+ };
905
+ } catch (error) {
906
+ console.warn(`Failed to read module.yaml for ${moduleName}: ${error.message}`);
907
+ }
908
+ }
909
+
910
+ // Unknown module
911
+ return {
912
+ version: null,
913
+ source: 'unknown',
914
+ npmPackage: null,
915
+ repoUrl: null,
916
+ };
917
+ }
918
+
919
+ /**
920
+ * Fetch latest version from npm for a package
921
+ * @param {string} packageName - npm package name
922
+ * @returns {string|null} Latest version or null
923
+ */
924
+ async fetchNpmVersion(packageName) {
925
+ try {
926
+ const https = require('node:https');
927
+ const { execSync } = require('node:child_process');
928
+
929
+ // Try using npm view first (more reliable)
930
+ try {
931
+ const result = execSync(`npm view ${packageName} version`, {
932
+ encoding: 'utf8',
933
+ stdio: 'pipe',
934
+ timeout: 10_000,
935
+ });
936
+ return result.trim();
937
+ } catch {
938
+ // Fallback to npm registry API
939
+ return new Promise((resolve, reject) => {
940
+ https
941
+ .get(`https://registry.npmjs.org/${packageName}`, (res) => {
942
+ let data = '';
943
+ res.on('data', (chunk) => (data += chunk));
944
+ res.on('end', () => {
945
+ try {
946
+ const pkg = JSON.parse(data);
947
+ resolve(pkg['dist-tags']?.latest || pkg.version || null);
948
+ } catch {
949
+ resolve(null);
950
+ }
951
+ });
952
+ })
953
+ .on('error', () => resolve(null));
954
+ });
955
+ }
956
+ } catch {
957
+ return null;
958
+ }
959
+ }
960
+
961
+ /**
962
+ * Check for available updates for installed modules
963
+ * @param {string} bmadDir - Path to bmad directory
964
+ * @returns {Array} Array of update info objects
965
+ */
966
+ async checkForUpdates(bmadDir) {
967
+ const modules = await this.getAllModuleVersions(bmadDir);
968
+ const updates = [];
969
+
970
+ for (const module of modules) {
971
+ if (!module.npmPackage) {
972
+ continue; // Skip modules without npm package (built-in)
973
+ }
974
+
975
+ const latestVersion = await this.fetchNpmVersion(module.npmPackage);
976
+ if (!latestVersion) {
977
+ continue;
978
+ }
979
+
980
+ if (module.version !== latestVersion) {
981
+ updates.push({
982
+ name: module.name,
983
+ installedVersion: module.version,
984
+ latestVersion: latestVersion,
985
+ npmPackage: module.npmPackage,
986
+ updateAvailable: true,
987
+ });
988
+ }
989
+ }
990
+
991
+ return updates;
992
+ }
993
+
994
+ /**
995
+ * Compare two semantic versions
996
+ * @param {string} v1 - First version
997
+ * @param {string} v2 - Second version
998
+ * @returns {number} -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2
999
+ */
1000
+ compareVersions(v1, v2) {
1001
+ if (!v1 || !v2) return 0;
1002
+
1003
+ const normalize = (v) => {
1004
+ // Remove leading 'v' if present
1005
+ v = v.replace(/^v/, '');
1006
+ // Handle prerelease tags
1007
+ const parts = v.split('-');
1008
+ const main = parts[0].split('.');
1009
+ const prerelease = parts[1];
1010
+ return { main, prerelease };
1011
+ };
1012
+
1013
+ const n1 = normalize(v1);
1014
+ const n2 = normalize(v2);
1015
+
1016
+ // Compare main version parts
1017
+ for (let i = 0; i < 3; i++) {
1018
+ const num1 = parseInt(n1.main[i] || '0', 10);
1019
+ const num2 = parseInt(n2.main[i] || '0', 10);
1020
+ if (num1 !== num2) {
1021
+ return num1 < num2 ? -1 : 1;
1022
+ }
1023
+ }
1024
+
1025
+ // If main versions are equal, compare prerelease
1026
+ if (n1.prerelease && n2.prerelease) {
1027
+ return n1.prerelease < n2.prerelease ? -1 : n1.prerelease > n2.prerelease ? 1 : 0;
1028
+ }
1029
+ if (n1.prerelease) return -1; // Prerelease is older than stable
1030
+ if (n2.prerelease) return 1; // Stable is newer than prerelease
1031
+
1032
+ return 0;
1033
+ }
1034
+ }
1035
+
1036
+ module.exports = { Manifest };