bmad-method 4.37.0 → 4.39.1

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 (251) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +3 -3
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +3 -3
  3. package/.github/workflows/discord.yaml +11 -2
  4. package/.github/workflows/format-check.yaml +42 -0
  5. package/.github/workflows/manual-release.yaml +173 -0
  6. package/.husky/pre-commit +3 -0
  7. package/.vscode/settings.json +26 -1
  8. package/CHANGELOG.md +2 -23
  9. package/README.md +2 -0
  10. package/bmad-core/agent-teams/team-all.yaml +1 -1
  11. package/bmad-core/agents/analyst.md +16 -15
  12. package/bmad-core/agents/architect.md +11 -11
  13. package/bmad-core/agents/bmad-master.md +23 -22
  14. package/bmad-core/agents/bmad-orchestrator.md +13 -17
  15. package/bmad-core/agents/dev.md +14 -11
  16. package/bmad-core/agents/pm.md +15 -14
  17. package/bmad-core/agents/po.md +9 -8
  18. package/bmad-core/agents/qa.md +42 -22
  19. package/bmad-core/agents/sm.md +7 -6
  20. package/bmad-core/agents/ux-expert.md +6 -5
  21. package/bmad-core/core-config.yaml +2 -0
  22. package/bmad-core/data/bmad-kb.md +1 -1
  23. package/bmad-core/data/test-levels-framework.md +146 -0
  24. package/bmad-core/data/test-priorities-matrix.md +172 -0
  25. package/bmad-core/tasks/apply-qa-fixes.md +148 -0
  26. package/bmad-core/tasks/facilitate-brainstorming-session.md +1 -1
  27. package/bmad-core/tasks/nfr-assess.md +343 -0
  28. package/bmad-core/tasks/qa-gate.md +161 -0
  29. package/bmad-core/tasks/review-story.md +234 -74
  30. package/bmad-core/tasks/risk-profile.md +353 -0
  31. package/bmad-core/tasks/test-design.md +174 -0
  32. package/bmad-core/tasks/trace-requirements.md +264 -0
  33. package/bmad-core/templates/architecture-tmpl.yaml +49 -49
  34. package/bmad-core/templates/brainstorming-output-tmpl.yaml +5 -5
  35. package/bmad-core/templates/brownfield-architecture-tmpl.yaml +31 -31
  36. package/bmad-core/templates/brownfield-prd-tmpl.yaml +13 -13
  37. package/bmad-core/templates/competitor-analysis-tmpl.yaml +19 -6
  38. package/bmad-core/templates/front-end-architecture-tmpl.yaml +21 -9
  39. package/bmad-core/templates/front-end-spec-tmpl.yaml +24 -24
  40. package/bmad-core/templates/fullstack-architecture-tmpl.yaml +122 -104
  41. package/bmad-core/templates/market-research-tmpl.yaml +2 -2
  42. package/bmad-core/templates/prd-tmpl.yaml +9 -9
  43. package/bmad-core/templates/project-brief-tmpl.yaml +4 -4
  44. package/bmad-core/templates/qa-gate-tmpl.yaml +102 -0
  45. package/bmad-core/templates/story-tmpl.yaml +12 -12
  46. package/bmad-core/workflows/brownfield-fullstack.yaml +9 -9
  47. package/bmad-core/workflows/brownfield-service.yaml +1 -1
  48. package/bmad-core/workflows/brownfield-ui.yaml +1 -1
  49. package/bmad-core/workflows/greenfield-fullstack.yaml +1 -1
  50. package/bmad-core/workflows/greenfield-service.yaml +1 -1
  51. package/bmad-core/workflows/greenfield-ui.yaml +1 -1
  52. package/common/utils/bmad-doc-template.md +5 -5
  53. package/dist/agents/analyst.txt +1086 -1079
  54. package/dist/agents/architect.txt +1534 -1526
  55. package/dist/agents/bmad-master.txt +646 -632
  56. package/dist/agents/bmad-orchestrator.txt +40 -18
  57. package/dist/agents/dev.txt +158 -19
  58. package/dist/agents/pm.txt +1082 -1107
  59. package/dist/agents/po.txt +314 -332
  60. package/dist/agents/qa.txt +1754 -151
  61. package/dist/agents/sm.txt +88 -98
  62. package/dist/agents/ux-expert.txt +80 -87
  63. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +109 -146
  64. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +75 -86
  65. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +41 -48
  66. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +1903 -1941
  67. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +15 -50
  68. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +149 -195
  69. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +0 -15
  70. package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +20 -37
  71. package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +2660 -2752
  72. package/dist/expansion-packs/bmad-creative-writing/agents/beta-reader.txt +871 -0
  73. package/dist/expansion-packs/bmad-creative-writing/agents/book-critic.txt +78 -0
  74. package/dist/expansion-packs/bmad-creative-writing/agents/character-psychologist.txt +839 -0
  75. package/dist/expansion-packs/bmad-creative-writing/agents/cover-designer.txt +85 -0
  76. package/dist/expansion-packs/bmad-creative-writing/agents/dialog-specialist.txt +861 -0
  77. package/dist/expansion-packs/bmad-creative-writing/agents/editor.txt +796 -0
  78. package/dist/expansion-packs/bmad-creative-writing/agents/genre-specialist.txt +927 -0
  79. package/dist/expansion-packs/bmad-creative-writing/agents/narrative-designer.txt +842 -0
  80. package/dist/expansion-packs/bmad-creative-writing/agents/plot-architect.txt +1126 -0
  81. package/dist/expansion-packs/bmad-creative-writing/agents/world-builder.txt +864 -0
  82. package/dist/expansion-packs/bmad-creative-writing/teams/agent-team.txt +5917 -0
  83. package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +25 -27
  84. package/dist/teams/team-all.txt +5541 -3768
  85. package/dist/teams/team-fullstack.txt +3014 -2987
  86. package/dist/teams/team-ide-minimal.txt +2219 -469
  87. package/dist/teams/team-no-ui.txt +2993 -2966
  88. package/docs/enhanced-ide-development-workflow.md +220 -15
  89. package/docs/user-guide.md +271 -18
  90. package/docs/versioning-and-releases.md +122 -44
  91. package/docs/working-in-the-brownfield.md +264 -31
  92. package/eslint.config.mjs +119 -0
  93. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +4 -4
  94. package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +1 -1
  95. package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +1 -1
  96. package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +26 -28
  97. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +50 -50
  98. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +23 -23
  99. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +24 -24
  100. package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +42 -42
  101. package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +65 -65
  102. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +5 -5
  103. package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +1 -1
  104. package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +3 -3
  105. package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +1 -1
  106. package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +1 -1
  107. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +23 -23
  108. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +63 -63
  109. package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +20 -20
  110. package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +65 -65
  111. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +5 -5
  112. package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +1 -1
  113. package/expansion-packs/bmad-creative-writing/README.md +132 -0
  114. package/expansion-packs/bmad-creative-writing/agent-teams/agent-team.yaml +19 -0
  115. package/expansion-packs/bmad-creative-writing/agents/beta-reader.md +91 -0
  116. package/expansion-packs/bmad-creative-writing/agents/book-critic.md +35 -0
  117. package/expansion-packs/bmad-creative-writing/agents/character-psychologist.md +90 -0
  118. package/expansion-packs/bmad-creative-writing/agents/cover-designer.md +41 -0
  119. package/expansion-packs/bmad-creative-writing/agents/dialog-specialist.md +89 -0
  120. package/expansion-packs/bmad-creative-writing/agents/editor.md +90 -0
  121. package/expansion-packs/bmad-creative-writing/agents/genre-specialist.md +92 -0
  122. package/expansion-packs/bmad-creative-writing/agents/narrative-designer.md +90 -0
  123. package/expansion-packs/bmad-creative-writing/agents/plot-architect.md +92 -0
  124. package/expansion-packs/bmad-creative-writing/agents/world-builder.md +91 -0
  125. package/expansion-packs/bmad-creative-writing/checklists/beta-feedback-closure-checklist.md +16 -0
  126. package/expansion-packs/bmad-creative-writing/checklists/character-consistency-checklist.md +16 -0
  127. package/expansion-packs/bmad-creative-writing/checklists/comedic-timing-checklist.md +16 -0
  128. package/expansion-packs/bmad-creative-writing/checklists/cyberpunk-aesthetic-checklist.md +16 -0
  129. package/expansion-packs/bmad-creative-writing/checklists/ebook-formatting-checklist.md +15 -0
  130. package/expansion-packs/bmad-creative-writing/checklists/epic-poetry-meter-checklist.md +16 -0
  131. package/expansion-packs/bmad-creative-writing/checklists/fantasy-magic-system-checklist.md +16 -0
  132. package/expansion-packs/bmad-creative-writing/checklists/foreshadowing-payoff-checklist.md +15 -0
  133. package/expansion-packs/bmad-creative-writing/checklists/genre-tropes-checklist.md +15 -0
  134. package/expansion-packs/bmad-creative-writing/checklists/historical-accuracy-checklist.md +16 -0
  135. package/expansion-packs/bmad-creative-writing/checklists/horror-suspense-checklist.md +16 -0
  136. package/expansion-packs/bmad-creative-writing/checklists/kdp-cover-ready-checklist.md +18 -0
  137. package/expansion-packs/bmad-creative-writing/checklists/line-edit-quality-checklist.md +16 -0
  138. package/expansion-packs/bmad-creative-writing/checklists/marketing-copy-checklist.md +16 -0
  139. package/expansion-packs/bmad-creative-writing/checklists/mystery-clue-trail-checklist.md +16 -0
  140. package/expansion-packs/bmad-creative-writing/checklists/orbital-mechanics-checklist.md +16 -0
  141. package/expansion-packs/bmad-creative-writing/checklists/plot-structure-checklist.md +49 -0
  142. package/expansion-packs/bmad-creative-writing/checklists/publication-readiness-checklist.md +16 -0
  143. package/expansion-packs/bmad-creative-writing/checklists/romance-emotional-beats-checklist.md +16 -0
  144. package/expansion-packs/bmad-creative-writing/checklists/scene-quality-checklist.md +16 -0
  145. package/expansion-packs/bmad-creative-writing/checklists/scifi-technology-plausibility-checklist.md +15 -0
  146. package/expansion-packs/bmad-creative-writing/checklists/sensitivity-representation-checklist.md +16 -0
  147. package/expansion-packs/bmad-creative-writing/checklists/steampunk-gadget-checklist.md +16 -0
  148. package/expansion-packs/bmad-creative-writing/checklists/thriller-pacing-stakes-checklist.md +16 -0
  149. package/expansion-packs/bmad-creative-writing/checklists/timeline-continuity-checklist.md +16 -0
  150. package/expansion-packs/bmad-creative-writing/checklists/world-building-continuity-checklist.md +16 -0
  151. package/expansion-packs/bmad-creative-writing/checklists/ya-appropriateness-checklist.md +16 -0
  152. package/expansion-packs/bmad-creative-writing/config.yaml +11 -0
  153. package/expansion-packs/bmad-creative-writing/data/bmad-kb.md +197 -0
  154. package/expansion-packs/bmad-creative-writing/data/story-structures.md +58 -0
  155. package/expansion-packs/bmad-creative-writing/docs/brief.md +183 -0
  156. package/expansion-packs/bmad-creative-writing/tasks/advanced-elicitation.md +117 -0
  157. package/expansion-packs/bmad-creative-writing/tasks/analyze-reader-feedback.md +16 -0
  158. package/expansion-packs/bmad-creative-writing/tasks/analyze-story-structure.md +55 -0
  159. package/expansion-packs/bmad-creative-writing/tasks/assemble-kdp-package.md +22 -0
  160. package/expansion-packs/bmad-creative-writing/tasks/brainstorm-premise.md +16 -0
  161. package/expansion-packs/bmad-creative-writing/tasks/build-world.md +17 -0
  162. package/expansion-packs/bmad-creative-writing/tasks/character-depth-pass.md +15 -0
  163. package/expansion-packs/bmad-creative-writing/tasks/create-doc.md +101 -0
  164. package/expansion-packs/bmad-creative-writing/tasks/create-draft-section.md +19 -0
  165. package/expansion-packs/bmad-creative-writing/tasks/critical-review.md +19 -0
  166. package/expansion-packs/bmad-creative-writing/tasks/develop-character.md +17 -0
  167. package/expansion-packs/bmad-creative-writing/tasks/execute-checklist.md +93 -0
  168. package/expansion-packs/bmad-creative-writing/tasks/expand-premise.md +16 -0
  169. package/expansion-packs/bmad-creative-writing/tasks/expand-synopsis.md +16 -0
  170. package/expansion-packs/bmad-creative-writing/tasks/final-polish.md +16 -0
  171. package/expansion-packs/bmad-creative-writing/tasks/generate-cover-brief.md +18 -0
  172. package/expansion-packs/bmad-creative-writing/tasks/generate-cover-prompts.md +19 -0
  173. package/expansion-packs/bmad-creative-writing/tasks/generate-scene-list.md +16 -0
  174. package/expansion-packs/bmad-creative-writing/tasks/incorporate-feedback.md +18 -0
  175. package/expansion-packs/bmad-creative-writing/tasks/outline-scenes.md +16 -0
  176. package/expansion-packs/bmad-creative-writing/tasks/provide-feedback.md +17 -0
  177. package/expansion-packs/bmad-creative-writing/tasks/publish-chapter.md +16 -0
  178. package/expansion-packs/bmad-creative-writing/tasks/quick-feedback.md +15 -0
  179. package/expansion-packs/bmad-creative-writing/tasks/select-next-arc.md +16 -0
  180. package/expansion-packs/bmad-creative-writing/tasks/workshop-dialog.md +51 -0
  181. package/expansion-packs/bmad-creative-writing/templates/beta-feedback-form.yaml +96 -0
  182. package/expansion-packs/bmad-creative-writing/templates/chapter-draft-tmpl.yaml +81 -0
  183. package/expansion-packs/bmad-creative-writing/templates/character-profile-tmpl.yaml +92 -0
  184. package/expansion-packs/bmad-creative-writing/templates/cover-design-brief-tmpl.yaml +97 -0
  185. package/expansion-packs/bmad-creative-writing/templates/premise-brief-tmpl.yaml +77 -0
  186. package/expansion-packs/bmad-creative-writing/templates/scene-list-tmpl.yaml +54 -0
  187. package/expansion-packs/bmad-creative-writing/templates/story-outline-tmpl.yaml +96 -0
  188. package/expansion-packs/bmad-creative-writing/templates/world-guide-tmpl.yaml +88 -0
  189. package/expansion-packs/bmad-creative-writing/workflows/book-cover-design-workflow.md +176 -0
  190. package/expansion-packs/bmad-creative-writing/workflows/novel-greenfield-workflow.yaml +58 -0
  191. package/expansion-packs/bmad-creative-writing/workflows/novel-serial-workflow.yaml +51 -0
  192. package/expansion-packs/bmad-creative-writing/workflows/novel-snowflake-workflow.yaml +69 -0
  193. package/expansion-packs/bmad-creative-writing/workflows/novel-writing.yaml +92 -0
  194. package/expansion-packs/bmad-creative-writing/workflows/screenplay-development.yaml +86 -0
  195. package/expansion-packs/bmad-creative-writing/workflows/series-planning.yaml +79 -0
  196. package/expansion-packs/bmad-creative-writing/workflows/short-story-creation.yaml +65 -0
  197. package/expansion-packs/bmad-infrastructure-devops/config.yaml +1 -1
  198. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +20 -20
  199. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +7 -7
  200. package/package.json +62 -39
  201. package/prettier.config.mjs +32 -0
  202. package/sync-version.sh +23 -0
  203. package/tools/bmad-npx-wrapper.js +10 -10
  204. package/tools/builders/web-builder.js +124 -130
  205. package/tools/bump-all-versions.js +42 -33
  206. package/tools/bump-expansion-version.js +23 -16
  207. package/tools/cli.js +10 -12
  208. package/tools/flattener/aggregate.js +10 -10
  209. package/tools/flattener/binary.js +44 -17
  210. package/tools/flattener/discovery.js +19 -18
  211. package/tools/flattener/files.js +6 -6
  212. package/tools/flattener/ignoreRules.js +125 -125
  213. package/tools/flattener/main.js +426 -70
  214. package/tools/flattener/projectRoot.js +186 -25
  215. package/tools/flattener/prompts.js +9 -9
  216. package/tools/flattener/stats.helpers.js +395 -0
  217. package/tools/flattener/stats.js +64 -14
  218. package/tools/flattener/test-matrix.js +413 -0
  219. package/tools/flattener/xml.js +33 -31
  220. package/tools/installer/bin/bmad.js +156 -113
  221. package/tools/installer/config/ide-agent-config.yaml +1 -1
  222. package/tools/installer/config/install.config.yaml +13 -3
  223. package/tools/installer/lib/config-loader.js +46 -42
  224. package/tools/installer/lib/file-manager.js +91 -113
  225. package/tools/installer/lib/ide-base-setup.js +57 -56
  226. package/tools/installer/lib/ide-setup.js +545 -399
  227. package/tools/installer/lib/installer.js +875 -714
  228. package/tools/installer/lib/memory-profiler.js +54 -53
  229. package/tools/installer/lib/module-manager.js +19 -15
  230. package/tools/installer/lib/resource-locator.js +26 -28
  231. package/tools/installer/package.json +19 -19
  232. package/tools/lib/dependency-resolver.js +26 -30
  233. package/tools/lib/yaml-utils.js +7 -7
  234. package/tools/preview-release-notes.js +66 -0
  235. package/tools/shared/bannerArt.js +3 -3
  236. package/tools/sync-installer-version.js +7 -9
  237. package/tools/update-expansion-version.js +14 -15
  238. package/tools/upgraders/v3-to-v4-upgrader.js +203 -294
  239. package/tools/version-bump.js +41 -26
  240. package/tools/yaml-format.js +56 -43
  241. package/.github/workflows/release.yaml +0 -60
  242. package/.releaserc.json +0 -21
  243. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/Complete AI Agent System - Flowchart.svg +0 -102
  244. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash copy.txt +0 -13
  245. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.1 Google Cloud Project Setup/1.1.1 - Initial Project Configuration - bash.txt +0 -13
  246. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.2 Agent Development Kit Installation/1.2.2 - Basic Project Structure - txt.txt +0 -25
  247. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.1 - settings.py +0 -34
  248. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.3 Core Configuration Files/1.3.2 - main.py - Base Application.py +0 -70
  249. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/PART 1 - Google Cloud Vertex AI Setup Documentation/1.4 Deployment Configuration/1.4.2 - cloudbuild.yaml +0 -26
  250. package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +0 -109
  251. package/tools/semantic-release-sync-installer.js +0 -30
@@ -1,15 +1,15 @@
1
- const fs = require("fs").promises;
2
- const path = require("path");
3
- const { glob } = require("glob");
1
+ const fs = require('node:fs').promises;
2
+ const path = require('node:path');
3
+ const { glob } = require('glob');
4
4
 
5
5
  // Dynamic imports for ES modules
6
6
  let chalk, ora, inquirer;
7
7
 
8
8
  // Initialize ES modules
9
9
  async function initializeModules() {
10
- chalk = (await import("chalk")).default;
11
- ora = (await import("ora")).default;
12
- inquirer = (await import("inquirer")).default;
10
+ chalk = (await import('chalk')).default;
11
+ ora = (await import('ora')).default;
12
+ inquirer = (await import('inquirer')).default;
13
13
  }
14
14
 
15
15
  class V3ToV4Upgrader {
@@ -25,23 +25,15 @@ class V3ToV4Upgrader {
25
25
  process.stdin.resume();
26
26
 
27
27
  // 1. Welcome message
28
- console.log(
29
- chalk.bold("\nWelcome to BMad-Method V3 to V4 Upgrade Tool\n")
30
- );
31
- console.log(
32
- "This tool will help you upgrade your BMad-Method V3 project to V4.\n"
33
- );
34
- console.log(chalk.cyan("What this tool does:"));
35
- console.log("- Creates a backup of your V3 files (.bmad-v3-backup/)");
36
- console.log("- Installs the new V4 .bmad-core structure");
37
- console.log(
38
- "- Preserves your PRD, Architecture, and Stories in the new format\n"
39
- );
40
- console.log(chalk.yellow("What this tool does NOT do:"));
41
- console.log(
42
- "- Modify your document content (use doc-migration-task after upgrade)"
43
- );
44
- console.log("- Touch any files outside bmad-agent/ and docs/\n");
28
+ console.log(chalk.bold('\nWelcome to BMad-Method V3 to V4 Upgrade Tool\n'));
29
+ console.log('This tool will help you upgrade your BMad-Method V3 project to V4.\n');
30
+ console.log(chalk.cyan('What this tool does:'));
31
+ console.log('- Creates a backup of your V3 files (.bmad-v3-backup/)');
32
+ console.log('- Installs the new V4 .bmad-core structure');
33
+ console.log('- Preserves your PRD, Architecture, and Stories in the new format\n');
34
+ console.log(chalk.yellow('What this tool does NOT do:'));
35
+ console.log('- Modify your document content (use doc-migration-task after upgrade)');
36
+ console.log('- Touch any files outside bmad-agent/ and docs/\n');
45
37
 
46
38
  // 2. Get project path
47
39
  const projectPath = await this.getProjectPath(options.projectPath);
@@ -49,15 +41,11 @@ class V3ToV4Upgrader {
49
41
  // 3. Validate V3 structure
50
42
  const validation = await this.validateV3Project(projectPath);
51
43
  if (!validation.isValid) {
52
- console.error(
53
- chalk.red("\nError: This doesn't appear to be a V3 project.")
54
- );
55
- console.error("Expected to find:");
56
- console.error("- bmad-agent/ directory");
57
- console.error("- docs/ directory\n");
58
- console.error(
59
- "Please check you're in the correct directory and try again."
60
- );
44
+ console.error(chalk.red("\nError: This doesn't appear to be a V3 project."));
45
+ console.error('Expected to find:');
46
+ console.error('- bmad-agent/ directory');
47
+ console.error('- docs/ directory\n');
48
+ console.error("Please check you're in the correct directory and try again.");
61
49
  return;
62
50
  }
63
51
 
@@ -68,15 +56,15 @@ class V3ToV4Upgrader {
68
56
  if (!options.dryRun) {
69
57
  const { confirm } = await inquirer.prompt([
70
58
  {
71
- type: "confirm",
72
- name: "confirm",
73
- message: "Continue with upgrade?",
59
+ type: 'confirm',
60
+ name: 'confirm',
61
+ message: 'Continue with upgrade?',
74
62
  default: true,
75
63
  },
76
64
  ]);
77
65
 
78
66
  if (!confirm) {
79
- console.log("Upgrade cancelled.");
67
+ console.log('Upgrade cancelled.');
80
68
  return;
81
69
  }
82
70
  }
@@ -106,7 +94,7 @@ class V3ToV4Upgrader {
106
94
 
107
95
  process.exit(0);
108
96
  } catch (error) {
109
- console.error(chalk.red("\nUpgrade error:"), error.message);
97
+ console.error(chalk.red('\nUpgrade error:'), error.message);
110
98
  process.exit(1);
111
99
  }
112
100
  }
@@ -118,9 +106,9 @@ class V3ToV4Upgrader {
118
106
 
119
107
  const { projectPath } = await inquirer.prompt([
120
108
  {
121
- type: "input",
122
- name: "projectPath",
123
- message: "Please enter the path to your V3 project:",
109
+ type: 'input',
110
+ name: 'projectPath',
111
+ message: 'Please enter the path to your V3 project:',
124
112
  default: process.cwd(),
125
113
  },
126
114
  ]);
@@ -129,45 +117,45 @@ class V3ToV4Upgrader {
129
117
  }
130
118
 
131
119
  async validateV3Project(projectPath) {
132
- const spinner = ora("Validating project structure...").start();
120
+ const spinner = ora('Validating project structure...').start();
133
121
 
134
122
  try {
135
- const bmadAgentPath = path.join(projectPath, "bmad-agent");
136
- const docsPath = path.join(projectPath, "docs");
123
+ const bmadAgentPath = path.join(projectPath, 'bmad-agent');
124
+ const docsPath = path.join(projectPath, 'docs');
137
125
 
138
126
  const hasBmadAgent = await this.pathExists(bmadAgentPath);
139
127
  const hasDocs = await this.pathExists(docsPath);
140
128
 
141
129
  if (hasBmadAgent) {
142
- spinner.text = "✓ Found bmad-agent/ directory";
143
- console.log(chalk.green("\n✓ Found bmad-agent/ directory"));
130
+ spinner.text = '✓ Found bmad-agent/ directory';
131
+ console.log(chalk.green('\n✓ Found bmad-agent/ directory'));
144
132
  }
145
133
 
146
134
  if (hasDocs) {
147
- console.log(chalk.green("✓ Found docs/ directory"));
135
+ console.log(chalk.green('✓ Found docs/ directory'));
148
136
  }
149
137
 
150
138
  const isValid = hasBmadAgent && hasDocs;
151
139
 
152
140
  if (isValid) {
153
- spinner.succeed("This appears to be a valid V3 project");
141
+ spinner.succeed('This appears to be a valid V3 project');
154
142
  } else {
155
- spinner.fail("Invalid V3 project structure");
143
+ spinner.fail('Invalid V3 project structure');
156
144
  }
157
145
 
158
146
  return { isValid, hasBmadAgent, hasDocs };
159
147
  } catch (error) {
160
- spinner.fail("Validation failed");
148
+ spinner.fail('Validation failed');
161
149
  throw error;
162
150
  }
163
151
  }
164
152
 
165
153
  async analyzeProject(projectPath) {
166
- const docsPath = path.join(projectPath, "docs");
167
- const bmadAgentPath = path.join(projectPath, "bmad-agent");
154
+ const docsPath = path.join(projectPath, 'docs');
155
+ const bmadAgentPath = path.join(projectPath, 'bmad-agent');
168
156
 
169
157
  // Find PRD
170
- const prdCandidates = ["prd.md", "PRD.md", "product-requirements.md"];
158
+ const prdCandidates = ['prd.md', 'PRD.md', 'product-requirements.md'];
171
159
  let prdFile = null;
172
160
  for (const candidate of prdCandidates) {
173
161
  const candidatePath = path.join(docsPath, candidate);
@@ -178,11 +166,7 @@ class V3ToV4Upgrader {
178
166
  }
179
167
 
180
168
  // Find Architecture
181
- const archCandidates = [
182
- "architecture.md",
183
- "Architecture.md",
184
- "technical-architecture.md",
185
- ];
169
+ const archCandidates = ['architecture.md', 'Architecture.md', 'technical-architecture.md'];
186
170
  let archFile = null;
187
171
  for (const candidate of archCandidates) {
188
172
  const candidatePath = path.join(docsPath, candidate);
@@ -194,9 +178,9 @@ class V3ToV4Upgrader {
194
178
 
195
179
  // Find Front-end Architecture (V3 specific)
196
180
  const frontEndCandidates = [
197
- "front-end-architecture.md",
198
- "frontend-architecture.md",
199
- "ui-architecture.md",
181
+ 'front-end-architecture.md',
182
+ 'frontend-architecture.md',
183
+ 'ui-architecture.md',
200
184
  ];
201
185
  let frontEndArchFile = null;
202
186
  for (const candidate of frontEndCandidates) {
@@ -209,10 +193,10 @@ class V3ToV4Upgrader {
209
193
 
210
194
  // Find UX/UI spec
211
195
  const uxSpecCandidates = [
212
- "ux-ui-spec.md",
213
- "ux-ui-specification.md",
214
- "ui-spec.md",
215
- "ux-spec.md",
196
+ 'ux-ui-spec.md',
197
+ 'ux-ui-specification.md',
198
+ 'ui-spec.md',
199
+ 'ux-spec.md',
216
200
  ];
217
201
  let uxSpecFile = null;
218
202
  for (const candidate of uxSpecCandidates) {
@@ -224,12 +208,7 @@ class V3ToV4Upgrader {
224
208
  }
225
209
 
226
210
  // Find v0 prompt or UX prompt
227
- const uxPromptCandidates = [
228
- "v0-prompt.md",
229
- "ux-prompt.md",
230
- "ui-prompt.md",
231
- "design-prompt.md",
232
- ];
211
+ const uxPromptCandidates = ['v0-prompt.md', 'ux-prompt.md', 'ui-prompt.md', 'design-prompt.md'];
233
212
  let uxPromptFile = null;
234
213
  for (const candidate of uxPromptCandidates) {
235
214
  const candidatePath = path.join(docsPath, candidate);
@@ -240,19 +219,19 @@ class V3ToV4Upgrader {
240
219
  }
241
220
 
242
221
  // Find epic files
243
- const epicFiles = await glob("epic*.md", { cwd: docsPath });
222
+ const epicFiles = await glob('epic*.md', { cwd: docsPath });
244
223
 
245
224
  // Find story files
246
- const storiesPath = path.join(docsPath, "stories");
225
+ const storiesPath = path.join(docsPath, 'stories');
247
226
  let storyFiles = [];
248
227
  if (await this.pathExists(storiesPath)) {
249
- storyFiles = await glob("*.md", { cwd: storiesPath });
228
+ storyFiles = await glob('*.md', { cwd: storiesPath });
250
229
  }
251
230
 
252
231
  // Count custom files in bmad-agent
253
- const bmadAgentFiles = await glob("**/*.md", {
232
+ const bmadAgentFiles = await glob('**/*.md', {
254
233
  cwd: bmadAgentPath,
255
- ignore: ["node_modules/**"],
234
+ ignore: ['node_modules/**'],
256
235
  });
257
236
 
258
237
  return {
@@ -268,279 +247,233 @@ class V3ToV4Upgrader {
268
247
  }
269
248
 
270
249
  async showPreflightCheck(analysis, options) {
271
- console.log(chalk.bold("\nProject Analysis:"));
250
+ console.log(chalk.bold('\nProject Analysis:'));
272
251
  console.log(
273
- `- PRD found: ${
274
- analysis.prdFile
275
- ? `docs/${analysis.prdFile}`
276
- : chalk.yellow("Not found")
277
- }`
252
+ `- PRD found: ${analysis.prdFile ? `docs/${analysis.prdFile}` : chalk.yellow('Not found')}`,
278
253
  );
279
254
  console.log(
280
255
  `- Architecture found: ${
281
- analysis.archFile
282
- ? `docs/${analysis.archFile}`
283
- : chalk.yellow("Not found")
284
- }`
256
+ analysis.archFile ? `docs/${analysis.archFile}` : chalk.yellow('Not found')
257
+ }`,
285
258
  );
286
259
  if (analysis.frontEndArchFile) {
287
- console.log(
288
- `- Front-end Architecture found: docs/${analysis.frontEndArchFile}`
289
- );
260
+ console.log(`- Front-end Architecture found: docs/${analysis.frontEndArchFile}`);
290
261
  }
291
262
  console.log(
292
263
  `- UX/UI Spec found: ${
293
- analysis.uxSpecFile
294
- ? `docs/${analysis.uxSpecFile}`
295
- : chalk.yellow("Not found")
296
- }`
264
+ analysis.uxSpecFile ? `docs/${analysis.uxSpecFile}` : chalk.yellow('Not found')
265
+ }`,
297
266
  );
298
267
  console.log(
299
268
  `- UX/Design Prompt found: ${
300
- analysis.uxPromptFile
301
- ? `docs/${analysis.uxPromptFile}`
302
- : chalk.yellow("Not found")
303
- }`
304
- );
305
- console.log(
306
- `- Epic files found: ${analysis.epicFiles.length} files (epic*.md)`
307
- );
308
- console.log(
309
- `- Stories found: ${analysis.storyFiles.length} files in docs/stories/`
269
+ analysis.uxPromptFile ? `docs/${analysis.uxPromptFile}` : chalk.yellow('Not found')
270
+ }`,
310
271
  );
272
+ console.log(`- Epic files found: ${analysis.epicFiles.length} files (epic*.md)`);
273
+ console.log(`- Stories found: ${analysis.storyFiles.length} files in docs/stories/`);
311
274
  console.log(`- Custom files in bmad-agent/: ${analysis.customFileCount}`);
312
275
 
313
276
  if (!options.dryRun) {
314
- console.log("\nThe following will be backed up to .bmad-v3-backup/:");
315
- console.log("- bmad-agent/ (entire directory)");
316
- console.log("- docs/ (entire directory)");
277
+ console.log('\nThe following will be backed up to .bmad-v3-backup/:');
278
+ console.log('- bmad-agent/ (entire directory)');
279
+ console.log('- docs/ (entire directory)');
317
280
 
318
281
  if (analysis.epicFiles.length > 0) {
319
282
  console.log(
320
283
  chalk.green(
321
- "\nNote: Epic files found! They will be placed in docs/prd/ with an index.md file."
322
- )
284
+ '\nNote: Epic files found! They will be placed in docs/prd/ with an index.md file.',
285
+ ),
323
286
  );
324
287
  console.log(
325
- chalk.green(
326
- "Since epic files exist, you won't need to shard the PRD after upgrade."
327
- )
288
+ chalk.green("Since epic files exist, you won't need to shard the PRD after upgrade."),
328
289
  );
329
290
  }
330
291
  }
331
292
  }
332
293
 
333
294
  async createBackup(projectPath) {
334
- const spinner = ora("Creating backup...").start();
295
+ const spinner = ora('Creating backup...').start();
335
296
 
336
297
  try {
337
- const backupPath = path.join(projectPath, ".bmad-v3-backup");
298
+ const backupPath = path.join(projectPath, '.bmad-v3-backup');
338
299
 
339
300
  // Check if backup already exists
340
301
  if (await this.pathExists(backupPath)) {
341
- spinner.fail("Backup directory already exists");
342
- console.error(
343
- chalk.red(
344
- "\nError: Backup directory .bmad-v3-backup/ already exists."
345
- )
346
- );
347
- console.error("\nThis might mean an upgrade was already attempted.");
348
- console.error(
349
- "Please remove or rename the existing backup and try again."
350
- );
351
- throw new Error("Backup already exists");
302
+ spinner.fail('Backup directory already exists');
303
+ console.error(chalk.red('\nError: Backup directory .bmad-v3-backup/ already exists.'));
304
+ console.error('\nThis might mean an upgrade was already attempted.');
305
+ console.error('Please remove or rename the existing backup and try again.');
306
+ throw new Error('Backup already exists');
352
307
  }
353
308
 
354
309
  // Create backup directory
355
310
  await fs.mkdir(backupPath, { recursive: true });
356
- spinner.text = "✓ Created .bmad-v3-backup/";
357
- console.log(chalk.green("\n✓ Created .bmad-v3-backup/"));
311
+ spinner.text = '✓ Created .bmad-v3-backup/';
312
+ console.log(chalk.green('\n✓ Created .bmad-v3-backup/'));
358
313
 
359
314
  // Move bmad-agent
360
- const bmadAgentSrc = path.join(projectPath, "bmad-agent");
361
- const bmadAgentDest = path.join(backupPath, "bmad-agent");
362
- await fs.rename(bmadAgentSrc, bmadAgentDest);
363
- console.log(chalk.green("✓ Moved bmad-agent/ to backup"));
315
+ const bmadAgentSource = path.join(projectPath, 'bmad-agent');
316
+ const bmadAgentDestination = path.join(backupPath, 'bmad-agent');
317
+ await fs.rename(bmadAgentSource, bmadAgentDestination);
318
+ console.log(chalk.green('✓ Moved bmad-agent/ to backup'));
364
319
 
365
320
  // Move docs
366
- const docsSrc = path.join(projectPath, "docs");
367
- const docsDest = path.join(backupPath, "docs");
321
+ const docsSrc = path.join(projectPath, 'docs');
322
+ const docsDest = path.join(backupPath, 'docs');
368
323
  await fs.rename(docsSrc, docsDest);
369
- console.log(chalk.green("✓ Moved docs/ to backup"));
324
+ console.log(chalk.green('✓ Moved docs/ to backup'));
370
325
 
371
- spinner.succeed("Backup created successfully");
326
+ spinner.succeed('Backup created successfully');
372
327
  } catch (error) {
373
- spinner.fail("Backup failed");
328
+ spinner.fail('Backup failed');
374
329
  throw error;
375
330
  }
376
331
  }
377
332
 
378
333
  async installV4Structure(projectPath) {
379
- const spinner = ora("Installing V4 structure...").start();
334
+ const spinner = ora('Installing V4 structure...').start();
380
335
 
381
336
  try {
382
337
  // Get the source bmad-core directory (without dot prefix)
383
- const sourcePath = path.join(__dirname, "..", "..", "bmad-core");
384
- const destPath = path.join(projectPath, ".bmad-core");
338
+ const sourcePath = path.join(__dirname, '..', '..', 'bmad-core');
339
+ const destinationPath = path.join(projectPath, '.bmad-core');
385
340
 
386
341
  // Copy .bmad-core
387
- await this.copyDirectory(sourcePath, destPath);
388
- spinner.text = "✓ Copied fresh .bmad-core/ directory from V4";
389
- console.log(
390
- chalk.green("\n✓ Copied fresh .bmad-core/ directory from V4")
391
- );
342
+ await this.copyDirectory(sourcePath, destinationPath);
343
+ spinner.text = '✓ Copied fresh .bmad-core/ directory from V4';
344
+ console.log(chalk.green('\n✓ Copied fresh .bmad-core/ directory from V4'));
392
345
 
393
346
  // Create docs directory
394
- const docsPath = path.join(projectPath, "docs");
347
+ const docsPath = path.join(projectPath, 'docs');
395
348
  await fs.mkdir(docsPath, { recursive: true });
396
- console.log(chalk.green("✓ Created new docs/ directory"));
349
+ console.log(chalk.green('✓ Created new docs/ directory'));
397
350
 
398
351
  // Create install manifest for future updates
399
352
  await this.createInstallManifest(projectPath);
400
- console.log(chalk.green("✓ Created install manifest"));
353
+ console.log(chalk.green('✓ Created install manifest'));
401
354
 
402
355
  console.log(
403
- chalk.yellow(
404
- "\nNote: Your V3 bmad-agent content has been backed up and NOT migrated."
405
- )
356
+ chalk.yellow('\nNote: Your V3 bmad-agent content has been backed up and NOT migrated.'),
406
357
  );
407
358
  console.log(
408
359
  chalk.yellow(
409
- "The new V4 agents are completely different and look for different file structures."
410
- )
360
+ 'The new V4 agents are completely different and look for different file structures.',
361
+ ),
411
362
  );
412
363
 
413
- spinner.succeed("V4 structure installed successfully");
364
+ spinner.succeed('V4 structure installed successfully');
414
365
  } catch (error) {
415
- spinner.fail("V4 installation failed");
366
+ spinner.fail('V4 installation failed');
416
367
  throw error;
417
368
  }
418
369
  }
419
370
 
420
371
  async migrateDocuments(projectPath, analysis) {
421
- const spinner = ora("Migrating your project documents...").start();
372
+ const spinner = ora('Migrating your project documents...').start();
422
373
 
423
374
  try {
424
- const backupDocsPath = path.join(projectPath, ".bmad-v3-backup", "docs");
425
- const newDocsPath = path.join(projectPath, "docs");
375
+ const backupDocsPath = path.join(projectPath, '.bmad-v3-backup', 'docs');
376
+ const newDocsPath = path.join(projectPath, 'docs');
426
377
  let copiedCount = 0;
427
378
 
428
379
  // Copy PRD
429
380
  if (analysis.prdFile) {
430
- const src = path.join(backupDocsPath, analysis.prdFile);
431
- const dest = path.join(newDocsPath, analysis.prdFile);
432
- await fs.copyFile(src, dest);
381
+ const source = path.join(backupDocsPath, analysis.prdFile);
382
+ const destination = path.join(newDocsPath, analysis.prdFile);
383
+ await fs.copyFile(source, destination);
433
384
  console.log(chalk.green(`\n✓ Copied PRD to docs/${analysis.prdFile}`));
434
385
  copiedCount++;
435
386
  }
436
387
 
437
388
  // Copy Architecture
438
389
  if (analysis.archFile) {
439
- const src = path.join(backupDocsPath, analysis.archFile);
440
- const dest = path.join(newDocsPath, analysis.archFile);
441
- await fs.copyFile(src, dest);
442
- console.log(
443
- chalk.green(`✓ Copied Architecture to docs/${analysis.archFile}`)
444
- );
390
+ const source = path.join(backupDocsPath, analysis.archFile);
391
+ const destination = path.join(newDocsPath, analysis.archFile);
392
+ await fs.copyFile(source, destination);
393
+ console.log(chalk.green(`✓ Copied Architecture to docs/${analysis.archFile}`));
445
394
  copiedCount++;
446
395
  }
447
396
 
448
397
  // Copy Front-end Architecture if exists
449
398
  if (analysis.frontEndArchFile) {
450
- const src = path.join(backupDocsPath, analysis.frontEndArchFile);
451
- const dest = path.join(newDocsPath, analysis.frontEndArchFile);
452
- await fs.copyFile(src, dest);
399
+ const source = path.join(backupDocsPath, analysis.frontEndArchFile);
400
+ const destination = path.join(newDocsPath, analysis.frontEndArchFile);
401
+ await fs.copyFile(source, destination);
453
402
  console.log(
454
- chalk.green(
455
- `✓ Copied Front-end Architecture to docs/${analysis.frontEndArchFile}`
456
- )
403
+ chalk.green(`✓ Copied Front-end Architecture to docs/${analysis.frontEndArchFile}`),
457
404
  );
458
405
  console.log(
459
406
  chalk.yellow(
460
- "Note: V4 uses a single full-stack-architecture.md - use doc-migration-task to merge"
461
- )
407
+ 'Note: V4 uses a single full-stack-architecture.md - use doc-migration-task to merge',
408
+ ),
462
409
  );
463
410
  copiedCount++;
464
411
  }
465
412
 
466
413
  // Copy UX/UI Spec if exists
467
414
  if (analysis.uxSpecFile) {
468
- const src = path.join(backupDocsPath, analysis.uxSpecFile);
469
- const dest = path.join(newDocsPath, analysis.uxSpecFile);
470
- await fs.copyFile(src, dest);
471
- console.log(
472
- chalk.green(`✓ Copied UX/UI Spec to docs/${analysis.uxSpecFile}`)
473
- );
415
+ const source = path.join(backupDocsPath, analysis.uxSpecFile);
416
+ const destination = path.join(newDocsPath, analysis.uxSpecFile);
417
+ await fs.copyFile(source, destination);
418
+ console.log(chalk.green(`✓ Copied UX/UI Spec to docs/${analysis.uxSpecFile}`));
474
419
  copiedCount++;
475
420
  }
476
421
 
477
422
  // Copy UX/Design Prompt if exists
478
423
  if (analysis.uxPromptFile) {
479
- const src = path.join(backupDocsPath, analysis.uxPromptFile);
480
- const dest = path.join(newDocsPath, analysis.uxPromptFile);
481
- await fs.copyFile(src, dest);
482
- console.log(
483
- chalk.green(
484
- `✓ Copied UX/Design Prompt to docs/${analysis.uxPromptFile}`
485
- )
486
- );
424
+ const source = path.join(backupDocsPath, analysis.uxPromptFile);
425
+ const destination = path.join(newDocsPath, analysis.uxPromptFile);
426
+ await fs.copyFile(source, destination);
427
+ console.log(chalk.green(`✓ Copied UX/Design Prompt to docs/${analysis.uxPromptFile}`));
487
428
  copiedCount++;
488
429
  }
489
430
 
490
431
  // Copy stories
491
432
  if (analysis.storyFiles.length > 0) {
492
- const storiesDir = path.join(newDocsPath, "stories");
433
+ const storiesDir = path.join(newDocsPath, 'stories');
493
434
  await fs.mkdir(storiesDir, { recursive: true });
494
435
 
495
436
  for (const storyFile of analysis.storyFiles) {
496
- const src = path.join(backupDocsPath, "stories", storyFile);
497
- const dest = path.join(storiesDir, storyFile);
498
- await fs.copyFile(src, dest);
437
+ const source = path.join(backupDocsPath, 'stories', storyFile);
438
+ const destination = path.join(storiesDir, storyFile);
439
+ await fs.copyFile(source, destination);
499
440
  }
500
441
  console.log(
501
- chalk.green(
502
- `✓ Copied ${analysis.storyFiles.length} story files to docs/stories/`
503
- )
442
+ chalk.green(`✓ Copied ${analysis.storyFiles.length} story files to docs/stories/`),
504
443
  );
505
444
  copiedCount += analysis.storyFiles.length;
506
445
  }
507
446
 
508
447
  // Copy epic files to prd subfolder
509
448
  if (analysis.epicFiles.length > 0) {
510
- const prdDir = path.join(newDocsPath, "prd");
449
+ const prdDir = path.join(newDocsPath, 'prd');
511
450
  await fs.mkdir(prdDir, { recursive: true });
512
451
 
513
452
  for (const epicFile of analysis.epicFiles) {
514
- const src = path.join(backupDocsPath, epicFile);
515
- const dest = path.join(prdDir, epicFile);
516
- await fs.copyFile(src, dest);
453
+ const source = path.join(backupDocsPath, epicFile);
454
+ const destination = path.join(prdDir, epicFile);
455
+ await fs.copyFile(source, destination);
517
456
  }
518
457
  console.log(
519
- chalk.green(
520
- `✓ Found and copied ${analysis.epicFiles.length} epic files to docs/prd/`
521
- )
458
+ chalk.green(`✓ Found and copied ${analysis.epicFiles.length} epic files to docs/prd/`),
522
459
  );
523
460
 
524
461
  // Create index.md for the prd folder
525
462
  await this.createPrdIndex(projectPath, analysis);
526
- console.log(chalk.green("✓ Created index.md in docs/prd/"));
463
+ console.log(chalk.green('✓ Created index.md in docs/prd/'));
527
464
 
528
465
  console.log(
529
466
  chalk.green(
530
- "\nNote: Epic files detected! These are compatible with V4 and have been copied."
531
- )
532
- );
533
- console.log(
534
- chalk.green(
535
- "You won't need to shard the PRD since epics already exist."
536
- )
467
+ '\nNote: Epic files detected! These are compatible with V4 and have been copied.',
468
+ ),
537
469
  );
470
+ console.log(chalk.green("You won't need to shard the PRD since epics already exist."));
538
471
  copiedCount += analysis.epicFiles.length;
539
472
  }
540
473
 
541
474
  spinner.succeed(`Migrated ${copiedCount} documents successfully`);
542
475
  } catch (error) {
543
- spinner.fail("Document migration failed");
476
+ spinner.fail('Document migration failed');
544
477
  throw error;
545
478
  }
546
479
  }
@@ -548,21 +481,21 @@ class V3ToV4Upgrader {
548
481
  async setupIDE(projectPath, selectedIdes) {
549
482
  // Use the IDE selections passed from the installer
550
483
  if (!selectedIdes || selectedIdes.length === 0) {
551
- console.log(chalk.dim("No IDE setup requested - skipping"));
484
+ console.log(chalk.dim('No IDE setup requested - skipping'));
552
485
  return;
553
486
  }
554
487
 
555
- const ideSetup = require("../installer/lib/ide-setup");
556
- const spinner = ora("Setting up IDE rules for all agents...").start();
488
+ const ideSetup = require('../installer/lib/ide-setup');
489
+ const spinner = ora('Setting up IDE rules for all agents...').start();
557
490
 
558
491
  try {
559
492
  const ideMessages = {
560
- cursor: "Rules created in .cursor/rules/bmad/",
561
- "claude-code": "Commands created in .claude/commands/BMad/",
562
- windsurf: "Rules created in .windsurf/rules/",
563
- trae: "Rules created in.trae/rules/",
564
- roo: "Custom modes created in .roomodes",
565
- cline: "Rules created in .clinerules/",
493
+ cursor: 'Rules created in .cursor/rules/bmad/',
494
+ 'claude-code': 'Commands created in .claude/commands/BMad/',
495
+ windsurf: 'Rules created in .windsurf/workflows/',
496
+ trae: 'Rules created in.trae/rules/',
497
+ roo: 'Custom modes created in .roomodes',
498
+ cline: 'Rules created in .clinerules/',
566
499
  };
567
500
 
568
501
  // Setup each selected IDE
@@ -573,17 +506,15 @@ class V3ToV4Upgrader {
573
506
  }
574
507
 
575
508
  spinner.succeed(`IDE setup complete for ${selectedIdes.length} IDE(s)!`);
576
- } catch (error) {
577
- spinner.fail("IDE setup failed");
578
- console.error(
579
- chalk.yellow("IDE setup failed, but upgrade is complete.")
580
- );
509
+ } catch {
510
+ spinner.fail('IDE setup failed');
511
+ console.error(chalk.yellow('IDE setup failed, but upgrade is complete.'));
581
512
  }
582
513
  }
583
514
 
584
515
  showCompletionReport(projectPath, analysis) {
585
- console.log(chalk.bold.green("\n✓ Upgrade Complete!\n"));
586
- console.log(chalk.bold("Summary:"));
516
+ console.log(chalk.bold.green('\n✓ Upgrade Complete!\n'));
517
+ console.log(chalk.bold('Summary:'));
587
518
  console.log(`- V3 files backed up to: .bmad-v3-backup/`);
588
519
  console.log(`- V4 structure installed: .bmad-core/ (fresh from V4)`);
589
520
 
@@ -596,50 +527,36 @@ class V3ToV4Upgrader {
596
527
  analysis.storyFiles.length;
597
528
  console.log(
598
529
  `- Documents migrated: ${totalDocs} files${
599
- analysis.epicFiles.length > 0
600
- ? ` + ${analysis.epicFiles.length} epics`
601
- : ""
602
- }`
530
+ analysis.epicFiles.length > 0 ? ` + ${analysis.epicFiles.length} epics` : ''
531
+ }`,
603
532
  );
604
533
 
605
- console.log(chalk.bold("\nImportant Changes:"));
606
- console.log(
607
- "- The V4 agents (sm, dev, etc.) expect different file structures than V3"
608
- );
609
- console.log(
610
- "- Your V3 bmad-agent content was NOT migrated (it's incompatible)"
611
- );
534
+ console.log(chalk.bold('\nImportant Changes:'));
535
+ console.log('- The V4 agents (sm, dev, etc.) expect different file structures than V3');
536
+ console.log("- Your V3 bmad-agent content was NOT migrated (it's incompatible)");
612
537
  if (analysis.epicFiles.length > 0) {
613
- console.log(
614
- "- Epic files were found and copied - no PRD sharding needed!"
615
- );
538
+ console.log('- Epic files were found and copied - no PRD sharding needed!');
616
539
  }
617
540
  if (analysis.frontEndArchFile) {
618
541
  console.log(
619
- "- Front-end architecture found - V4 uses full-stack-architecture.md, migration needed"
542
+ '- Front-end architecture found - V4 uses full-stack-architecture.md, migration needed',
620
543
  );
621
544
  }
622
545
  if (analysis.uxSpecFile || analysis.uxPromptFile) {
623
- console.log(
624
- "- UX/UI design files found and copied - ready for use with V4"
625
- );
546
+ console.log('- UX/UI design files found and copied - ready for use with V4');
626
547
  }
627
548
 
628
- console.log(chalk.bold("\nNext Steps:"));
629
- console.log("1. Review your documents in the new docs/ folder");
549
+ console.log(chalk.bold('\nNext Steps:'));
550
+ console.log('1. Review your documents in the new docs/ folder');
630
551
  console.log(
631
- "2. Use @bmad-master agent to run the doc-migration-task to align your documents with V4 templates"
552
+ '2. Use @bmad-master agent to run the doc-migration-task to align your documents with V4 templates',
632
553
  );
633
554
  if (analysis.epicFiles.length === 0) {
634
- console.log(
635
- "3. Use @bmad-master agent to shard the PRD to create epic files"
636
- );
555
+ console.log('3. Use @bmad-master agent to shard the PRD to create epic files');
637
556
  }
638
557
 
639
558
  console.log(
640
- chalk.dim(
641
- "\nYour V3 backup is preserved in .bmad-v3-backup/ and can be restored if needed."
642
- )
559
+ chalk.dim('\nYour V3 backup is preserved in .bmad-v3-backup/ and can be restored if needed.'),
643
560
  );
644
561
  }
645
562
 
@@ -652,67 +569,61 @@ class V3ToV4Upgrader {
652
569
  }
653
570
  }
654
571
 
655
- async copyDirectory(src, dest) {
656
- await fs.mkdir(dest, { recursive: true });
657
- const entries = await fs.readdir(src, { withFileTypes: true });
572
+ async copyDirectory(source, destination) {
573
+ await fs.mkdir(destination, { recursive: true });
574
+ const entries = await fs.readdir(source, { withFileTypes: true });
658
575
 
659
576
  for (const entry of entries) {
660
- const srcPath = path.join(src, entry.name);
661
- const destPath = path.join(dest, entry.name);
577
+ const sourcePath = path.join(source, entry.name);
578
+ const destinationPath = path.join(destination, entry.name);
662
579
 
663
- if (entry.isDirectory()) {
664
- await this.copyDirectory(srcPath, destPath);
665
- } else {
666
- await fs.copyFile(srcPath, destPath);
667
- }
580
+ await (entry.isDirectory()
581
+ ? this.copyDirectory(sourcePath, destinationPath)
582
+ : fs.copyFile(sourcePath, destinationPath));
668
583
  }
669
584
  }
670
585
 
671
586
  async createPrdIndex(projectPath, analysis) {
672
- const prdIndexPath = path.join(projectPath, "docs", "prd", "index.md");
673
- const prdPath = path.join(
674
- projectPath,
675
- "docs",
676
- analysis.prdFile || "prd.md"
677
- );
587
+ const prdIndexPath = path.join(projectPath, 'docs', 'prd', 'index.md');
588
+ const prdPath = path.join(projectPath, 'docs', analysis.prdFile || 'prd.md');
678
589
 
679
- let indexContent = "# Product Requirements Document\n\n";
590
+ let indexContent = '# Product Requirements Document\n\n';
680
591
 
681
592
  // Try to read the PRD to get the title and intro content
682
593
  if (analysis.prdFile && (await this.pathExists(prdPath))) {
683
594
  try {
684
- const prdContent = await fs.readFile(prdPath, "utf8");
685
- const lines = prdContent.split("\n");
595
+ const prdContent = await fs.readFile(prdPath, 'utf8');
596
+ const lines = prdContent.split('\n');
686
597
 
687
598
  // Find the first heading
688
- const titleMatch = lines.find((line) => line.startsWith("# "));
599
+ const titleMatch = lines.find((line) => line.startsWith('# '));
689
600
  if (titleMatch) {
690
- indexContent = titleMatch + "\n\n";
601
+ indexContent = titleMatch + '\n\n';
691
602
  }
692
603
 
693
604
  // Get any content before the first ## section
694
- let introContent = "";
605
+ let introContent = '';
695
606
  let foundFirstSection = false;
696
607
  for (const line of lines) {
697
- if (line.startsWith("## ")) {
608
+ if (line.startsWith('## ')) {
698
609
  foundFirstSection = true;
699
610
  break;
700
611
  }
701
- if (!line.startsWith("# ")) {
702
- introContent += line + "\n";
612
+ if (!line.startsWith('# ')) {
613
+ introContent += line + '\n';
703
614
  }
704
615
  }
705
616
 
706
617
  if (introContent.trim()) {
707
- indexContent += introContent.trim() + "\n\n";
618
+ indexContent += introContent.trim() + '\n\n';
708
619
  }
709
- } catch (error) {
620
+ } catch {
710
621
  // If we can't read the PRD, just use default content
711
622
  }
712
623
  }
713
624
 
714
625
  // Add sections list
715
- indexContent += "## Sections\n\n";
626
+ indexContent += '## Sections\n\n';
716
627
 
717
628
  // Sort epic files for consistent ordering
718
629
  const sortedEpics = [...analysis.epicFiles].sort();
@@ -720,38 +631,36 @@ class V3ToV4Upgrader {
720
631
  for (const epicFile of sortedEpics) {
721
632
  // Extract epic name from filename
722
633
  const epicName = epicFile
723
- .replace(/\.md$/, "")
724
- .replace(/^epic-?/i, "")
725
- .replace(/-/g, " ")
726
- .replace(/^\d+\s*/, "") // Remove leading numbers
634
+ .replace(/\.md$/, '')
635
+ .replace(/^epic-?/i, '')
636
+ .replaceAll('-', ' ')
637
+ .replace(/^\d+\s*/, '') // Remove leading numbers
727
638
  .trim();
728
639
 
729
640
  const displayName = epicName.charAt(0).toUpperCase() + epicName.slice(1);
730
- indexContent += `- [${
731
- displayName || epicFile.replace(".md", "")
732
- }](./${epicFile})\n`;
641
+ indexContent += `- [${displayName || epicFile.replace('.md', '')}](./${epicFile})\n`;
733
642
  }
734
643
 
735
644
  await fs.writeFile(prdIndexPath, indexContent);
736
645
  }
737
646
 
738
647
  async createInstallManifest(projectPath) {
739
- const fileManager = require("../installer/lib/file-manager");
740
- const { glob } = require("glob");
648
+ const fileManager = require('../installer/lib/file-manager');
649
+ const { glob } = require('glob');
741
650
 
742
651
  // Get all files in .bmad-core for the manifest
743
- const bmadCorePath = path.join(projectPath, ".bmad-core");
744
- const files = await glob("**/*", {
652
+ const bmadCorePath = path.join(projectPath, '.bmad-core');
653
+ const files = await glob('**/*', {
745
654
  cwd: bmadCorePath,
746
655
  nodir: true,
747
- ignore: ["**/.git/**", "**/node_modules/**"],
656
+ ignore: ['**/.git/**', '**/node_modules/**'],
748
657
  });
749
658
 
750
659
  // Prepend .bmad-core/ to file paths for manifest
751
- const manifestFiles = files.map((file) => path.join(".bmad-core", file));
660
+ const manifestFiles = files.map((file) => path.join('.bmad-core', file));
752
661
 
753
662
  const config = {
754
- installType: "full",
663
+ installType: 'full',
755
664
  agent: null,
756
665
  ide: null, // Will be set if IDE setup is done later
757
666
  };