bmad-enhanced 1.1.2 → 1.3.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.
- package/README.md +178 -58
- package/package.json +7 -3
- package/scripts/install-all-agents.js +10 -12
- package/scripts/install-emma.js +5 -5
- package/scripts/install-wade.js +5 -5
- package/scripts/postinstall.js +100 -11
- package/scripts/update/bmad-migrate.js +116 -0
- package/scripts/update/bmad-update.js +206 -0
- package/scripts/update/bmad-version.js +94 -0
- package/scripts/update/lib/backup-manager.js +279 -0
- package/scripts/update/lib/config-merger.js +232 -0
- package/scripts/update/lib/migration-runner.js +402 -0
- package/scripts/update/lib/validator.js +430 -0
- package/scripts/update/lib/version-detector.js +246 -0
- package/scripts/update/migrations/1.0.x-to-1.3.0.js +265 -0
- package/scripts/update/migrations/1.1.x-to-1.3.0.js +166 -0
- package/scripts/update/migrations/1.2.x-to-1.3.0.js +166 -0
- package/scripts/update/migrations/registry.js +185 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const yaml = require('js-yaml');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Migration Registry for BMAD-Enhanced
|
|
9
|
+
* Tracks available migrations and determines execution order
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Registry of all available migrations
|
|
13
|
+
const MIGRATIONS = [
|
|
14
|
+
{
|
|
15
|
+
name: '1.0.x-to-1.3.0',
|
|
16
|
+
fromVersion: '1.0.x',
|
|
17
|
+
toVersion: '1.3.0',
|
|
18
|
+
breaking: true,
|
|
19
|
+
description: 'Migrate empathy-map workflow to lean-persona',
|
|
20
|
+
module: null // Loaded on demand
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: '1.1.x-to-1.3.0',
|
|
24
|
+
fromVersion: '1.1.x',
|
|
25
|
+
toVersion: '1.3.0',
|
|
26
|
+
breaking: false,
|
|
27
|
+
description: 'Archive deprecated workflows, update agents',
|
|
28
|
+
module: null // Loaded on demand
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: '1.2.x-to-1.3.0',
|
|
32
|
+
fromVersion: '1.2.x',
|
|
33
|
+
toVersion: '1.3.0',
|
|
34
|
+
breaking: false,
|
|
35
|
+
description: 'Update to v1.3.0 with migration system',
|
|
36
|
+
module: null // Loaded on demand
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get migrations applicable for version upgrade
|
|
42
|
+
* @param {string} fromVersion - Current version
|
|
43
|
+
* @param {string} toVersion - Target version
|
|
44
|
+
* @returns {Array} List of applicable migrations
|
|
45
|
+
*/
|
|
46
|
+
function getMigrationsFor(fromVersion, toVersion) {
|
|
47
|
+
const applicable = [];
|
|
48
|
+
|
|
49
|
+
for (const migration of MIGRATIONS) {
|
|
50
|
+
if (matchesVersionRange(fromVersion, migration.fromVersion) &&
|
|
51
|
+
matchesVersionRange(toVersion, migration.toVersion)) {
|
|
52
|
+
|
|
53
|
+
// Lazy load the migration module
|
|
54
|
+
if (!migration.module) {
|
|
55
|
+
try {
|
|
56
|
+
migration.module = require(`./${migration.name}`);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error(`Failed to load migration ${migration.name}:`, error.message);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
applicable.push(migration);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Sort by version order (oldest to newest)
|
|
68
|
+
applicable.sort((a, b) => {
|
|
69
|
+
const aVersion = a.fromVersion.replace('.x', '.0');
|
|
70
|
+
const bVersion = b.fromVersion.replace('.x', '.0');
|
|
71
|
+
return compareVersions(aVersion, bVersion);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return applicable;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Check if migration has already been applied
|
|
79
|
+
* @param {string} migrationName - Name of migration
|
|
80
|
+
* @param {string} configPath - Path to config.yaml
|
|
81
|
+
* @returns {boolean} True if already applied
|
|
82
|
+
*/
|
|
83
|
+
function hasMigrationBeenApplied(migrationName, configPath) {
|
|
84
|
+
if (!fs.existsSync(configPath)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
90
|
+
const config = yaml.load(configContent);
|
|
91
|
+
|
|
92
|
+
if (!config.migration_history || !Array.isArray(config.migration_history)) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return config.migration_history.some(entry =>
|
|
97
|
+
entry.migrations_applied && entry.migrations_applied.includes(migrationName)
|
|
98
|
+
);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.warn('Could not check migration history:', error.message);
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get breaking changes for version upgrade
|
|
107
|
+
* @param {string} fromVersion - Current version
|
|
108
|
+
* @param {string} toVersion - Target version
|
|
109
|
+
* @returns {Array<string>} List of breaking change descriptions
|
|
110
|
+
*/
|
|
111
|
+
function getBreakingChanges(fromVersion, toVersion) {
|
|
112
|
+
const migrations = getMigrationsFor(fromVersion, toVersion);
|
|
113
|
+
const breakingChanges = [];
|
|
114
|
+
|
|
115
|
+
for (const migration of migrations) {
|
|
116
|
+
if (migration.breaking) {
|
|
117
|
+
breakingChanges.push(migration.description);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return breakingChanges;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Match version against version range pattern
|
|
126
|
+
* @param {string} version - Version to check (e.g., "1.0.5")
|
|
127
|
+
* @param {string} pattern - Pattern to match (e.g., "1.0.x")
|
|
128
|
+
* @returns {boolean} True if matches
|
|
129
|
+
*/
|
|
130
|
+
function matchesVersionRange(version, pattern) {
|
|
131
|
+
if (pattern === version) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Handle wildcard patterns (e.g., "1.0.x")
|
|
136
|
+
if (pattern.endsWith('.x')) {
|
|
137
|
+
const patternParts = pattern.split('.');
|
|
138
|
+
const versionParts = version.split('.');
|
|
139
|
+
|
|
140
|
+
// Match major.minor, ignore patch
|
|
141
|
+
return patternParts[0] === versionParts[0] &&
|
|
142
|
+
patternParts[1] === versionParts[1];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Compare two semantic versions
|
|
150
|
+
* @param {string} v1 - First version
|
|
151
|
+
* @param {string} v2 - Second version
|
|
152
|
+
* @returns {number} -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
153
|
+
*/
|
|
154
|
+
function compareVersions(v1, v2) {
|
|
155
|
+
const parts1 = v1.split('.').map(Number);
|
|
156
|
+
const parts2 = v2.split('.').map(Number);
|
|
157
|
+
|
|
158
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
159
|
+
const part1 = parts1[i] || 0;
|
|
160
|
+
const part2 = parts2[i] || 0;
|
|
161
|
+
|
|
162
|
+
if (part1 < part2) return -1;
|
|
163
|
+
if (part1 > part2) return 1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get all registered migrations
|
|
171
|
+
* @returns {Array} All migrations
|
|
172
|
+
*/
|
|
173
|
+
function getAllMigrations() {
|
|
174
|
+
return [...MIGRATIONS];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = {
|
|
178
|
+
MIGRATIONS,
|
|
179
|
+
getMigrationsFor,
|
|
180
|
+
hasMigrationBeenApplied,
|
|
181
|
+
getBreakingChanges,
|
|
182
|
+
matchesVersionRange,
|
|
183
|
+
compareVersions,
|
|
184
|
+
getAllMigrations
|
|
185
|
+
};
|