mdan-cli 2.5.0 → 2.5.2

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