refactor(ide): delegate detection to handlers (#680)
This commit is contained in:
@@ -15,6 +15,8 @@ class BaseIdeSetup {
|
|||||||
this.preferred = preferred; // Whether this IDE should be shown in preferred list
|
this.preferred = preferred; // Whether this IDE should be shown in preferred list
|
||||||
this.configDir = null; // Override in subclasses
|
this.configDir = null; // Override in subclasses
|
||||||
this.rulesDir = null; // Override in subclasses
|
this.rulesDir = null; // Override in subclasses
|
||||||
|
this.configFile = null; // Override in subclasses when detection is file-based
|
||||||
|
this.detectionPaths = []; // Additional paths that indicate the IDE is configured
|
||||||
this.xmlHandler = new XmlHandler();
|
this.xmlHandler = new XmlHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +48,40 @@ class BaseIdeSetup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect whether this IDE already has configuration in the project
|
||||||
|
* Subclasses can override for custom logic
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
async detect(projectDir) {
|
||||||
|
const pathsToCheck = [];
|
||||||
|
|
||||||
|
if (this.configDir) {
|
||||||
|
pathsToCheck.push(path.join(projectDir, this.configDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.configFile) {
|
||||||
|
pathsToCheck.push(path.join(projectDir, this.configFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(this.detectionPaths)) {
|
||||||
|
for (const candidate of this.detectionPaths) {
|
||||||
|
if (!candidate) continue;
|
||||||
|
const resolved = path.isAbsolute(candidate) ? candidate : path.join(projectDir, candidate);
|
||||||
|
pathsToCheck.push(resolved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const candidate of pathsToCheck) {
|
||||||
|
if (await fs.pathExists(candidate)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get list of agents from BMAD installation
|
* Get list of agents from BMAD installation
|
||||||
* @param {string} bmadDir - BMAD installation directory
|
* @param {string} bmadDir - BMAD installation directory
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ class AuggieSetup extends BaseIdeSetup {
|
|||||||
{ name: 'User Home (~/.auggie/commands)', value: path.join(os.homedir(), '.auggie', 'commands') },
|
{ name: 'User Home (~/.auggie/commands)', value: path.join(os.homedir(), '.auggie', 'commands') },
|
||||||
{ name: 'Custom Location', value: 'custom' },
|
{ name: 'Custom Location', value: 'custom' },
|
||||||
];
|
];
|
||||||
|
this.detectionPaths = ['.auggie'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,6 +80,20 @@ class CodexSetup extends BaseIdeSetup {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect Codex installation by checking for BMAD prompt exports
|
||||||
|
*/
|
||||||
|
async detect(_projectDir) {
|
||||||
|
const destDir = this.getCodexPromptDir();
|
||||||
|
|
||||||
|
if (!(await fs.pathExists(destDir))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entries = await fs.readdir(destDir);
|
||||||
|
return entries.some((entry) => entry.startsWith('bmad-'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect Claude-style artifacts for Codex export.
|
* Collect Claude-style artifacts for Codex export.
|
||||||
* Returns the normalized artifact list for further processing.
|
* Returns the normalized artifact list for further processing.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const os = require('node:os');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IDE Manager - handles IDE-specific setup
|
* IDE Manager - handles IDE-specific setup
|
||||||
@@ -166,38 +165,9 @@ class IdeManager {
|
|||||||
async detectInstalledIdes(projectDir) {
|
async detectInstalledIdes(projectDir) {
|
||||||
const detected = [];
|
const detected = [];
|
||||||
|
|
||||||
// Check for IDE-specific directories
|
for (const [name, handler] of this.handlers) {
|
||||||
const ideChecks = {
|
if (typeof handler.detect === 'function' && (await handler.detect(projectDir))) {
|
||||||
cursor: '.cursor',
|
detected.push(name);
|
||||||
'claude-code': '.claude',
|
|
||||||
windsurf: '.windsurf',
|
|
||||||
cline: '.clinerules',
|
|
||||||
roo: '.roomodes',
|
|
||||||
trae: '.trae',
|
|
||||||
kilo: '.kilocodemodes',
|
|
||||||
gemini: '.gemini',
|
|
||||||
qwen: '.qwen',
|
|
||||||
crush: '.crush',
|
|
||||||
iflow: '.iflow',
|
|
||||||
auggie: '.auggie',
|
|
||||||
'github-copilot': '.github/chatmodes',
|
|
||||||
vscode: '.vscode',
|
|
||||||
idea: '.idea',
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const [ide, dir] of Object.entries(ideChecks)) {
|
|
||||||
const idePath = path.join(projectDir, dir);
|
|
||||||
if (await fs.pathExists(idePath)) {
|
|
||||||
detected.push(ide);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check Codex prompt directory for BMAD exports
|
|
||||||
const codexPromptDir = path.join(os.homedir(), '.codex', 'prompts');
|
|
||||||
if (await fs.pathExists(codexPromptDir)) {
|
|
||||||
const codexEntries = await fs.readdir(codexPromptDir);
|
|
||||||
if (codexEntries.some((file) => file.startsWith('bmad-'))) {
|
|
||||||
detected.push('codex');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user