mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-29 16:14:59 +00:00
agent customzation almost working again
This commit is contained in:
@@ -32,7 +32,7 @@ class CustomModuleCache {
|
||||
|
||||
const content = await fs.readFile(this.manifestPath, 'utf8');
|
||||
const yaml = require('js-yaml');
|
||||
return yaml.load(content) || {};
|
||||
return yaml.parse(content) || {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,7 @@ class Detector {
|
||||
if (await fs.pathExists(coreConfigPath)) {
|
||||
try {
|
||||
const configContent = await fs.readFile(coreConfigPath, 'utf8');
|
||||
const config = yaml.load(configContent);
|
||||
const config = yaml.parse(configContent);
|
||||
if (!result.version && config.version) {
|
||||
result.version = config.version;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ class Detector {
|
||||
if (await fs.pathExists(moduleConfigPath)) {
|
||||
try {
|
||||
const configContent = await fs.readFile(moduleConfigPath, 'utf8');
|
||||
const config = yaml.load(configContent);
|
||||
const config = yaml.parse(configContent);
|
||||
moduleInfo.version = config.version || 'unknown';
|
||||
moduleInfo.name = config.name || moduleId;
|
||||
moduleInfo.description = config.description;
|
||||
@@ -106,7 +106,7 @@ class Detector {
|
||||
|
||||
try {
|
||||
const configContent = await fs.readFile(moduleConfigPath, 'utf8');
|
||||
const config = yaml.load(configContent);
|
||||
const config = yaml.parse(configContent);
|
||||
moduleInfo.version = config.version || 'unknown';
|
||||
moduleInfo.name = config.name || entry.name;
|
||||
moduleInfo.description = config.description;
|
||||
@@ -239,7 +239,7 @@ class Detector {
|
||||
try {
|
||||
const yaml = require('js-yaml');
|
||||
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
||||
const manifest = yaml.load(manifestContent);
|
||||
const manifest = yaml.parse(manifestContent);
|
||||
// V6+ manifest has installation.version
|
||||
return manifest && manifest.installation && manifest.installation.version;
|
||||
} catch {
|
||||
|
||||
@@ -1448,6 +1448,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
await fs.ensureDir(bmadDir);
|
||||
await fs.ensureDir(path.join(bmadDir, '_cfg'));
|
||||
await fs.ensureDir(path.join(bmadDir, '_cfg', 'agents'));
|
||||
await fs.ensureDir(path.join(bmadDir, '_cfg', 'custom'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1699,25 +1700,55 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
const sourcePath = getModulePath('core');
|
||||
const targetPath = path.join(bmadDir, 'core');
|
||||
|
||||
// Copy core files with filtering for localskip agents
|
||||
await this.copyDirectoryWithFiltering(sourcePath, targetPath);
|
||||
// Copy core files (skip .agent.yaml files like modules do)
|
||||
await this.copyCoreFiles(sourcePath, targetPath);
|
||||
|
||||
// Compile agents using the same compiler as modules
|
||||
const { ModuleManager } = require('../modules/manager');
|
||||
const moduleManager = new ModuleManager();
|
||||
await moduleManager.compileModuleAgents(sourcePath, targetPath, 'core', bmadDir);
|
||||
|
||||
// Process agent files to inject activation block
|
||||
await this.processAgentFiles(targetPath, 'core');
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy directory with filtering for localskip agents
|
||||
* @param {string} sourcePath - Source directory path
|
||||
* @param {string} targetPath - Target directory path
|
||||
* Copy core files (similar to copyModuleWithFiltering but for core)
|
||||
* @param {string} sourcePath - Source path
|
||||
* @param {string} targetPath - Target path
|
||||
*/
|
||||
async copyDirectoryWithFiltering(sourcePath, targetPath) {
|
||||
// Get all files in source directory
|
||||
async copyCoreFiles(sourcePath, targetPath) {
|
||||
// Get all files in source
|
||||
const files = await this.getFileList(sourcePath);
|
||||
|
||||
for (const file of files) {
|
||||
// Skip sub-modules directory - these are IDE-specific and handled separately
|
||||
if (file.startsWith('sub-modules/')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip sidecar directories - they are handled separately during agent compilation
|
||||
if (
|
||||
path
|
||||
.dirname(file)
|
||||
.split('/')
|
||||
.some((dir) => dir.toLowerCase().includes('sidecar'))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip _module-installer directory - it's only needed at install time
|
||||
if (file.startsWith('_module-installer/') || file === 'module.yaml') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip config.yaml templates - we'll generate clean ones with actual values
|
||||
if (file === 'config.yaml' || file.endsWith('/config.yaml')) {
|
||||
if (file === 'config.yaml' || file.endsWith('/config.yaml') || file === 'custom.yaml' || file.endsWith('/custom.yaml')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip .agent.yaml files - they will be compiled separately
|
||||
if (file.endsWith('.agent.yaml')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1725,7 +1756,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
const targetFile = path.join(targetPath, file);
|
||||
|
||||
// Check if this is an agent file
|
||||
if (file.includes('agents/') && file.endsWith('.md')) {
|
||||
if (file.startsWith('agents/') && file.endsWith('.md')) {
|
||||
// Read the file to check for localskip
|
||||
const content = await fs.readFile(sourceFile, 'utf8');
|
||||
|
||||
@@ -1737,8 +1768,14 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the file with placeholder replacement
|
||||
await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile, this.bmadFolderName || 'bmad');
|
||||
// Check if this is a workflow.yaml file
|
||||
if (file.endsWith('workflow.yaml')) {
|
||||
await fs.ensureDir(path.dirname(targetFile));
|
||||
await this.copyWorkflowYamlStripped(sourceFile, targetFile);
|
||||
} else {
|
||||
// Copy the file with placeholder replacement
|
||||
await this.copyFileWithPlaceholderReplacement(sourceFile, targetFile, this.bmadFolderName || 'bmad');
|
||||
}
|
||||
|
||||
// Track the installed file
|
||||
this.installedFiles.push(targetFile);
|
||||
@@ -1798,104 +1835,77 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
const agentFiles = await fs.readdir(agentsPath);
|
||||
|
||||
for (const agentFile of agentFiles) {
|
||||
// Handle YAML agents - build them to .md
|
||||
// Skip .agent.yaml files - they should already be compiled by compileModuleAgents
|
||||
if (agentFile.endsWith('.agent.yaml')) {
|
||||
const agentName = agentFile.replace('.agent.yaml', '');
|
||||
const yamlPath = path.join(agentsPath, agentFile);
|
||||
const mdPath = path.join(agentsPath, `${agentName}.md`);
|
||||
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create customize template if it doesn't exist
|
||||
if (!(await fs.pathExists(customizePath))) {
|
||||
const genericTemplatePath = getSourcePath('utility', 'agent-components', 'agent.customize.template.yaml');
|
||||
if (await fs.pathExists(genericTemplatePath)) {
|
||||
await this.copyFileWithPlaceholderReplacement(genericTemplatePath, customizePath, this.bmadFolderName || 'bmad');
|
||||
console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`));
|
||||
}
|
||||
// Only process .md files (already compiled from YAML)
|
||||
if (!agentFile.endsWith('.md')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const agentName = agentFile.replace('.md', '');
|
||||
const mdPath = path.join(agentsPath, agentFile);
|
||||
const customizePath = path.join(cfgAgentsDir, `${moduleName}-${agentName}.customize.yaml`);
|
||||
|
||||
// For .md files that are already compiled, we don't need to do much
|
||||
// Just ensure the customize template exists
|
||||
if (!(await fs.pathExists(customizePath))) {
|
||||
const genericTemplatePath = getSourcePath('utility', 'agent-components', 'agent.customize.template.yaml');
|
||||
if (await fs.pathExists(genericTemplatePath)) {
|
||||
await this.copyFileWithPlaceholderReplacement(genericTemplatePath, customizePath, this.bmadFolderName || 'bmad');
|
||||
console.log(chalk.dim(` Created customize: ${moduleName}-${agentName}.customize.yaml`));
|
||||
}
|
||||
}
|
||||
|
||||
// Build YAML + customize to .md
|
||||
const customizeExists = await fs.pathExists(customizePath);
|
||||
let xmlContent = await this.xmlHandler.buildFromYaml(yamlPath, customizeExists ? customizePath : null, {
|
||||
includeMetadata: true,
|
||||
});
|
||||
// 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
|
||||
}
|
||||
|
||||
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
||||
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
||||
// Copy sidecar files if agent has hasSidecar flag
|
||||
if (hasSidecar) {
|
||||
const { copyAgentSidecarFiles } = require('../../../lib/agent/installer');
|
||||
|
||||
// Replace _bmad with actual folder name
|
||||
xmlContent = xmlContent.replaceAll('_bmad', this.bmadFolderName || 'bmad');
|
||||
// Get agent sidecar folder from core config
|
||||
const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml');
|
||||
let agentSidecarFolder;
|
||||
|
||||
// Replace {agent_sidecar_folder} if configured
|
||||
const coreConfig = this.configCollector.collectedConfig.core || {};
|
||||
if (coreConfig.agent_sidecar_folder && xmlContent.includes('{agent_sidecar_folder}')) {
|
||||
xmlContent = xmlContent.replaceAll('{agent_sidecar_folder}', coreConfig.agent_sidecar_folder);
|
||||
}
|
||||
|
||||
// Process TTS injection points (pass targetPath for tracking)
|
||||
xmlContent = this.processTTSInjectionPoints(xmlContent, mdPath);
|
||||
|
||||
// Check if agent has sidecar and copy it
|
||||
let agentYamlContent = null;
|
||||
let hasSidecar = false;
|
||||
|
||||
try {
|
||||
agentYamlContent = await fs.readFile(yamlPath, 'utf8');
|
||||
if (await fs.pathExists(coreConfigPath)) {
|
||||
const yamlLib = require('yaml');
|
||||
const agentYaml = yamlLib.parse(agentYamlContent);
|
||||
hasSidecar = agentYaml?.agent?.metadata?.hasSidecar === true;
|
||||
} catch {
|
||||
// Continue without sidecar processing
|
||||
const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
|
||||
const coreConfig = yamlLib.parse(coreConfigContent);
|
||||
agentSidecarFolder = coreConfig.agent_sidecar_folder || agentSidecarFolder;
|
||||
}
|
||||
|
||||
// Write the built .md file to bmad/{module}/agents/ with POSIX-compliant final newline
|
||||
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
||||
await fs.writeFile(mdPath, content, 'utf8');
|
||||
this.installedFiles.push(mdPath);
|
||||
// Resolve path variables
|
||||
const resolvedSidecarFolder = agentSidecarFolder
|
||||
.replaceAll('{project-root}', projectDir)
|
||||
.replaceAll('_bmad', this.bmadFolderName || 'bmad');
|
||||
|
||||
// Copy sidecar files if agent has hasSidecar flag
|
||||
if (hasSidecar) {
|
||||
const { copyAgentSidecarFiles } = require('../../../lib/agent/installer');
|
||||
// Create sidecar directory for this agent
|
||||
const agentSidecarDir = path.join(resolvedSidecarFolder, agentName);
|
||||
await fs.ensureDir(agentSidecarDir);
|
||||
|
||||
// Get agent sidecar folder from core config
|
||||
const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml');
|
||||
let agentSidecarFolder;
|
||||
// Find and copy sidecar folder from source module
|
||||
const sourceModulePath = moduleName === 'core' ? getModulePath('core') : getSourcePath(`modules/${moduleName}`);
|
||||
const sourceAgentPath = path.join(sourceModulePath, 'agents');
|
||||
|
||||
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;
|
||||
}
|
||||
// Copy sidecar files (preserve existing, add new)
|
||||
const sidecarResult = copyAgentSidecarFiles(sourceAgentPath, agentSidecarDir, null);
|
||||
|
||||
// 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 = getSourcePath(`modules/${moduleName}`);
|
||||
const sourceAgentPath = path.join(sourceModulePath, 'agents');
|
||||
|
||||
// Copy sidecar files (preserve existing, add new)
|
||||
const sidecarResult = copyAgentSidecarFiles(sourceAgentPath, agentSidecarDir, yamlPath);
|
||||
|
||||
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)`));
|
||||
}
|
||||
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)`));
|
||||
}
|
||||
|
||||
// Remove the source YAML file - we can regenerate from installer source if needed
|
||||
await fs.remove(yamlPath);
|
||||
|
||||
console.log(chalk.dim(` Built agent: ${agentName}.md${hasSidecar ? ' (with sidecar)' : ''}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1940,7 +1950,7 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
if (customizeExists) {
|
||||
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
||||
const yaml = require('js-yaml');
|
||||
const customizeYaml = yaml.load(customizeContent);
|
||||
const customizeYaml = yaml.parse(customizeContent);
|
||||
|
||||
// Detect what fields are customized (similar to rebuildAgentFiles)
|
||||
if (customizeYaml) {
|
||||
@@ -2064,34 +2074,52 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
}
|
||||
}
|
||||
|
||||
// Build YAML + customize to .md
|
||||
let xmlContent = await this.xmlHandler.buildFromYaml(sourceYamlPath, customizeExists ? customizePath : null, {
|
||||
includeMetadata: true,
|
||||
// Read the YAML content
|
||||
const yamlContent = await fs.readFile(sourceYamlPath, 'utf8');
|
||||
|
||||
// Read customize content if exists
|
||||
let customizeData = {};
|
||||
if (customizeExists) {
|
||||
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
||||
const yaml = require('yaml');
|
||||
customizeData = yaml.parse(customizeContent);
|
||||
}
|
||||
|
||||
// Build agent answers from customize data
|
||||
const answers = {};
|
||||
if (customizeData.persona) {
|
||||
Object.assign(answers, customizeData.persona);
|
||||
}
|
||||
if (customizeData.agent?.metadata) {
|
||||
Object.assign(answers, { metadata: customizeData.agent.metadata });
|
||||
}
|
||||
if (customizeData.critical_actions) {
|
||||
answers.critical_actions = customizeData.critical_actions;
|
||||
}
|
||||
if (customizeData.memories) {
|
||||
answers.memories = customizeData.memories;
|
||||
}
|
||||
|
||||
// Get core config for agent_sidecar_folder
|
||||
const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml');
|
||||
let coreConfig = {};
|
||||
if (await fs.pathExists(coreConfigPath)) {
|
||||
const yaml = require('yaml');
|
||||
const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
|
||||
coreConfig = yaml.parse(coreConfigContent);
|
||||
}
|
||||
|
||||
// Compile using the same compiler as initial installation
|
||||
const { compileAgent } = require('../../../lib/agent/compiler');
|
||||
const { xml } = await compileAgent(yamlContent, answers, agentName, path.relative(bmadDir, targetMdPath), {
|
||||
config: coreConfig,
|
||||
});
|
||||
|
||||
// DO NOT replace {project-root} - LLMs understand this placeholder at runtime
|
||||
// const processedContent = xmlContent.replaceAll('{project-root}', projectDir);
|
||||
|
||||
// Replace {agent_sidecar_folder} if configured
|
||||
const coreConfigPath = path.join(bmadDir, 'bmb', 'config.yaml');
|
||||
let agentSidecarFolder = null;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (agentSidecarFolder && xmlContent.includes('{agent_sidecar_folder}')) {
|
||||
xmlContent = xmlContent.replaceAll('{agent_sidecar_folder}', agentSidecarFolder);
|
||||
}
|
||||
|
||||
// Process TTS injection points (pass targetPath for tracking)
|
||||
xmlContent = this.processTTSInjectionPoints(xmlContent, targetMdPath);
|
||||
// Replace _bmad with actual folder name if needed
|
||||
const finalXml = xml.replaceAll('_bmad', path.basename(bmadDir));
|
||||
|
||||
// Write the rebuilt .md file with POSIX-compliant final newline
|
||||
const content = xmlContent.endsWith('\n') ? xmlContent : xmlContent + '\n';
|
||||
const content = finalXml.endsWith('\n') ? finalXml : finalXml + '\n';
|
||||
await fs.writeFile(targetMdPath, content, 'utf8');
|
||||
|
||||
// Display result with customizations if any
|
||||
@@ -2119,8 +2147,18 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
throw new Error(`BMAD not installed at ${bmadDir}`);
|
||||
}
|
||||
|
||||
// Get installed modules from manifest
|
||||
const manifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
||||
let installedModules = [];
|
||||
let manifest = null;
|
||||
if (await fs.pathExists(manifestPath)) {
|
||||
const manifestContent = await fs.readFile(manifestPath, 'utf8');
|
||||
const yaml = require('js-yaml');
|
||||
manifest = yaml.load(manifestContent);
|
||||
installedModules = manifest.modules || [];
|
||||
}
|
||||
|
||||
// Check for custom modules with missing sources
|
||||
const manifest = await this.manifest.read(bmadDir);
|
||||
if (manifest && manifest.customModules && manifest.customModules.length > 0) {
|
||||
console.log(chalk.yellow('\nChecking custom module sources before compilation...'));
|
||||
|
||||
@@ -2130,7 +2168,6 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
}
|
||||
|
||||
const projectRoot = getProjectRoot();
|
||||
const installedModules = manifest.modules || [];
|
||||
await this.handleMissingCustomSources(customModuleSources, bmadDir, projectRoot, 'compile-agents', installedModules);
|
||||
}
|
||||
|
||||
@@ -2177,21 +2214,9 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
}
|
||||
}
|
||||
|
||||
// Skip full manifest regeneration during compileAgents to preserve custom agents
|
||||
// Custom agents are already added to manifests during individual installation
|
||||
// Only regenerate YAML manifest for IDE updates if needed
|
||||
const existingManifestPath = path.join(bmadDir, '_cfg', 'manifest.yaml');
|
||||
let existingIdes = [];
|
||||
if (await fs.pathExists(existingManifestPath)) {
|
||||
const manifestContent = await fs.readFile(existingManifestPath, 'utf8');
|
||||
const yaml = require('js-yaml');
|
||||
const manifest = yaml.load(manifestContent);
|
||||
existingIdes = manifest.ides || [];
|
||||
}
|
||||
|
||||
// Update IDE configurations using the existing IDE list from manifest
|
||||
if (existingIdes && existingIdes.length > 0) {
|
||||
for (const ide of existingIdes) {
|
||||
if (manifest && manifest.ides && manifest.ides.length > 0) {
|
||||
for (const ide of manifest.ides) {
|
||||
await this.ideManager.setup(ide, projectDir, bmadDir, {
|
||||
selectedModules: installedModules,
|
||||
skipModuleInstall: true, // Skip module installation, just update IDE files
|
||||
@@ -2770,8 +2795,11 @@ If AgentVibes party mode is enabled, immediately trigger TTS with agent's voice:
|
||||
const relativePath = path.relative(bmadDir, fullPath);
|
||||
const fileName = path.basename(fullPath);
|
||||
|
||||
// Skip _cfg directory - system files
|
||||
if (relativePath.startsWith('_cfg/') || relativePath.startsWith('_cfg\\')) {
|
||||
// Skip _cfg directory EXCEPT for agent customizations
|
||||
if (
|
||||
(relativePath.startsWith('_cfg/') || relativePath.startsWith('_cfg\\')) && // Allow .customize.yaml files in _cfg/agents/
|
||||
!(relativePath.includes('/agents/') && fileName.endsWith('.customize.yaml'))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,14 +142,14 @@ class ManifestGenerator {
|
||||
let workflow;
|
||||
if (entry.name === 'workflow.yaml') {
|
||||
// Parse YAML workflow
|
||||
workflow = yaml.load(content);
|
||||
workflow = yaml.parse(content);
|
||||
} else {
|
||||
// Parse MD workflow with YAML frontmatter
|
||||
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
||||
if (!frontmatterMatch) {
|
||||
continue; // Skip MD files without frontmatter
|
||||
}
|
||||
workflow = yaml.load(frontmatterMatch[1]);
|
||||
workflow = yaml.parse(frontmatterMatch[1]);
|
||||
}
|
||||
|
||||
// Skip template workflows (those with placeholder values)
|
||||
@@ -459,7 +459,7 @@ class ManifestGenerator {
|
||||
if (await fs.pathExists(manifestPath)) {
|
||||
try {
|
||||
const existingContent = await fs.readFile(manifestPath, 'utf8');
|
||||
const existingManifest = yaml.load(existingContent);
|
||||
const existingManifest = yaml.parse(existingContent);
|
||||
if (existingManifest && existingManifest.customModules) {
|
||||
existingCustomModules = existingManifest.customModules;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class CustomHandler {
|
||||
// Try to parse YAML with error handling
|
||||
let config;
|
||||
try {
|
||||
config = yaml.load(configContent);
|
||||
config = yaml.parse(configContent);
|
||||
} catch (parseError) {
|
||||
console.warn(chalk.yellow(`Warning: YAML parse error in ${configPath}:`, parseError.message));
|
||||
return null;
|
||||
|
||||
@@ -348,7 +348,7 @@ class BaseIdeSetup {
|
||||
try {
|
||||
const yaml = require('js-yaml');
|
||||
const content = await fs.readFile(fullPath, 'utf8');
|
||||
const workflowData = yaml.load(content);
|
||||
const workflowData = yaml.parse(content);
|
||||
|
||||
if (workflowData && workflowData.name) {
|
||||
workflows.push({
|
||||
@@ -456,7 +456,7 @@ class BaseIdeSetup {
|
||||
if (frontmatterMatch) {
|
||||
const yaml = require('js-yaml');
|
||||
try {
|
||||
const frontmatter = yaml.load(frontmatterMatch[1]);
|
||||
const frontmatter = yaml.parse(frontmatterMatch[1]);
|
||||
standalone = frontmatter.standalone === true;
|
||||
} catch {
|
||||
// Ignore YAML parse errors
|
||||
|
||||
@@ -50,7 +50,7 @@ class AntigravitySetup extends BaseIdeSetup {
|
||||
try {
|
||||
// Load injection configuration
|
||||
const configContent = await fs.readFile(injectionConfigPath, 'utf8');
|
||||
const injectionConfig = yaml.load(configContent);
|
||||
const injectionConfig = yaml.parse(configContent);
|
||||
|
||||
// Ask about subagents if they exist and we haven't asked yet
|
||||
if (injectionConfig.subagents && !config.subagentChoices) {
|
||||
|
||||
@@ -49,7 +49,7 @@ class ClaudeCodeSetup extends BaseIdeSetup {
|
||||
try {
|
||||
// Load injection configuration
|
||||
const configContent = await fs.readFile(injectionConfigPath, 'utf8');
|
||||
const injectionConfig = yaml.load(configContent);
|
||||
const injectionConfig = yaml.parse(configContent);
|
||||
|
||||
// Ask about subagents if they exist and we haven't asked yet
|
||||
if (injectionConfig.subagents && !config.subagentChoices) {
|
||||
|
||||
@@ -34,7 +34,7 @@ class GeminiSetup extends BaseIdeSetup {
|
||||
if (await fs.pathExists(coreConfigPath)) {
|
||||
try {
|
||||
const configContent = await fs.readFile(coreConfigPath, 'utf8');
|
||||
const config = yaml.load(configContent);
|
||||
const config = yaml.parse(configContent);
|
||||
|
||||
if (config.user_name) {
|
||||
configValues.user_name = config.user_name;
|
||||
|
||||
@@ -150,7 +150,7 @@ class KiroCliSetup extends BaseIdeSetup {
|
||||
*/
|
||||
async processAgentFile(agentFile, agentsDir, projectDir) {
|
||||
const yamlContent = await fs.readFile(agentFile, 'utf8');
|
||||
const agentData = yaml.load(yamlContent);
|
||||
const agentData = yaml.parse(yamlContent);
|
||||
|
||||
if (!this.validateBmadCompliance(agentData)) {
|
||||
return;
|
||||
|
||||
@@ -152,7 +152,7 @@ class OpenCodeSetup extends BaseIdeSetup {
|
||||
|
||||
let frontmatter = {};
|
||||
try {
|
||||
frontmatter = yaml.load(match[1]) || {};
|
||||
frontmatter = yaml.parse(match[1]) || {};
|
||||
} catch {
|
||||
frontmatter = {};
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ async function loadModuleInjectionConfig(handler, moduleName) {
|
||||
}
|
||||
|
||||
const configContent = await fs.readFile(configPath, 'utf8');
|
||||
const config = yaml.load(configContent) || {};
|
||||
const config = yaml.parse(configContent) || {};
|
||||
|
||||
return {
|
||||
config,
|
||||
|
||||
@@ -822,12 +822,27 @@ class ModuleManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for customizations
|
||||
// Check for customizations and build answers object
|
||||
let customizedFields = [];
|
||||
let answers = {};
|
||||
if (await fs.pathExists(customizePath)) {
|
||||
const customizeContent = await fs.readFile(customizePath, 'utf8');
|
||||
const customizeData = yaml.load(customizeContent);
|
||||
customizedFields = customizeData.customized_fields || [];
|
||||
|
||||
// Build answers object from customizations
|
||||
if (customizeData.persona) {
|
||||
Object.assign(answers, customizeData.persona);
|
||||
}
|
||||
if (customizeData.agent?.metadata) {
|
||||
Object.assign(answers, { metadata: customizeData.agent.metadata });
|
||||
}
|
||||
if (customizeData.critical_actions) {
|
||||
answers.critical_actions = customizeData.critical_actions;
|
||||
}
|
||||
if (customizeData.memories) {
|
||||
answers.memories = customizeData.memories;
|
||||
}
|
||||
}
|
||||
|
||||
// Load core config to get agent_sidecar_folder
|
||||
@@ -835,23 +850,22 @@ class ModuleManager {
|
||||
let coreConfig = {};
|
||||
|
||||
if (await fs.pathExists(coreConfigPath)) {
|
||||
const yamlLib = require('yaml');
|
||||
const yaml = require('yaml');
|
||||
const coreConfigContent = await fs.readFile(coreConfigPath, 'utf8');
|
||||
coreConfig = yamlLib.parse(coreConfigContent);
|
||||
coreConfig = yaml.load(coreConfigContent);
|
||||
}
|
||||
|
||||
// Check if agent has sidecar
|
||||
let hasSidecar = false;
|
||||
try {
|
||||
const yamlLib = require('yaml');
|
||||
const agentYaml = yamlLib.parse(yamlContent);
|
||||
const agentYaml = yaml.parse(yamlContent);
|
||||
hasSidecar = agentYaml?.agent?.metadata?.hasSidecar === true;
|
||||
} catch {
|
||||
// Continue without sidecar processing
|
||||
}
|
||||
|
||||
// Compile with customizations if any
|
||||
const { xml } = compileAgent(yamlContent, {}, agentName, relativePath, { config: this.coreConfig });
|
||||
const { xml } = await compileAgent(yamlContent, answers, agentName, relativePath, { config: coreConfig });
|
||||
|
||||
// Replace _bmad placeholder if needed
|
||||
if (xml.includes('_bmad') && this.bmadFolderName) {
|
||||
|
||||
Reference in New Issue
Block a user