From face4e43677509b1c7b4a957ff3f5fe76d08334e Mon Sep 17 00:00:00 2001 From: Brian Madison Date: Thu, 13 Nov 2025 18:58:50 -0600 Subject: [PATCH] resolved blocking issues when folder name is changed during install --- .../installers/lib/core/config-collector.js | 39 +++++++++++++++++++ tools/cli/installers/lib/core/installer.js | 28 +++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/tools/cli/installers/lib/core/config-collector.js b/tools/cli/installers/lib/core/config-collector.js index e468496c..cd3a8aef 100644 --- a/tools/cli/installers/lib/core/config-collector.js +++ b/tools/cli/installers/lib/core/config-collector.js @@ -48,6 +48,36 @@ class ConfigCollector { return path.join(projectDir, 'bmad'); } + /** + * Detect the existing BMAD folder name in a project + * @param {string} projectDir - Project directory + * @returns {Promise} Folder name (just the name, not full path) or null if not found + */ + async detectExistingBmadFolder(projectDir) { + // Check if project directory exists + if (!(await fs.pathExists(projectDir))) { + return null; + } + + // Look for ANY directory with _cfg/manifest.yaml + try { + const entries = await fs.readdir(projectDir, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isDirectory()) { + const manifestPath = path.join(projectDir, entry.name, '_cfg', 'manifest.yaml'); + if (await fs.pathExists(manifestPath)) { + // Found a V6+ installation, return just the folder name + return entry.name; + } + } + } + } catch { + // Ignore errors + } + + return null; + } + /** * Load existing config if it exists from module config files * @param {string} projectDir - Target project directory @@ -565,6 +595,15 @@ class ConfigCollector { } } + // Special handling for bmad_folder: detect existing folder name + if (moduleName === 'core' && key === 'bmad_folder' && !existingValue && this.currentProjectDir) { + // Try to detect the existing BMAD folder name + const detectedFolder = await this.detectExistingBmadFolder(this.currentProjectDir); + if (detectedFolder) { + existingValue = detectedFolder; + } + } + // Determine question type and default value let questionType = 'input'; let defaultValue = item.default; diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 25aab3b6..95a33bd2 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -562,7 +562,12 @@ class Installer { config.skipIde = toolSelection.skipIde; const ideConfigurations = toolSelection.configurations; - spinner.start('Continuing installation...'); + // Check if spinner is already running (e.g., from folder name change scenario) + if (spinner.isSpinning) { + spinner.text = 'Continuing installation...'; + } else { + spinner.start('Continuing installation...'); + } // Create bmad directory structure spinner.text = 'Creating directory structure...'; @@ -1753,8 +1758,19 @@ class Installer { lastModified: new Date().toISOString(), }; - // Now run the full installation with the collected configs - spinner.start('Updating BMAD installation...'); + // Check if bmad_folder has changed + const existingBmadFolderName = path.basename(bmadDir); + const newBmadFolderName = this.configCollector.collectedConfig.core?.bmad_folder || existingBmadFolderName; + + if (existingBmadFolderName === newBmadFolderName) { + // Normal quick update - start the spinner + spinner.start('Updating BMAD installation...'); + } else { + // Folder name has changed - stop spinner and let install() handle it + spinner.stop(); + console.log(chalk.yellow(`\n⚠️ Folder name will change: ${existingBmadFolderName} → ${newBmadFolderName}`)); + console.log(chalk.yellow('The installer will handle the folder migration.\n')); + } // Build the config object for the installer const installConfig = { @@ -1773,7 +1789,11 @@ class Installer { // Call the standard install method const result = await this.install(installConfig); - spinner.succeed('Quick update complete!'); + // Only succeed the spinner if it's still spinning + // (install method might have stopped it if folder name changed) + if (spinner.isSpinning) { + spinner.succeed('Quick update complete!'); + } return { success: true,