const fs = require('fs').promises;
const path = require('path');
const yaml = require('js-yaml');
const { extractYamlFromAgent } = require('./yaml-utils');

class DependencyResolver {
  constructor(rootDir) {
    this.rootDir = rootDir;
    this.bmadCore = path.join(rootDir, 'bmad-core');
    this.common = path.join(rootDir, 'common');
    this.cache = new Map();
  }

  async resolveAgentDependencies(agentId) {
    const agentPath = path.join(this.bmadCore, 'agents', `${agentId}.md`);
    const agentContent = await fs.readFile(agentPath, 'utf8');

    // Extract YAML from markdown content with command cleaning
    const yamlContent = extractYamlFromAgent(agentContent, true);
    if (!yamlContent) {
      throw new Error(`No YAML configuration found in agent ${agentId}`);
    }

    const agentConfig = yaml.load(yamlContent);

    const dependencies = {
      agent: {
        id: agentId,
        path: agentPath,
        content: agentContent,
        config: agentConfig
      },
      resources: []
    };

    // Personas are now embedded in agent configs, no need to resolve separately

    // Resolve other dependencies
    const depTypes = ['tasks', 'templates', 'checklists', 'data', 'utils'];
    for (const depType of depTypes) {
      const deps = agentConfig.dependencies?.[depType] || [];
      for (const depId of deps) {
        const resource = await this.loadResource(depType, depId);
        if (resource) dependencies.resources.push(resource);
      }
    }

    return dependencies;
  }

  async resolveTeamDependencies(teamId) {
    const teamPath = path.join(this.bmadCore, 'agent-teams', `${teamId}.yaml`);
    const teamContent = await fs.readFile(teamPath, 'utf8');
    const teamConfig = yaml.load(teamContent);

    const dependencies = {
      team: {
        id: teamId,
        path: teamPath,
        content: teamContent,
        config: teamConfig
      },
      agents: [],
      resources: new Map() // Use Map to deduplicate resources
    };

    // Always add bmad-orchestrator agent first if it's a team
    const bmadAgent = await this.resolveAgentDependencies('bmad-orchestrator');
    dependencies.agents.push(bmadAgent.agent);
    bmadAgent.resources.forEach(res => {
      dependencies.resources.set(res.path, res);
    });

    // Resolve all agents in the team
    let agentsToResolve = teamConfig.agents || [];

    // Handle wildcard "*" - include all agents except bmad-master
    if (agentsToResolve.includes('*')) {
      const allAgents = await this.listAgents();
      // Remove wildcard and add all agents except those already in the list and bmad-master
      agentsToResolve = agentsToResolve.filter(a => a !== '*');
      for (const agent of allAgents) {
        if (!agentsToResolve.includes(agent) && agent !== 'bmad-master') {
          agentsToResolve.push(agent);
        }
      }
    }

    for (const agentId of agentsToResolve) {
      if (agentId === 'bmad-orchestrator' || agentId === 'bmad-master') continue; // Already added or excluded
      const agentDeps = await this.resolveAgentDependencies(agentId);
      dependencies.agents.push(agentDeps.agent);

      // Add resources with deduplication
      agentDeps.resources.forEach(res => {
        dependencies.resources.set(res.path, res);
      });
    }

    // Resolve workflows
    for (const workflowId of teamConfig.workflows || []) {
      const resource = await this.loadResource('workflows', workflowId);
      if (resource) dependencies.resources.set(resource.path, resource);
    }

    // Convert Map back to array
    dependencies.resources = Array.from(dependencies.resources.values());

    return dependencies;
  }

  async loadResource(type, id) {
    const cacheKey = `${type}#${id}`;
    if (this.cache.has(cacheKey)) {
      return this.cache.get(cacheKey);
    }

    try {
      let content = null;
      let filePath = null;

      // First try bmad-core
      try {
        filePath = path.join(this.bmadCore, type, id);
        content = await fs.readFile(filePath, 'utf8');
      } catch (e) {
        // If not found in bmad-core, try common folder
        try {
          filePath = path.join(this.common, type, id);
          content = await fs.readFile(filePath, 'utf8');
        } catch (e2) {
          // File not found in either location
        }
      }

      if (!content) {
        console.warn(`Resource not found: ${type}/${id}`);
        return null;
      }

      const resource = {
        type,
        id,
        path: filePath,
        content
      };

      this.cache.set(cacheKey, resource);
      return resource;
    } catch (error) {
      console.error(`Error loading resource ${type}/${id}:`, error.message);
      return null;
    }
  }

  async listAgents() {
    try {
      const files = await fs.readdir(path.join(this.bmadCore, 'agents'));
      return files
        .filter(f => f.endsWith('.md'))
        .map(f => f.replace('.md', ''));
    } catch (error) {
      return [];
    }
  }

  async listTeams() {
    try {
      const files = await fs.readdir(path.join(this.bmadCore, 'agent-teams'));
      return files
        .filter(f => f.endsWith('.yaml'))
        .map(f => f.replace('.yaml', ''));
    } catch (error) {
      return [];
    }
  }
}

module.exports = DependencyResolver;

#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

const args = process.argv.slice(2);
const bumpType = args[0] || 'minor'; // default to minor

if (!['major', 'minor', 'patch'].includes(bumpType)) {
  console.log('Usage: node bump-all-versions.js [major|minor|patch]');
  console.log('Default: minor');
  process.exit(1);
}

function bumpVersion(currentVersion, type) {
  const [major, minor, patch] = currentVersion.split('.').map(Number);

  switch (type) {
    case 'major':
      return `${major + 1}.0.0`;
    case 'minor':
      return `${major}.${minor + 1}.0`;
    case 'patch':
      return `${major}.${minor}.${patch + 1}`;
    default:
      return currentVersion;
  }
}

async function bumpAllVersions() {
  const updatedItems = [];

  // First, bump the core version (package.json)
  const packagePath = path.join(__dirname, '..', 'package.json');
  try {
    const packageContent = fs.readFileSync(packagePath, 'utf8');
    const packageJson = JSON.parse(packageContent);
    const oldCoreVersion = packageJson.version || '1.0.0';
    const newCoreVersion = bumpVersion(oldCoreVersion, bumpType);

    packageJson.version = newCoreVersion;

    fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n');

    updatedItems.push({ type: 'core', name: 'BMad Core', oldVersion: oldCoreVersion, newVersion: newCoreVersion });
    console.log(`✓ BMad Core (package.json): ${oldCoreVersion} → ${newCoreVersion}`);
  } catch (error) {
    console.error(`✗ Failed to update BMad Core: ${error.message}`);
  }

  // Then, bump all expansion packs
  const expansionPacksDir = path.join(__dirname, '..', 'expansion-packs');

  try {
    const entries = fs.readdirSync(expansionPacksDir, { withFileTypes: true });

    for (const entry of entries) {
      if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'README.md') {
        const packId = entry.name;
        const configPath = path.join(expansionPacksDir, packId, 'config.yaml');

        if (fs.existsSync(configPath)) {
          try {
            const configContent = fs.readFileSync(configPath, 'utf8');
            const config = yaml.load(configContent);
            const oldVersion = config.version || '1.0.0';
            const newVersion = bumpVersion(oldVersion, bumpType);

            config.version = newVersion;

            const updatedYaml = yaml.dump(config, { indent: 2 });
            fs.writeFileSync(configPath, updatedYaml);

            updatedItems.push({ type: 'expansion', name: packId, oldVersion, newVersion });
            console.log(`✓ ${packId}: ${oldVersion} → ${newVersion}`);

          } catch (error) {
            console.error(`✗ Failed to update ${packId}: ${error.message}`);
          }
        }
      }
    }

    if (updatedItems.length > 0) {
      const coreCount = updatedItems.filter(i => i.type === 'core').length;
      const expansionCount = updatedItems.filter(i => i.type === 'expansion').length;

      console.log(`\n✓ Successfully bumped ${updatedItems.length} item(s) with ${bumpType} version bump`);
      if (coreCount > 0) console.log(`  - ${coreCount} core`);
      if (expansionCount > 0) console.log(`  - ${expansionCount} expansion pack(s)`);

      console.log('\nNext steps:');
      console.log('1. Test the changes');
      console.log('2. Commit: git add -A && git commit -m "chore: bump all versions (' + bumpType + ')"');
    } else {
      console.log('No items found to update');
    }

  } catch (error) {
    console.error('Error reading expansion packs directory:', error.message);
    process.exit(1);
  }
}

bumpAllVersions();

#!/usr/bin/env node

// Load required modules
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

// Parse CLI arguments
const args = process.argv.slice(2);
const packId = args[0];
const bumpType = args[1] || 'minor';

// Validate arguments
if (!packId || args.length > 2) {
  console.log('Usage: node bump-expansion-version.js <expansion-pack-id> [major|minor|patch]');
  console.log('Default: minor');
  console.log('Example: node bump-expansion-version.js bmad-creator-tools patch');
  process.exit(1);
}

if (!['major', 'minor', 'patch'].includes(bumpType)) {
  console.error('Error: Bump type must be major, minor, or patch');
  process.exit(1);
}

// Version bump logic
function bumpVersion(currentVersion, type) {
  const [major, minor, patch] = currentVersion.split('.').map(Number);

  switch (type) {
    case 'major': return `${major + 1}.0.0`;
    case 'minor': return `${major}.${minor + 1}.0`;
    case 'patch': return `${major}.${minor}.${patch + 1}`;
    default: return currentVersion;
  }
}

// Main function to bump version
async function updateVersion() {
  const configPath = path.join(__dirname, '..', 'expansion-packs', packId, 'config.yaml');

  // Check if config exists
  if (!fs.existsSync(configPath)) {
    console.error(`Error: Expansion pack '${packId}' not found`);
    console.log('\nAvailable expansion packs:');

    const packsDir = path.join(__dirname, '..', 'expansion-packs');
    const entries = fs.readdirSync(packsDir, { withFileTypes: true });

    entries.forEach(entry => {
      if (entry.isDirectory() && !entry.name.startsWith('.')) {
        console.log(`  - ${entry.name}`);
      }
    });

    process.exit(1);
  }

  try {
    const configContent = fs.readFileSync(configPath, 'utf8');
    const config = yaml.load(configContent);

    const oldVersion = config.version || '1.0.0';
    const newVersion = bumpVersion(oldVersion, bumpType);

    config.version = newVersion;

    const updatedYaml = yaml.dump(config, { indent: 2 });
    fs.writeFileSync(configPath, updatedYaml);

    console.log(`✓ ${packId}: ${oldVersion} → ${newVersion}`);
    console.log(`\n✓ Successfully bumped ${packId} with ${bumpType} version bump`);
    console.log('\nNext steps:');
    console.log(`1. Test the changes`);
    console.log(`2. Commit: git add -A && git commit -m "chore: bump ${packId} version (${bumpType})"`);

  } catch (error) {
    console.error('Error updating version:', error.message);
    process.exit(1);
  }
}

updateVersion();

#!/usr/bin/env node

const { Command } = require('commander');
const WebBuilder = require('./builders/web-builder');
const V3ToV4Upgrader = require('./upgraders/v3-to-v4-upgrader');
const IdeSetup = require('./installer/lib/ide-setup');
const path = require('path');

const program = new Command();

program
  .name('bmad-build')
  .description('BMad-Method build tool for creating web bundles')
  .version('4.0.0');

program
  .command('build')
  .description('Build web bundles for agents and teams')
  .option('-a, --agents-only', 'Build only agent bundles')
  .option('-t, --teams-only', 'Build only team bundles')
  .option('-e, --expansions-only', 'Build only expansion pack bundles')
  .option('--no-expansions', 'Skip building expansion packs')
  .option('--no-clean', 'Skip cleaning output directories')
  .action(async (options) => {
    const builder = new WebBuilder({
      rootDir: process.cwd()
    });

    try {
      if (options.clean) {
        console.log('Cleaning output directories...');
        await builder.cleanOutputDirs();
      }

      if (options.expansionsOnly) {
        console.log('Building expansion pack bundles...');
        await builder.buildAllExpansionPacks({ clean: false });
      } else {
        if (!options.teamsOnly) {
          console.log('Building agent bundles...');
          await builder.buildAgents();
        }

        if (!options.agentsOnly) {
          console.log('Building team bundles...');
          await builder.buildTeams();
        }

        if (!options.noExpansions) {
          console.log('Building expansion pack bundles...');
          await builder.buildAllExpansionPacks({ clean: false });
        }
      }

      console.log('Build completed successfully!');
    } catch (error) {
      console.error('Build failed:', error.message);
      process.exit(1);
    }
  });

program
  .command('build:expansions')
  .description('Build web bundles for all expansion packs')
  .option('--expansion <name>', 'Build specific expansion pack only')
  .option('--no-clean', 'Skip cleaning output directories')
  .action(async (options) => {
    const builder = new WebBuilder({
      rootDir: process.cwd()
    });

    try {
      if (options.expansion) {
        console.log(`Building expansion pack: ${options.expansion}`);
        await builder.buildExpansionPack(options.expansion, { clean: options.clean });
      } else {
        console.log('Building all expansion packs...');
        await builder.buildAllExpansionPacks({ clean: options.clean });
      }

      console.log('Expansion pack build completed successfully!');
    } catch (error) {
      console.error('Expansion pack build failed:', error.message);
      process.exit(1);
    }
  });

program
  .command('list:agents')
  .description('List all available agents')
  .action(async () => {
    const builder = new WebBuilder({ rootDir: process.cwd() });
    const agents = await builder.resolver.listAgents();
    console.log('Available agents:');
    agents.forEach(agent => console.log(`  - ${agent}`));
  });

program
  .command('list:expansions')
  .description('List all available expansion packs')
  .action(async () => {
    const builder = new WebBuilder({ rootDir: process.cwd() });
    const expansions = await builder.listExpansionPacks();
    console.log('Available expansion packs:');
    expansions.forEach(expansion => console.log(`  - ${expansion}`));
  });

program
  .command('validate')
  .description('Validate agent and team configurations')
  .action(async () => {
    const builder = new WebBuilder({ rootDir: process.cwd() });
    try {
      // Validate by attempting to build all agents and teams
      const agents = await builder.resolver.listAgents();
      const teams = await builder.resolver.listTeams();

      console.log('Validating agents...');
      for (const agent of agents) {
        await builder.resolver.resolveAgentDependencies(agent);
        console.log(`  ✓ ${agent}`);
      }

      console.log('\nValidating teams...');
      for (const team of teams) {
        await builder.resolver.resolveTeamDependencies(team);
        console.log(`  ✓ ${team}`);
      }

      console.log('\nAll configurations are valid!');
    } catch (error) {
      console.error('Validation failed:', error.message);
      process.exit(1);
    }
  });

program
  .command('upgrade')
  .description('Upgrade a BMad-Method V3 project to V4')
  .option('-p, --project <path>', 'Path to V3 project (defaults to current directory)')
  .option('--dry-run', 'Show what would be changed without making changes')
  .option('--no-backup', 'Skip creating backup (not recommended)')
  .action(async (options) => {
    const upgrader = new V3ToV4Upgrader();
    await upgrader.upgrade({
      projectPath: options.project,
      dryRun: options.dryRun,
      backup: options.backup
    });
  });

program
  .command('flatten')
  .description('Flatten codebase to XML format')
  .option('-o, --output <path>', 'Output file path', 'flattened-codebase.xml')
  .action(async (options) => {
    const flattener = require('./flattener/main');
    await flattener.parseAsync(['flatten', '--output', options.output], { from: 'user' });
  });

program.parse();

#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

const args = process.argv.slice(2);

if (args.length < 2) {
  console.log('Usage: node update-expansion-version.js <expansion-pack-id> <new-version>');
  console.log('Example: node update-expansion-version.js bmad-creator-tools 1.1.0');
  process.exit(1);
}

const [packId, newVersion] = args;

// Validate version format
if (!/^\d+\.\d+\.\d+$/.test(newVersion)) {
  console.error('Error: Version must be in format X.Y.Z (e.g., 1.2.3)');
  process.exit(1);
}

async function updateVersion() {
  try {
    // Update in config.yaml
    const configPath = path.join(__dirname, '..', 'expansion-packs', packId, 'config.yaml');

    if (!fs.existsSync(configPath)) {
      console.error(`Error: Expansion pack '${packId}' not found`);
      process.exit(1);
    }

    const configContent = fs.readFileSync(configPath, 'utf8');
    const config = yaml.load(configContent);
    const oldVersion = config.version || 'unknown';

    config.version = newVersion;

    const updatedYaml = yaml.dump(config, { indent: 2 });
    fs.writeFileSync(configPath, updatedYaml);

    console.log(`✓ Updated ${packId}/config.yaml: ${oldVersion} → ${newVersion}`);
    console.log(`\n✓ Successfully updated ${packId} to version ${newVersion}`);
    console.log('\nNext steps:');
    console.log('1. Test the changes');
    console.log('2. Commit: git add -A && git commit -m "chore: bump ' + packId + ' to v' + newVersion + '"');

  } catch (error) {
    console.error('Error updating version:', error.message);
    process.exit(1);
  }
}

updateVersion();

#!/usr/bin/env node

/**
 * BMad Method CLI - Direct execution wrapper for npx
 * This file ensures proper execution when run via npx from GitHub
 */

const { execSync } = require('child_process');
const path = require('path');
const fs = require('fs');

// Check if we're running in an npx temporary directory
const isNpxExecution = __dirname.includes('_npx') || __dirname.includes('.npm');

// If running via npx, we need to handle things differently
if (isNpxExecution) {
  // The actual bmad.js is in installer/bin/ (relative to tools directory)
  const bmadScriptPath = path.join(__dirname, 'installer', 'bin', 'bmad.js');

  // Verify the file exists
  if (!fs.existsSync(bmadScriptPath)) {
    console.error('Error: Could not find bmad.js at', bmadScriptPath);
    console.error('Current directory:', __dirname);
    process.exit(1);
  }

  // Execute with proper working directory
  try {
    execSync(`node "${bmadScriptPath}" ${process.argv.slice(2).join(' ')}`, {
      stdio: 'inherit',
      cwd: path.dirname(__dirname)
    });
  } catch (error) {
    // execSync will throw if the command exits with non-zero
    // But the stdio is inherited, so the error is already displayed
    process.exit(error.status || 1);
  }
} else {
  // Local execution - just require the installer directly
  require('./installer/bin/bmad.js');
}

/**
 * Utility functions for YAML extraction from agent files
 */

/**
 * Extract YAML content from agent markdown files
 * @param {string} agentContent - The full content of the agent file
 * @param {boolean} cleanCommands - Whether to clean command descriptions (default: false)
 * @returns {string|null} - The extracted YAML content or null if not found
 */
function extractYamlFromAgent(agentContent, cleanCommands = false) {
  // Remove carriage returns and match YAML block
  const yamlMatch = agentContent.replace(/\r/g, "").match(/```ya?ml\n([\s\S]*?)\n```/);
  if (!yamlMatch) return null;

  let yamlContent = yamlMatch[1].trim();

  // Clean up command descriptions if requested
  // Converts "- command - description" to just "- command"
  if (cleanCommands) {
    yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
  }

  return yamlContent;
}

module.exports = {
  extractYamlFromAgent
};

/**
 * Semantic-release plugin to sync installer package.json version
 */

const fs = require('fs');
const path = require('path');

// This function runs during the "prepare" step of semantic-release
function prepare(_, { nextRelease, logger }) {
  // Define the path to the installer package.json file
  const file = path.join(process.cwd(), 'tools/installer/package.json');

  // If the file does not exist, skip syncing and log a message
  if (!fs.existsSync(file)) return logger.log('Installer package.json not found, skipping');

  // Read and parse the package.json file
  const pkg = JSON.parse(fs.readFileSync(file, 'utf8'));

  // Update the version field with the next release version
  pkg.version = nextRelease.version;

  // Write the updated JSON back to the file
  fs.writeFileSync(file, JSON.stringify(pkg, null, 2) + '\n');

  // Log success message
  logger.log(`Synced installer package.json to version ${nextRelease.version}`);
}

// Export the prepare function so semantic-release can use it
module.exports = { prepare };

This code segment functions to: Manage and retrieve system configuration data by loading settings from multiple YAML files, enumerating available components from designated directories, and resolving dependency relationships between system resources while handling error conditions gracefully.

```javascript
[TASK_BEGIN]
class ConfigLoader {
    constructor() {
        this.rootPath = path.join(__dirname, '..');
    }

    async load() {
        // Core configuration loading handled in individual methods
    }

    async getInstallationOptions() {
        const configPath = path.join(this.rootPath, 'config.yml');
        return yaml.load(await fs.readFile(configPath, 'utf8'));
    }

    async getAvailableAgents() {
        const agentsDir = path.join(this.rootPath, 'agents');
        return this._getYamlConfigs(agentsDir, '.agent.yml');
    }

    async getAvailableExpansionPacks() {
        const packsDir = path.join(this.rootPath, 'expansion-packs');
        return this._getYamlConfigs(packsDir, '.expansion.yml');
    }

    async getAgentDependencies(agentId) {
        const agentPath = this.getAgentPath(agentId);
        const yamlContent = await extractYamlFromAgent(agentPath);
        return yamlContent.dependencies || [];
    }

    async getIdeConfiguration(ide) {
        const config = await this.getInstallationOptions();
        return config.ide_configurations?.[ide] || {};
    }

    getBmadCorePath() {
        return path.join(this.rootPath, 'bmad-core');
    }

    getDistPath() {
        return path.join(this.rootPath, 'dist');
    }

    getAgentPath(agentId) {
        return path.join(this.rootPath, 'agents', agentId);
    }

    async getAvailableTeams() {
        const teamsDir = path.join(this.rootPath, 'teams');
        return this._getYamlConfigs(teamsDir, '.team.yml');
    }

    getTeamPath(teamId) {
        return path.join(this.rootPath, 'teams', teamId);
    }

    async getTeamDependencies(teamId) {
        const teamPath = this.getTeamPath(teamId);
        const configFile = path.join(teamPath, 'team.yml');
        const config = yaml.load(await fs.readFile(configFile, 'utf8'));
        return config.dependencies || [];
    }

    async _getYamlConfigs(dir, suffix) {
        if (!(await fs.pathExists(dir))) return [];

        const items = await fs.readdir(dir);
        return Promise.all(items.map(async item => {
            const itemPath = path.join(dir, item);
            if ((await fs.stat(itemPath)).isDirectory()) {
                const configFile = path.join(itemPath, `${item}${suffix}`);
                if (await fs.pathExists(configFile)) {
                    return yaml.load(await fs.readFile(configFile, 'utf8'));
                }
            }
            return null;
        })).then(results => results.filter(Boolean));
    }
}
[TASK_END]
```

class ConfigLoader {
    constructor() {
        this.rootPath = path.join(__dirname, '..');
    }
    async load() {
    }
    async getInstallationOptions() {
        const configPath = path.join(this.rootPath, 'config.yml');
        return yaml.load(await fs.readFile(configPath, 'utf8'));
    }
    async getAvailableAgents() {
        const agentsDir = path.join(this.rootPath, 'agents');
        return this._getYamlConfigs(agentsDir, '.agent.yml');
    }
    async getAvailableExpansionPacks() {
        const packsDir = path.join(this.rootPath, 'expansion-packs');
        return this._getYamlConfigs(packsDir, '.expansion.yml');
    }
    async getAgentDependencies(agentId) {
        const agentPath = this.getAgentPath(agentId);
        const yamlContent = await extractYamlFromAgent(agentPath);
        return yamlContent.dependencies || [];
    }
    async getIdeConfiguration(ide) {
        const config = await this.getInstallationOptions();
        return config.ide_configurations?.[ide] || {};
    }
    getBmadCorePath() {
        return path.join(this.rootPath, 'bmad-core');
    }
    getDistPath() {
        return path.join(this.rootPath, 'dist');
    }
    getAgentPath(agentId) {
        return path.join(this.rootPath, 'agents', agentId);
    }
    async getAvailableTeams() {
        const teamsDir = path.join(this.rootPath, 'teams');
        return this._getYamlConfigs(teamsDir, '.team.yml');
    }
    getTeamPath(teamId) {
        return path.join(this.rootPath, 'teams', teamId);
    }
    async getTeamDependencies(teamId) {
        const teamPath = this.getTeamPath(teamId);
        const configFile = path.join(teamPath, 'team.yml');
        const config = yaml.load(await fs.readFile(configFile, 'utf8'));
        return config.dependencies || [];
    }
    async _getYamlConfigs(dir, suffix) {
        if (!(await fs.pathExists(dir))) return [];
        const items = await fs.readdir(dir);
        return Promise.all(items.map(async item => {
            const itemPath = path.join(dir, item);
            if ((await fs.stat(itemPath)).isDirectory()) {
                const configFile = path.join(itemPath, `${item}${suffix}`);
                if (await fs.pathExists(configFile)) {
                    return yaml.load(await fs.readFile(configFile, 'utf8'));
                }
            }
            return null;
        })).then(results => results.filter(Boolean));
    }
}