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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +3 -3
- package/.github/ISSUE_TEMPLATE/feature_request.md +3 -3
- package/.github/workflows/discord.yaml +11 -2
- package/.github/workflows/format-check.yaml +42 -0
- package/.github/workflows/manual-release.yaml +173 -0
- package/.husky/pre-commit +3 -0
- package/.vscode/settings.json +26 -1
- package/CHANGELOG.md +2 -23
- package/README.md +2 -0
- package/bmad-core/agent-teams/team-all.yaml +1 -1
- package/bmad-core/agents/analyst.md +16 -15
- package/bmad-core/agents/architect.md +11 -11
- package/bmad-core/agents/bmad-master.md +23 -22
- package/bmad-core/agents/bmad-orchestrator.md +13 -17
- package/bmad-core/agents/dev.md +14 -11
- package/bmad-core/agents/pm.md +15 -14
- package/bmad-core/agents/po.md +9 -8
- package/bmad-core/agents/qa.md +42 -22
- package/bmad-core/agents/sm.md +7 -6
- package/bmad-core/agents/ux-expert.md +6 -5
- package/bmad-core/core-config.yaml +2 -0
- package/bmad-core/data/bmad-kb.md +1 -1
- package/bmad-core/data/test-levels-framework.md +146 -0
- package/bmad-core/data/test-priorities-matrix.md +172 -0
- package/bmad-core/tasks/apply-qa-fixes.md +148 -0
- package/bmad-core/tasks/facilitate-brainstorming-session.md +1 -1
- package/bmad-core/tasks/nfr-assess.md +343 -0
- package/bmad-core/tasks/qa-gate.md +161 -0
- package/bmad-core/tasks/review-story.md +234 -74
- package/bmad-core/tasks/risk-profile.md +353 -0
- package/bmad-core/tasks/test-design.md +174 -0
- package/bmad-core/tasks/trace-requirements.md +264 -0
- package/bmad-core/templates/architecture-tmpl.yaml +49 -49
- package/bmad-core/templates/brainstorming-output-tmpl.yaml +5 -5
- package/bmad-core/templates/brownfield-architecture-tmpl.yaml +31 -31
- package/bmad-core/templates/brownfield-prd-tmpl.yaml +13 -13
- package/bmad-core/templates/competitor-analysis-tmpl.yaml +19 -6
- package/bmad-core/templates/front-end-architecture-tmpl.yaml +21 -9
- package/bmad-core/templates/front-end-spec-tmpl.yaml +24 -24
- package/bmad-core/templates/fullstack-architecture-tmpl.yaml +122 -104
- package/bmad-core/templates/market-research-tmpl.yaml +2 -2
- package/bmad-core/templates/prd-tmpl.yaml +9 -9
- package/bmad-core/templates/project-brief-tmpl.yaml +4 -4
- package/bmad-core/templates/qa-gate-tmpl.yaml +102 -0
- package/bmad-core/templates/story-tmpl.yaml +12 -12
- package/bmad-core/workflows/brownfield-fullstack.yaml +9 -9
- package/bmad-core/workflows/brownfield-service.yaml +1 -1
- package/bmad-core/workflows/brownfield-ui.yaml +1 -1
- package/bmad-core/workflows/greenfield-fullstack.yaml +1 -1
- package/bmad-core/workflows/greenfield-service.yaml +1 -1
- package/bmad-core/workflows/greenfield-ui.yaml +1 -1
- package/common/utils/bmad-doc-template.md +5 -5
- package/dist/agents/analyst.txt +1086 -1079
- package/dist/agents/architect.txt +1534 -1526
- package/dist/agents/bmad-master.txt +646 -632
- package/dist/agents/bmad-orchestrator.txt +40 -18
- package/dist/agents/dev.txt +158 -19
- package/dist/agents/pm.txt +1082 -1107
- package/dist/agents/po.txt +314 -332
- package/dist/agents/qa.txt +1754 -151
- package/dist/agents/sm.txt +88 -98
- package/dist/agents/ux-expert.txt +80 -87
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +109 -146
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +75 -86
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +41 -48
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +1903 -1941
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-architect.txt +15 -50
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-designer.txt +149 -195
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.txt +0 -15
- package/dist/expansion-packs/bmad-2d-unity-game-dev/agents/game-sm.txt +20 -37
- package/dist/expansion-packs/bmad-2d-unity-game-dev/teams/unity-2d-game-team.txt +2660 -2752
- package/dist/expansion-packs/bmad-creative-writing/agents/beta-reader.txt +871 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/book-critic.txt +78 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/character-psychologist.txt +839 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/cover-designer.txt +85 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/dialog-specialist.txt +861 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/editor.txt +796 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/genre-specialist.txt +927 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/narrative-designer.txt +842 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/plot-architect.txt +1126 -0
- package/dist/expansion-packs/bmad-creative-writing/agents/world-builder.txt +864 -0
- package/dist/expansion-packs/bmad-creative-writing/teams/agent-team.txt +5917 -0
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +25 -27
- package/dist/teams/team-all.txt +5541 -3768
- package/dist/teams/team-fullstack.txt +3014 -2987
- package/dist/teams/team-ide-minimal.txt +2219 -469
- package/dist/teams/team-no-ui.txt +2993 -2966
- package/docs/enhanced-ide-development-workflow.md +220 -15
- package/docs/user-guide.md +271 -18
- package/docs/versioning-and-releases.md +122 -44
- package/docs/working-in-the-brownfield.md +264 -31
- package/eslint.config.mjs +119 -0
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.md +4 -4
- package/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.md +1 -1
- package/expansion-packs/bmad-2d-phaser-game-dev/config.yaml +1 -1
- package/expansion-packs/bmad-2d-phaser-game-dev/data/development-guidelines.md +26 -28
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-architecture-tmpl.yaml +50 -50
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-brief-tmpl.yaml +23 -23
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-design-doc-tmpl.yaml +24 -24
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/game-story-tmpl.yaml +42 -42
- package/expansion-packs/bmad-2d-phaser-game-dev/templates/level-design-doc-tmpl.yaml +65 -65
- package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-dev-greenfield.yaml +5 -5
- package/expansion-packs/bmad-2d-phaser-game-dev/workflows/game-prototype.yaml +1 -1
- package/expansion-packs/bmad-2d-unity-game-dev/agents/game-developer.md +3 -3
- package/expansion-packs/bmad-2d-unity-game-dev/config.yaml +1 -1
- package/expansion-packs/bmad-2d-unity-game-dev/data/bmad-kb.md +1 -1
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-brief-tmpl.yaml +23 -23
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-design-doc-tmpl.yaml +63 -63
- package/expansion-packs/bmad-2d-unity-game-dev/templates/game-story-tmpl.yaml +20 -20
- package/expansion-packs/bmad-2d-unity-game-dev/templates/level-design-doc-tmpl.yaml +65 -65
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-dev-greenfield.yaml +5 -5
- package/expansion-packs/bmad-2d-unity-game-dev/workflows/game-prototype.yaml +1 -1
- package/expansion-packs/bmad-creative-writing/README.md +132 -0
- package/expansion-packs/bmad-creative-writing/agent-teams/agent-team.yaml +19 -0
- package/expansion-packs/bmad-creative-writing/agents/beta-reader.md +91 -0
- package/expansion-packs/bmad-creative-writing/agents/book-critic.md +35 -0
- package/expansion-packs/bmad-creative-writing/agents/character-psychologist.md +90 -0
- package/expansion-packs/bmad-creative-writing/agents/cover-designer.md +41 -0
- package/expansion-packs/bmad-creative-writing/agents/dialog-specialist.md +89 -0
- package/expansion-packs/bmad-creative-writing/agents/editor.md +90 -0
- package/expansion-packs/bmad-creative-writing/agents/genre-specialist.md +92 -0
- package/expansion-packs/bmad-creative-writing/agents/narrative-designer.md +90 -0
- package/expansion-packs/bmad-creative-writing/agents/plot-architect.md +92 -0
- package/expansion-packs/bmad-creative-writing/agents/world-builder.md +91 -0
- package/expansion-packs/bmad-creative-writing/checklists/beta-feedback-closure-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/character-consistency-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/comedic-timing-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/cyberpunk-aesthetic-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/ebook-formatting-checklist.md +15 -0
- package/expansion-packs/bmad-creative-writing/checklists/epic-poetry-meter-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/fantasy-magic-system-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/foreshadowing-payoff-checklist.md +15 -0
- package/expansion-packs/bmad-creative-writing/checklists/genre-tropes-checklist.md +15 -0
- package/expansion-packs/bmad-creative-writing/checklists/historical-accuracy-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/horror-suspense-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/kdp-cover-ready-checklist.md +18 -0
- package/expansion-packs/bmad-creative-writing/checklists/line-edit-quality-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/marketing-copy-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/mystery-clue-trail-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/orbital-mechanics-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/plot-structure-checklist.md +49 -0
- package/expansion-packs/bmad-creative-writing/checklists/publication-readiness-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/romance-emotional-beats-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/scene-quality-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/scifi-technology-plausibility-checklist.md +15 -0
- package/expansion-packs/bmad-creative-writing/checklists/sensitivity-representation-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/steampunk-gadget-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/thriller-pacing-stakes-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/timeline-continuity-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/world-building-continuity-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/checklists/ya-appropriateness-checklist.md +16 -0
- package/expansion-packs/bmad-creative-writing/config.yaml +11 -0
- package/expansion-packs/bmad-creative-writing/data/bmad-kb.md +197 -0
- package/expansion-packs/bmad-creative-writing/data/story-structures.md +58 -0
- package/expansion-packs/bmad-creative-writing/docs/brief.md +183 -0
- package/expansion-packs/bmad-creative-writing/tasks/advanced-elicitation.md +117 -0
- package/expansion-packs/bmad-creative-writing/tasks/analyze-reader-feedback.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/analyze-story-structure.md +55 -0
- package/expansion-packs/bmad-creative-writing/tasks/assemble-kdp-package.md +22 -0
- package/expansion-packs/bmad-creative-writing/tasks/brainstorm-premise.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/build-world.md +17 -0
- package/expansion-packs/bmad-creative-writing/tasks/character-depth-pass.md +15 -0
- package/expansion-packs/bmad-creative-writing/tasks/create-doc.md +101 -0
- package/expansion-packs/bmad-creative-writing/tasks/create-draft-section.md +19 -0
- package/expansion-packs/bmad-creative-writing/tasks/critical-review.md +19 -0
- package/expansion-packs/bmad-creative-writing/tasks/develop-character.md +17 -0
- package/expansion-packs/bmad-creative-writing/tasks/execute-checklist.md +93 -0
- package/expansion-packs/bmad-creative-writing/tasks/expand-premise.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/expand-synopsis.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/final-polish.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/generate-cover-brief.md +18 -0
- package/expansion-packs/bmad-creative-writing/tasks/generate-cover-prompts.md +19 -0
- package/expansion-packs/bmad-creative-writing/tasks/generate-scene-list.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/incorporate-feedback.md +18 -0
- package/expansion-packs/bmad-creative-writing/tasks/outline-scenes.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/provide-feedback.md +17 -0
- package/expansion-packs/bmad-creative-writing/tasks/publish-chapter.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/quick-feedback.md +15 -0
- package/expansion-packs/bmad-creative-writing/tasks/select-next-arc.md +16 -0
- package/expansion-packs/bmad-creative-writing/tasks/workshop-dialog.md +51 -0
- package/expansion-packs/bmad-creative-writing/templates/beta-feedback-form.yaml +96 -0
- package/expansion-packs/bmad-creative-writing/templates/chapter-draft-tmpl.yaml +81 -0
- package/expansion-packs/bmad-creative-writing/templates/character-profile-tmpl.yaml +92 -0
- package/expansion-packs/bmad-creative-writing/templates/cover-design-brief-tmpl.yaml +97 -0
- package/expansion-packs/bmad-creative-writing/templates/premise-brief-tmpl.yaml +77 -0
- package/expansion-packs/bmad-creative-writing/templates/scene-list-tmpl.yaml +54 -0
- package/expansion-packs/bmad-creative-writing/templates/story-outline-tmpl.yaml +96 -0
- package/expansion-packs/bmad-creative-writing/templates/world-guide-tmpl.yaml +88 -0
- package/expansion-packs/bmad-creative-writing/workflows/book-cover-design-workflow.md +176 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-greenfield-workflow.yaml +58 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-serial-workflow.yaml +51 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-snowflake-workflow.yaml +69 -0
- package/expansion-packs/bmad-creative-writing/workflows/novel-writing.yaml +92 -0
- package/expansion-packs/bmad-creative-writing/workflows/screenplay-development.yaml +86 -0
- package/expansion-packs/bmad-creative-writing/workflows/series-planning.yaml +79 -0
- package/expansion-packs/bmad-creative-writing/workflows/short-story-creation.yaml +65 -0
- package/expansion-packs/bmad-infrastructure-devops/config.yaml +1 -1
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-architecture-tmpl.yaml +20 -20
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.yaml +7 -7
- package/package.json +62 -39
- package/prettier.config.mjs +32 -0
- package/sync-version.sh +23 -0
- package/tools/bmad-npx-wrapper.js +10 -10
- package/tools/builders/web-builder.js +124 -130
- package/tools/bump-all-versions.js +42 -33
- package/tools/bump-expansion-version.js +23 -16
- package/tools/cli.js +10 -12
- package/tools/flattener/aggregate.js +10 -10
- package/tools/flattener/binary.js +44 -17
- package/tools/flattener/discovery.js +19 -18
- package/tools/flattener/files.js +6 -6
- package/tools/flattener/ignoreRules.js +125 -125
- package/tools/flattener/main.js +426 -70
- package/tools/flattener/projectRoot.js +186 -25
- package/tools/flattener/prompts.js +9 -9
- package/tools/flattener/stats.helpers.js +395 -0
- package/tools/flattener/stats.js +64 -14
- package/tools/flattener/test-matrix.js +413 -0
- package/tools/flattener/xml.js +33 -31
- package/tools/installer/bin/bmad.js +156 -113
- package/tools/installer/config/ide-agent-config.yaml +1 -1
- package/tools/installer/config/install.config.yaml +13 -3
- package/tools/installer/lib/config-loader.js +46 -42
- package/tools/installer/lib/file-manager.js +91 -113
- package/tools/installer/lib/ide-base-setup.js +57 -56
- package/tools/installer/lib/ide-setup.js +545 -399
- package/tools/installer/lib/installer.js +875 -714
- package/tools/installer/lib/memory-profiler.js +54 -53
- package/tools/installer/lib/module-manager.js +19 -15
- package/tools/installer/lib/resource-locator.js +26 -28
- package/tools/installer/package.json +19 -19
- package/tools/lib/dependency-resolver.js +26 -30
- package/tools/lib/yaml-utils.js +7 -7
- package/tools/preview-release-notes.js +66 -0
- package/tools/shared/bannerArt.js +3 -3
- package/tools/sync-installer-version.js +7 -9
- package/tools/update-expansion-version.js +14 -15
- package/tools/upgraders/v3-to-v4-upgrader.js +203 -294
- package/tools/version-bump.js +41 -26
- package/tools/yaml-format.js +56 -43
- package/.github/workflows/release.yaml +0 -60
- package/.releaserc.json +0 -21
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/Complete AI Agent System - Flowchart.svg +0 -102
- 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
- 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
- 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
- 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
- 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
- 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
- package/expansion-packs/Complete AI Agent System - Blank Templates & Google Cloud Setup/README.md +0 -109
- package/tools/semantic-release-sync-installer.js +0 -30
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const path = require(
|
|
3
|
-
const { glob } = require(
|
|
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(
|
|
11
|
-
ora = (await import(
|
|
12
|
-
inquirer = (await import(
|
|
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
|
-
|
|
30
|
-
);
|
|
31
|
-
console.log(
|
|
32
|
-
|
|
33
|
-
);
|
|
34
|
-
console.log(chalk.
|
|
35
|
-
console.log(
|
|
36
|
-
console.log(
|
|
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
|
-
|
|
54
|
-
);
|
|
55
|
-
console.error(
|
|
56
|
-
console.error("
|
|
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:
|
|
72
|
-
name:
|
|
73
|
-
message:
|
|
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(
|
|
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(
|
|
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:
|
|
122
|
-
name:
|
|
123
|
-
message:
|
|
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(
|
|
120
|
+
const spinner = ora('Validating project structure...').start();
|
|
133
121
|
|
|
134
122
|
try {
|
|
135
|
-
const bmadAgentPath = path.join(projectPath,
|
|
136
|
-
const docsPath = path.join(projectPath,
|
|
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 =
|
|
143
|
-
console.log(chalk.green(
|
|
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(
|
|
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(
|
|
141
|
+
spinner.succeed('This appears to be a valid V3 project');
|
|
154
142
|
} else {
|
|
155
|
-
spinner.fail(
|
|
143
|
+
spinner.fail('Invalid V3 project structure');
|
|
156
144
|
}
|
|
157
145
|
|
|
158
146
|
return { isValid, hasBmadAgent, hasDocs };
|
|
159
147
|
} catch (error) {
|
|
160
|
-
spinner.fail(
|
|
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,
|
|
167
|
-
const bmadAgentPath = path.join(projectPath,
|
|
154
|
+
const docsPath = path.join(projectPath, 'docs');
|
|
155
|
+
const bmadAgentPath = path.join(projectPath, 'bmad-agent');
|
|
168
156
|
|
|
169
157
|
// Find PRD
|
|
170
|
-
const prdCandidates = [
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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(
|
|
222
|
+
const epicFiles = await glob('epic*.md', { cwd: docsPath });
|
|
244
223
|
|
|
245
224
|
// Find story files
|
|
246
|
-
const storiesPath = path.join(docsPath,
|
|
225
|
+
const storiesPath = path.join(docsPath, 'stories');
|
|
247
226
|
let storyFiles = [];
|
|
248
227
|
if (await this.pathExists(storiesPath)) {
|
|
249
|
-
storyFiles = await glob(
|
|
228
|
+
storyFiles = await glob('*.md', { cwd: storiesPath });
|
|
250
229
|
}
|
|
251
230
|
|
|
252
231
|
// Count custom files in bmad-agent
|
|
253
|
-
const bmadAgentFiles = await glob(
|
|
232
|
+
const bmadAgentFiles = await glob('**/*.md', {
|
|
254
233
|
cwd: bmadAgentPath,
|
|
255
|
-
ignore: [
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
315
|
-
console.log(
|
|
316
|
-
console.log(
|
|
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
|
-
|
|
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(
|
|
295
|
+
const spinner = ora('Creating backup...').start();
|
|
335
296
|
|
|
336
297
|
try {
|
|
337
|
-
const backupPath = path.join(projectPath,
|
|
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(
|
|
342
|
-
console.error(
|
|
343
|
-
|
|
344
|
-
|
|
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 =
|
|
357
|
-
console.log(chalk.green(
|
|
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
|
|
361
|
-
const
|
|
362
|
-
await fs.rename(
|
|
363
|
-
console.log(chalk.green(
|
|
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,
|
|
367
|
-
const docsDest = path.join(backupPath,
|
|
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(
|
|
324
|
+
console.log(chalk.green('✓ Moved docs/ to backup'));
|
|
370
325
|
|
|
371
|
-
spinner.succeed(
|
|
326
|
+
spinner.succeed('Backup created successfully');
|
|
372
327
|
} catch (error) {
|
|
373
|
-
spinner.fail(
|
|
328
|
+
spinner.fail('Backup failed');
|
|
374
329
|
throw error;
|
|
375
330
|
}
|
|
376
331
|
}
|
|
377
332
|
|
|
378
333
|
async installV4Structure(projectPath) {
|
|
379
|
-
const spinner = ora(
|
|
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,
|
|
384
|
-
const
|
|
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,
|
|
388
|
-
spinner.text =
|
|
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,
|
|
347
|
+
const docsPath = path.join(projectPath, 'docs');
|
|
395
348
|
await fs.mkdir(docsPath, { recursive: true });
|
|
396
|
-
console.log(chalk.green(
|
|
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(
|
|
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
|
-
|
|
410
|
-
)
|
|
360
|
+
'The new V4 agents are completely different and look for different file structures.',
|
|
361
|
+
),
|
|
411
362
|
);
|
|
412
363
|
|
|
413
|
-
spinner.succeed(
|
|
364
|
+
spinner.succeed('V4 structure installed successfully');
|
|
414
365
|
} catch (error) {
|
|
415
|
-
spinner.fail(
|
|
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(
|
|
372
|
+
const spinner = ora('Migrating your project documents...').start();
|
|
422
373
|
|
|
423
374
|
try {
|
|
424
|
-
const backupDocsPath = path.join(projectPath,
|
|
425
|
-
const newDocsPath = path.join(projectPath,
|
|
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
|
|
431
|
-
const
|
|
432
|
-
await fs.copyFile(
|
|
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
|
|
440
|
-
const
|
|
441
|
-
await fs.copyFile(
|
|
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
|
|
451
|
-
const
|
|
452
|
-
await fs.copyFile(
|
|
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
|
-
|
|
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
|
|
469
|
-
const
|
|
470
|
-
await fs.copyFile(
|
|
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
|
|
480
|
-
const
|
|
481
|
-
await fs.copyFile(
|
|
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,
|
|
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
|
|
497
|
-
const
|
|
498
|
-
await fs.copyFile(
|
|
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,
|
|
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
|
|
515
|
-
const
|
|
516
|
-
await fs.copyFile(
|
|
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(
|
|
463
|
+
console.log(chalk.green('✓ Created index.md in docs/prd/'));
|
|
527
464
|
|
|
528
465
|
console.log(
|
|
529
466
|
chalk.green(
|
|
530
|
-
|
|
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(
|
|
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(
|
|
484
|
+
console.log(chalk.dim('No IDE setup requested - skipping'));
|
|
552
485
|
return;
|
|
553
486
|
}
|
|
554
487
|
|
|
555
|
-
const ideSetup = require(
|
|
556
|
-
const spinner = ora(
|
|
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:
|
|
561
|
-
|
|
562
|
-
windsurf:
|
|
563
|
-
trae:
|
|
564
|
-
roo:
|
|
565
|
-
cline:
|
|
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
|
|
577
|
-
spinner.fail(
|
|
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(
|
|
586
|
-
console.log(chalk.bold(
|
|
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
|
-
|
|
601
|
-
: ""
|
|
602
|
-
}`
|
|
530
|
+
analysis.epicFiles.length > 0 ? ` + ${analysis.epicFiles.length} epics` : ''
|
|
531
|
+
}`,
|
|
603
532
|
);
|
|
604
533
|
|
|
605
|
-
console.log(chalk.bold(
|
|
606
|
-
console.log(
|
|
607
|
-
|
|
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
|
-
|
|
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(
|
|
629
|
-
console.log(
|
|
549
|
+
console.log(chalk.bold('\nNext Steps:'));
|
|
550
|
+
console.log('1. Review your documents in the new docs/ folder');
|
|
630
551
|
console.log(
|
|
631
|
-
|
|
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(
|
|
656
|
-
await fs.mkdir(
|
|
657
|
-
const entries = await fs.readdir(
|
|
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
|
|
661
|
-
const
|
|
577
|
+
const sourcePath = path.join(source, entry.name);
|
|
578
|
+
const destinationPath = path.join(destination, entry.name);
|
|
662
579
|
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
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,
|
|
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 =
|
|
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,
|
|
685
|
-
const lines = prdContent.split(
|
|
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 +
|
|
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 +
|
|
612
|
+
if (!line.startsWith('# ')) {
|
|
613
|
+
introContent += line + '\n';
|
|
703
614
|
}
|
|
704
615
|
}
|
|
705
616
|
|
|
706
617
|
if (introContent.trim()) {
|
|
707
|
-
indexContent += introContent.trim() +
|
|
618
|
+
indexContent += introContent.trim() + '\n\n';
|
|
708
619
|
}
|
|
709
|
-
} catch
|
|
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 +=
|
|
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
|
-
.
|
|
726
|
-
.replace(/^\d+\s*/,
|
|
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(
|
|
740
|
-
const { glob } = require(
|
|
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,
|
|
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: [
|
|
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(
|
|
660
|
+
const manifestFiles = files.map((file) => path.join('.bmad-core', file));
|
|
752
661
|
|
|
753
662
|
const config = {
|
|
754
|
-
installType:
|
|
663
|
+
installType: 'full',
|
|
755
664
|
agent: null,
|
|
756
665
|
ide: null, // Will be set if IDE setup is done later
|
|
757
666
|
};
|