96 lines
3.0 KiB
Plaintext
96 lines
3.0 KiB
Plaintext
diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js
|
|
index 6df7b66a..40daa81c 100644
|
|
--- a/tools/cli/installers/lib/core/installer.js
|
|
+++ b/tools/cli/installers/lib/core/installer.js
|
|
@@ -620,12 +620,88 @@ class Installer {
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
+ * Find BMAD installation by searching up the directory tree
|
|
+ * Searches for both modern (bmad/) and legacy (.bmad-core, .bmad-method, .bmm, .cis) installations
|
|
+ * Prefers modern installation if multiple found
|
|
+ * @param {string} startPath - Starting directory to search from
|
|
+ * @returns {string|null} Path to BMAD directory, or null if not found
|
|
+ */
|
|
+ async findInstallation(startPath) {
|
|
+ const resolvedPath = path.resolve(startPath);
|
|
+ const root = path.parse(resolvedPath).root;
|
|
+ let currentPath = resolvedPath;
|
|
+
|
|
+ // Legacy folder names to check
|
|
+ const legacyFolders = ['.bmad-core', '.bmad-method', '.bmm', '.cis'];
|
|
+
|
|
+ // Search up the directory tree
|
|
+ while (currentPath !== root) {
|
|
+ // First check for modern bmad/ folder
|
|
+ const modernPath = path.join(currentPath, 'bmad');
|
|
+ if (await fs.pathExists(modernPath)) {
|
|
+ // Verify it's a valid BMAD installation
|
|
+ const status = await this.detector.detect(modernPath);
|
|
+ if (status.installed || status.hasCore) {
|
|
+ return modernPath;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Then check for legacy folders
|
|
+ for (const legacyFolder of legacyFolders) {
|
|
+ const legacyPath = path.join(currentPath, legacyFolder);
|
|
+ if (await fs.pathExists(legacyPath)) {
|
|
+ // Verify it's a valid BMAD installation
|
|
+ const status = await this.detector.detect(legacyPath);
|
|
+ if (status.installed || status.hasCore) {
|
|
+ return legacyPath;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // Move up one directory
|
|
+ const parentPath = path.dirname(currentPath);
|
|
+ if (parentPath === currentPath) {
|
|
+ // Reached filesystem root
|
|
+ break;
|
|
+ }
|
|
+ currentPath = parentPath;
|
|
+ }
|
|
+
|
|
+ // Not found
|
|
+ return null;
|
|
+ }
|
|
+
|
|
/**
|
|
* Get installation status
|
|
+ * Searches directory tree if installation not found at specified location
|
|
*/
|
|
async getStatus(directory) {
|
|
- const bmadDir = path.join(path.resolve(directory), 'bmad');
|
|
- return await this.detector.detect(bmadDir);
|
|
+ const resolvedDir = path.resolve(directory);
|
|
+ let bmadDir = path.join(resolvedDir, 'bmad');
|
|
+
|
|
+ // First check the exact path
|
|
+ let status = await this.detector.detect(bmadDir);
|
|
+ if (status.installed || status.hasCore) {
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ // If not found at exact location, search the directory tree
|
|
+ const foundPath = await this.findInstallation(resolvedDir);
|
|
+ if (foundPath) {
|
|
+ return await this.detector.detect(foundPath);
|
|
+ }
|
|
+
|
|
+ // Not found anywhere - return not installed
|
|
+ return {
|
|
+ installed: false,
|
|
+ path: bmadDir,
|
|
+ version: null,
|
|
+ hasCore: false,
|
|
+ modules: [],
|
|
+ ides: [],
|
|
+ manifest: null,
|
|
+ };
|
|
}
|
|
|
|
/**
|