bmad-enhanced 1.3.8 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
 
3
3
  const fs = require('fs-extra');
4
4
  const path = require('path');
5
+ const { refreshInstallation } = require('./update/lib/refresh-installation');
5
6
 
6
7
  const BOLD = '\x1b[1m';
7
8
  const RESET = '\x1b[0m';
@@ -17,17 +18,16 @@ function printBanner() {
17
18
  console.log(`${MAGENTA}${BOLD}║ ║${RESET}`);
18
19
  console.log(`${MAGENTA}${BOLD}║ BMAD-Enhanced Complete Installer 🚀 ║${RESET}`);
19
20
  console.log(`${MAGENTA}${BOLD}║ ║${RESET}`);
20
- console.log(`${MAGENTA}${BOLD}║ Installing Emma + Wade Design Agents ║${RESET}`);
21
+ console.log(`${MAGENTA}${BOLD}║ Installing Emma + Wade Vortex Agents ║${RESET}`);
21
22
  console.log(`${MAGENTA}${BOLD}║ ║${RESET}`);
22
23
  console.log(`${MAGENTA}${BOLD}╚════════════════════════════════════════════════════╝${RESET}`);
23
24
  console.log('');
24
25
  }
25
26
 
26
- function checkPrerequisites() {
27
+ function checkPrerequisites(projectRoot) {
27
28
  console.log(`${CYAN}[1/6]${RESET} Checking prerequisites...`);
28
29
 
29
- const targetDir = process.cwd();
30
- const bmadDir = path.join(targetDir, '_bmad');
30
+ const bmadDir = path.join(projectRoot, '_bmad');
31
31
 
32
32
  // Create _bmad directory if it doesn't exist
33
33
  if (!fs.existsSync(bmadDir)) {
@@ -48,160 +48,54 @@ function checkPrerequisites() {
48
48
  console.log(`${GREEN} ✓${RESET} Prerequisites met`);
49
49
  }
50
50
 
51
- function copyAllAgentFiles() {
52
- console.log(`${CYAN}[2/6]${RESET} Installing Emma + Wade agent files...`);
51
+ function archiveDeprecatedWorkflows(projectRoot) {
52
+ console.log(`${CYAN}[2/6]${RESET} Archiving deprecated workflows...`);
53
53
 
54
54
  const sourceDir = path.join(__dirname, '..', '_bmad', 'bme', '_vortex');
55
- const targetDir = path.join(process.cwd(), '_bmad', 'bme', '_vortex');
56
-
57
- // Create target directory structure
58
- fs.mkdirSync(path.join(targetDir, 'agents'), { recursive: true });
59
- fs.mkdirSync(path.join(targetDir, 'workflows', '_deprecated', 'empathy-map', 'steps'), { recursive: true });
60
- fs.mkdirSync(path.join(targetDir, 'workflows', '_deprecated', 'wireframe', 'steps'), { recursive: true });
61
-
62
- // Copy Emma agent file
63
- console.log(`${CYAN} →${RESET} Installing Emma (contextualization-expert)...`);
64
- fs.copyFileSync(
65
- path.join(sourceDir, 'agents', 'contextualization-expert.md'),
66
- path.join(targetDir, 'agents', 'contextualization-expert.md')
67
- );
68
-
69
- // Copy Emma workflow files
70
- const emmaWorkflowFiles = [
71
- 'workflow.md',
72
- 'empathy-map.template.md',
73
- 'steps/step-01-define-user.md',
74
- 'steps/step-02-says-thinks.md',
75
- 'steps/step-03-does-feels.md',
76
- 'steps/step-04-pain-points.md',
77
- 'steps/step-05-gains.md',
78
- 'steps/step-06-synthesize.md'
79
- ];
80
-
81
- emmaWorkflowFiles.forEach(file => {
82
- fs.copyFileSync(
83
- path.join(sourceDir, 'workflows', '_deprecated', 'empathy-map', file),
84
- path.join(targetDir, 'workflows', '_deprecated', 'empathy-map', file)
85
- );
86
- });
87
-
88
- console.log(`${GREEN} ✓${RESET} Emma installed`);
89
-
90
- // Copy Wade agent file
91
- console.log(`${CYAN} →${RESET} Installing Wade (lean-experiments-specialist)...`);
92
- fs.copyFileSync(
93
- path.join(sourceDir, 'agents', 'lean-experiments-specialist.md'),
94
- path.join(targetDir, 'agents', 'lean-experiments-specialist.md')
95
- );
96
-
97
- // Copy Wade workflow files
98
- const wadeWorkflowFiles = [
99
- 'workflow.md',
100
- 'wireframe.template.md',
101
- 'steps/step-01-define-requirements.md',
102
- 'steps/step-02-user-flows.md',
103
- 'steps/step-03-information-architecture.md',
104
- 'steps/step-04-wireframe-sketch.md',
105
- 'steps/step-05-components.md',
106
- 'steps/step-06-synthesize.md'
107
- ];
108
-
109
- wadeWorkflowFiles.forEach(file => {
110
- fs.copyFileSync(
111
- path.join(sourceDir, 'workflows', '_deprecated', 'wireframe', file),
112
- path.join(targetDir, 'workflows', '_deprecated', 'wireframe', file)
113
- );
114
- });
55
+ const targetDir = path.join(projectRoot, '_bmad', 'bme', '_vortex');
115
56
 
116
- console.log(`${GREEN} ✓${RESET} Wade installed`);
117
-
118
- // Copy all 7 new workflow directories
119
- console.log(`${CYAN} →${RESET} Installing Vortex Framework workflows...`);
120
- const workflows = [
121
- 'lean-persona',
122
- 'product-vision',
123
- 'contextualize-scope',
124
- 'mvp',
125
- 'lean-experiment',
126
- 'proof-of-concept',
127
- 'proof-of-value'
128
- ];
57
+ // Create deprecated workflow archive directories
58
+ const deprecatedWorkflows = ['empathy-map', 'wireframe'];
129
59
 
130
- workflows.forEach(workflow => {
131
- const workflowSourceDir = path.join(sourceDir, 'workflows', workflow);
132
- const workflowTargetDir = path.join(targetDir, 'workflows', workflow);
60
+ for (const workflow of deprecatedWorkflows) {
61
+ const workflowSourceDir = path.join(sourceDir, 'workflows', '_deprecated', workflow);
62
+ const workflowTargetDir = path.join(targetDir, 'workflows', '_deprecated', workflow);
133
63
 
134
64
  if (fs.existsSync(workflowSourceDir)) {
135
65
  fs.copySync(workflowSourceDir, workflowTargetDir);
136
- console.log(`${GREEN} ✓${RESET} ${workflow}`);
137
- } else {
138
- console.log(`${YELLOW} ⚠${RESET} ${workflow} not found in package (skipping)`);
66
+ console.log(`${GREEN} ✓${RESET} Archived ${workflow} to _deprecated/`);
139
67
  }
140
- });
68
+ }
141
69
 
142
- console.log(`${GREEN} ✓${RESET} All workflows installed`);
70
+ // Legacy cleanup
71
+ cleanupLegacyFiles(projectRoot);
143
72
  }
144
73
 
145
- function updateConfig() {
146
- console.log(`${CYAN}[3/6]${RESET} Configuring agents...`);
147
-
148
- const configPath = path.join(process.cwd(), '_bmad', 'bme', '_vortex', 'config.yaml');
149
- const manifestPath = path.join(process.cwd(), '_bmad', '_config', 'agent-manifest.csv');
150
-
151
- console.log(`${CYAN} →${RESET} Config path: ${configPath}`);
152
-
153
- // Create config
154
- const configContent = `---
155
- submodule_name: _vortex
156
- description: Contextualize and Externalize streams - Strategic framing and validated learning
157
- module: bme
158
- version: 1.3.8
159
-
160
- # Output Configuration
161
- output_folder: "{project-root}/_bmad-output/vortex-artifacts"
162
- user_name: "{user}"
163
- communication_language: "en"
164
-
165
- # Agents in this submodule
166
- agents:
167
- - contextualization-expert # Emma - Contextualization Expert
168
- - lean-experiments-specialist # Wade - Lean Experiments Specialist
169
-
170
- # Workflows available
171
- workflows:
172
- # Emma - Contextualize Stream
173
- - lean-persona # Create lean user personas
174
- - product-vision # Define product vision
175
- - contextualize-scope # Decide which problem space to investigate
176
-
177
- # Wade - Externalize Stream
178
- - mvp # Design Minimum Viable Product
179
- - lean-experiment # Run Build-Measure-Learn cycle
180
- - proof-of-concept # Validate technical feasibility
181
- - proof-of-value # Validate business value
182
-
183
- # Integration
184
- party_mode_enabled: true
185
- core_module: bme
186
- `;
74
+ function cleanupLegacyFiles(projectRoot) {
75
+ console.log(`${CYAN} →${RESET} Cleaning up legacy files...`);
187
76
 
188
- try {
189
- fs.mkdirSync(path.dirname(configPath), { recursive: true });
190
- fs.writeFileSync(configPath, configContent);
77
+ // Remove _designos directory (pre-Vortex structure) from all possible locations
78
+ const legacyPaths = [
79
+ path.join(projectRoot, '_bmad', 'bme', '_designos'),
80
+ path.join(projectRoot, '_bmad', '_designos'),
81
+ ];
191
82
 
192
- // Verify file was created
193
- if (fs.existsSync(configPath)) {
194
- console.log(`${GREEN} ✓${RESET} Created config.yaml`);
195
- } else {
196
- console.error(`${RED} ✗${RESET} Config file not found after write!`);
83
+ for (const legacyPath of legacyPaths) {
84
+ if (fs.existsSync(legacyPath)) {
85
+ fs.removeSync(legacyPath);
86
+ console.log(`${GREEN} ✓${RESET} Removed legacy directory: ${path.relative(projectRoot, legacyPath)}`);
197
87
  }
198
- } catch (error) {
199
- console.error(`${RED} ✗${RESET} Error creating config.yaml:`, error.message);
200
- throw error;
201
88
  }
202
89
 
203
- // Create manifest
90
+ console.log(`${GREEN} ✓${RESET} Legacy cleanup complete`);
91
+ }
92
+
93
+ function createAgentManifest(projectRoot) {
94
+ console.log(`${CYAN}[3/6]${RESET} Creating agent manifest...`);
95
+
96
+ const manifestPath = path.join(projectRoot, '_bmad', '_config', 'agent-manifest.csv');
204
97
  fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
98
+
205
99
  const header = '"agent_id","name","title","icon","role","identity","communication_style","expertise","submodule","path"\n';
206
100
  const emmaRow = '"contextualization-expert","Emma","Contextualization Expert","🎯","Strategic Framing + Problem-Product Space Navigator","Expert in helping teams contextualize their product strategy by defining clear problem spaces and validating assumptions. Specializes in Lean Startup methodologies, persona creation, and product vision framing. Guides teams through the critical \'Contextualize\' stream of the Vortex framework.","Strategic yet approachable - speaks in frameworks and validated learning. Like a product strategist who asks \'What are we really solving?\' and \'Who is this truly for?\' Uses Lean Startup language (hypotheses, assumptions, pivots) and focuses on clarity before action.","- Master of Lean Startup and strategic framing methodologies - Personas over demographics - focus on jobs-to-be-done and problem contexts - Vision before features - align team around the \'why\' before the \'what\' - Challenge assumptions - every belief is a hypothesis until validated - Problem-solution fit comes before product-market fit","bme","_bmad/bme/_vortex/agents/contextualization-expert.md"\n';
207
101
  const wadeRow = '"lean-experiments-specialist","Wade","Lean Experiments Specialist","🧪","Lean Startup + Validated Learning Expert","Lean Startup practitioner specialized in running rapid experiments to validate product hypotheses. Helps teams move from assumptions to evidence through Build-Measure-Learn cycles. Guides teams through the \'Externalize\' stream - taking ideas into the real world to test with actual users.","Experimental and evidence-driven - speaks in hypotheses, metrics, and learning. Like a scientist who says \'Let\'s test that assumption\' and \'What would prove us wrong?\' Uses Lean language (MVPs, pivots, validated learning) and focuses on speed-to-insight over perfection.","- Master of Lean Startup and rapid experimentation - Build the smallest thing that tests the riskiest assumption - Measure what matters - focus on actionable metrics, not vanity metrics - Learn fast, pivot faster - every experiment teaches something - Proof-of-concept before proof-of-value - validate feasibility before business case - Fail fast is good, learn fast is better","bme","_bmad/bme/_vortex/agents/lean-experiments-specialist.md"\n';
@@ -209,30 +103,27 @@ core_module: bme
209
103
  console.log(`${GREEN} ✓${RESET} Created agent-manifest.csv`);
210
104
  }
211
105
 
212
- function createOutputDirectory() {
106
+ function createOutputDirectory(projectRoot) {
213
107
  console.log(`${CYAN}[4/6]${RESET} Setting up output directory...`);
214
108
 
215
- const outputDir = path.join(process.cwd(), '_bmad-output', 'vortex-artifacts');
109
+ const outputDir = path.join(projectRoot, '_bmad-output', 'vortex-artifacts');
216
110
  fs.mkdirSync(outputDir, { recursive: true });
217
111
 
218
112
  console.log(`${GREEN} ✓${RESET} Output directory ready`);
219
113
  }
220
114
 
221
- function verifyInstallation() {
222
- console.log(`${CYAN}[5/6]${RESET} Verifying installation...`);
115
+ function verifyInstallation(projectRoot) {
116
+ console.log(`${CYAN}[6/6]${RESET} Verifying installation...`);
223
117
 
224
- const targetDir = process.cwd();
225
118
  const checks = [
226
119
  { path: '_bmad/bme/_vortex/agents/contextualization-expert.md', name: 'Emma agent file' },
227
120
  { path: '_bmad/bme/_vortex/agents/lean-experiments-specialist.md', name: 'Wade agent file' },
228
- { path: '_bmad/bme/_vortex/workflows/_deprecated/empathy-map/workflow.md', name: 'Emma workflow (legacy)' },
229
- { path: '_bmad/bme/_vortex/workflows/_deprecated/wireframe/workflow.md', name: 'Wade workflow (legacy)' },
230
121
  { path: '_bmad/bme/_vortex/config.yaml', name: 'Configuration file' },
231
122
  ];
232
123
 
233
124
  let allChecksPass = true;
234
125
  checks.forEach(check => {
235
- const fullPath = path.join(targetDir, check.path);
126
+ const fullPath = path.join(projectRoot, check.path);
236
127
  if (fs.existsSync(fullPath)) {
237
128
  console.log(`${GREEN} ✓${RESET} ${check.name}`);
238
129
  } else {
@@ -250,24 +141,6 @@ function verifyInstallation() {
250
141
  console.log(`${GREEN} ✓${RESET} All files installed successfully`);
251
142
  }
252
143
 
253
- function copyUserGuides() {
254
- console.log(`${CYAN}[6/6]${RESET} Installing user guides...`);
255
-
256
- const sourceDir = path.join(__dirname, '..', '_bmad-output', 'vortex-artifacts');
257
- const targetDir = path.join(process.cwd(), '_bmad-output', 'vortex-artifacts');
258
-
259
- // Copy user guides if they exist
260
- const guides = ['EMMA-USER-GUIDE.md', 'WADE-USER-GUIDE.md'];
261
- guides.forEach(guide => {
262
- const sourcePath = path.join(sourceDir, guide);
263
- if (fs.existsSync(sourcePath)) {
264
- fs.copyFileSync(sourcePath, path.join(targetDir, guide));
265
- }
266
- });
267
-
268
- console.log(`${GREEN} ✓${RESET} User guides installed`);
269
- }
270
-
271
144
  function printSuccess() {
272
145
  console.log('');
273
146
  console.log(`${GREEN}${BOLD}╔════════════════════════════════════════════════════╗${RESET}`);
@@ -289,51 +162,24 @@ function printSuccess() {
289
162
  console.log(' Activate Wade:');
290
163
  console.log(` ${CYAN}cat _bmad/bme/_vortex/agents/lean-experiments-specialist.md${RESET}`);
291
164
  console.log('');
292
- console.log(`${YELLOW}Note: User guides being updated for v1.2.0${RESET}`);
293
- console.log('');
294
- }
295
-
296
- function cleanupLegacyFiles() {
297
- console.log(`${CYAN} →${RESET} Cleaning up legacy files...`);
298
-
299
- // Remove _designos directory (pre-Vortex structure) from all possible locations
300
- const legacyPaths = [
301
- path.join(process.cwd(), '_bmad', 'bme', '_designos'),
302
- path.join(process.cwd(), '_bmad', '_designos'),
303
- ];
304
-
305
- for (const legacyPath of legacyPaths) {
306
- if (fs.existsSync(legacyPath)) {
307
- fs.removeSync(legacyPath);
308
- console.log(`${GREEN} ✓${RESET} Removed legacy directory: ${path.relative(process.cwd(), legacyPath)}`);
309
- }
310
- }
311
-
312
- // Remove deprecated agent files from _vortex/agents
313
- const agentsDir = path.join(process.cwd(), '_bmad', 'bme', '_vortex', 'agents');
314
- const deprecatedAgents = ['empathy-mapper.md', 'wireframe-designer.md'];
315
-
316
- for (const agent of deprecatedAgents) {
317
- const agentPath = path.join(agentsDir, agent);
318
- if (fs.existsSync(agentPath)) {
319
- fs.removeSync(agentPath);
320
- console.log(`${GREEN} ✓${RESET} Removed deprecated agent: ${agent}`);
321
- }
322
- }
323
-
324
- console.log(`${GREEN} ✓${RESET} Legacy cleanup complete`);
325
165
  }
326
166
 
327
167
  async function main() {
328
168
  try {
169
+ const projectRoot = process.cwd();
170
+
329
171
  printBanner();
330
- checkPrerequisites();
331
- copyAllAgentFiles();
332
- cleanupLegacyFiles();
333
- updateConfig();
334
- createOutputDirectory();
335
- verifyInstallation();
336
- copyUserGuides();
172
+ checkPrerequisites(projectRoot);
173
+ archiveDeprecatedWorkflows(projectRoot);
174
+ createAgentManifest(projectRoot);
175
+ createOutputDirectory(projectRoot);
176
+
177
+ // Use refreshInstallation for agents, workflows, config, and user guides
178
+ console.log(`${CYAN}[5/6]${RESET} Installing agents, workflows, config, and guides...`);
179
+ await refreshInstallation(projectRoot, { backupGuides: false });
180
+ console.log(`${GREEN} ✓${RESET} Installation refreshed`);
181
+
182
+ verifyInstallation(projectRoot);
337
183
  printSuccess();
338
184
  } catch (error) {
339
185
  console.error(`${RED}✗ Installation failed:${RESET}`, error.message);
@@ -27,9 +27,12 @@ async function main() {
27
27
  const versionDetector = require('./update/lib/version-detector');
28
28
  const registry = require('./update/migrations/registry');
29
29
 
30
- const currentVersion = versionDetector.getCurrentVersion();
30
+ const { findProjectRoot, compareVersions } = require('./update/lib/utils');
31
+ const projectRoot = findProjectRoot();
32
+
33
+ const currentVersion = versionDetector.getCurrentVersion(projectRoot);
31
34
  const targetVersion = versionDetector.getTargetVersion();
32
- const scenario = versionDetector.detectInstallationScenario();
35
+ const scenario = versionDetector.detectInstallationScenario(projectRoot);
33
36
 
34
37
  // Fresh install
35
38
  if (scenario === 'fresh' || !currentVersion) {
@@ -52,7 +55,7 @@ async function main() {
52
55
  }
53
56
 
54
57
  // Upgrade detected
55
- if (versionDetector.compareVersions(currentVersion, targetVersion) < 0) {
58
+ if (compareVersions(currentVersion, targetVersion) < 0) {
56
59
  console.log(`${YELLOW}${BOLD}⚠ UPGRADE DETECTED${RESET}`);
57
60
  console.log('');
58
61
  console.log(` Current version: ${RED}${currentVersion}${RESET}`);
@@ -60,7 +63,7 @@ async function main() {
60
63
  console.log('');
61
64
 
62
65
  // Check for breaking changes
63
- const breakingChanges = registry.getBreakingChanges(currentVersion, targetVersion);
66
+ const breakingChanges = registry.getBreakingChanges(currentVersion);
64
67
  if (breakingChanges.length > 0) {
65
68
  console.log(`${RED}${BOLD} ⚠ Breaking changes detected!${RESET}`);
66
69
  console.log('');
@@ -83,7 +86,7 @@ async function main() {
83
86
  }
84
87
 
85
88
  // Downgrade (shouldn't happen normally)
86
- if (versionDetector.compareVersions(currentVersion, targetVersion) > 0) {
89
+ if (compareVersions(currentVersion, targetVersion) > 0) {
87
90
  console.log(`${YELLOW}Note: Package version (${targetVersion}) is older than installed version (${currentVersion})${RESET}`);
88
91
  console.log('');
89
92
  return;
@@ -95,8 +98,8 @@ async function main() {
95
98
  console.log(` ${CYAN}npx bmad-install-agents${RESET} - Install all agents (Emma + Wade)`);
96
99
  console.log('');
97
100
  console.log('Or install individually:');
98
- console.log(` ${CYAN}npx bmad-install-emma${RESET} - Install Emma (empathy-mapper)`);
99
- console.log(` ${CYAN}npx bmad-install-wade${RESET} - Install Wade (wireframe-designer)`);
101
+ console.log(` ${CYAN}npx bmad-install-emma${RESET} - Install Emma (contextualization-expert)`);
102
+ console.log(` ${CYAN}npx bmad-install-wade${RESET} - Install Wade (lean-experiments-specialist)`);
100
103
  console.log('');
101
104
  }
102
105
  }
@@ -2,6 +2,9 @@
2
2
 
3
3
  const chalk = require('chalk');
4
4
  const registry = require('./migrations/registry');
5
+ const backupManager = require('./lib/backup-manager');
6
+ const { refreshInstallation } = require('./lib/refresh-installation');
7
+ const { findProjectRoot } = require('./lib/utils');
5
8
 
6
9
  /**
7
10
  * BMAD-Enhanced Migrate CLI
@@ -11,6 +14,15 @@ const registry = require('./migrations/registry');
11
14
  async function main() {
12
15
  const args = process.argv.slice(2);
13
16
 
17
+ // Validate project root
18
+ const projectRoot = findProjectRoot();
19
+ if (!projectRoot) {
20
+ console.error('');
21
+ console.error(chalk.red('Not in a BMAD project. Could not find _bmad/ directory.'));
22
+ console.error('');
23
+ process.exit(1);
24
+ }
25
+
14
26
  // No args - show available migrations
15
27
  if (args.length === 0) {
16
28
  showAvailableMigrations();
@@ -32,6 +44,15 @@ async function main() {
32
44
  process.exit(1);
33
45
  }
34
46
 
47
+ // Check if already applied
48
+ const configPath = require('path').join(projectRoot, '_bmad/bme/_vortex/config.yaml');
49
+ if (registry.hasMigrationBeenApplied(migrationName, configPath)) {
50
+ console.log('');
51
+ console.log(chalk.yellow(`Migration '${migrationName}' has already been applied.`));
52
+ console.log('');
53
+ process.exit(0);
54
+ }
55
+
35
56
  // Load migration module
36
57
  if (!migration.module) {
37
58
  try {
@@ -44,29 +65,61 @@ async function main() {
44
65
  }
45
66
  }
46
67
 
47
- // Run migration
68
+ // Run migration with backup and refresh
48
69
  console.log('');
49
70
  console.log(chalk.cyan.bold(`Running migration: ${migration.name}`));
50
71
  console.log(chalk.gray(migration.description));
51
72
  console.log('');
52
73
 
74
+ let backupMetadata = null;
75
+
53
76
  try {
54
- const changes = await migration.module.apply();
77
+ // Create backup before running delta
78
+ console.log(chalk.cyan('Creating backup...'));
79
+ backupMetadata = await backupManager.createBackup('manual', projectRoot);
80
+ console.log(chalk.green(`✓ Backup created: ${require('path').basename(backupMetadata.backup_dir)}`));
81
+ console.log('');
82
+
83
+ // Run the delta
84
+ const changes = await migration.module.apply(projectRoot);
55
85
 
56
86
  console.log('');
57
- console.log(chalk.green.bold('✓ Migration completed'));
87
+ console.log(chalk.green.bold('✓ Migration delta completed'));
58
88
  console.log('');
59
- console.log(chalk.cyan('Changes:'));
89
+ console.log(chalk.cyan('Delta changes:'));
60
90
  changes.forEach(change => {
61
91
  console.log(chalk.gray(` - ${change}`));
62
92
  });
63
93
  console.log('');
64
94
 
95
+ // Refresh installation after delta
96
+ console.log(chalk.cyan('Refreshing installation files...'));
97
+ const refreshChanges = await refreshInstallation(projectRoot);
98
+ console.log(chalk.green('✓ Installation refreshed'));
99
+ console.log('');
100
+
65
101
  } catch (error) {
66
102
  console.error('');
67
103
  console.error(chalk.red.bold('✗ Migration failed'));
68
104
  console.error(chalk.red(error.message));
69
105
  console.error('');
106
+
107
+ // Rollback if we have a backup
108
+ if (backupMetadata) {
109
+ console.log(chalk.yellow('Restoring from backup...'));
110
+ try {
111
+ await backupManager.restoreBackup(backupMetadata, projectRoot);
112
+ console.log(chalk.green('✓ Installation restored from backup'));
113
+ console.log('');
114
+ } catch (restoreError) {
115
+ console.error(chalk.red('✗ Restore failed!'));
116
+ console.error(chalk.red(restoreError.message));
117
+ console.error('');
118
+ console.error(chalk.yellow(`Manual restore may be needed from: ${backupMetadata.backup_dir}`));
119
+ console.error('');
120
+ }
121
+ }
122
+
70
123
  if (error.stack) {
71
124
  console.error(chalk.gray(error.stack));
72
125
  console.error('');
@@ -95,7 +148,7 @@ function showAvailableMigrations() {
95
148
  const breaking = m.breaking ? chalk.red('[BREAKING]') : chalk.green('[SAFE]');
96
149
  console.log(` ${index + 1}. ${chalk.cyan(m.name)} ${breaking}`);
97
150
  console.log(` ${chalk.gray(m.description)}`);
98
- console.log(` ${chalk.gray(`${m.fromVersion} ${m.toVersion}`)}`);
151
+ console.log(` ${chalk.gray(`From: ${m.fromVersion}`)}`);
99
152
  console.log('');
100
153
  });
101
154
 
@@ -5,6 +5,7 @@ const chalk = require('chalk');
5
5
  const versionDetector = require('./lib/version-detector');
6
6
  const migrationRunner = require('./lib/migration-runner');
7
7
  const registry = require('./migrations/registry');
8
+ const { findProjectRoot } = require('./lib/utils');
8
9
 
9
10
  /**
10
11
  * BMAD-Enhanced Update CLI
@@ -15,7 +16,6 @@ async function main() {
15
16
  const args = process.argv.slice(2);
16
17
  const dryRun = args.includes('--dry-run');
17
18
  const yes = args.includes('--yes') || args.includes('-y');
18
- const force = args.includes('--force');
19
19
  const verbose = args.includes('--verbose') || args.includes('-v');
20
20
 
21
21
  // Header
@@ -25,10 +25,20 @@ async function main() {
25
25
  console.log(chalk.bold.magenta('╚════════════════════════════════════════╝'));
26
26
  console.log('');
27
27
 
28
+ // Validate project root
29
+ const projectRoot = findProjectRoot();
30
+ if (!projectRoot) {
31
+ console.log(chalk.red('Not in a BMAD project. Could not find _bmad/ directory.'));
32
+ console.log('');
33
+ console.log('Run: ' + chalk.cyan('npx bmad-install-agents'));
34
+ console.log('');
35
+ process.exit(1);
36
+ }
37
+
28
38
  // 1. Detect current state
29
- const currentVersion = versionDetector.getCurrentVersion();
39
+ const currentVersion = versionDetector.getCurrentVersion(projectRoot);
30
40
  const targetVersion = versionDetector.getTargetVersion();
31
- const scenario = versionDetector.detectInstallationScenario();
41
+ const scenario = versionDetector.detectInstallationScenario(projectRoot);
32
42
 
33
43
  // Handle different scenarios
34
44
  if (scenario === 'fresh') {
@@ -88,7 +98,7 @@ async function main() {
88
98
  console.log(` To: ${chalk.green(targetVersion)}`);
89
99
  console.log('');
90
100
 
91
- const migrations = registry.getMigrationsFor(currentVersion, targetVersion);
101
+ const migrations = registry.getMigrationsFor(currentVersion);
92
102
 
93
103
  if (migrations.length === 0) {
94
104
  console.log(chalk.yellow('No migrations needed (versions compatible)'));
@@ -104,7 +114,7 @@ async function main() {
104
114
  console.log('');
105
115
 
106
116
  // 3. Show breaking changes warning
107
- const breakingChanges = registry.getBreakingChanges(currentVersion, targetVersion);
117
+ const breakingChanges = registry.getBreakingChanges(currentVersion);
108
118
  if (breakingChanges.length > 0) {
109
119
  console.log(chalk.red.bold('⚠ BREAKING CHANGES:'));
110
120
  breakingChanges.forEach(change => {
@@ -119,7 +129,7 @@ async function main() {
119
129
  console.log('');
120
130
 
121
131
  try {
122
- await migrationRunner.runMigrations(currentVersion, targetVersion, { dryRun: true, verbose });
132
+ await migrationRunner.runMigrations(currentVersion, { dryRun: true, verbose });
123
133
  } catch (error) {
124
134
  console.error(chalk.red('Error during preview:'), error.message);
125
135
  process.exit(1);
@@ -148,7 +158,7 @@ async function main() {
148
158
  console.log(chalk.cyan.bold('Starting migration...'));
149
159
 
150
160
  try {
151
- const result = await migrationRunner.runMigrations(currentVersion, targetVersion, { verbose });
161
+ const result = await migrationRunner.runMigrations(currentVersion, { verbose });
152
162
 
153
163
  // 7. Show success report
154
164
  console.log('');
@@ -5,6 +5,7 @@ const path = require('path');
5
5
  const chalk = require('chalk');
6
6
  const yaml = require('js-yaml');
7
7
  const versionDetector = require('./lib/version-detector');
8
+ const { findProjectRoot, compareVersions } = require('./lib/utils');
8
9
 
9
10
  /**
10
11
  * BMAD-Enhanced Version CLI
@@ -12,14 +13,26 @@ const versionDetector = require('./lib/version-detector');
12
13
  */
13
14
 
14
15
  async function main() {
15
- const currentVersion = versionDetector.getCurrentVersion();
16
+ const projectRoot = findProjectRoot();
16
17
  const targetVersion = versionDetector.getTargetVersion();
17
- const scenario = versionDetector.detectInstallationScenario();
18
18
 
19
19
  console.log('');
20
20
  console.log(chalk.bold('BMAD-Enhanced Version Information'));
21
21
  console.log('');
22
22
 
23
+ // Not in a BMAD project
24
+ if (!projectRoot) {
25
+ console.log(chalk.yellow('Status: Not in a BMAD project'));
26
+ console.log(`Package version: ${chalk.cyan(targetVersion)}`);
27
+ console.log('');
28
+ console.log('Run: ' + chalk.cyan('npx bmad-install-agents'));
29
+ console.log('');
30
+ return;
31
+ }
32
+
33
+ const currentVersion = versionDetector.getCurrentVersion(projectRoot);
34
+ const scenario = versionDetector.detectInstallationScenario(projectRoot);
35
+
23
36
  // Fresh install - not installed yet
24
37
  if (scenario === 'fresh') {
25
38
  console.log(chalk.yellow('Status: Not installed'));
@@ -64,7 +77,7 @@ async function main() {
64
77
  // Status
65
78
  if (currentVersion === targetVersion) {
66
79
  console.log(chalk.green('Status: ✓ Up to date'));
67
- } else if (versionDetector.compareVersions(currentVersion, targetVersion) < 0) {
80
+ } else if (compareVersions(currentVersion, targetVersion) < 0) {
68
81
  console.log(chalk.yellow('Status: ⚠ Update available'));
69
82
  console.log('');
70
83
  console.log('Run: ' + chalk.cyan('npx bmad-update --dry-run') + ' (to preview)');
@@ -74,7 +87,7 @@ async function main() {
74
87
  }
75
88
 
76
89
  // Show migration history
77
- const migrationHistory = await getMigrationHistory();
90
+ const migrationHistory = await getMigrationHistory(projectRoot);
78
91
  if (migrationHistory && migrationHistory.length > 0) {
79
92
  console.log('');
80
93
  console.log(chalk.cyan('Migration History:'));
@@ -94,10 +107,11 @@ async function main() {
94
107
 
95
108
  /**
96
109
  * Get migration history from config.yaml
110
+ * @param {string} projectRoot - Project root
97
111
  * @returns {Promise<Array|null>} Migration history or null
98
112
  */
99
- async function getMigrationHistory() {
100
- const configPath = path.join(process.cwd(), '_bmad/bme/_vortex/config.yaml');
113
+ async function getMigrationHistory(projectRoot) {
114
+ const configPath = path.join(projectRoot, '_bmad/bme/_vortex/config.yaml');
101
115
 
102
116
  if (!fs.existsSync(configPath)) {
103
117
  return null;