or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

programmatic-api.mddocs/reference/

Programmatic API Reference

Node.js/JavaScript API for using bmad-method programmatically in your own scripts and applications.

Overview

The bmad-method package exports several modules that can be imported and used programmatically for:

  • Installing and configuring BMad Method
  • Building web bundles
  • Resolving agent/team dependencies
  • Upgrading V3 projects to V4
  • Version management

Installation Module

Main installation and management API exported from tools/installer/lib/installer.js.

const installer = require('bmad-method/tools/installer/lib/installer');

Install Method

Install BMad Method to a project directory.

/**
 * Install BMad Method with specified configuration
 * @param {InstallConfig} config - Installation configuration
 * @returns {Promise<void>}
 */
await installer.install(config);

interface InstallConfig {
  installType: 'full' | 'expansion-only';
  directory: string;              // Installation directory (absolute or relative)
  ides?: string[];                // IDE IDs to configure (optional)
  expansionPacks?: string[];      // Expansion pack IDs to install (optional)
  prdSharded?: boolean;           // Enable PRD sharding (default: true)
  architectureSharded?: boolean;  // Enable architecture sharding (default: true)
  includeWebBundles?: boolean;    // Include web bundles (default: false)
  webBundlesDirectory?: string;   // Web bundles directory (default: 'web-bundles')
}

Example:

const installer = require('bmad-method/tools/installer/lib/installer');

await installer.install({
  installType: 'full',
  directory: '/path/to/project',
  ides: ['claude-code', 'cursor'],
  expansionPacks: ['bmad-godot-game-dev'],
  prdSharded: true,
  architectureSharded: true,
  includeWebBundles: true,
  webBundlesDirectory: './web-bundles'
});

Update Method

Update an existing BMad installation.

/**
 * Update existing BMad installation
 * @returns {Promise<void>}
 */
await installer.update();

Example:

await installer.update();

Detect Installation State

Check the installation state of a directory.

/**
 * Detect installation state
 * @param {string} installDir - Directory to check
 * @returns {Promise<InstallationState>}
 */
await installer.detectInstallationState(dirPath);

interface InstallationState {
  type: 'clean' | 'v4_existing' | 'v3_existing' | 'unknown_existing';
  hasV4Manifest: boolean;
  hasV3Structure: boolean;
  hasBmadCore: boolean;
  hasOtherFiles: boolean;
  manifest: object | null;
  expansionPacks: Record<string, ExpansionPackInfo>;
}

Example:

const state = await installer.detectInstallationState('/path/to/project');
console.log('Installation type:', state.type);
if (state.manifest) {
  console.log('Installed version:', state.manifest.coreVersion);
}

List Expansion Packs

Display available expansion packs.

/**
 * List available expansion packs
 * @returns {Promise<void>} - Prints to console
 */
await installer.listExpansionPacks();

Get Available Expansion Packs

Get array of available expansion packs.

/**
 * Get available expansion packs
 * @returns {Promise<ExpansionPack[]>}
 */
await installer.getAvailableExpansionPacks();

interface ExpansionPack {
  id: string;
  name: string;
  version: string;
  description: string;
  author?: string;
}

Get Available Teams

Get array of available agent teams.

/**
 * Get available teams
 * @returns {Promise<string[]>}
 */
await installer.getAvailableTeams();

Show Status

Display installation status.

/**
 * Show installation status
 * @returns {Promise<void>} - Prints to console
 */
await installer.showStatus();

Get Core Version

Get the BMad core version.

/**
 * Get BMad core version
 * @returns {Promise<string>}
 */
await installer.getCoreVersion();

Flatten Codebase

Flatten a codebase to XML format for brownfield development.

/**
 * Flatten codebase to XML
 * @param {FlattenOptions} options - Flatten options
 * @returns {Promise<void>}
 */
await installer.flatten(options);

interface FlattenOptions {
  input?: string;   // Input directory (default: current directory)
  output?: string;  // Output file path (default: 'flattened-codebase.xml')
}

Example:

await installer.flatten({
  input: './src',
  output: 'src-flattened.xml'
});

Web Builder Module

Build web bundles for agents and teams. Exported from tools/builders/web-builder.js.

const WebBuilder = require('bmad-method/tools/builders/web-builder');

Constructor

/**
 * Create WebBuilder instance
 * @param {WebBuilderOptions} options
 */
const builder = new WebBuilder(options);

interface WebBuilderOptions {
  rootDir: string;  // Root directory (default: process.cwd())
}

Build Agents

Build web bundles for all agents.

/**
 * Build agent bundles
 * @returns {Promise<void>}
 */
await builder.buildAgents();

Example:

const WebBuilder = require('bmad-method/tools/builders/web-builder');
const builder = new WebBuilder({ rootDir: process.cwd() });

await builder.buildAgents();
// Output: dist/agents/*.txt

Build Teams

Build web bundles for all teams.

/**
 * Build team bundles
 * @returns {Promise<void>}
 */
await builder.buildTeams();

Build All Expansion Packs

Build web bundles for all expansion packs.

/**
 * Build all expansion pack bundles
 * @param {BuildOptions} options
 * @returns {Promise<void>}
 */
await builder.buildAllExpansionPacks(options);

interface BuildOptions {
  clean?: boolean;  // Clean output directory first (default: true)
}

Build Expansion Pack

Build web bundle for a specific expansion pack.

/**
 * Build specific expansion pack bundle
 * @param {string} packName - Expansion pack ID
 * @param {BuildOptions} options
 * @returns {Promise<void>}
 */
await builder.buildExpansionPack(packName, options);

Example:

await builder.buildExpansionPack('bmad-creative-writing', { clean: true });
// Output: dist/expansion-packs/bmad-creative-writing/*.txt

List Expansion Packs

List available expansion packs.

/**
 * List expansion packs
 * @returns {Promise<string[]>}
 */
const packs = await builder.listExpansionPacks();

Clean Output Directories

Clean output directories before building.

/**
 * Clean output directories
 * @returns {Promise<void>}
 */
await builder.cleanOutputDirs();

Dependency Resolver Module

Resolve agent and team dependencies. Exported from tools/lib/dependency-resolver.js.

const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');

Constructor

/**
 * Create DependencyResolver instance
 * @param {string} projectRoot - Project root directory
 */
const resolver = new DependencyResolver(projectRoot);

Resolve Agent Dependencies

Resolve all dependencies for an agent.

/**
 * Resolve agent dependencies
 * @param {string} agentId - Agent ID (e.g., 'dev', 'pm', 'qa')
 * @returns {Promise<ResolvedDependencies>}
 */
const deps = await resolver.resolveAgentDependencies(agentId);

interface ResolvedDependencies {
  tasks: string[];       // Task file paths
  templates: string[];   // Template file paths
  checklists: string[]; // Checklist file paths
  data: string[];       // Data file paths
  agents: string[];     // Referenced agent file paths
}

Example:

const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');
const resolver = new DependencyResolver('/path/to/project');

const devDeps = await resolver.resolveAgentDependencies('dev');
console.log('Dev agent tasks:', devDeps.tasks);
console.log('Dev agent templates:', devDeps.templates);

Resolve Team Dependencies

Resolve all dependencies for a team.

/**
 * Resolve team dependencies
 * @param {string} teamId - Team ID (e.g., 'team-fullstack')
 * @returns {Promise<TeamDependencies>}
 */
const teamDeps = await resolver.resolveTeamDependencies(teamId);

interface TeamDependencies {
  agents: string[];      // Agent IDs in team
  workflows: string[];   // Workflow file paths
  allDeps: ResolvedDependencies;  // Combined dependencies from all agents
}

List Agents

List all available agents.

/**
 * List all agents
 * @returns {Promise<string[]>} - Agent IDs
 */
const agents = await resolver.listAgents();

Example:

const agents = await resolver.listAgents();
// Returns: ['bmad-orchestrator', 'analyst', 'pm', 'architect', 'dev', 'qa', 'sm', 'po', 'ux-expert']

List Teams

List all available teams.

/**
 * List all teams
 * @returns {Promise<string[]>} - Team IDs
 */
const teams = await resolver.listTeams();

Example:

const teams = await resolver.listTeams();
// Returns: ['team-fullstack', 'team-ide-minimal', 'team-no-ui', 'team-all']

V3 to V4 Upgrader Module

Upgrade V3 projects to V4 format. Exported from tools/upgraders/v3-to-v4-upgrader.js.

const V3ToV4Upgrader = require('bmad-method/tools/upgraders/v3-to-v4-upgrader');

Constructor

/**
 * Create V3ToV4Upgrader instance
 */
const upgrader = new V3ToV4Upgrader();

Upgrade Project

Upgrade a V3 project to V4.

/**
 * Upgrade V3 project to V4
 * @param {UpgradeOptions} options
 * @returns {Promise<void>}
 */
await upgrader.upgrade(options);

interface UpgradeOptions {
  projectPath?: string;  // Path to V3 project (default: current directory)
  dryRun?: boolean;      // Preview changes without applying (default: false)
  backup?: boolean;      // Create backup before upgrade (default: true)
}

Example:

const V3ToV4Upgrader = require('bmad-method/tools/upgraders/v3-to-v4-upgrader');
const upgrader = new V3ToV4Upgrader();

// Preview upgrade
await upgrader.upgrade({
  projectPath: '/path/to/v3/project',
  dryRun: true
});

// Apply upgrade
await upgrader.upgrade({
  projectPath: '/path/to/v3/project',
  dryRun: false,
  backup: true
});

Version Management Module

Manage package versions. Exported from tools/version-bump.js.

const { bumpVersion, getCurrentVersion } = require('bmad-method/tools/version-bump');

Get Current Version

Get current package version.

/**
 * Get current version
 * @returns {Promise<string>}
 */
const version = await getCurrentVersion();

Bump Version

Bump package version.

/**
 * Bump package version
 * @param {string} type - Version bump type ('major' | 'minor' | 'patch')
 * @returns {Promise<string>} - New version
 */
const newVersion = await bumpVersion(type);

Example:

const { bumpVersion, getCurrentVersion } = require('bmad-method/tools/version-bump');

const currentVersion = await getCurrentVersion();
console.log('Current version:', currentVersion);  // 4.44.3

const newVersion = await bumpVersion('patch');
console.log('New version:', newVersion);  // 4.44.4

YAML Utilities Module

Parse YAML from agent definition files. Exported from tools/lib/yaml-utils.js.

const { extractYamlFromAgent } = require('bmad-method/tools/lib/yaml-utils');

Extract YAML from Agent

Extract YAML configuration from agent markdown file.

/**
 * Extract YAML from agent file
 * @param {string} filePath - Path to agent .md file
 * @returns {Promise<AgentConfig>}
 */
const config = await extractYamlFromAgent(filePath);

interface AgentConfig {
  agent: {
    id: string;
    name: string;
    title: string;
    icon: string;
    whenToUse: string;
  };
  persona: {
    role: string;
    style: string;
    identity: string;
    focus: string;
  };
  commands: Array<Record<string, string>>;
  dependencies?: {
    tasks?: string[];
    templates?: string[];
    checklists?: string[];
    data?: string[];
    agents?: string[];
  };
  'activation-instructions'?: string[];
}

Example:

const { extractYamlFromAgent } = require('bmad-method/tools/lib/yaml-utils');

const config = await extractYamlFromAgent('.bmad-core/agents/dev.md');
console.log('Agent ID:', config.agent.id);
console.log('Agent name:', config.agent.name);
console.log('Commands:', config.commands);
console.log('Dependencies:', config.dependencies);

Complete Integration Example

const installer = require('bmad-method/tools/installer/lib/installer');
const WebBuilder = require('bmad-method/tools/builders/web-builder');
const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');

async function setupBmadProject() {
  // 1. Install BMad to a project
  await installer.install({
    installType: 'full',
    directory: './my-project',
    ides: ['claude-code', 'cursor'],
    expansionPacks: ['bmad-godot-game-dev'],
    prdSharded: true,
    architectureSharded: true
  });

  // 2. Check installation status
  const state = await installer.detectInstallationState('./my-project');
  console.log('Installation state:', state.type);

  // 3. List available agents
  const resolver = new DependencyResolver('./my-project');
  const agents = await resolver.listAgents();
  console.log('Available agents:', agents);

  // 4. Resolve dependencies for dev agent
  const devDeps = await resolver.resolveAgentDependencies('dev');
  console.log('Dev agent dependencies:', devDeps);

  // 5. Build web bundles
  const builder = new WebBuilder({ rootDir: './my-project' });
  await builder.buildAgents();
  await builder.buildTeams();
  console.log('Web bundles built successfully');
}

setupBmadProject().catch(console.error);

Error Handling

All asynchronous methods throw errors that should be caught and handled.

Error Types

interface BMadError extends Error {
  code: string;
  message: string;
  details?: string;
}

// Common error codes
type ErrorCode =
  | 'EACCES'        // Permission denied
  | 'ENOENT'        // File/directory not found
  | 'EEXIST'        // File/directory already exists
  | 'INVALID_CONFIG'  // Invalid configuration
  | 'INVALID_IDE'    // Unknown IDE
  | 'INVALID_PACK'   // Unknown expansion pack
  | 'BUILD_FAILED'   // Build process failed
  | 'RESOLVE_FAILED' // Dependency resolution failed
  | 'UPGRADE_FAILED' // Upgrade process failed
  | 'VERSION_ERROR'  // Version management error
  | 'YAML_PARSE_ERROR'; // YAML parsing failed

Error Handling Example

try {
  await installer.install(config);
} catch (error) {
  console.error('Installation failed:', error.message);

  // Handle specific error cases
  switch (error.code) {
    case 'EACCES':
      console.error('Permission denied. Try a different directory or use sudo.');
      break;

    case 'ENOENT':
      console.error('Directory not found. Check the path:', config.directory);
      break;

    case 'EEXIST':
      console.error('Installation already exists. Use update command instead.');
      break;

    case 'INVALID_CONFIG':
      console.error('Invalid configuration:', error.details);
      break;

    case 'INVALID_IDE':
      console.error('Unknown IDE. Valid options:', ['cursor', 'claude-code', 'windsurf']);
      break;

    case 'INVALID_PACK':
      console.error('Unknown expansion pack. Use list:expansions to see available packs.');
      const packs = await installer.getAvailableExpansionPacks();
      console.log('Available:', packs.map(p => p.id));
      break;

    default:
      console.error('Unexpected error:', error);
  }
}

Error Handling for Builds

const WebBuilder = require('bmad-method/tools/builders/web-builder');
const builder = new WebBuilder({ rootDir: process.cwd() });

try {
  await builder.buildAgents();
} catch (error) {
  if (error.code === 'BUILD_FAILED') {
    console.error('Build failed:', error.details);
    console.error('Check that bmad-core is properly installed');
  } else {
    console.error('Unexpected build error:', error);
  }
}

Error Handling for Dependencies

const DependencyResolver = require('bmad-method/tools/lib/dependency-resolver');
const resolver = new DependencyResolver('/path/to/project');

try {
  const deps = await resolver.resolveAgentDependencies('invalid-agent');
} catch (error) {
  if (error.code === 'ENOENT') {
    console.error('Agent not found. Available agents:');
    const agents = await resolver.listAgents();
    console.log(agents.join(', '));
  } else if (error.code === 'RESOLVE_FAILED') {
    console.error('Failed to resolve dependencies:', error.details);
  }
}

TypeScript Support

While bmad-method is written in JavaScript, you can use it in TypeScript projects by creating type declaration files based on the interfaces documented above, or by using @ts-check comments with JSDoc annotations.

Best Practices

interface ProgrammaticAPIBestPractices {
  installation: {
    validateDirectory: 'Always check directory exists before installing';
    handleErrors: 'Wrap all async calls in try-catch';
    checkState: 'Use detectInstallationState before operations';
  };

  building: {
    cleanFirst: 'Clean output directories before building';
    sequential: 'Build agents, then teams, then expansion packs';
    verify: 'Check output directory after build completes';
  };

  dependencies: {
    resolve: 'Always resolve dependencies before bundling';
    cache: 'Cache resolver instance for repeated operations';
    validate: 'Validate all dependencies exist before building';
  };

  versioning: {
    check: 'Check current version before bumping';
    backup: 'Always backup before version changes';
    validate: 'Validate new version format';
  };
}