bmad-method 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/.github/FUNDING.yaml +15 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  4. package/.github/workflows/discord.yaml +25 -0
  5. package/.github/workflows/format-check.yaml +42 -0
  6. package/.github/workflows/manual-release.yaml +173 -0
  7. package/.husky/pre-commit +3 -2
  8. package/.vscode/settings.json +67 -74
  9. package/CHANGELOG.md +564 -19
  10. package/CONTRIBUTING.md +168 -5
  11. package/LICENSE +1 -1
  12. package/README.md +146 -218
  13. package/bmad-core/agent-teams/team-all.yaml +14 -0
  14. package/bmad-core/agent-teams/team-fullstack.yaml +18 -0
  15. package/bmad-core/agent-teams/team-ide-minimal.yaml +10 -0
  16. package/bmad-core/agent-teams/team-no-ui.yaml +13 -0
  17. package/bmad-core/agents/analyst.md +81 -0
  18. package/bmad-core/agents/architect.md +83 -0
  19. package/bmad-core/agents/bmad-master.md +107 -0
  20. package/bmad-core/agents/bmad-orchestrator.md +149 -0
  21. package/bmad-core/agents/dev.md +75 -0
  22. package/bmad-core/agents/pm.md +81 -0
  23. package/bmad-core/agents/po.md +76 -0
  24. package/bmad-core/agents/qa.md +88 -0
  25. package/bmad-core/agents/sm.md +62 -0
  26. package/bmad-core/agents/ux-expert.md +66 -0
  27. package/{.bmad-core → bmad-core}/checklists/architect-checklist.md +0 -5
  28. package/{.bmad-core → bmad-core}/checklists/change-checklist.md +2 -2
  29. package/{.bmad-core → bmad-core}/checklists/pm-checklist.md +0 -5
  30. package/{.bmad-core → bmad-core}/checklists/po-master-checklist.md +0 -9
  31. package/{.bmad-core → bmad-core}/checklists/story-dod-checklist.md +0 -7
  32. package/{.bmad-core → bmad-core}/checklists/story-draft-checklist.md +1 -4
  33. package/bmad-core/core-config.yaml +20 -0
  34. package/bmad-core/data/bmad-kb.md +806 -0
  35. package/bmad-core/data/brainstorming-techniques.md +36 -0
  36. package/bmad-core/data/elicitation-methods.md +154 -0
  37. package/bmad-core/data/test-levels-framework.md +146 -0
  38. package/bmad-core/data/test-priorities-matrix.md +172 -0
  39. package/bmad-core/tasks/advanced-elicitation.md +117 -0
  40. package/{.bmad-core → bmad-core}/tasks/correct-course.md +9 -12
  41. package/bmad-core/tasks/create-brownfield-story.md +312 -0
  42. package/{.bmad-core → bmad-core}/tasks/create-deep-research-prompt.md +4 -27
  43. package/bmad-core/tasks/create-next-story.md +112 -0
  44. package/bmad-core/tasks/document-project.md +343 -0
  45. package/bmad-core/tasks/facilitate-brainstorming-session.md +136 -0
  46. package/bmad-core/tasks/generate-ai-frontend-prompt.md +51 -0
  47. package/{.bmad-core → bmad-core}/tasks/index-docs.md +3 -13
  48. package/bmad-core/tasks/kb-mode-interaction.md +75 -0
  49. package/bmad-core/tasks/nfr-assess.md +343 -0
  50. package/bmad-core/tasks/qa-gate.md +159 -0
  51. package/bmad-core/tasks/review-story.md +314 -0
  52. package/bmad-core/tasks/risk-profile.md +353 -0
  53. package/{.bmad-core → bmad-core}/tasks/shard-doc.md +27 -15
  54. package/bmad-core/tasks/test-design.md +174 -0
  55. package/bmad-core/tasks/trace-requirements.md +264 -0
  56. package/bmad-core/tasks/validate-next-story.md +134 -0
  57. package/bmad-core/templates/architecture-tmpl.yaml +650 -0
  58. package/bmad-core/templates/brainstorming-output-tmpl.yaml +156 -0
  59. package/bmad-core/templates/brownfield-architecture-tmpl.yaml +476 -0
  60. package/bmad-core/templates/brownfield-prd-tmpl.yaml +280 -0
  61. package/bmad-core/templates/competitor-analysis-tmpl.yaml +306 -0
  62. package/bmad-core/templates/front-end-architecture-tmpl.yaml +218 -0
  63. package/bmad-core/templates/front-end-spec-tmpl.yaml +349 -0
  64. package/bmad-core/templates/fullstack-architecture-tmpl.yaml +823 -0
  65. package/bmad-core/templates/market-research-tmpl.yaml +252 -0
  66. package/bmad-core/templates/prd-tmpl.yaml +202 -0
  67. package/bmad-core/templates/project-brief-tmpl.yaml +221 -0
  68. package/bmad-core/templates/qa-gate-tmpl.yaml +102 -0
  69. package/bmad-core/templates/story-tmpl.yaml +137 -0
  70. package/bmad-core/workflows/brownfield-fullstack.yaml +297 -0
  71. package/bmad-core/workflows/brownfield-service.yaml +187 -0
  72. package/bmad-core/workflows/brownfield-ui.yaml +197 -0
  73. package/{.bmad-core/workflows/greenfield-fullstack.yml → bmad-core/workflows/greenfield-fullstack.yaml} +140 -77
  74. package/bmad-core/workflows/greenfield-service.yaml +206 -0
  75. package/bmad-core/workflows/greenfield-ui.yaml +235 -0
  76. package/common/tasks/create-doc.md +101 -0
  77. package/{.bmad-core → common}/tasks/execute-checklist.md +2 -13
  78. package/common/utils/bmad-doc-template.md +325 -0
  79. package/common/utils/workflow-management.md +69 -0
  80. package/dist/agents/analyst.txt +2889 -0
  81. package/dist/agents/architect.txt +3552 -0
  82. package/dist/agents/bmad-master.txt +8769 -0
  83. package/dist/agents/bmad-orchestrator.txt +1513 -0
  84. package/dist/agents/dev.txt +414 -0
  85. package/{.bmad-core/web-bundles → dist}/agents/pm.txt +668 -1119
  86. package/{.bmad-core/web-bundles → dist}/agents/po.txt +341 -484
  87. package/dist/agents/qa.txt +1987 -0
  88. package/dist/agents/sm.txt +658 -0
  89. package/dist/agents/ux-expert.txt +694 -0
  90. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +2371 -0
  91. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +1620 -0
  92. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +815 -0
  93. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +10952 -0
  94. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +4012 -0
  95. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +3698 -0
  96. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +450 -0
  97. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +973 -0
  98. package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +15376 -0
  99. package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +2075 -0
  100. package/dist/teams/team-all.txt +12682 -0
  101. package/dist/teams/team-fullstack.txt +10421 -0
  102. package/dist/teams/team-ide-minimal.txt +5103 -0
  103. package/dist/teams/team-no-ui.txt +8980 -0
  104. package/docs/GUIDING-PRINCIPLES.md +91 -0
  105. package/docs/core-architecture.md +219 -0
  106. package/docs/enhanced-ide-development-workflow.md +248 -0
  107. package/docs/expansion-packs.md +280 -0
  108. package/docs/how-to-contribute-with-pull-requests.md +158 -0
  109. package/docs/user-guide.md +504 -0
  110. package/docs/versioning-and-releases.md +8 -16
  111. package/docs/versions.md +4 -5
  112. package/docs/working-in-the-brownfield.md +597 -0
  113. package/eslint.config.mjs +119 -0
  114. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/Complete AI Agent System - Flowchart.svg +102 -0
  115. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash copy.txt +13 -0
  116. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash.txt +13 -0
  117. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.2 Agent Development Kit Installation/1.2.2 - Basic Project Structure - txt.txt +25 -0
  118. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.1 - settings.py +34 -0
  119. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.2 - main.py - Base Application.py +70 -0
  120. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.4 Deployment Configuration/1.4.2 - cloudbuild.yaml +26 -0
  121. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +109 -0
  122. package/expansion-packs/README.md +2 -112
  123. package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/phaser-2d-nodejs-game-team.yaml +13 -0
  124. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.md +71 -0
  125. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +78 -0
  126. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +64 -0
  127. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-design-checklist.md +201 -0
  128. package/expansion-packs/bmad-2d-phaser-game-dev/checklists/game-story-dod-checklist.md +160 -0
  129. package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +8 -0
  130. package/expansion-packs/bmad-2d-phaser-game-dev/data/bmad-kb.md +250 -0
  131. package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +647 -0
  132. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/advanced-elicitation.md +110 -0
  133. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/create-game-story.md +216 -0
  134. package/expansion-packs/bmad-2d-phaser-game-dev/tasks/game-design-brainstorming.md +290 -0
  135. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +613 -0
  136. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +356 -0
  137. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +343 -0
  138. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +253 -0
  139. package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +484 -0
  140. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +183 -0
  141. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +175 -0
  142. package/expansion-packs/bmad-2d-unity-game-dev/agent-teams/unity-2d-game-team.yaml +14 -0
  143. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.md +80 -0
  144. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.md +77 -0
  145. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +78 -0
  146. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.md +65 -0
  147. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-architect-checklist.md +391 -0
  148. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-change-checklist.md +203 -0
  149. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-design-checklist.md +201 -0
  150. package/expansion-packs/bmad-2d-unity-game-dev/checklists/game-story-dod-checklist.md +124 -0
  151. package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +6 -0
  152. package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +769 -0
  153. package/expansion-packs/bmad-2d-unity-game-dev/data/development-guidelines.md +586 -0
  154. package/expansion-packs/bmad-2d-unity-game-dev/tasks/advanced-elicitation.md +110 -0
  155. package/expansion-packs/bmad-2d-unity-game-dev/tasks/correct-course-game.md +141 -0
  156. package/expansion-packs/bmad-2d-unity-game-dev/tasks/create-game-story.md +184 -0
  157. package/expansion-packs/bmad-2d-unity-game-dev/tasks/game-design-brainstorming.md +290 -0
  158. package/expansion-packs/bmad-2d-unity-game-dev/tasks/validate-game-story.md +200 -0
  159. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-architecture-tmpl.yaml +1030 -0
  160. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +356 -0
  161. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +705 -0
  162. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +256 -0
  163. package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +484 -0
  164. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +183 -0
  165. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +175 -0
  166. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/README.md +9 -9
  167. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/agents/infra-devops-platform.md +30 -18
  168. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/checklists/infrastructure-checklist.md +1 -1
  169. package/expansion-packs/bmad-infrastructure-devops/config.yaml +9 -0
  170. package/expansion-packs/bmad-infrastructure-devops/data/bmad-kb.md +305 -0
  171. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/review-infrastructure.md +4 -5
  172. package/expansion-packs/{infrastructure-devops → bmad-infrastructure-devops}/tasks/validate-infrastructure.md +4 -5
  173. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +424 -0
  174. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +629 -0
  175. package/package.json +74 -42
  176. package/prettier.config.mjs +32 -0
  177. package/release_notes.md +25 -0
  178. package/tools/bmad-npx-wrapper.js +13 -15
  179. package/tools/builders/web-builder.js +544 -15
  180. package/tools/bump-all-versions.js +115 -0
  181. package/tools/bump-expansion-version.js +90 -0
  182. package/tools/cli.js +65 -32
  183. package/tools/flattener/aggregate.js +76 -0
  184. package/tools/flattener/binary.js +80 -0
  185. package/tools/flattener/discovery.js +71 -0
  186. package/tools/flattener/files.js +35 -0
  187. package/tools/flattener/ignoreRules.js +176 -0
  188. package/tools/flattener/main.js +573 -0
  189. package/tools/flattener/projectRoot.js +206 -0
  190. package/tools/flattener/prompts.js +44 -0
  191. package/tools/flattener/stats.helpers.js +395 -0
  192. package/tools/flattener/stats.js +80 -0
  193. package/tools/flattener/test-matrix.js +413 -0
  194. package/tools/flattener/xml.js +88 -0
  195. package/tools/installer/README.md +3 -53
  196. package/tools/installer/bin/bmad.js +475 -90
  197. package/tools/installer/config/ide-agent-config.yaml +58 -0
  198. package/tools/installer/config/install.config.yaml +123 -0
  199. package/tools/installer/lib/config-loader.js +208 -40
  200. package/tools/installer/lib/file-manager.js +258 -55
  201. package/tools/installer/lib/ide-base-setup.js +228 -0
  202. package/tools/installer/lib/ide-setup.js +1265 -253
  203. package/tools/installer/lib/installer.js +1651 -310
  204. package/tools/installer/lib/memory-profiler.js +225 -0
  205. package/tools/installer/lib/module-manager.js +114 -0
  206. package/tools/installer/lib/resource-locator.js +308 -0
  207. package/tools/installer/package.json +25 -24
  208. package/tools/lib/dependency-resolver.js +44 -48
  209. package/tools/lib/yaml-utils.js +29 -0
  210. package/tools/md-assets/web-agent-startup-instructions.md +39 -0
  211. package/tools/preview-release-notes.js +66 -0
  212. package/tools/shared/bannerArt.js +105 -0
  213. package/tools/sync-installer-version.js +7 -9
  214. package/tools/update-expansion-version.js +53 -0
  215. package/tools/upgraders/v3-to-v4-upgrader.js +221 -320
  216. package/tools/version-bump.js +42 -27
  217. package/tools/yaml-format.js +57 -44
  218. package/.bmad-core/agent-teams/team-all.yml +0 -16
  219. package/.bmad-core/agent-teams/team-fullstack.yml +0 -26
  220. package/.bmad-core/agent-teams/team-no-ui.yml +0 -15
  221. package/.bmad-core/agents/analyst.md +0 -59
  222. package/.bmad-core/agents/architect.md +0 -66
  223. package/.bmad-core/agents/bmad-master.md +0 -104
  224. package/.bmad-core/agents/bmad-orchestrator.md +0 -81
  225. package/.bmad-core/agents/dev.md +0 -70
  226. package/.bmad-core/agents/pm.md +0 -59
  227. package/.bmad-core/agents/po.md +0 -60
  228. package/.bmad-core/agents/qa.md +0 -52
  229. package/.bmad-core/agents/sm.md +0 -55
  230. package/.bmad-core/agents/ux-expert.md +0 -66
  231. package/.bmad-core/data/bmad-kb.md +0 -47
  232. package/.bmad-core/schemas/agent-team-schema.yml +0 -153
  233. package/.bmad-core/tasks/advanced-elicitation.md +0 -92
  234. package/.bmad-core/tasks/brainstorming-techniques.md +0 -238
  235. package/.bmad-core/tasks/core-dump.md +0 -74
  236. package/.bmad-core/tasks/create-agent.md +0 -202
  237. package/.bmad-core/tasks/create-doc.md +0 -74
  238. package/.bmad-core/tasks/create-expansion-pack.md +0 -425
  239. package/.bmad-core/tasks/create-next-story.md +0 -206
  240. package/.bmad-core/tasks/create-team.md +0 -229
  241. package/.bmad-core/tasks/doc-migration-task.md +0 -143
  242. package/.bmad-core/tasks/generate-ai-frontend-prompt.md +0 -58
  243. package/.bmad-core/templates/agent-tmpl.md +0 -58
  244. package/.bmad-core/templates/architecture-tmpl.md +0 -771
  245. package/.bmad-core/templates/brownfield-architecture-tmpl.md +0 -542
  246. package/.bmad-core/templates/brownfield-prd-tmpl.md +0 -240
  247. package/.bmad-core/templates/competitor-analysis-tmpl.md +0 -289
  248. package/.bmad-core/templates/expansion-pack-plan-tmpl.md +0 -91
  249. package/.bmad-core/templates/front-end-architecture-tmpl.md +0 -173
  250. package/.bmad-core/templates/front-end-spec-tmpl.md +0 -411
  251. package/.bmad-core/templates/fullstack-architecture-tmpl.md +0 -1016
  252. package/.bmad-core/templates/market-research-tmpl.md +0 -261
  253. package/.bmad-core/templates/prd-tmpl.md +0 -200
  254. package/.bmad-core/templates/project-brief-tmpl.md +0 -228
  255. package/.bmad-core/templates/simple-project-prd-tmpl.md +0 -461
  256. package/.bmad-core/templates/story-tmpl.md +0 -61
  257. package/.bmad-core/templates/web-agent-startup-instructions-template.md +0 -39
  258. package/.bmad-core/utils/agent-switcher.ide.md +0 -112
  259. package/.bmad-core/utils/template-format.md +0 -26
  260. package/.bmad-core/utils/workflow-management.md +0 -224
  261. package/.bmad-core/web-bundles/agents/analyst.txt +0 -1684
  262. package/.bmad-core/web-bundles/agents/architect.txt +0 -3584
  263. package/.bmad-core/web-bundles/agents/bmad-master.txt +0 -9491
  264. package/.bmad-core/web-bundles/agents/bmad-orchestrator.txt +0 -1466
  265. package/.bmad-core/web-bundles/agents/dev.txt +0 -316
  266. package/.bmad-core/web-bundles/agents/qa.txt +0 -129
  267. package/.bmad-core/web-bundles/agents/sm.txt +0 -658
  268. package/.bmad-core/web-bundles/agents/ux-expert.txt +0 -1099
  269. package/.bmad-core/web-bundles/teams/team-all.txt +0 -10757
  270. package/.bmad-core/web-bundles/teams/team-fullstack.txt +0 -10109
  271. package/.bmad-core/web-bundles/teams/team-no-ui.txt +0 -8950
  272. package/.bmad-core/workflows/brownfield-fullstack.yml +0 -116
  273. package/.bmad-core/workflows/brownfield-service.yml +0 -117
  274. package/.bmad-core/workflows/brownfield-ui.yml +0 -127
  275. package/.bmad-core/workflows/greenfield-service.yml +0 -143
  276. package/.bmad-core/workflows/greenfield-ui.yml +0 -172
  277. package/.claude/commands/analyst.md +0 -63
  278. package/.claude/commands/architect.md +0 -70
  279. package/.claude/commands/bmad-master.md +0 -108
  280. package/.claude/commands/bmad-orchestrator.md +0 -85
  281. package/.claude/commands/dev.md +0 -74
  282. package/.claude/commands/pm.md +0 -63
  283. package/.claude/commands/po.md +0 -64
  284. package/.claude/commands/qa.md +0 -56
  285. package/.claude/commands/sm.md +0 -59
  286. package/.claude/commands/ux-expert.md +0 -70
  287. package/.cursor/rules/analyst.mdc +0 -77
  288. package/.cursor/rules/architect.mdc +0 -84
  289. package/.cursor/rules/bmad-master.mdc +0 -122
  290. package/.cursor/rules/bmad-orchestrator.mdc +0 -99
  291. package/.cursor/rules/dev.mdc +0 -88
  292. package/.cursor/rules/pm.mdc +0 -77
  293. package/.cursor/rules/po.mdc +0 -78
  294. package/.cursor/rules/qa.mdc +0 -70
  295. package/.cursor/rules/sm.mdc +0 -73
  296. package/.cursor/rules/ux-expert.mdc +0 -84
  297. package/.github/workflows/release.yml +0 -59
  298. package/.releaserc.json +0 -18
  299. package/.roo/.roomodes +0 -95
  300. package/.roo/README.md +0 -38
  301. package/.vscode/extensions.json +0 -6
  302. package/.windsurf/rules/analyst.md +0 -71
  303. package/.windsurf/rules/architect.md +0 -78
  304. package/.windsurf/rules/bmad-master.md +0 -116
  305. package/.windsurf/rules/bmad-orchestrator.md +0 -93
  306. package/.windsurf/rules/dev.md +0 -82
  307. package/.windsurf/rules/pm.md +0 -71
  308. package/.windsurf/rules/po.md +0 -72
  309. package/.windsurf/rules/qa.md +0 -64
  310. package/.windsurf/rules/sm.md +0 -67
  311. package/.windsurf/rules/ux-expert.md +0 -78
  312. package/docs/bmad-workflow-guide.md +0 -161
  313. package/docs/claude-code-guide.md +0 -119
  314. package/docs/cursor-guide.md +0 -127
  315. package/docs/roo-code-guide.md +0 -140
  316. package/docs/sample-output/simple-fullstack-greenfield/prd.md +0 -42
  317. package/docs/windsurf-guide.md +0 -127
  318. package/expansion-packs/infrastructure-devops/manifest.yml +0 -38
  319. package/expansion-packs/infrastructure-devops/templates/infrastructure-architecture-tmpl.md +0 -415
  320. package/expansion-packs/infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.md +0 -0
  321. package/tools/installer/config/install.config.yml +0 -139
  322. package/tools/installer/package-lock.json +0 -906
  323. package/tools/installer/templates/claude-commands.md +0 -7
  324. package/tools/installer/templates/cursor-rules.md +0 -22
  325. package/tools/installer/templates/windsurf-rules.md +0 -22
  326. package/tools/semantic-release-sync-installer.js +0 -31
  327. /package/{.bmad-core → bmad-core}/data/technical-preferences.md +0 -0
  328. /package/{.bmad-core → bmad-core}/tasks/brownfield-create-epic.md +0 -0
  329. /package/{.bmad-core → bmad-core}/tasks/brownfield-create-story.md +0 -0
@@ -1,31 +1,26 @@
1
- const fs = require("fs-extra");
2
- const path = require("path");
3
- const crypto = require("crypto");
4
- const glob = require("glob");
5
-
6
- // Dynamic import for ES module
7
- let chalk;
8
-
9
- // Initialize ES modules
10
- async function initializeModules() {
11
- if (!chalk) {
12
- chalk = (await import("chalk")).default;
13
- }
14
- }
1
+ const fs = require('fs-extra');
2
+ const path = require('node:path');
3
+ const crypto = require('node:crypto');
4
+ const yaml = require('js-yaml');
5
+ const chalk = require('chalk');
6
+ const { createReadStream, createWriteStream, promises: fsPromises } = require('node:fs');
7
+ const { pipeline } = require('node:stream/promises');
8
+ const resourceLocator = require('./resource-locator');
15
9
 
16
10
  class FileManager {
17
- constructor() {
18
- this.manifestDir = ".bmad-core";
19
- this.manifestFile = "install-manifest.yml";
20
- }
11
+ constructor() {}
21
12
 
22
13
  async copyFile(source, destination) {
23
14
  try {
24
15
  await fs.ensureDir(path.dirname(destination));
25
- await fs.copy(source, destination);
16
+
17
+ // Use streaming for large files (> 10MB)
18
+ const stats = await fs.stat(source);
19
+ await (stats.size > 10 * 1024 * 1024
20
+ ? pipeline(createReadStream(source), createWriteStream(destination))
21
+ : fs.copy(source, destination));
26
22
  return true;
27
23
  } catch (error) {
28
- await initializeModules();
29
24
  console.error(chalk.red(`Failed to copy ${source}:`), error.message);
30
25
  return false;
31
26
  }
@@ -34,27 +29,46 @@ class FileManager {
34
29
  async copyDirectory(source, destination) {
35
30
  try {
36
31
  await fs.ensureDir(destination);
37
- await fs.copy(source, destination);
32
+
33
+ // Use streaming copy for large directories
34
+ const files = await resourceLocator.findFiles('**/*', {
35
+ cwd: source,
36
+ nodir: true,
37
+ });
38
+
39
+ // Process files in batches to avoid memory issues
40
+ const batchSize = 50;
41
+ for (let index = 0; index < files.length; index += batchSize) {
42
+ const batch = files.slice(index, index + batchSize);
43
+ await Promise.all(
44
+ batch.map((file) => this.copyFile(path.join(source, file), path.join(destination, file))),
45
+ );
46
+ }
38
47
  return true;
39
48
  } catch (error) {
40
- await initializeModules();
41
- console.error(
42
- chalk.red(`Failed to copy directory ${source}:`),
43
- error.message
44
- );
49
+ console.error(chalk.red(`Failed to copy directory ${source}:`), error.message);
45
50
  return false;
46
51
  }
47
52
  }
48
53
 
49
- async copyGlobPattern(pattern, sourceDir, destDir) {
50
- const files = glob.sync(pattern, { cwd: sourceDir });
54
+ async copyGlobPattern(pattern, sourceDir, destDir, rootValue = null) {
55
+ const files = await resourceLocator.findFiles(pattern, { cwd: sourceDir });
51
56
  const copied = [];
52
57
 
53
58
  for (const file of files) {
54
59
  const sourcePath = path.join(sourceDir, file);
55
- const destPath = path.join(destDir, file);
60
+ const destinationPath = path.join(destDir, file);
61
+
62
+ // Use root replacement if rootValue is provided and file needs it
63
+ const needsRootReplacement =
64
+ rootValue && (file.endsWith('.md') || file.endsWith('.yaml') || file.endsWith('.yml'));
65
+
66
+ let success = false;
67
+ success = await (needsRootReplacement
68
+ ? this.copyFileWithRootReplacement(sourcePath, destinationPath, rootValue)
69
+ : this.copyFile(sourcePath, destinationPath));
56
70
 
57
- if (await this.copyFile(sourcePath, destPath)) {
71
+ if (success) {
58
72
  copied.push(file);
59
73
  }
60
74
  }
@@ -64,31 +78,40 @@ class FileManager {
64
78
 
65
79
  async calculateFileHash(filePath) {
66
80
  try {
67
- const content = await fs.readFile(filePath);
68
- return crypto
69
- .createHash("sha256")
70
- .update(content)
71
- .digest("hex")
72
- .slice(0, 16);
73
- } catch (error) {
81
+ // Use streaming for hash calculation to reduce memory usage
82
+ const stream = createReadStream(filePath);
83
+ const hash = crypto.createHash('sha256');
84
+
85
+ for await (const chunk of stream) {
86
+ hash.update(chunk);
87
+ }
88
+
89
+ return hash.digest('hex').slice(0, 16);
90
+ } catch {
74
91
  return null;
75
92
  }
76
93
  }
77
94
 
78
95
  async createManifest(installDir, config, files) {
79
- const manifestPath = path.join(
80
- installDir,
81
- this.manifestDir,
82
- this.manifestFile
83
- );
96
+ const manifestPath = path.join(installDir, this.manifestDir, this.manifestFile);
97
+
98
+ // Read version from package.json
99
+ let coreVersion = 'unknown';
100
+ try {
101
+ const packagePath = path.join(__dirname, '..', '..', '..', 'package.json');
102
+ const packageJson = require(packagePath);
103
+ coreVersion = packageJson.version;
104
+ } catch {
105
+ console.warn("Could not read version from package.json, using 'unknown'");
106
+ }
84
107
 
85
108
  const manifest = {
86
- version: require("../../../package.json").version,
109
+ version: coreVersion,
87
110
  installed_at: new Date().toISOString(),
88
111
  install_type: config.installType,
89
112
  agent: config.agent || null,
90
- ide_setup: config.ide || null,
91
113
  ides_setup: config.ides || [],
114
+ expansion_packs: config.expansionPacks || [],
92
115
  files: [],
93
116
  };
94
117
 
@@ -106,22 +129,29 @@ class FileManager {
106
129
 
107
130
  // Write manifest
108
131
  await fs.ensureDir(path.dirname(manifestPath));
109
- await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
132
+ await fs.writeFile(manifestPath, yaml.dump(manifest, { indent: 2 }));
110
133
 
111
134
  return manifest;
112
135
  }
113
136
 
114
137
  async readManifest(installDir) {
115
- const manifestPath = path.join(
116
- installDir,
117
- this.manifestDir,
118
- this.manifestFile
119
- );
138
+ const manifestPath = path.join(installDir, this.manifestDir, this.manifestFile);
120
139
 
121
140
  try {
122
- const content = await fs.readFile(manifestPath, "utf8");
123
- return JSON.parse(content);
124
- } catch (error) {
141
+ const content = await fs.readFile(manifestPath, 'utf8');
142
+ return yaml.load(content);
143
+ } catch {
144
+ return null;
145
+ }
146
+ }
147
+
148
+ async readExpansionPackManifest(installDir, packId) {
149
+ const manifestPath = path.join(installDir, `.${packId}`, this.manifestFile);
150
+
151
+ try {
152
+ const content = await fs.readFile(manifestPath, 'utf8');
153
+ return yaml.load(content);
154
+ } catch {
125
155
  return null;
126
156
  }
127
157
  }
@@ -141,8 +171,35 @@ class FileManager {
141
171
  return modified;
142
172
  }
143
173
 
174
+ async checkFileIntegrity(installDir, manifest) {
175
+ const result = {
176
+ missing: [],
177
+ modified: [],
178
+ };
179
+
180
+ for (const file of manifest.files) {
181
+ const filePath = path.join(installDir, file.path);
182
+
183
+ // Skip checking the manifest file itself - it will always be different due to timestamps
184
+ if (file.path.endsWith('install-manifest.yaml')) {
185
+ continue;
186
+ }
187
+
188
+ if (await this.pathExists(filePath)) {
189
+ const currentHash = await this.calculateFileHash(filePath);
190
+ if (currentHash && currentHash !== file.hash) {
191
+ result.modified.push(file.path);
192
+ }
193
+ } else {
194
+ result.missing.push(file.path);
195
+ }
196
+ }
197
+
198
+ return result;
199
+ }
200
+
144
201
  async backupFile(filePath) {
145
- const backupPath = filePath + ".bak";
202
+ const backupPath = filePath + '.bak';
146
203
  let counter = 1;
147
204
  let finalBackupPath = backupPath;
148
205
 
@@ -170,7 +227,7 @@ class FileManager {
170
227
  }
171
228
 
172
229
  async readFile(filePath) {
173
- return fs.readFile(filePath, "utf8");
230
+ return fs.readFile(filePath, 'utf8');
174
231
  }
175
232
 
176
233
  async writeFile(filePath, content) {
@@ -181,6 +238,152 @@ class FileManager {
181
238
  async removeDirectory(dirPath) {
182
239
  await fs.remove(dirPath);
183
240
  }
241
+
242
+ async createExpansionPackManifest(installDir, packId, config, files) {
243
+ const manifestPath = path.join(installDir, `.${packId}`, this.manifestFile);
244
+
245
+ const manifest = {
246
+ version: config.expansionPackVersion || require('../../../package.json').version,
247
+ installed_at: new Date().toISOString(),
248
+ install_type: config.installType,
249
+ expansion_pack_id: config.expansionPackId,
250
+ expansion_pack_name: config.expansionPackName,
251
+ ides_setup: config.ides || [],
252
+ files: [],
253
+ };
254
+
255
+ // Add file information
256
+ for (const file of files) {
257
+ const filePath = path.join(installDir, file);
258
+ const hash = await this.calculateFileHash(filePath);
259
+
260
+ manifest.files.push({
261
+ path: file,
262
+ hash: hash,
263
+ modified: false,
264
+ });
265
+ }
266
+
267
+ // Write manifest
268
+ await fs.ensureDir(path.dirname(manifestPath));
269
+ await fs.writeFile(manifestPath, yaml.dump(manifest, { indent: 2 }));
270
+
271
+ return manifest;
272
+ }
273
+
274
+ async modifyCoreConfig(installDir, config) {
275
+ const coreConfigPath = path.join(installDir, '.bmad-core', 'core-config.yaml');
276
+
277
+ try {
278
+ // Read the existing core-config.yaml
279
+ const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
280
+ const coreConfig = yaml.load(coreConfigContent);
281
+
282
+ // Modify sharding settings if provided
283
+ if (config.prdSharded !== undefined) {
284
+ coreConfig.prd.prdSharded = config.prdSharded;
285
+ }
286
+
287
+ if (config.architectureSharded !== undefined) {
288
+ coreConfig.architecture.architectureSharded = config.architectureSharded;
289
+ }
290
+
291
+ // Write back the modified config
292
+ await fs.writeFile(coreConfigPath, yaml.dump(coreConfig, { indent: 2 }));
293
+
294
+ return true;
295
+ } catch (error) {
296
+ console.error(chalk.red(`Failed to modify core-config.yaml:`), error.message);
297
+ return false;
298
+ }
299
+ }
300
+
301
+ async copyFileWithRootReplacement(source, destination, rootValue) {
302
+ try {
303
+ // Check file size to determine if we should stream
304
+ const stats = await fs.stat(source);
305
+
306
+ if (stats.size > 5 * 1024 * 1024) {
307
+ // 5MB threshold
308
+ // Use streaming for large files
309
+ const { Transform } = require('node:stream');
310
+ const replaceStream = new Transform({
311
+ transform(chunk, encoding, callback) {
312
+ const modified = chunk.toString().replaceAll('{root}', rootValue);
313
+ callback(null, modified);
314
+ },
315
+ });
316
+
317
+ await this.ensureDirectory(path.dirname(destination));
318
+ await pipeline(
319
+ createReadStream(source, { encoding: 'utf8' }),
320
+ replaceStream,
321
+ createWriteStream(destination, { encoding: 'utf8' }),
322
+ );
323
+ } else {
324
+ // Regular approach for smaller files
325
+ const content = await fsPromises.readFile(source, 'utf8');
326
+ const updatedContent = content.replaceAll('{root}', rootValue);
327
+ await this.ensureDirectory(path.dirname(destination));
328
+ await fsPromises.writeFile(destination, updatedContent, 'utf8');
329
+ }
330
+
331
+ return true;
332
+ } catch (error) {
333
+ console.error(chalk.red(`Failed to copy ${source} with root replacement:`), error.message);
334
+ return false;
335
+ }
336
+ }
337
+
338
+ async copyDirectoryWithRootReplacement(
339
+ source,
340
+ destination,
341
+ rootValue,
342
+ fileExtensions = ['.md', '.yaml', '.yml'],
343
+ ) {
344
+ try {
345
+ await this.ensureDirectory(destination);
346
+
347
+ // Get all files in source directory
348
+ const files = await resourceLocator.findFiles('**/*', {
349
+ cwd: source,
350
+ nodir: true,
351
+ });
352
+
353
+ let replacedCount = 0;
354
+
355
+ for (const file of files) {
356
+ const sourcePath = path.join(source, file);
357
+ const destinationPath = path.join(destination, file);
358
+
359
+ // Check if this file type should have {root} replacement
360
+ const shouldReplace = fileExtensions.some((extension) => file.endsWith(extension));
361
+
362
+ if (shouldReplace) {
363
+ if (await this.copyFileWithRootReplacement(sourcePath, destinationPath, rootValue)) {
364
+ replacedCount++;
365
+ }
366
+ } else {
367
+ // Regular copy for files that don't need replacement
368
+ await this.copyFile(sourcePath, destinationPath);
369
+ }
370
+ }
371
+
372
+ if (replacedCount > 0) {
373
+ console.log(chalk.dim(` Processed ${replacedCount} files with {root} replacement`));
374
+ }
375
+
376
+ return true;
377
+ } catch (error) {
378
+ console.error(
379
+ chalk.red(`Failed to copy directory ${source} with root replacement:`),
380
+ error.message,
381
+ );
382
+ return false;
383
+ }
384
+ }
385
+ manifestDir = '.bmad-core';
386
+ manifestFile = 'install-manifest.yaml';
184
387
  }
185
388
 
186
389
  module.exports = new FileManager();
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Base IDE Setup - Common functionality for all IDE setups
3
+ * Reduces duplication and provides shared methods
4
+ */
5
+
6
+ const path = require('node:path');
7
+ const fs = require('fs-extra');
8
+ const yaml = require('js-yaml');
9
+ const chalk = require('chalk').default || require('chalk');
10
+ const fileManager = require('./file-manager');
11
+ const resourceLocator = require('./resource-locator');
12
+ const { extractYamlFromAgent } = require('../../lib/yaml-utils');
13
+
14
+ class BaseIdeSetup {
15
+ constructor() {
16
+ this._agentCache = new Map();
17
+ this._pathCache = new Map();
18
+ }
19
+
20
+ /**
21
+ * Get all agent IDs with caching
22
+ */
23
+ async getAllAgentIds(installDir) {
24
+ const cacheKey = `all-agents:${installDir}`;
25
+ if (this._agentCache.has(cacheKey)) {
26
+ return this._agentCache.get(cacheKey);
27
+ }
28
+
29
+ const allAgents = new Set();
30
+
31
+ // Get core agents
32
+ const coreAgents = await this.getCoreAgentIds(installDir);
33
+ for (const id of coreAgents) allAgents.add(id);
34
+
35
+ // Get expansion pack agents
36
+ const expansionPacks = await this.getInstalledExpansionPacks(installDir);
37
+ for (const pack of expansionPacks) {
38
+ const packAgents = await this.getExpansionPackAgents(pack.path);
39
+ for (const id of packAgents) allAgents.add(id);
40
+ }
41
+
42
+ const result = [...allAgents];
43
+ this._agentCache.set(cacheKey, result);
44
+ return result;
45
+ }
46
+
47
+ /**
48
+ * Get core agent IDs
49
+ */
50
+ async getCoreAgentIds(installDir) {
51
+ const coreAgents = [];
52
+ const corePaths = [
53
+ path.join(installDir, '.bmad-core', 'agents'),
54
+ path.join(installDir, 'bmad-core', 'agents'),
55
+ ];
56
+
57
+ for (const agentsDir of corePaths) {
58
+ if (await fileManager.pathExists(agentsDir)) {
59
+ const files = await resourceLocator.findFiles('*.md', { cwd: agentsDir });
60
+ coreAgents.push(...files.map((file) => path.basename(file, '.md')));
61
+ break; // Use first found
62
+ }
63
+ }
64
+
65
+ return coreAgents;
66
+ }
67
+
68
+ /**
69
+ * Find agent path with caching
70
+ */
71
+ async findAgentPath(agentId, installDir) {
72
+ const cacheKey = `agent-path:${agentId}:${installDir}`;
73
+ if (this._pathCache.has(cacheKey)) {
74
+ return this._pathCache.get(cacheKey);
75
+ }
76
+
77
+ // Use resource locator for efficient path finding
78
+ let agentPath = await resourceLocator.getAgentPath(agentId);
79
+
80
+ if (!agentPath) {
81
+ // Check installation-specific paths
82
+ const possiblePaths = [
83
+ path.join(installDir, '.bmad-core', 'agents', `${agentId}.md`),
84
+ path.join(installDir, 'bmad-core', 'agents', `${agentId}.md`),
85
+ path.join(installDir, 'common', 'agents', `${agentId}.md`),
86
+ ];
87
+
88
+ for (const testPath of possiblePaths) {
89
+ if (await fileManager.pathExists(testPath)) {
90
+ agentPath = testPath;
91
+ break;
92
+ }
93
+ }
94
+ }
95
+
96
+ if (agentPath) {
97
+ this._pathCache.set(cacheKey, agentPath);
98
+ }
99
+ return agentPath;
100
+ }
101
+
102
+ /**
103
+ * Get agent title from metadata
104
+ */
105
+ async getAgentTitle(agentId, installDir) {
106
+ const agentPath = await this.findAgentPath(agentId, installDir);
107
+ if (!agentPath) return agentId;
108
+
109
+ try {
110
+ const content = await fileManager.readFile(agentPath);
111
+ const yamlContent = extractYamlFromAgent(content);
112
+ if (yamlContent) {
113
+ const metadata = yaml.load(yamlContent);
114
+ return metadata.agent_name || agentId;
115
+ }
116
+ } catch {
117
+ // Fallback to agent ID
118
+ }
119
+ return agentId;
120
+ }
121
+
122
+ /**
123
+ * Get installed expansion packs
124
+ */
125
+ async getInstalledExpansionPacks(installDir) {
126
+ const cacheKey = `expansion-packs:${installDir}`;
127
+ if (this._pathCache.has(cacheKey)) {
128
+ return this._pathCache.get(cacheKey);
129
+ }
130
+
131
+ const expansionPacks = [];
132
+
133
+ // Check for dot-prefixed expansion packs
134
+ const dotExpansions = await resourceLocator.findFiles('.bmad-*', { cwd: installDir });
135
+
136
+ for (const dotExpansion of dotExpansions) {
137
+ if (dotExpansion !== '.bmad-core') {
138
+ const packPath = path.join(installDir, dotExpansion);
139
+ const packName = dotExpansion.slice(1); // remove the dot
140
+ expansionPacks.push({
141
+ name: packName,
142
+ path: packPath,
143
+ });
144
+ }
145
+ }
146
+
147
+ // Check other dot folders that have config.yaml
148
+ const allDotFolders = await resourceLocator.findFiles('.*', { cwd: installDir });
149
+ for (const folder of allDotFolders) {
150
+ if (!folder.startsWith('.bmad-') && folder !== '.bmad-core') {
151
+ const packPath = path.join(installDir, folder);
152
+ const configPath = path.join(packPath, 'config.yaml');
153
+ if (await fileManager.pathExists(configPath)) {
154
+ expansionPacks.push({
155
+ name: folder.slice(1), // remove the dot
156
+ path: packPath,
157
+ });
158
+ }
159
+ }
160
+ }
161
+
162
+ this._pathCache.set(cacheKey, expansionPacks);
163
+ return expansionPacks;
164
+ }
165
+
166
+ /**
167
+ * Get expansion pack agents
168
+ */
169
+ async getExpansionPackAgents(packPath) {
170
+ const agentsDir = path.join(packPath, 'agents');
171
+ if (!(await fileManager.pathExists(agentsDir))) {
172
+ return [];
173
+ }
174
+
175
+ const agentFiles = await resourceLocator.findFiles('*.md', { cwd: agentsDir });
176
+ return agentFiles.map((file) => path.basename(file, '.md'));
177
+ }
178
+
179
+ /**
180
+ * Create agent rule content (shared logic)
181
+ */
182
+ async createAgentRuleContent(agentId, agentPath, installDir, format = 'mdc') {
183
+ const agentContent = await fileManager.readFile(agentPath);
184
+ const agentTitle = await this.getAgentTitle(agentId, installDir);
185
+ const yamlContent = extractYamlFromAgent(agentContent);
186
+
187
+ let content = '';
188
+
189
+ if (format === 'mdc') {
190
+ // MDC format for Cursor
191
+ content = '---\n';
192
+ content += 'description: \n';
193
+ content += 'globs: []\n';
194
+ content += 'alwaysApply: false\n';
195
+ content += '---\n\n';
196
+ content += `# ${agentId.toUpperCase()} Agent Rule\n\n`;
197
+ content += `This rule is triggered when the user types \`@${agentId}\` and activates the ${agentTitle} agent persona.\n\n`;
198
+ content += '## Agent Activation\n\n';
199
+ content +=
200
+ 'CRITICAL: Read the full YAML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:\n\n';
201
+ content += '```yaml\n';
202
+ content += yamlContent || agentContent.replace(/^#.*$/m, '').trim();
203
+ content += '\n```\n\n';
204
+ content += '## File Reference\n\n';
205
+ const relativePath = path.relative(installDir, agentPath).replaceAll('\\', '/');
206
+ content += `The complete agent definition is available in [${relativePath}](mdc:${relativePath}).\n\n`;
207
+ content += '## Usage\n\n';
208
+ content += `When the user types \`@${agentId}\`, activate this ${agentTitle} persona and follow all instructions defined in the YAML configuration above.\n`;
209
+ } else if (format === 'claude') {
210
+ // Claude Code format
211
+ content = `# /${agentId} Command\n\n`;
212
+ content += `When this command is used, adopt the following agent persona:\n\n`;
213
+ content += agentContent;
214
+ }
215
+
216
+ return content;
217
+ }
218
+
219
+ /**
220
+ * Clear all caches
221
+ */
222
+ clearCache() {
223
+ this._agentCache.clear();
224
+ this._pathCache.clear();
225
+ }
226
+ }
227
+
228
+ module.exports = BaseIdeSetup;