mirror of
https://github.com/bmad-code-org/BMAD-METHOD.git
synced 2026-01-30 04:32:02 +00:00
allow updates from any beta, warn on alpha and v4
This commit is contained in:
@@ -139,7 +139,7 @@ b) **HALT and wait for user selection.**
|
|||||||
#### Menu Handling Logic:
|
#### Menu Handling Logic:
|
||||||
|
|
||||||
- IF A: Read fully and follow: `{advanced_elicitation}` with current spec content, process enhanced insights, ask user "Accept improvements? (y/n)", if yes update spec then redisplay menu, if no keep original then redisplay menu
|
- IF A: Read fully and follow: `{advanced_elicitation}` with current spec content, process enhanced insights, ask user "Accept improvements? (y/n)", if yes update spec then redisplay menu, if no keep original then redisplay menu
|
||||||
- IF B: Load and execute `{quick_dev_workflow}` with the final spec file (warn: fresh context is better)
|
- IF B: Read the entire workflow file at `{quick_dev_workflow}` and follow the instructions with the final spec file (warn: fresh context is better)
|
||||||
- IF D: Exit workflow - display final confirmation and path to spec
|
- IF D: Exit workflow - display final confirmation and path to spec
|
||||||
- IF P: Read fully and follow: `{party_mode_exec}` with current spec content, process collaborative insights, ask user "Accept changes? (y/n)", if yes update spec then redisplay menu, if no keep original then redisplay menu
|
- IF P: Read fully and follow: `{party_mode_exec}` with current spec content, process collaborative insights, ask user "Accept changes? (y/n)", if yes update spec then redisplay menu, if no keep original then redisplay menu
|
||||||
- IF R: Execute Adversarial Review (see below)
|
- IF R: Execute Adversarial Review (see below)
|
||||||
|
|||||||
@@ -999,6 +999,9 @@ class Installer {
|
|||||||
|
|
||||||
// Configure IDEs and copy documentation
|
// Configure IDEs and copy documentation
|
||||||
if (!config.skipIde && config.ides && config.ides.length > 0) {
|
if (!config.skipIde && config.ides && config.ides.length > 0) {
|
||||||
|
// Ensure IDE manager is initialized (handlers may not be loaded in quick update flow)
|
||||||
|
await this.ideManager.ensureInitialized();
|
||||||
|
|
||||||
// Filter out any undefined/null values from the IDE list
|
// Filter out any undefined/null values from the IDE list
|
||||||
const validIdes = config.ides.filter((ide) => ide && typeof ide === 'string');
|
const validIdes = config.ides.filter((ide) => ide && typeof ide === 'string');
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ description: '${description.replaceAll("'", "''")}'
|
|||||||
|
|
||||||
# ${item.displayName || item.name}
|
# ${item.displayName || item.name}
|
||||||
|
|
||||||
LOAD and execute the ${type} at: ${itemPath}
|
Read the entire ${type} file at: ${itemPath}
|
||||||
|
|
||||||
Follow all instructions in the ${type} file exactly as written.
|
Follow all instructions in the ${type} file exactly as written.
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
---
|
||||||
name: '{{name}}'
|
name: '{{name}}'
|
||||||
description: '{{description}}'
|
description: '{{description}}'
|
||||||
|
---
|
||||||
|
|
||||||
LOAD and execute the workflow at: {project-root}/_bmad/{{workflow_path}}
|
Read the entire workflow file at: {project-root}/_bmad/{{workflow_path}}
|
||||||
|
|
||||||
Follow all instructions in the workflow file exactly as written.
|
Follow all instructions in the workflow file exactly as written.
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
LOAD and execute the workflow at: {project-root}/_bmad/{{workflow_path}}
|
Read the entire workflow file at: {project-root}/_bmad/{{workflow_path}}
|
||||||
|
|
||||||
Follow all instructions in the workflow file exactly as written.
|
Follow all instructions in the workflow file exactly as written.
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
|
|
||||||
## Instructions
|
## Instructions
|
||||||
|
|
||||||
LOAD and execute the workflow at: {project-root}/_bmad/{{workflow_path}}
|
Read the entire workflow file at: {project-root}/_bmad/{{workflow_path}}
|
||||||
|
|
||||||
Follow all instructions in the workflow file exactly as written.
|
Follow all instructions in the workflow file exactly as written.
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ auto_execution_mode: "iterate"
|
|||||||
|
|
||||||
# {{name}}
|
# {{name}}
|
||||||
|
|
||||||
LOAD and execute the workflow at: {project-root}/_bmad/{{workflow_path}}
|
Read the entire workflow file at {project-root}/_bmad/{{workflow_path}}
|
||||||
|
|
||||||
Follow all instructions in the workflow file exactly as written.
|
Follow all instructions in the workflow file exactly as written.
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class UI {
|
|||||||
hasLegacyCfg = bmadResult.hasLegacyCfg;
|
hasLegacyCfg = bmadResult.hasLegacyCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle legacy .bmad or _cfg folder - these are very old (more than 2 versions behind)
|
// Handle legacy .bmad or _cfg folder - these are very old (v4 or alpha)
|
||||||
// Show version warning instead of offering conversion
|
// Show version warning instead of offering conversion
|
||||||
if (hasLegacyBmadFolder || hasLegacyCfg) {
|
if (hasLegacyBmadFolder || hasLegacyCfg) {
|
||||||
console.log('');
|
console.log('');
|
||||||
@@ -92,9 +92,8 @@ class UI {
|
|||||||
'Found a ".bmad"/"bmad" folder, or a legacy "_cfg" folder under the bmad folder - this is from a old BMAD version that is out of date for automatic upgrade, manual intervention required.',
|
'Found a ".bmad"/"bmad" folder, or a legacy "_cfg" folder under the bmad folder - this is from a old BMAD version that is out of date for automatic upgrade, manual intervention required.',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
console.log(chalk.yellow('This version is more than 2 alpha versions behind current.'));
|
console.log(chalk.yellow('You have a legacy version installed (v4 or alpha).'));
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log(chalk.dim('For stability, we only support updates from the previous 2 alpha versions.'));
|
|
||||||
console.log(chalk.dim('Legacy installations may have compatibility issues.'));
|
console.log(chalk.dim('Legacy installations may have compatibility issues.'));
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log(chalk.dim('For the best experience, we strongly recommend:'));
|
console.log(chalk.dim('For the best experience, we strongly recommend:'));
|
||||||
@@ -188,8 +187,8 @@ class UI {
|
|||||||
const currentVersion = require(packageJsonPath).version;
|
const currentVersion = require(packageJsonPath).version;
|
||||||
const installedVersion = existingInstall.version || 'unknown';
|
const installedVersion = existingInstall.version || 'unknown';
|
||||||
|
|
||||||
// Check if version is too old and warn user
|
// Check if version is pre beta
|
||||||
const shouldProceed = await this.showOldAlphaVersionWarning(installedVersion, currentVersion, path.basename(bmadDir));
|
const shouldProceed = await this.showLegacyVersionWarning(installedVersion, currentVersion, path.basename(bmadDir));
|
||||||
|
|
||||||
// If user chose to cancel, exit the installer
|
// If user chose to cancel, exit the installer
|
||||||
if (!shouldProceed) {
|
if (!shouldProceed) {
|
||||||
@@ -1457,96 +1456,40 @@ class UI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse alpha version string (e.g., "6.0.0-Alpha.20")
|
* Check if installed version is a legacy version that needs fresh install
|
||||||
* @param {string} version - Version string
|
|
||||||
* @returns {Object|null} Object with alphaNumber and fullVersion, or null if invalid
|
|
||||||
*/
|
|
||||||
parseAlphaVersion(version) {
|
|
||||||
if (!version || version === 'unknown') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove 'v' prefix if present
|
|
||||||
const cleanVersion = version.toString().replace(/^v/i, '');
|
|
||||||
|
|
||||||
// Match alpha version pattern: X.Y.Z-Alpha.N (case-insensitive)
|
|
||||||
const match = cleanVersion.match(/[\d.]+-Alpha\.(\d+)/i);
|
|
||||||
|
|
||||||
if (!match) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
alphaNumber: parseInt(match[1], 10),
|
|
||||||
fullVersion: cleanVersion,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if installed version is more than 2 alpha versions behind current
|
|
||||||
* @param {string} installedVersion - The installed version
|
* @param {string} installedVersion - The installed version
|
||||||
* @param {string} currentVersion - The current version
|
* @returns {boolean} True if legacy (v4 or any alpha)
|
||||||
* @returns {Object} Object with { isOldVersion, versionDiff, shouldWarn, installed, current }
|
|
||||||
*/
|
*/
|
||||||
checkAlphaVersionAge(installedVersion, currentVersion) {
|
isLegacyVersion(installedVersion) {
|
||||||
const installed = this.parseAlphaVersion(installedVersion);
|
if (!installedVersion || installedVersion === 'unknown') {
|
||||||
const current = this.parseAlphaVersion(currentVersion);
|
return true; // Treat unknown as legacy for safety
|
||||||
|
|
||||||
// If we can't parse either version, don't warn
|
|
||||||
if (!installed || !current) {
|
|
||||||
return { isOldVersion: false, versionDiff: 0, shouldWarn: false };
|
|
||||||
}
|
}
|
||||||
|
// Check if version string contains -alpha or -Alpha (any v6 alpha)
|
||||||
// Calculate alpha version difference
|
return /-alpha\./i.test(installedVersion);
|
||||||
const versionDiff = current.alphaNumber - installed.alphaNumber;
|
|
||||||
|
|
||||||
// Consider it old if more than 2 versions behind
|
|
||||||
const isOldVersion = versionDiff > 2;
|
|
||||||
|
|
||||||
return {
|
|
||||||
isOldVersion,
|
|
||||||
versionDiff,
|
|
||||||
shouldWarn: isOldVersion,
|
|
||||||
installed: installed.fullVersion,
|
|
||||||
current: current.fullVersion,
|
|
||||||
installedAlpha: installed.alphaNumber,
|
|
||||||
currentAlpha: current.alphaNumber,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show warning for old alpha version and ask if user wants to proceed
|
* Show warning for legacy version (v4 or alpha) and ask if user wants to proceed
|
||||||
* @param {string} installedVersion - The installed version
|
* @param {string} installedVersion - The installed version
|
||||||
* @param {string} currentVersion - The current version
|
* @param {string} currentVersion - The current version
|
||||||
* @param {string} bmadFolderName - Name of the BMAD folder
|
* @param {string} bmadFolderName - Name of the BMAD folder
|
||||||
* @returns {Promise<boolean>} True if user wants to proceed, false if they cancel
|
* @returns {Promise<boolean>} True if user wants to proceed, false if they cancel
|
||||||
*/
|
*/
|
||||||
async showOldAlphaVersionWarning(installedVersion, currentVersion, bmadFolderName) {
|
async showLegacyVersionWarning(installedVersion, currentVersion, bmadFolderName) {
|
||||||
const versionInfo = this.checkAlphaVersionAge(installedVersion, currentVersion);
|
if (!this.isLegacyVersion(installedVersion)) {
|
||||||
|
return true; // Not legacy, proceed
|
||||||
// Also warn if version is unknown or can't be parsed (legacy/unsupported)
|
|
||||||
const isUnknownVersion = installedVersion === 'unknown' || !versionInfo.installed;
|
|
||||||
|
|
||||||
if (!versionInfo.shouldWarn && !isUnknownVersion) {
|
|
||||||
return true; // Not old, proceed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log(chalk.yellow.bold('⚠️ VERSION WARNING'));
|
console.log(chalk.yellow.bold('⚠️ VERSION WARNING'));
|
||||||
console.log(chalk.yellow('─'.repeat(80)));
|
console.log(chalk.yellow('─'.repeat(80)));
|
||||||
|
|
||||||
if (isUnknownVersion) {
|
if (installedVersion === 'unknown') {
|
||||||
console.log(chalk.yellow('Unable to detect your installed BMAD version.'));
|
console.log(chalk.yellow('Unable to detect your installed BMAD version.'));
|
||||||
console.log(chalk.yellow('This appears to be a legacy or unsupported installation.'));
|
console.log(chalk.yellow('This appears to be a legacy or unsupported installation.'));
|
||||||
console.log('');
|
|
||||||
console.log(chalk.dim('For stability, we only support updates from the previous 2 alpha versions.'));
|
|
||||||
console.log(chalk.dim('Legacy installations may have compatibility issues.'));
|
|
||||||
} else {
|
} else {
|
||||||
console.log(chalk.yellow(`You are updating from ${versionInfo.installed} to ${versionInfo.current}.`));
|
console.log(chalk.yellow(`You are updating from ${installedVersion} to ${currentVersion}.`));
|
||||||
console.log(chalk.yellow(`This is ${versionInfo.versionDiff} alpha versions behind.`));
|
console.log(chalk.yellow('You have a legacy version installed (v4 or alpha).'));
|
||||||
console.log('');
|
|
||||||
console.log(chalk.dim(`For stability, we only support updates from the previous 2 alpha versions`));
|
|
||||||
console.log(chalk.dim(`(Alpha.${versionInfo.currentAlpha - 2} through Alpha.${versionInfo.currentAlpha - 1}).`));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|||||||
Reference in New Issue
Block a user