quickinstall duplicate success message removed
This commit is contained in:
parent
34cfdddd3a
commit
da21790531
|
|
@ -835,8 +835,6 @@ class Installer {
|
||||||
allModules = allModules.filter((m) => m !== 'core');
|
allModules = allModules.filter((m) => m !== 'core');
|
||||||
}
|
}
|
||||||
|
|
||||||
const modulesToInstall = allModules;
|
|
||||||
|
|
||||||
// For dependency resolution, we only need regular modules (not custom modules)
|
// For dependency resolution, we only need regular modules (not custom modules)
|
||||||
// Custom modules are already installed in _bmad and don't need dependency resolution from source
|
// Custom modules are already installed in _bmad and don't need dependency resolution from source
|
||||||
const regularModulesForResolution = allModules.filter((module) => {
|
const regularModulesForResolution = allModules.filter((module) => {
|
||||||
|
|
@ -882,7 +880,6 @@ class Installer {
|
||||||
// Check if this is a custom module
|
// Check if this is a custom module
|
||||||
let isCustomModule = false;
|
let isCustomModule = false;
|
||||||
let customInfo = null;
|
let customInfo = null;
|
||||||
let useCache = false;
|
|
||||||
|
|
||||||
// First check if we have a cached version
|
// First check if we have a cached version
|
||||||
if (finalCustomContent && finalCustomContent.cachedModules) {
|
if (finalCustomContent && finalCustomContent.cachedModules) {
|
||||||
|
|
@ -1215,17 +1212,19 @@ class Installer {
|
||||||
console.log(chalk.dim('Remove these .bak files it no longer needed\n'));
|
console.log(chalk.dim('Remove these .bak files it no longer needed\n'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display completion message
|
// Display completion message (skip if requested, e.g., for quick updates)
|
||||||
const { UI } = require('../../../lib/ui');
|
if (!config._skipCompletion) {
|
||||||
const ui = new UI();
|
const { UI } = require('../../../lib/ui');
|
||||||
ui.showInstallSummary({
|
const ui = new UI();
|
||||||
path: bmadDir,
|
ui.showInstallSummary({
|
||||||
modules: config.modules,
|
path: bmadDir,
|
||||||
ides: config.ides,
|
modules: config.modules,
|
||||||
customFiles: customFiles.length > 0 ? customFiles : undefined,
|
ides: config.ides,
|
||||||
ttsInjectedFiles: this.enableAgentVibes && this.ttsInjectedFiles.length > 0 ? this.ttsInjectedFiles : undefined,
|
customFiles: customFiles.length > 0 ? customFiles : undefined,
|
||||||
agentVibesEnabled: this.enableAgentVibes || false,
|
ttsInjectedFiles: this.enableAgentVibes && this.ttsInjectedFiles.length > 0 ? this.ttsInjectedFiles : undefined,
|
||||||
});
|
agentVibesEnabled: this.enableAgentVibes || false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
|
|
@ -1505,9 +1504,7 @@ class Installer {
|
||||||
* @param {string} bmadDir - BMAD installation directory
|
* @param {string} bmadDir - BMAD installation directory
|
||||||
* @param {Object} coreFiles - Core files to install
|
* @param {Object} coreFiles - Core files to install
|
||||||
*/
|
*/
|
||||||
async installCoreWithDependencies(bmadDir, coreFiles) {
|
async installCoreWithDependencies(bmadDir) {
|
||||||
const sourcePath = getModulePath('core');
|
|
||||||
const targetPath = path.join(bmadDir, 'core');
|
|
||||||
await this.installCore(bmadDir);
|
await this.installCore(bmadDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1517,7 +1514,7 @@ class Installer {
|
||||||
* @param {string} bmadDir - BMAD installation directory
|
* @param {string} bmadDir - BMAD installation directory
|
||||||
* @param {Object} moduleFiles - Module files to install
|
* @param {Object} moduleFiles - Module files to install
|
||||||
*/
|
*/
|
||||||
async installModuleWithDependencies(moduleName, bmadDir, moduleFiles) {
|
async installModuleWithDependencies(moduleName, bmadDir) {
|
||||||
// Get module configuration for conditional installation
|
// Get module configuration for conditional installation
|
||||||
const moduleConfig = this.configCollector.collectedConfig[moduleName] || {};
|
const moduleConfig = this.configCollector.collectedConfig[moduleName] || {};
|
||||||
|
|
||||||
|
|
@ -1789,7 +1786,6 @@ class Installer {
|
||||||
}
|
}
|
||||||
|
|
||||||
const agentName = agentFile.replace('.md', '');
|
const agentName = agentFile.replace('.md', '');
|
||||||
const mdPath = path.join(agentsPath, agentFile);
|
|
||||||
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
||||||
|
|
||||||
// For .md files that are already compiled, we don't need to do much
|
// For .md files that are already compiled, we don't need to do much
|
||||||
|
|
@ -2003,8 +1999,9 @@ class Installer {
|
||||||
_existingModules: installedModules, // Pass all installed modules for manifest generation
|
_existingModules: installedModules, // Pass all installed modules for manifest generation
|
||||||
};
|
};
|
||||||
|
|
||||||
// Call the standard install method
|
// Call the standard install method, but skip UI completion for quick updates
|
||||||
const result = await this.install(installConfig);
|
installConfig._skipCompletion = true;
|
||||||
|
await this.install(installConfig);
|
||||||
|
|
||||||
// Only succeed the spinner if it's still spinning
|
// Only succeed the spinner if it's still spinning
|
||||||
// (install method might have stopped it if folder name changed)
|
// (install method might have stopped it if folder name changed)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
|
|
@ -88,9 +89,9 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
* @param {string} projectDir - Project directory
|
* @param {string} projectDir - Project directory
|
||||||
*/
|
*/
|
||||||
async cleanup(projectDir) {
|
async cleanup(projectDir) {
|
||||||
const bmadWorkflowsDir = path.join(projectDir, this.configDir, this.workflowsDir, 'bmad');
|
const bmadWorkflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir, 'bmad');
|
||||||
|
|
||||||
if (await fs.pathExists(bmadWorkflowsDir)) {
|
if (await this.exists(bmadWorkflowsDir)) {
|
||||||
await fs.remove(bmadWorkflowsDir);
|
await fs.remove(bmadWorkflowsDir);
|
||||||
console.log(chalk.dim(` Removed old BMAD workflows from ${this.name}`));
|
console.log(chalk.dim(` Removed old BMAD workflows from ${this.name}`));
|
||||||
}
|
}
|
||||||
|
|
@ -112,9 +113,9 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Create .agent/workflows directory structure
|
// Create .agent/workflows directory structure
|
||||||
const agentDir = path.join(projectDir, this.configDir);
|
const agentDir = PathUtils.getConfigDir(projectDir, this.configDir);
|
||||||
const workflowsDir = path.join(agentDir, this.workflowsDir);
|
const workflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir);
|
||||||
const bmadWorkflowsDir = path.join(workflowsDir, 'bmad');
|
const bmadWorkflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir, 'bmad');
|
||||||
|
|
||||||
await this.ensureDir(bmadWorkflowsDir);
|
await this.ensureDir(bmadWorkflowsDir);
|
||||||
|
|
||||||
|
|
@ -190,7 +191,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
* Read and process file content
|
* Read and process file content
|
||||||
*/
|
*/
|
||||||
async readAndProcess(filePath, metadata) {
|
async readAndProcess(filePath, metadata) {
|
||||||
const content = await fs.readFile(filePath, 'utf8');
|
const content = await this.readFile(filePath);
|
||||||
return this.processContent(content, metadata);
|
return this.processContent(content, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +211,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
|
|
||||||
// Add core agents
|
// Add core agents
|
||||||
const corePath = getModulePath('core');
|
const corePath = getModulePath('core');
|
||||||
if (await fs.pathExists(path.join(corePath, 'agents'))) {
|
if (await this.exists(path.join(corePath, 'agents'))) {
|
||||||
const coreAgents = await getAgentsFromDir(path.join(corePath, 'agents'), 'core');
|
const coreAgents = await getAgentsFromDir(path.join(corePath, 'agents'), 'core');
|
||||||
agents.push(...coreAgents);
|
agents.push(...coreAgents);
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +221,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
const modulePath = path.join(sourceDir, moduleName);
|
const modulePath = path.join(sourceDir, moduleName);
|
||||||
const agentsPath = path.join(modulePath, 'agents');
|
const agentsPath = path.join(modulePath, 'agents');
|
||||||
|
|
||||||
if (await fs.pathExists(agentsPath)) {
|
if (await this.exists(agentsPath)) {
|
||||||
const moduleAgents = await getAgentsFromDir(agentsPath, moduleName);
|
const moduleAgents = await getAgentsFromDir(agentsPath, moduleName);
|
||||||
agents.push(...moduleAgents);
|
agents.push(...moduleAgents);
|
||||||
}
|
}
|
||||||
|
|
@ -387,7 +388,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
const targetPath = path.join(projectDir, injection.file);
|
const targetPath = path.join(projectDir, injection.file);
|
||||||
|
|
||||||
if (await this.exists(targetPath)) {
|
if (await this.exists(targetPath)) {
|
||||||
let content = await fs.readFile(targetPath, 'utf8');
|
let content = await this.readFile(targetPath);
|
||||||
const marker = `<!-- IDE-INJECT-POINT: ${injection.point} -->`;
|
const marker = `<!-- IDE-INJECT-POINT: ${injection.point} -->`;
|
||||||
|
|
||||||
if (content.includes(marker)) {
|
if (content.includes(marker)) {
|
||||||
|
|
@ -399,7 +400,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
content = content.replace(marker, injectionContent);
|
content = content.replace(marker, injectionContent);
|
||||||
await fs.writeFile(targetPath, content);
|
await this.writeFile(targetPath, content);
|
||||||
console.log(chalk.dim(` Injected: ${injection.point} → ${injection.file}`));
|
console.log(chalk.dim(` Injected: ${injection.point} → ${injection.file}`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -417,7 +418,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
targetDir = path.join(os.homedir(), '.agent', 'agents');
|
targetDir = path.join(os.homedir(), '.agent', 'agents');
|
||||||
console.log(chalk.dim(` Installing subagents globally to: ~/.agent/agents/`));
|
console.log(chalk.dim(` Installing subagents globally to: ~/.agent/agents/`));
|
||||||
} else {
|
} else {
|
||||||
targetDir = path.join(projectDir, '.agent', 'agents');
|
targetDir = PathUtils.getIdeSubDir(projectDir, '.agent', 'agents');
|
||||||
console.log(chalk.dim(` Installing subagents to project: .agent/agents/`));
|
console.log(chalk.dim(` Installing subagents to project: .agent/agents/`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,11 +465,11 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||||
*/
|
*/
|
||||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
// Create .agent/workflows/bmad directory structure (same as regular agents)
|
// Create .agent/workflows/bmad directory structure (same as regular agents)
|
||||||
const agentDir = path.join(projectDir, this.configDir);
|
const agentDir = PathUtils.getConfigDir(projectDir, this.configDir);
|
||||||
const workflowsDir = path.join(agentDir, this.workflowsDir);
|
const workflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir);
|
||||||
const bmadWorkflowsDir = path.join(workflowsDir, 'bmad');
|
const bmadWorkflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir, 'bmad');
|
||||||
|
|
||||||
await fs.ensureDir(bmadWorkflowsDir);
|
await this.ensureDir(bmadWorkflowsDir);
|
||||||
|
|
||||||
// Create custom agent launcher with same pattern as regular agents
|
// Create custom agent launcher with same pattern as regular agents
|
||||||
const launcherContent = `name: '${agentName}'
|
const launcherContent = `name: '${agentName}'
|
||||||
|
|
@ -493,7 +494,7 @@ usage: |
|
||||||
const launcherPath = path.join(bmadWorkflowsDir, fileName);
|
const launcherPath = path.join(bmadWorkflowsDir, fileName);
|
||||||
|
|
||||||
// Write the launcher file
|
// Write the launcher file
|
||||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
await this.writeFile(launcherPath, launcherContent);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ide: 'antigravity',
|
ide: 'antigravity',
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
|
|
||||||
|
|
@ -25,7 +26,7 @@ class AuggieSetup extends BaseIdeSetup {
|
||||||
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
||||||
|
|
||||||
// Always use project directory
|
// Always use project directory
|
||||||
const location = path.join(projectDir, '.augment', 'commands');
|
const location = PathUtils.getIdeSubDir(projectDir, '.augment', 'commands');
|
||||||
|
|
||||||
// Clean up old BMAD installation first
|
// Clean up old BMAD installation first
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
@ -52,11 +53,11 @@ class AuggieSetup extends BaseIdeSetup {
|
||||||
content: artifact.content,
|
content: artifact.content,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const bmadCommandsDir = path.join(location, 'bmad');
|
const bmadCommandsDir = PathUtils.getIdeSubDir(location, 'bmad');
|
||||||
const agentsDir = path.join(bmadCommandsDir, 'agents');
|
const agentsDir = PathUtils.getIdeSubDir(bmadCommandsDir, 'agents');
|
||||||
const tasksDir = path.join(bmadCommandsDir, 'tasks');
|
const tasksDir = PathUtils.getIdeSubDir(bmadCommandsDir, 'tasks');
|
||||||
const toolsDir = path.join(bmadCommandsDir, 'tools');
|
const toolsDir = PathUtils.getIdeSubDir(bmadCommandsDir, 'tools');
|
||||||
const workflowsDir = path.join(bmadCommandsDir, 'workflows');
|
const workflowsDir = PathUtils.getIdeSubDir(bmadCommandsDir, 'workflows');
|
||||||
|
|
||||||
await this.ensureDir(agentsDir);
|
await this.ensureDir(agentsDir);
|
||||||
await this.ensureDir(tasksDir);
|
await this.ensureDir(tasksDir);
|
||||||
|
|
@ -179,10 +180,10 @@ BMAD ${workflow.module.toUpperCase()} module
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
|
||||||
// Only clean up project directory
|
// Only clean up project directory
|
||||||
const location = path.join(projectDir, '.augment', 'commands');
|
const location = PathUtils.getIdeSubDir(projectDir, '.augment', 'commands');
|
||||||
const bmadDir = path.join(location, 'bmad');
|
const bmadDir = path.join(location, 'bmad');
|
||||||
|
|
||||||
if (await fs.pathExists(bmadDir)) {
|
if (await this.exists(bmadDir)) {
|
||||||
await fs.remove(bmadDir);
|
await fs.remove(bmadDir);
|
||||||
console.log(chalk.dim(` Removed old BMAD commands`));
|
console.log(chalk.dim(` Removed old BMAD commands`));
|
||||||
}
|
}
|
||||||
|
|
@ -198,12 +199,12 @@ BMAD ${workflow.module.toUpperCase()} module
|
||||||
*/
|
*/
|
||||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
// Auggie uses .augment/commands directory
|
// Auggie uses .augment/commands directory
|
||||||
const location = path.join(projectDir, '.augment', 'commands');
|
const location = PathUtils.getIdeSubDir(projectDir, '.augment', 'commands');
|
||||||
const bmadCommandsDir = path.join(location, 'bmad');
|
const bmadCommandsDir = PathUtils.getIdeSubDir(location, 'bmad');
|
||||||
const agentsDir = path.join(bmadCommandsDir, 'agents');
|
const agentsDir = PathUtils.getIdeSubDir(bmadCommandsDir, 'agents');
|
||||||
|
|
||||||
// Create .augment/commands/bmad/agents directory if it doesn't exist
|
// Create .augment/commands/bmad/agents directory if it doesn't exist
|
||||||
await fs.ensureDir(agentsDir);
|
await this.ensureDir(agentsDir);
|
||||||
|
|
||||||
// Create custom agent launcher
|
// Create custom agent launcher
|
||||||
const launcherContent = `---
|
const launcherContent = `---
|
||||||
|
|
@ -230,7 +231,7 @@ BMAD Custom agent
|
||||||
const launcherPath = path.join(agentsDir, fileName);
|
const launcherPath = path.join(agentsDir, fileName);
|
||||||
|
|
||||||
// Write the launcher file
|
// Write the launcher file
|
||||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
await this.writeFile(launcherPath, launcherContent);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ide: 'auggie',
|
ide: 'auggie',
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../../../lib/project-root');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
|
|
@ -48,7 +49,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Load injection configuration
|
// Load injection configuration
|
||||||
const configContent = await fs.readFile(injectionConfigPath, 'utf8');
|
const configContent = await this.readFile(injectionConfigPath);
|
||||||
const injectionConfig = yaml.parse(configContent);
|
const injectionConfig = yaml.parse(configContent);
|
||||||
|
|
||||||
// Ask about subagents if they exist and we haven't asked yet
|
// Ask about subagents if they exist and we haven't asked yet
|
||||||
|
|
@ -87,9 +88,9 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
* @param {string} projectDir - Project directory
|
* @param {string} projectDir - Project directory
|
||||||
*/
|
*/
|
||||||
async cleanup(projectDir) {
|
async cleanup(projectDir) {
|
||||||
const bmadCommandsDir = path.join(projectDir, this.configDir, this.commandsDir, 'bmad');
|
const bmadCommandsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir, 'bmad');
|
||||||
|
|
||||||
if (await fs.pathExists(bmadCommandsDir)) {
|
if (await this.exists(bmadCommandsDir)) {
|
||||||
await fs.remove(bmadCommandsDir);
|
await fs.remove(bmadCommandsDir);
|
||||||
console.log(chalk.dim(` Removed old BMAD commands from ${this.name}`));
|
console.log(chalk.dim(` Removed old BMAD commands from ${this.name}`));
|
||||||
}
|
}
|
||||||
|
|
@ -111,9 +112,9 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
||||||
// Create .claude/commands directory structure
|
// Create .claude/commands directory structure
|
||||||
const claudeDir = path.join(projectDir, this.configDir);
|
const claudeDir = PathUtils.getConfigDir(projectDir, this.configDir);
|
||||||
const commandsDir = path.join(claudeDir, this.commandsDir);
|
const commandsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir);
|
||||||
const bmadCommandsDir = path.join(commandsDir, 'bmad');
|
const bmadCommandsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir, 'bmad');
|
||||||
|
|
||||||
await this.ensureDir(bmadCommandsDir);
|
await this.ensureDir(bmadCommandsDir);
|
||||||
|
|
||||||
|
|
@ -159,7 +160,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
let workflowCommandCount = 0;
|
let workflowCommandCount = 0;
|
||||||
for (const artifact of workflowArtifacts) {
|
for (const artifact of workflowArtifacts) {
|
||||||
if (artifact.type === 'workflow-command') {
|
if (artifact.type === 'workflow-command') {
|
||||||
const moduleWorkflowsDir = path.join(bmadCommandsDir, artifact.module, 'workflows');
|
const moduleWorkflowsDir = PathUtils.getIdeSubDir(bmadCommandsDir, artifact.module, 'workflows');
|
||||||
await this.ensureDir(moduleWorkflowsDir);
|
await this.ensureDir(moduleWorkflowsDir);
|
||||||
const commandPath = path.join(moduleWorkflowsDir, path.basename(artifact.relativePath));
|
const commandPath = path.join(moduleWorkflowsDir, path.basename(artifact.relativePath));
|
||||||
await this.writeFile(commandPath, artifact.content);
|
await this.writeFile(commandPath, artifact.content);
|
||||||
|
|
@ -198,7 +199,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
* Read and process file content
|
* Read and process file content
|
||||||
*/
|
*/
|
||||||
async readAndProcess(filePath, metadata) {
|
async readAndProcess(filePath, metadata) {
|
||||||
const content = await fs.readFile(filePath, 'utf8');
|
const content = await this.readFile(filePath);
|
||||||
return this.processContent(content, metadata);
|
return this.processContent(content, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,7 +219,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
|
|
||||||
// Add core agents
|
// Add core agents
|
||||||
const corePath = getModulePath('core');
|
const corePath = getModulePath('core');
|
||||||
if (await fs.pathExists(path.join(corePath, 'agents'))) {
|
if (await this.exists(path.join(corePath, 'agents'))) {
|
||||||
const coreAgents = await getAgentsFromDir(path.join(corePath, 'agents'), 'core');
|
const coreAgents = await getAgentsFromDir(path.join(corePath, 'agents'), 'core');
|
||||||
agents.push(...coreAgents);
|
agents.push(...coreAgents);
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +229,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
const modulePath = path.join(sourceDir, moduleName);
|
const modulePath = path.join(sourceDir, moduleName);
|
||||||
const agentsPath = path.join(modulePath, 'agents');
|
const agentsPath = path.join(modulePath, 'agents');
|
||||||
|
|
||||||
if (await fs.pathExists(agentsPath)) {
|
if (await this.exists(agentsPath)) {
|
||||||
const moduleAgents = await getAgentsFromDir(agentsPath, moduleName);
|
const moduleAgents = await getAgentsFromDir(agentsPath, moduleName);
|
||||||
agents.push(...moduleAgents);
|
agents.push(...moduleAgents);
|
||||||
}
|
}
|
||||||
|
|
@ -395,7 +396,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
const targetPath = path.join(projectDir, injection.file);
|
const targetPath = path.join(projectDir, injection.file);
|
||||||
|
|
||||||
if (await this.exists(targetPath)) {
|
if (await this.exists(targetPath)) {
|
||||||
let content = await fs.readFile(targetPath, 'utf8');
|
let content = await this.readFile(targetPath);
|
||||||
const marker = `<!-- IDE-INJECT-POINT: ${injection.point} -->`;
|
const marker = `<!-- IDE-INJECT-POINT: ${injection.point} -->`;
|
||||||
|
|
||||||
if (content.includes(marker)) {
|
if (content.includes(marker)) {
|
||||||
|
|
@ -407,7 +408,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
content = content.replace(marker, injectionContent);
|
content = content.replace(marker, injectionContent);
|
||||||
await fs.writeFile(targetPath, content);
|
await this.writeFile(targetPath, content);
|
||||||
console.log(chalk.dim(` Injected: ${injection.point} → ${injection.file}`));
|
console.log(chalk.dim(` Injected: ${injection.point} → ${injection.file}`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +426,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
targetDir = path.join(os.homedir(), '.claude', 'agents');
|
targetDir = path.join(os.homedir(), '.claude', 'agents');
|
||||||
console.log(chalk.dim(` Installing subagents globally to: ~/.claude/agents/`));
|
console.log(chalk.dim(` Installing subagents globally to: ~/.claude/agents/`));
|
||||||
} else {
|
} else {
|
||||||
targetDir = path.join(projectDir, '.claude', 'agents');
|
targetDir = PathUtils.getIdeSubDir(projectDir, '.claude', 'agents');
|
||||||
console.log(chalk.dim(` Installing subagents to project: .claude/agents/`));
|
console.log(chalk.dim(` Installing subagents to project: .claude/agents/`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,7 +472,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||||
* @returns {Object|null} Info about created command
|
* @returns {Object|null} Info about created command
|
||||||
*/
|
*/
|
||||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
const customAgentsDir = path.join(projectDir, this.configDir, this.commandsDir, 'bmad', 'custom', 'agents');
|
const customAgentsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir, 'bmad', 'custom', 'agents');
|
||||||
|
|
||||||
if (!(await this.exists(path.join(projectDir, this.configDir)))) {
|
if (!(await this.exists(path.join(projectDir, this.configDir)))) {
|
||||||
return null; // IDE not configured for this project
|
return null; // IDE not configured for this project
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||||
|
|
@ -26,9 +27,8 @@ class ClineSetup extends BaseIdeSetup {
|
||||||
async setup(projectDir, bmadDir, options = {}) {
|
async setup(projectDir, bmadDir, options = {}) {
|
||||||
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
||||||
|
|
||||||
// Create .clinerules/workflows directory
|
// Create .clinerules/workflows directory using shared utilities
|
||||||
const clineDir = path.join(projectDir, this.configDir);
|
const workflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir);
|
||||||
const workflowsDir = path.join(clineDir, this.workflowsDir);
|
|
||||||
|
|
||||||
await this.ensureDir(workflowsDir);
|
await this.ensureDir(workflowsDir);
|
||||||
|
|
||||||
|
|
@ -72,9 +72,9 @@ class ClineSetup extends BaseIdeSetup {
|
||||||
* Detect Cline installation by checking for .clinerules/workflows directory
|
* Detect Cline installation by checking for .clinerules/workflows directory
|
||||||
*/
|
*/
|
||||||
async detect(projectDir) {
|
async detect(projectDir) {
|
||||||
const workflowsDir = path.join(projectDir, this.configDir, this.workflowsDir);
|
const workflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir);
|
||||||
|
|
||||||
if (!(await fs.pathExists(workflowsDir))) {
|
if (!(await this.exists(workflowsDir))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,8 +159,8 @@ class ClineSetup extends BaseIdeSetup {
|
||||||
|
|
||||||
for (const artifact of artifacts) {
|
for (const artifact of artifacts) {
|
||||||
const flattenedName = this.flattenFilename(artifact.relativePath);
|
const flattenedName = this.flattenFilename(artifact.relativePath);
|
||||||
const targetPath = path.join(destDir, flattenedName);
|
const targetPath = PathUtils.joinSafe(destDir, flattenedName);
|
||||||
await fs.writeFile(targetPath, artifact.content);
|
await this.writeFile(targetPath, artifact.content);
|
||||||
written++;
|
written++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +204,7 @@ class ClineSetup extends BaseIdeSetup {
|
||||||
* Cleanup Cline configuration
|
* Cleanup Cline configuration
|
||||||
*/
|
*/
|
||||||
async cleanup(projectDir) {
|
async cleanup(projectDir) {
|
||||||
const workflowsDir = path.join(projectDir, this.configDir, this.workflowsDir);
|
const workflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir);
|
||||||
await this.clearOldBmadFiles(workflowsDir);
|
await this.clearOldBmadFiles(workflowsDir);
|
||||||
console.log(chalk.dim(`Removed ${this.name} BMAD configuration`));
|
console.log(chalk.dim(`Removed ${this.name} BMAD configuration`));
|
||||||
}
|
}
|
||||||
|
|
@ -218,11 +218,10 @@ class ClineSetup extends BaseIdeSetup {
|
||||||
* @returns {Object} Installation result
|
* @returns {Object} Installation result
|
||||||
*/
|
*/
|
||||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
const clineDir = path.join(projectDir, this.configDir);
|
const workflowsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.workflowsDir);
|
||||||
const workflowsDir = path.join(clineDir, this.workflowsDir);
|
|
||||||
|
|
||||||
// Create .clinerules/workflows directory if it doesn't exist
|
// Create .clinerules/workflows directory if it doesn't exist
|
||||||
await fs.ensureDir(workflowsDir);
|
await this.ensureDir(workflowsDir);
|
||||||
|
|
||||||
// Create custom agent launcher workflow
|
// Create custom agent launcher workflow
|
||||||
const launcherContent = `name: ${agentName}
|
const launcherContent = `name: ${agentName}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
||||||
const os = require('node:os');
|
const os = require('node:os');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { getTasksFromBmad } = require('./shared/bmad-artifacts');
|
const { getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||||
|
|
@ -130,7 +131,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||||
const projectSpecificDir = this.getCodexPromptDir(projectDir_local, 'project');
|
const projectSpecificDir = this.getCodexPromptDir(projectDir_local, 'project');
|
||||||
|
|
||||||
// Check global location
|
// Check global location
|
||||||
if (await fs.pathExists(globalDir)) {
|
if (await this.exists(globalDir)) {
|
||||||
const entries = await fs.readdir(globalDir);
|
const entries = await fs.readdir(globalDir);
|
||||||
if (entries.some((entry) => entry.startsWith('bmad-'))) {
|
if (entries.some((entry) => entry.startsWith('bmad-'))) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -138,7 +139,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check project-specific location
|
// Check project-specific location
|
||||||
if (await fs.pathExists(projectSpecificDir)) {
|
if (await this.exists(projectSpecificDir)) {
|
||||||
const entries = await fs.readdir(projectSpecificDir);
|
const entries = await fs.readdir(projectSpecificDir);
|
||||||
if (entries.some((entry) => entry.startsWith('bmad-'))) {
|
if (entries.some((entry) => entry.startsWith('bmad-'))) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -207,7 +208,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||||
|
|
||||||
getCodexPromptDir(projectDir = null, location = 'global') {
|
getCodexPromptDir(projectDir = null, location = 'global') {
|
||||||
if (location === 'project' && projectDir) {
|
if (location === 'project' && projectDir) {
|
||||||
return path.join(projectDir, '.codex', 'prompts');
|
return PathUtils.getIdeSubDir(projectDir, '.codex', 'prompts');
|
||||||
}
|
}
|
||||||
return path.join(os.homedir(), '.codex', 'prompts');
|
return path.join(os.homedir(), '.codex', 'prompts');
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +219,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||||
for (const artifact of artifacts) {
|
for (const artifact of artifacts) {
|
||||||
const flattenedName = this.flattenFilename(artifact.relativePath);
|
const flattenedName = this.flattenFilename(artifact.relativePath);
|
||||||
const targetPath = path.join(destDir, flattenedName);
|
const targetPath = path.join(destDir, flattenedName);
|
||||||
await fs.writeFile(targetPath, artifact.content);
|
await this.writeFile(targetPath, artifact.content);
|
||||||
written++;
|
written++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -226,7 +227,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
async clearOldBmadFiles(destDir) {
|
async clearOldBmadFiles(destDir) {
|
||||||
if (!(await fs.pathExists(destDir))) {
|
if (!(await this.exists(destDir))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,7 +249,7 @@ class CodexSetup extends BaseIdeSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
async readAndProcessWithProject(filePath, metadata, projectDir) {
|
async readAndProcessWithProject(filePath, metadata, projectDir) {
|
||||||
const content = await fs.readFile(filePath, 'utf8');
|
const content = await this.readFile(filePath);
|
||||||
return super.processContent(content, metadata, projectDir);
|
return super.processContent(content, metadata, projectDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,7 +377,7 @@ You must fully embody this agent's persona and follow all activation instruction
|
||||||
|
|
||||||
const fileName = `bmad-custom-agents-${agentName}.md`;
|
const fileName = `bmad-custom-agents-${agentName}.md`;
|
||||||
const launcherPath = path.join(destDir, fileName);
|
const launcherPath = path.join(destDir, fileName);
|
||||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
await this.writeFile(launcherPath, launcherContent);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
path: path.relative(projectDir, launcherPath),
|
path: path.relative(projectDir, launcherPath),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
|
|
||||||
|
|
@ -26,8 +27,8 @@ class CrushSetup extends BaseIdeSetup {
|
||||||
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
||||||
|
|
||||||
// Create .crush/commands/bmad directory structure
|
// Create .crush/commands/bmad directory structure
|
||||||
const crushDir = path.join(projectDir, this.configDir);
|
const crushDir = PathUtils.getConfigDir(projectDir, this.configDir);
|
||||||
const commandsDir = path.join(crushDir, this.commandsDir, 'bmad');
|
const commandsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir, 'bmad');
|
||||||
|
|
||||||
await this.ensureDir(commandsDir);
|
await this.ensureDir(commandsDir);
|
||||||
|
|
||||||
|
|
@ -242,9 +243,9 @@ Part of the BMAD ${workflow.module.toUpperCase()} module.
|
||||||
*/
|
*/
|
||||||
async cleanup(projectDir) {
|
async cleanup(projectDir) {
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const bmadCommandsDir = path.join(projectDir, this.configDir, this.commandsDir, 'bmad');
|
const bmadCommandsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir, 'bmad');
|
||||||
|
|
||||||
if (await fs.pathExists(bmadCommandsDir)) {
|
if (await this.exists(bmadCommandsDir)) {
|
||||||
await fs.remove(bmadCommandsDir);
|
await fs.remove(bmadCommandsDir);
|
||||||
console.log(chalk.dim(`Removed BMAD commands from Crush`));
|
console.log(chalk.dim(`Removed BMAD commands from Crush`));
|
||||||
}
|
}
|
||||||
|
|
@ -259,8 +260,8 @@ Part of the BMAD ${workflow.module.toUpperCase()} module.
|
||||||
* @returns {Object} Installation result
|
* @returns {Object} Installation result
|
||||||
*/
|
*/
|
||||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||||
const crushDir = path.join(projectDir, this.configDir);
|
const crushDir = PathUtils.getConfigDir(projectDir, this.configDir);
|
||||||
const bmadCommandsDir = path.join(crushDir, this.commandsDir, 'bmad');
|
const bmadCommandsDir = PathUtils.getIdeSubDir(projectDir, this.configDir, this.commandsDir, 'bmad');
|
||||||
|
|
||||||
// Create .crush/commands/bmad directory if it doesn't exist
|
// Create .crush/commands/bmad directory if it doesn't exist
|
||||||
await fs.ensureDir(bmadCommandsDir);
|
await fs.ensureDir(bmadCommandsDir);
|
||||||
|
|
@ -286,7 +287,7 @@ The agent will follow the persona and instructions from the main agent file.
|
||||||
const launcherPath = path.join(bmadCommandsDir, fileName);
|
const launcherPath = path.join(bmadCommandsDir, fileName);
|
||||||
|
|
||||||
// Write the launcher file
|
// Write the launcher file
|
||||||
await fs.writeFile(launcherPath, launcherContent, 'utf8');
|
await this.writeFile(launcherPath, launcherContent);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ide: 'crush',
|
ide: 'crush',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
||||||
const yaml = require('yaml');
|
const yaml = require('yaml');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const inquirer = require('inquirer');
|
const inquirer = require('inquirer');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const yaml = require('yaml');
|
const yaml = require('yaml');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kiro CLI setup handler for BMad Method
|
* Kiro CLI setup handler for BMad Method
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ const os = require('node:os');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const yaml = require('yaml');
|
const yaml = require('yaml');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
const { getAgentsFromBmad, getTasksFromBmad } = require('./shared/bmad-artifacts');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
|
const { FileOps, PathUtils } = require('../../../lib/file-ops');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -201,4 +201,64 @@ class FileOps {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { FileOps };
|
/**
|
||||||
|
* Path utilities for common IDE path patterns
|
||||||
|
*/
|
||||||
|
const PathUtils = {
|
||||||
|
/**
|
||||||
|
* Get IDE configuration directory path
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} configDir - IDE-specific config directory
|
||||||
|
* @returns {string} Full path to IDE config directory
|
||||||
|
*/
|
||||||
|
getConfigDir(projectDir, configDir) {
|
||||||
|
return path.join(projectDir, configDir);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get IDE subdirectory path (e.g., workflows, agents, commands)
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} configDir - IDE-specific config directory
|
||||||
|
* @param {string} subDir - Subdirectory name
|
||||||
|
* @param {...string} additionalDirs - Additional directory levels
|
||||||
|
* @returns {string} Full path to IDE subdirectory
|
||||||
|
*/
|
||||||
|
getIdeSubDir(projectDir, configDir, subDir, ...additionalDirs) {
|
||||||
|
const parts = [projectDir, configDir, subDir, ...additionalDirs].filter(Boolean);
|
||||||
|
return path.join(...parts);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get BMAD subdirectory path
|
||||||
|
* @param {string} projectDir - Project directory
|
||||||
|
* @param {string} bmadDir - BMAD installation directory
|
||||||
|
* @param {string} subDir - Subdirectory name
|
||||||
|
* @param {...string} additionalDirs - Additional directory levels
|
||||||
|
* @returns {string} Full path to BMAD subdirectory
|
||||||
|
*/
|
||||||
|
getBmadSubDir(projectDir, bmadDir, subDir, ...additionalDirs) {
|
||||||
|
const parts = [projectDir, bmadDir, subDir, ...additionalDirs].filter(Boolean);
|
||||||
|
return path.join(...parts);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path relative to a base directory
|
||||||
|
* @param {string} baseDir - Base directory
|
||||||
|
* @param {...string} pathParts - Path parts
|
||||||
|
* @returns {string} Full path
|
||||||
|
*/
|
||||||
|
relativeTo(baseDir, ...pathParts) {
|
||||||
|
return path.join(baseDir, ...pathParts.filter(Boolean));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join multiple path parts safely (filters out null/undefined/empty)
|
||||||
|
* @param {...string} pathParts - Path parts
|
||||||
|
* @returns {string} Joined path
|
||||||
|
*/
|
||||||
|
joinSafe(...pathParts) {
|
||||||
|
return path.join(...pathParts.filter(Boolean));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { FileOps, PathUtils };
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,6 @@ platforms:
|
||||||
category: ide
|
category: ide
|
||||||
description: "Enhanced Cline fork"
|
description: "Enhanced Cline fork"
|
||||||
|
|
||||||
rovo:
|
|
||||||
name: "Rovo Dev"
|
|
||||||
preferred: false
|
|
||||||
category: ide
|
|
||||||
description: "Atlassian's AI coding assistant"
|
|
||||||
|
|
||||||
github-copilot:
|
github-copilot:
|
||||||
name: "GitHub Copilot"
|
name: "GitHub Copilot"
|
||||||
preferred: false
|
preferred: false
|
||||||
|
|
@ -115,6 +109,18 @@ platforms:
|
||||||
category: ide
|
category: ide
|
||||||
description: "AI coding tool"
|
description: "AI coding tool"
|
||||||
|
|
||||||
|
kiro-cli:
|
||||||
|
name: "Kiro CLI"
|
||||||
|
preferred: false
|
||||||
|
category: cli
|
||||||
|
description: "Kiro command line interface"
|
||||||
|
|
||||||
|
rovo-dev:
|
||||||
|
name: "Rovo Dev"
|
||||||
|
preferred: false
|
||||||
|
category: ide
|
||||||
|
description: "Atlassian's AI coding assistant"
|
||||||
|
|
||||||
# Platform categories
|
# Platform categories
|
||||||
categories:
|
categories:
|
||||||
ide:
|
ide:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue