diff --git a/tools/cli/installers/lib/core/installer.js b/tools/cli/installers/lib/core/installer.js index 402b5f98..77a8bb35 100644 --- a/tools/cli/installers/lib/core/installer.js +++ b/tools/cli/installers/lib/core/installer.js @@ -1920,55 +1920,6 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice: console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`)); } } - - // Read the existing .md file to check for sidecar info - let hasSidecar = false; - try { - const content = await fs.readFile(mdPath, 'utf8'); - // Look for sidecar metadata in the frontmatter or content - hasSidecar = content.includes('hasSidecar') && content.includes('true'); - } catch { - // Continue without sidecar processing - } - - // Copy sidecar files if agent has hasSidecar flag - if (hasSidecar) { - const { copyAgentSidecarFiles } = require('../../../lib/agent/installer'); - - // Get agent sidecar folder from core config - const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml'); - let agentSidecarFolder; - - if (await fs.pathExists(coreConfigPath)) { - const yamlLib = require('yaml'); - const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8'); - const coreConfig = yamlLib.parse(coreConfigContent); - agentSidecarFolder = coreConfig.agent_sidecar_folder || agentSidecarFolder; - } - - // Resolve path variables - const resolvedSidecarFolder = agentSidecarFolder - .replaceAll('{project-root}', projectDir) - .replaceAll('_bmad', this.bmadFolderName || 'bmad'); - - // Create sidecar directory for this agent - const agentSidecarDir = path.join(resolvedSidecarFolder, agentName); - await fs.ensureDir(agentSidecarDir); - - // Find and copy sidecar folder from source module - const sourceModulePath = moduleName === 'core' ? getModulePath('core') : getSourcePath(`modules/${moduleName}`); - const sourceAgentPath = path.join(sourceModulePath, 'agents'); - - // Copy sidecar files (preserve existing, add new) - const sidecarResult = copyAgentSidecarFiles(sourceAgentPath, agentSidecarDir, null); - - if (sidecarResult.copied.length > 0) { - console.log(chalk.dim(` Copied ${sidecarResult.copied.length} new sidecar file(s) to: ${agentSidecarDir}`)); - } - if (sidecarResult.preserved.length > 0) { - console.log(chalk.dim(` Preserved ${sidecarResult.preserved.length} existing sidecar file(s)`)); - } - } } } diff --git a/tools/cli/installers/lib/custom/handler.js b/tools/cli/installers/lib/custom/handler.js index 1170a8c8..115c4a4c 100644 --- a/tools/cli/installers/lib/custom/handler.js +++ b/tools/cli/installers/lib/custom/handler.js @@ -318,7 +318,6 @@ class CustomHandler { const { getSourcePath } = require('../../../lib/project-root'); const genericTemplatePath = getSourcePath('utility', 'agent-components', 'agent.customize.template.yaml'); if (await fs.pathExists(genericTemplatePath)) { - // Copy with placeholder replacement let templateContent = await fs.readFile(genericTemplatePath, 'utf8'); await fs.writeFile(customizePath, templateContent, 'utf8'); console.log(chalk.dim(` Created customize: custom-${agentName}.customize.yaml`)); @@ -337,41 +336,6 @@ class CustomHandler { // Write the compiled MD file await fs.writeFile(targetMdPath, processedXml, 'utf8'); - // Check if agent has sidecar - let hasSidecar = false; - try { - const yamlLib = require('yaml'); - const agentYaml = yamlLib.parse(yamlContent); - hasSidecar = agentYaml?.agent?.metadata?.hasSidecar === true; - } catch { - // Continue without sidecar processing - } - - // Copy sidecar files if agent has hasSidecar flag - if (hasSidecar && config.agent_sidecar_folder) { - const { copyAgentSidecarFiles } = require('../../../lib/agent/installer'); - - // Resolve agent sidecar folder path - const projectDir = path.dirname(bmadDir); - const resolvedSidecarFolder = config.agent_sidecar_folder - .replaceAll('{project-root}', projectDir) - .replaceAll('_bmad', path.basename(bmadDir)); - - // Create sidecar directory for this agent - const agentSidecarDir = path.join(resolvedSidecarFolder, agentName); - await fs.ensureDir(agentSidecarDir); - - // Copy sidecar files - const sidecarResult = copyAgentSidecarFiles(path.dirname(agentFile), agentSidecarDir, agentFile); - - if (sidecarResult.copied.length > 0) { - console.log(chalk.dim(` Copied ${sidecarResult.copied.length} sidecar file(s) to: ${agentSidecarDir}`)); - } - if (sidecarResult.preserved.length > 0) { - console.log(chalk.dim(` Preserved ${sidecarResult.preserved.length} existing sidecar file(s)`)); - } - } - // Track the file if (fileTrackingCallback) { fileTrackingCallback(targetMdPath); diff --git a/tools/cli/installers/lib/modules/manager.js b/tools/cli/installers/lib/modules/manager.js index d54e2cf3..c6de496e 100644 --- a/tools/cli/installers/lib/modules/manager.js +++ b/tools/cli/installers/lib/modules/manager.js @@ -905,35 +905,6 @@ class ModuleManager { await fs.writeFile(targetMdPath, xml, 'utf8'); } - // Copy sidecar files if agent has hasSidecar flag - if (hasSidecar) { - const { copyAgentSidecarFiles } = require('../../../lib/agent/installer'); - - // Get agent sidecar folder from core config (should always be set) - const agentSidecarFolder = this.coreConfig?.agent_sidecar_folder; - - // Resolve path variables - const projectDir = path.dirname(bmadDir); - const resolvedSidecarFolder = agentSidecarFolder - .replaceAll('{project-root}', projectDir) - .replaceAll('_bmad', path.basename(bmadDir)); - - // Create sidecar directory for this agent - const agentSidecarDir = path.join(resolvedSidecarFolder, agentName); - await fs.ensureDir(agentSidecarDir); - - // Copy sidecar files (preserve existing, add new) - const sidecarResult = copyAgentSidecarFiles(path.dirname(sourceYamlPath), agentSidecarDir, sourceYamlPath); - const totalFiles = sidecarResult.copied.length + sidecarResult.preserved.length; - - if (sidecarResult.copied.length > 0) { - console.log(chalk.dim(` Copied ${sidecarResult.copied.length} new sidecar file(s) to: ${agentSidecarDir}`)); - } - if (sidecarResult.preserved.length > 0) { - console.log(chalk.dim(` Preserved ${sidecarResult.preserved.length} existing sidecar file(s)`)); - } - } - console.log( chalk.dim(` Compiled agent: ${agentName} -> ${path.relative(targetPath, targetMdPath)}${hasSidecar ? ' (with sidecar)' : ''}`), ); diff --git a/tools/cli/lib/agent/installer.js b/tools/cli/lib/agent/installer.js index 62b8311f..b55502ed 100644 --- a/tools/cli/lib/agent/installer.js +++ b/tools/cli/lib/agent/installer.js @@ -262,129 +262,11 @@ function installAgent(agentInfo, answers, targetPath, options = {}) { agentName: metadata.name || agentInfo.name, targetDir: agentTargetDir, compiledFile: compiledPath, - sidecarCopied: false, }; - // Handle sidecar files for agents with hasSidecar flag - if (agentInfo.hasSidecar === true && agentInfo.type === 'expert') { - // Get agent sidecar folder from config or use default - const agentSidecarFolder = options.config?.agent_sidecar_folder || '{project-root}/.myagent-data'; - - // Resolve path variables - const resolvedSidecarFolder = agentSidecarFolder - .replaceAll('{project-root}', options.projectRoot || process.cwd()) - .replaceAll('_bmad', options_bmadFolder || '_bmad'); - - // Create sidecar directory for this agent - const agentSidecarDir = path.join(resolvedSidecarFolder, agentFolderName); - if (!fs.existsSync(agentSidecarDir)) { - fs.mkdirSync(agentSidecarDir, { recursive: true }); - } - - // Find and copy sidecar folder - const sidecarFiles = copyAgentSidecarFiles(agentInfo.path, agentSidecarDir, agentInfo.yamlFile); - result.sidecarCopied = true; - result.sidecarFiles = sidecarFiles; - result.sidecarDir = agentSidecarDir; - } - return result; } -/** - * Recursively copy sidecar files (everything except the .agent.yaml) - * @param {string} sourceDir - Source agent directory - * @param {string} targetDir - Target agent directory - * @param {string} excludeYaml - The .agent.yaml file to exclude - * @returns {Array} List of copied files - */ -function copySidecarFiles(sourceDir, targetDir, excludeYaml) { - const copied = []; - - function copyDir(src, dest) { - if (!fs.existsSync(dest)) { - fs.mkdirSync(dest, { recursive: true }); - } - - const entries = fs.readdirSync(src, { withFileTypes: true }); - for (const entry of entries) { - const srcPath = path.join(src, entry.name); - const destPath = path.join(dest, entry.name); - - // Skip the source YAML file - if (srcPath === excludeYaml) { - continue; - } - - if (entry.isDirectory()) { - copyDir(srcPath, destPath); - } else { - fs.copyFileSync(srcPath, destPath); - copied.push(destPath); - } - } - } - - copyDir(sourceDir, targetDir); - return copied; -} - -/** - * Find and copy agent sidecar folders - * @param {string} sourceDir - Source agent directory - * @param {string} targetSidecarDir - Target sidecar directory for the agent - * @param {string} excludeYaml - The .agent.yaml file to exclude - * @returns {Array} List of copied files - */ -function copyAgentSidecarFiles(sourceDir, targetSidecarDir, excludeYaml) { - const copied = []; - const preserved = []; - - // Find folders with "sidecar" in the name - const entries = fs.readdirSync(sourceDir, { withFileTypes: true }); - - for (const entry of entries) { - if (entry.isDirectory() && entry.name.toLowerCase().includes('sidecar')) { - const sidecarSourcePath = path.join(sourceDir, entry.name); - - // Recursively sync the sidecar folder contents (preserve existing, add new) - function syncSidecarDir(src, dest) { - if (!fs.existsSync(dest)) { - fs.mkdirSync(dest, { recursive: true }); - } - - // Get all files in source - const sourceEntries = fs.readdirSync(src, { withFileTypes: true }); - - for (const sourceEntry of sourceEntries) { - const srcPath = path.join(src, sourceEntry.name); - const destPath = path.join(dest, sourceEntry.name); - - if (sourceEntry.isDirectory()) { - // Recursively sync subdirectories - syncSidecarDir(srcPath, destPath); - } else { - // Check if file already exists in destination - if (fs.existsSync(destPath)) { - // File exists - preserve it - preserved.push(destPath); - } else { - // File doesn't exist - copy it - fs.copyFileSync(srcPath, destPath); - copied.push(destPath); - } - } - } - } - - syncSidecarDir(sidecarSourcePath, targetSidecarDir); - } - } - - // Return info about what was preserved and what was copied - return { copied, preserved }; -} - /** * Update agent metadata ID to reflect installed location * @param {string} compiledContent - Compiled XML content @@ -820,8 +702,6 @@ module.exports = { loadAgentConfig, promptInstallQuestions, installAgent, - copySidecarFiles, - copyAgentSidecarFiles, updateAgentId, detectBmadProject, addToManifest,