moved bmad-core to dot folder so when adding to project it is clear its not part of the project it is added to

This commit is contained in:
Brian Madison
2025-06-13 19:11:17 -05:00
parent 03241a73d6
commit 7c71e1f815
86 changed files with 87 additions and 28247 deletions

41
tools/bmad-npx-wrapper.js Executable file
View File

@@ -0,0 +1,41 @@
#!/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');
}

View File

@@ -7,10 +7,10 @@ class WebBuilder {
this.rootDir = options.rootDir || process.cwd();
this.outputDirs = options.outputDirs || [
path.join(this.rootDir, 'dist'),
path.join(this.rootDir, 'bmad-core', 'web-bundles')
path.join(this.rootDir, '.bmad-core', 'web-bundles')
];
this.resolver = new DependencyResolver(this.rootDir);
this.templatePath = path.join(this.rootDir, 'bmad-core', 'templates', 'web-agent-startup-instructions-template.md');
this.templatePath = path.join(this.rootDir, '.bmad-core', 'templates', 'web-agent-startup-instructions-template.md');
}
async cleanOutputDirs() {

View File

@@ -34,7 +34,7 @@ program
program
.command('install')
.description('Install BMAD Method agents and tools')
.option('-f, --full', 'Install complete bmad-core folder')
.option('-f, --full', 'Install complete .bmad-core folder')
.option('-a, --agent <agent>', 'Install specific agent with dependencies')
.option('-d, --directory <path>', 'Installation directory (default: ./bmad-core)')
.option('-i, --ide <ide>', 'Configure for specific IDE (cursor, claude-code, windsurf)')
@@ -49,7 +49,7 @@ program
const config = {
installType: options.full ? 'full' : 'single-agent',
agent: options.agent,
directory: options.directory || './bmad-core',
directory: options.directory || './.bmad-core',
ide: options.ide
};
await installer.install(config);
@@ -109,7 +109,7 @@ async function promptInstallation(options) {
type: 'input',
name: 'directory',
message: 'Where would you like to install BMAD?',
default: './bmad-core'
default: './.bmad-core'
}
]);
answers.directory = directory;

View File

@@ -4,9 +4,9 @@
installation-options:
full:
name: "Complete BMAD Core"
description: "Copy the entire bmad-core folder with all agents, templates, and tools"
description: "Copy the entire .bmad-core folder with all agents, templates, and tools"
action: "copy-folder"
source: "bmad-core"
source: ".bmad-core"
single-agent:
name: "Single Agent"
@@ -17,53 +17,53 @@ installation-options:
# These are the core files that should be included with any single agent installation
agent-dependencies:
core-files:
- "bmad-core/data/bmad-kb.md"
- "bmad-core/data/technical-preferences.md"
- "bmad-core/utils/template-format.md"
- ".bmad-core/data/bmad-kb.md"
- ".bmad-core/data/technical-preferences.md"
- ".bmad-core/utils/template-format.md"
# Agent-specific dependencies (parsed from agent files or explicitly defined)
dev:
- "bmad-core/templates/story-tmpl.md"
- "bmad-core/checklists/story-dod-checklist.md"
- ".bmad-core/templates/story-tmpl.md"
- ".bmad-core/checklists/story-dod-checklist.md"
pm:
- "bmad-core/templates/prd-tmpl.md"
- "bmad-core/checklists/pm-checklist.md"
- "bmad-core/tasks/advanced-elicitation.md"
- ".bmad-core/templates/prd-tmpl.md"
- ".bmad-core/checklists/pm-checklist.md"
- ".bmad-core/tasks/advanced-elicitation.md"
architect:
- "bmad-core/templates/architecture-tmpl.md"
- "bmad-core/checklists/architect-checklist.md"
- ".bmad-core/templates/architecture-tmpl.md"
- ".bmad-core/checklists/architect-checklist.md"
sm:
- "bmad-core/templates/story-tmpl.md"
- "bmad-core/checklists/story-draft-checklist.md"
- "bmad-core/workflows/*.yml"
- ".bmad-core/templates/story-tmpl.md"
- ".bmad-core/checklists/story-draft-checklist.md"
- ".bmad-core/workflows/*.yml"
po:
- "bmad-core/checklists/po-master-checklist.md"
- "bmad-core/templates/acceptance-criteria-tmpl.md"
- ".bmad-core/checklists/po-master-checklist.md"
- ".bmad-core/templates/acceptance-criteria-tmpl.md"
analyst:
- "bmad-core/templates/prd-tmpl.md"
- "bmad-core/tasks/advanced-elicitation.md"
- ".bmad-core/templates/prd-tmpl.md"
- ".bmad-core/tasks/advanced-elicitation.md"
qa:
- "bmad-core/checklists/story-dod-checklist.md"
- "bmad-core/templates/test-plan-tmpl.md"
- ".bmad-core/checklists/story-dod-checklist.md"
- ".bmad-core/templates/test-plan-tmpl.md"
ux-expert:
- "bmad-core/templates/ux-tmpl.md"
- ".bmad-core/templates/ux-tmpl.md"
# Meta agents typically need access to more resources
bmad-master:
- "bmad-core/templates/*.md"
- "bmad-core/tasks/*.md"
- "bmad-core/schemas/*.yml"
- ".bmad-core/templates/*.md"
- ".bmad-core/tasks/*.md"
- ".bmad-core/schemas/*.yml"
bmad-orchestrator:
- "bmad-core/agent-teams/*.yml"
- "bmad-core/workflows/*.yml"
- ".bmad-core/agent-teams/*.yml"
- ".bmad-core/workflows/*.yml"
# IDE-specific configuration for generating rules/commands
ide-configurations:
@@ -118,50 +118,50 @@ ide-configurations:
available-agents:
- id: "analyst"
name: "Business Analyst"
file: "bmad-core/agents/analyst.md"
file: ".bmad-core/agents/analyst.md"
description: "Requirements gathering and analysis"
- id: "pm"
name: "Product Manager"
file: "bmad-core/agents/pm.md"
file: ".bmad-core/agents/pm.md"
description: "Product strategy and roadmap planning"
- id: "architect"
name: "Solution Architect"
file: "bmad-core/agents/architect.md"
file: ".bmad-core/agents/architect.md"
description: "Technical design and architecture"
- id: "po"
name: "Product Owner"
file: "bmad-core/agents/po.md"
file: ".bmad-core/agents/po.md"
description: "Backlog management and prioritization"
- id: "sm"
name: "Scrum Master"
file: "bmad-core/agents/sm.md"
file: ".bmad-core/agents/sm.md"
description: "Agile process and story creation"
- id: "dev"
name: "Developer"
file: "bmad-core/agents/dev.md"
file: ".bmad-core/agents/dev.md"
description: "Code implementation and testing"
- id: "qa"
name: "QA Engineer"
file: "bmad-core/agents/qa.md"
file: ".bmad-core/agents/qa.md"
description: "Quality assurance and testing"
- id: "ux-expert"
name: "UX Expert"
file: "bmad-core/agents/ux-expert.md"
file: ".bmad-core/agents/ux-expert.md"
description: "User experience design"
- id: "bmad-master"
name: "BMAD Master"
file: "bmad-core/agents/bmad-master.md"
file: ".bmad-core/agents/bmad-master.md"
description: "BMAD framework expert and guide"
- id: "bmad-orchestrator"
name: "BMAD Orchestrator"
file: "bmad-core/agents/bmad-orchestrator.md"
file: ".bmad-core/agents/bmad-orchestrator.md"
description: "Multi-agent workflow coordinator"

View File

@@ -50,8 +50,8 @@ class ConfigLoader {
}
getBmadCorePath() {
// Get the path to bmad-core relative to the installer (now under tools)
return path.join(__dirname, '..', '..', '..', 'bmad-core');
// Get the path to .bmad-core relative to the installer (now under tools)
return path.join(__dirname, '..', '..', '..', '.bmad-core');
}
getAgentPath(agentId) {

View File

@@ -32,8 +32,8 @@ class IdeSetup {
await fileManager.ensureDirectory(cursorRulesDir);
for (const agentId of agents) {
// Check if bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, 'bmad-core', 'agents', `${agentId}.md`);
// Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, '.bmad-core', 'agents', `${agentId}.md`);
if (!await fileManager.pathExists(agentPath)) {
agentPath = path.join(installDir, 'agents', `${agentId}.md`);
}
@@ -63,7 +63,7 @@ class IdeSetup {
}
mdcContent += '\n```\n\n';
mdcContent += '## File Reference\n\n';
mdcContent += `The complete agent definition is available in [bmad-core/agents/${agentId}.md](mdc:bmad-core/agents/${agentId}.md).\n\n`;
mdcContent += `The complete agent definition is available in [.bmad-core/agents/${agentId}.md](mdc:.bmad-core/agents/${agentId}.md).\n\n`;
mdcContent += '## Usage\n\n';
mdcContent += `When the user types \`@${agentId}\`, activate this ${this.getAgentTitle(agentId)} persona and follow all instructions defined in the YML configuration above.\n`;
@@ -84,8 +84,8 @@ class IdeSetup {
await fileManager.ensureDirectory(commandsDir);
for (const agentId of agents) {
// Check if bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, 'bmad-core', 'agents', `${agentId}.md`);
// Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, '.bmad-core', 'agents', `${agentId}.md`);
if (!await fileManager.pathExists(agentPath)) {
agentPath = path.join(installDir, 'agents', `${agentId}.md`);
}
@@ -117,8 +117,8 @@ class IdeSetup {
await fileManager.ensureDirectory(windsurfRulesDir);
for (const agentId of agents) {
// Check if bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, 'bmad-core', 'agents', `${agentId}.md`);
// Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentPath = path.join(installDir, '.bmad-core', 'agents', `${agentId}.md`);
if (!await fileManager.pathExists(agentPath)) {
agentPath = path.join(installDir, 'agents', `${agentId}.md`);
}
@@ -143,7 +143,7 @@ class IdeSetup {
}
mdContent += '\n```\n\n';
mdContent += '## File Reference\n\n';
mdContent += `The complete agent definition is available in [bmad-core/agents/${agentId}.md](bmad-core/agents/${agentId}.md).\n\n`;
mdContent += `The complete agent definition is available in [.bmad-core/agents/${agentId}.md](.bmad-core/agents/${agentId}.md).\n\n`;
mdContent += '## Usage\n\n';
mdContent += `When the user types \`@${agentId}\`, activate this ${this.getAgentTitle(agentId)} persona and follow all instructions defined in the YML configuration above.\n`;
@@ -158,8 +158,8 @@ class IdeSetup {
}
async getAllAgentIds(installDir) {
// Check if bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentsDir = path.join(installDir, 'bmad-core', 'agents');
// Check if .bmad-core is a subdirectory (full install) or if agents are in root (single agent install)
let agentsDir = path.join(installDir, '.bmad-core', 'agents');
if (!await fileManager.pathExists(agentsDir)) {
agentsDir = path.join(installDir, 'agents');
}

View File

@@ -26,10 +26,10 @@ class Installer {
let files = [];
if (config.installType === 'full') {
// Full installation - copy entire bmad-core folder as a subdirectory
spinner.text = 'Copying complete bmad-core folder...';
// Full installation - copy entire .bmad-core folder as a subdirectory
spinner.text = 'Copying complete .bmad-core folder...';
const sourceDir = configLoader.getBmadCorePath();
const bmadCoreDestDir = path.join(installDir, 'bmad-core');
const bmadCoreDestDir = path.join(installDir, '.bmad-core');
await fileManager.copyDirectory(sourceDir, bmadCoreDestDir);
// Get list of all files for manifest
@@ -38,7 +38,7 @@ class Installer {
cwd: bmadCoreDestDir,
nodir: true,
ignore: ['**/.git/**', '**/node_modules/**']
}).map(file => path.join('bmad-core', file));
}).map(file => path.join('.bmad-core', file));
} else if (config.installType === 'single-agent') {
// Single agent installation
@@ -60,18 +60,18 @@ class Installer {
if (dep.includes('*')) {
// Handle glob patterns
const copiedFiles = await fileManager.copyGlobPattern(
dep.replace('bmad-core/', ''),
dep.replace('.bmad-core/', ''),
sourceBase,
installDir
);
files.push(...copiedFiles);
} else {
// Handle single files
const sourcePath = path.join(sourceBase, dep.replace('bmad-core/', ''));
const destPath = path.join(installDir, dep.replace('bmad-core/', ''));
const sourcePath = path.join(sourceBase, dep.replace('.bmad-core/', ''));
const destPath = path.join(installDir, dep.replace('.bmad-core/', ''));
if (await fileManager.copyFile(sourcePath, destPath)) {
files.push(dep.replace('bmad-core/', ''));
files.push(dep.replace('.bmad-core/', ''));
}
}
}
@@ -80,7 +80,7 @@ class Installer {
// Set up IDE integration if requested
if (config.ide) {
spinner.text = `Setting up ${config.ide} integration...`;
// For full installations, IDE rules should be in the root install dir, not bmad-core
// For full installations, IDE rules should be in the root install dir, not .bmad-core
await ideSetup.setup(config.ide, installDir, config.agent);
}
@@ -240,11 +240,11 @@ class Installer {
}
async findInstallation() {
// Look for bmad-core in current directory or parent directories
// Look for .bmad-core in current directory or parent directories
let currentDir = process.cwd();
while (currentDir !== path.dirname(currentDir)) {
const bmadDir = path.join(currentDir, 'bmad-core');
const bmadDir = path.join(currentDir, '.bmad-core');
const manifestPath = path.join(bmadDir, '.bmad', 'install-manifest.yml');
if (await fileManager.pathExists(manifestPath)) {
@@ -254,8 +254,8 @@ class Installer {
currentDir = path.dirname(currentDir);
}
// Also check if we're inside a bmad-core directory
if (path.basename(process.cwd()) === 'bmad-core') {
// Also check if we're inside a .bmad-core directory
if (path.basename(process.cwd()) === '.bmad-core') {
const manifestPath = path.join(process.cwd(), '.bmad', 'install-manifest.yml');
if (await fileManager.pathExists(manifestPath)) {
return process.cwd();

View File

@@ -5,7 +5,7 @@ const yaml = require('js-yaml');
class DependencyResolver {
constructor(rootDir) {
this.rootDir = rootDir;
this.bmadCore = path.join(rootDir, 'bmad-core');
this.bmadCore = path.join(rootDir, '.bmad-core');
this.cache = new Map();
}