bmad-method 1.1.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bmad-core/agents/analyst.md +14 -20
- package/.bmad-core/agents/architect.md +15 -20
- package/.bmad-core/agents/bmad-master.md +18 -26
- package/.bmad-core/agents/bmad-orchestrator.md +16 -28
- package/.bmad-core/agents/dev.md +5 -4
- package/.bmad-core/agents/pm.md +11 -16
- package/.bmad-core/agents/sm.md +20 -25
- package/.bmad-core/bmad-core-config.yml +60 -0
- package/.bmad-core/data/bmad-kb.md +12 -1
- package/.bmad-core/tasks/doc-migration-task.md +91 -146
- package/.bmad-core/tasks/document-project.md +389 -0
- package/.bmad-core/tasks/generate-ai-frontend-prompt.md +41 -48
- package/.bmad-core/tasks/index-docs.md +4 -1
- package/.bmad-core/templates/architecture-tmpl.md +15 -12
- package/.bmad-core/templates/fullstack-architecture-tmpl.md +85 -103
- package/.bmad-core/templates/prd-tmpl.md +1 -1
- package/.bmad-core/templates/simple-project-prd-tmpl.md +461 -0
- package/.bmad-core/templates/story-tmpl.md +2 -2
- package/.bmad-core/utils/workflow-management.md +14 -15
- package/.bmad-core/web-bundles/agents/analyst.txt +26 -21
- package/.bmad-core/web-bundles/agents/architect.txt +605 -233
- package/.bmad-core/web-bundles/agents/bmad-master.txt +457 -1039
- package/.bmad-core/web-bundles/agents/bmad-orchestrator.txt +36 -903
- package/.bmad-core/web-bundles/agents/dev.txt +5 -4
- package/.bmad-core/web-bundles/agents/pm.txt +476 -17
- package/.bmad-core/web-bundles/agents/po.txt +2 -2
- package/.bmad-core/web-bundles/agents/sm.txt +22 -27
- package/.bmad-core/web-bundles/agents/ux-expert.txt +41 -48
- package/.bmad-core/web-bundles/teams/team-all.txt +4394 -4447
- package/.bmad-core/web-bundles/teams/team-fullstack.txt +2760 -2809
- package/.bmad-core/web-bundles/teams/team-no-ui.txt +2718 -2760
- package/.bmad-core/workflows/greenfield-fullstack.yml +3 -3
- package/.claude/commands/analyst.md +14 -20
- package/.claude/commands/architect.md +15 -20
- package/.claude/commands/bmad-master.md +18 -26
- package/.claude/commands/bmad-orchestrator.md +16 -28
- package/.claude/commands/dev.md +5 -4
- package/.claude/commands/pm.md +11 -16
- package/.claude/commands/sm.md +20 -25
- package/.cursor/rules/analyst.mdc +13 -19
- package/.cursor/rules/architect.mdc +14 -19
- package/.cursor/rules/bmad-master.mdc +18 -26
- package/.cursor/rules/bmad-orchestrator.mdc +15 -27
- package/.cursor/rules/dev.mdc +5 -4
- package/.cursor/rules/pm.mdc +11 -16
- package/.cursor/rules/sm.mdc +19 -24
- package/.releaserc.json +2 -1
- package/.vscode/settings.json +4 -0
- package/.windsurf/rules/analyst.md +13 -19
- package/.windsurf/rules/architect.md +14 -19
- package/.windsurf/rules/bmad-master.md +18 -26
- package/.windsurf/rules/bmad-orchestrator.md +15 -27
- package/.windsurf/rules/dev.md +5 -4
- package/.windsurf/rules/pm.md +11 -16
- package/.windsurf/rules/sm.md +19 -24
- package/CHANGELOG.md +120 -2
- package/CONTRIBUTING.md +2 -0
- package/README.md +21 -3
- package/{.bmad-core → creator-tools}/tasks/create-agent.md +10 -12
- package/{.bmad-core/tasks/create-expansion-pack.md → creator-tools/tasks/generate-expansion-pack.md} +8 -6
- package/docs/bmad-workflow-guide.md +161 -0
- package/docs/claude-code-guide.md +119 -0
- package/docs/core-architecture.md +213 -0
- package/docs/cursor-guide.md +127 -0
- package/docs/how-to-contribute-with-pull-requests.md +141 -0
- package/docs/roo-code-guide.md +140 -0
- package/docs/user-guide.md +1044 -0
- package/docs/windsurf-guide.md +127 -0
- package/expansion-packs/README.md +1 -111
- package/expansion-packs/infrastructure-devops/agents/infra-devops-platform.md +1 -1
- package/expansion-packs/infrastructure-devops/tasks/create-doc.md +74 -0
- package/package.json +19 -13
- package/tools/builders/web-builder.js +16 -15
- package/tools/installer/bin/bmad.js +50 -29
- package/tools/installer/lib/file-manager.js +20 -3
- package/tools/installer/lib/ide-setup.js +11 -1
- package/tools/installer/lib/installer.js +149 -29
- package/tools/installer/package-lock.json +537 -335
- package/tools/installer/package.json +7 -7
- package/tools/lib/dependency-resolver.js +1 -1
- package/tools/semantic-release-sync-installer.js +31 -0
- package/tools/sync-installer-version.js +34 -0
- package/tools/upgraders/v3-to-v4-upgrader.js +18 -13
- package/tools/version-bump.js +33 -26
- package/tools/yaml-format.js +54 -25
- package/.bmad-core/schemas/agent-team-schema.yml +0 -153
- package/.bmad-core/tasks/create-team.md +0 -229
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bmad-method",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "BMAD Method installer - AI-powered Agile development framework",
|
|
5
5
|
"main": "lib/installer.js",
|
|
6
6
|
"bin": {
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"author": "BMAD Team",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"chalk": "^4.1
|
|
26
|
-
"commander": "^
|
|
27
|
-
"fs-extra": "^11.
|
|
28
|
-
"inquirer": "^
|
|
25
|
+
"chalk": "^5.4.1",
|
|
26
|
+
"commander": "^14.0.0",
|
|
27
|
+
"fs-extra": "^11.3.0",
|
|
28
|
+
"inquirer": "^12.6.3",
|
|
29
29
|
"js-yaml": "^4.1.0",
|
|
30
|
-
"ora": "^
|
|
30
|
+
"ora": "^8.2.0"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=14.0.0"
|
|
@@ -40,4 +40,4 @@
|
|
|
40
40
|
"url": "https://github.com/bmad-team/bmad-method/issues"
|
|
41
41
|
},
|
|
42
42
|
"homepage": "https://github.com/bmad-team/bmad-method#readme"
|
|
43
|
-
}
|
|
43
|
+
}
|
|
@@ -14,7 +14,7 @@ class DependencyResolver {
|
|
|
14
14
|
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
15
15
|
|
|
16
16
|
// Extract YAML from markdown content
|
|
17
|
-
const yamlMatch = agentContent.match(/```
|
|
17
|
+
const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)\n```/);
|
|
18
18
|
if (!yamlMatch) {
|
|
19
19
|
throw new Error(`No YAML configuration found in agent ${agentId}`);
|
|
20
20
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic-release plugin to sync installer package.json version
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
function prepare(pluginConfig, context) {
|
|
9
|
+
const { nextRelease, logger } = context;
|
|
10
|
+
|
|
11
|
+
// Path to installer package.json
|
|
12
|
+
const installerPackagePath = path.join(process.cwd(), 'tools', 'installer', 'package.json');
|
|
13
|
+
|
|
14
|
+
if (!fs.existsSync(installerPackagePath)) {
|
|
15
|
+
logger.log('Installer package.json not found, skipping sync');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Read installer package.json
|
|
20
|
+
const installerPackage = JSON.parse(fs.readFileSync(installerPackagePath, 'utf8'));
|
|
21
|
+
|
|
22
|
+
// Update version
|
|
23
|
+
installerPackage.version = nextRelease.version;
|
|
24
|
+
|
|
25
|
+
// Write back
|
|
26
|
+
fs.writeFileSync(installerPackagePath, JSON.stringify(installerPackage, null, 2) + '\n');
|
|
27
|
+
|
|
28
|
+
logger.log(`Synced installer package.json to version ${nextRelease.version}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { prepare };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sync installer package.json version with main package.json
|
|
5
|
+
* Used by semantic-release to keep versions in sync
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
function syncInstallerVersion() {
|
|
12
|
+
// Read main package.json
|
|
13
|
+
const mainPackagePath = path.join(__dirname, '..', 'package.json');
|
|
14
|
+
const mainPackage = JSON.parse(fs.readFileSync(mainPackagePath, 'utf8'));
|
|
15
|
+
|
|
16
|
+
// Read installer package.json
|
|
17
|
+
const installerPackagePath = path.join(__dirname, 'installer', 'package.json');
|
|
18
|
+
const installerPackage = JSON.parse(fs.readFileSync(installerPackagePath, 'utf8'));
|
|
19
|
+
|
|
20
|
+
// Update installer version to match main version
|
|
21
|
+
installerPackage.version = mainPackage.version;
|
|
22
|
+
|
|
23
|
+
// Write back installer package.json
|
|
24
|
+
fs.writeFileSync(installerPackagePath, JSON.stringify(installerPackage, null, 2) + '\n');
|
|
25
|
+
|
|
26
|
+
console.log(`Synced installer version to ${mainPackage.version}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Run if called directly
|
|
30
|
+
if (require.main === module) {
|
|
31
|
+
syncInstallerVersion();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = { syncInstallerVersion };
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
const fs = require("fs").promises;
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
const { glob } = require("glob");
|
|
4
|
+
|
|
5
|
+
// Dynamic imports for ES modules
|
|
6
|
+
let chalk, ora, inquirer;
|
|
7
|
+
|
|
8
|
+
// Initialize ES modules
|
|
9
|
+
async function initializeModules() {
|
|
10
|
+
chalk = (await import("chalk")).default;
|
|
11
|
+
ora = (await import("ora")).default;
|
|
12
|
+
inquirer = (await import("inquirer")).default;
|
|
13
|
+
}
|
|
9
14
|
|
|
10
15
|
class V3ToV4Upgrader {
|
|
11
16
|
constructor() {
|
|
@@ -14,6 +19,8 @@ class V3ToV4Upgrader {
|
|
|
14
19
|
|
|
15
20
|
async upgrade(options = {}) {
|
|
16
21
|
try {
|
|
22
|
+
// Initialize ES modules
|
|
23
|
+
await initializeModules();
|
|
17
24
|
// Keep readline open throughout the process
|
|
18
25
|
process.stdin.resume();
|
|
19
26
|
|
|
@@ -233,17 +240,17 @@ class V3ToV4Upgrader {
|
|
|
233
240
|
}
|
|
234
241
|
|
|
235
242
|
// Find epic files
|
|
236
|
-
const epicFiles = await
|
|
243
|
+
const epicFiles = await glob("epic*.md", { cwd: docsPath });
|
|
237
244
|
|
|
238
245
|
// Find story files
|
|
239
246
|
const storiesPath = path.join(docsPath, "stories");
|
|
240
247
|
let storyFiles = [];
|
|
241
248
|
if (await this.pathExists(storiesPath)) {
|
|
242
|
-
storyFiles = await
|
|
249
|
+
storyFiles = await glob("*.md", { cwd: storiesPath });
|
|
243
250
|
}
|
|
244
251
|
|
|
245
252
|
// Count custom files in bmad-agent
|
|
246
|
-
const bmadAgentFiles = await
|
|
253
|
+
const bmadAgentFiles = await glob("**/*.md", {
|
|
247
254
|
cwd: bmadAgentPath,
|
|
248
255
|
ignore: ["node_modules/**"],
|
|
249
256
|
});
|
|
@@ -738,13 +745,11 @@ class V3ToV4Upgrader {
|
|
|
738
745
|
|
|
739
746
|
async createInstallManifest(projectPath) {
|
|
740
747
|
const fileManager = require("../installer/lib/file-manager");
|
|
741
|
-
const glob = require("glob");
|
|
742
|
-
const { promisify } = require("util");
|
|
743
|
-
const globAsync = promisify(glob);
|
|
748
|
+
const { glob } = require("glob");
|
|
744
749
|
|
|
745
750
|
// Get all files in .bmad-core for the manifest
|
|
746
751
|
const bmadCorePath = path.join(projectPath, ".bmad-core");
|
|
747
|
-
const files = await
|
|
752
|
+
const files = await glob("**/*", {
|
|
748
753
|
cwd: bmadCorePath,
|
|
749
754
|
nodir: true,
|
|
750
755
|
ignore: ["**/.git/**", "**/node_modules/**"],
|
package/tools/version-bump.js
CHANGED
|
@@ -2,7 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const { execSync } = require('child_process');
|
|
5
|
-
const
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
// Dynamic import for ES module
|
|
8
|
+
let chalk;
|
|
9
|
+
|
|
10
|
+
// Initialize ES modules
|
|
11
|
+
async function initializeModules() {
|
|
12
|
+
if (!chalk) {
|
|
13
|
+
chalk = (await import('chalk')).default;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
6
16
|
|
|
7
17
|
/**
|
|
8
18
|
* Simple version bumping script for BMAD-METHOD
|
|
@@ -14,38 +24,32 @@ function getCurrentVersion() {
|
|
|
14
24
|
return packageJson.version;
|
|
15
25
|
}
|
|
16
26
|
|
|
17
|
-
function bumpVersion(type = 'patch') {
|
|
27
|
+
async function bumpVersion(type = 'patch') {
|
|
28
|
+
await initializeModules();
|
|
29
|
+
|
|
18
30
|
const validTypes = ['patch', 'minor', 'major'];
|
|
19
31
|
if (!validTypes.includes(type)) {
|
|
20
32
|
console.error(chalk.red(`Invalid version type: ${type}. Use: ${validTypes.join(', ')}`));
|
|
21
33
|
process.exit(1);
|
|
22
34
|
}
|
|
23
35
|
|
|
24
|
-
console.log(chalk.
|
|
36
|
+
console.log(chalk.yellow('⚠️ Manual version bumping is disabled.'));
|
|
37
|
+
console.log(chalk.blue('🤖 This project uses semantic-release for automated versioning.'));
|
|
38
|
+
console.log('');
|
|
39
|
+
console.log(chalk.bold('To create a new release, use conventional commits:'));
|
|
40
|
+
console.log(chalk.cyan(' feat: new feature (minor version bump)'));
|
|
41
|
+
console.log(chalk.cyan(' fix: bug fix (patch version bump)'));
|
|
42
|
+
console.log(chalk.cyan(' feat!: breaking change (major version bump)'));
|
|
43
|
+
console.log('');
|
|
44
|
+
console.log(chalk.dim('Example: git commit -m "feat: add new installer features"'));
|
|
45
|
+
console.log(chalk.dim('Then push to main branch to trigger automatic release.'));
|
|
25
46
|
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const newVersion = execSync(`npm version ${type} --no-git-tag-version`, { encoding: 'utf8' }).trim();
|
|
29
|
-
console.log(chalk.green(`✅ Version bumped to ${newVersion}`));
|
|
30
|
-
|
|
31
|
-
// Stage the package.json change
|
|
32
|
-
execSync('git add package.json');
|
|
33
|
-
|
|
34
|
-
// Create commit and tag
|
|
35
|
-
execSync(`git commit -m "chore: bump version to ${newVersion}"`);
|
|
36
|
-
execSync(`git tag -a ${newVersion} -m "Release ${newVersion}"`);
|
|
37
|
-
|
|
38
|
-
console.log(chalk.green(`✅ Created git tag: ${newVersion}`));
|
|
39
|
-
console.log(chalk.yellow(`💡 Run 'git push && git push --tags' to publish`));
|
|
40
|
-
|
|
41
|
-
return newVersion;
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.error(chalk.red('❌ Version bump failed:'), error.message);
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
47
|
+
return null;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
function main() {
|
|
50
|
+
async function main() {
|
|
51
|
+
await initializeModules();
|
|
52
|
+
|
|
49
53
|
const type = process.argv[2] || 'patch';
|
|
50
54
|
const currentVersion = getCurrentVersion();
|
|
51
55
|
|
|
@@ -59,14 +63,17 @@ function main() {
|
|
|
59
63
|
process.exit(1);
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
const newVersion = bumpVersion(type);
|
|
66
|
+
const newVersion = await bumpVersion(type);
|
|
63
67
|
|
|
64
68
|
console.log(chalk.green(`\n🎉 Version bump complete!`));
|
|
65
69
|
console.log(chalk.blue(`📦 ${currentVersion} → ${newVersion}`));
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
if (require.main === module) {
|
|
69
|
-
main()
|
|
73
|
+
main().catch(error => {
|
|
74
|
+
console.error('Error:', error);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
module.exports = { bumpVersion, getCurrentVersion };
|
package/tools/yaml-format.js
CHANGED
|
@@ -4,14 +4,24 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const yaml = require('js-yaml');
|
|
6
6
|
const { execSync } = require('child_process');
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
// Dynamic import for ES module
|
|
9
|
+
let chalk;
|
|
10
|
+
|
|
11
|
+
// Initialize ES modules
|
|
12
|
+
async function initializeModules() {
|
|
13
|
+
if (!chalk) {
|
|
14
|
+
chalk = (await import('chalk')).default;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
8
17
|
|
|
9
18
|
/**
|
|
10
19
|
* YAML Formatter and Linter for BMAD-METHOD
|
|
11
20
|
* Formats and validates YAML files and YAML embedded in Markdown
|
|
12
21
|
*/
|
|
13
22
|
|
|
14
|
-
function formatYamlContent(content, filename) {
|
|
23
|
+
async function formatYamlContent(content, filename) {
|
|
24
|
+
await initializeModules();
|
|
15
25
|
try {
|
|
16
26
|
// First try to fix common YAML issues
|
|
17
27
|
let fixedContent = content
|
|
@@ -62,7 +72,8 @@ function formatYamlContent(content, filename) {
|
|
|
62
72
|
}
|
|
63
73
|
}
|
|
64
74
|
|
|
65
|
-
function processMarkdownFile(filePath) {
|
|
75
|
+
async function processMarkdownFile(filePath) {
|
|
76
|
+
await initializeModules();
|
|
66
77
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
67
78
|
let modified = false;
|
|
68
79
|
let newContent = content;
|
|
@@ -77,22 +88,34 @@ function processMarkdownFile(filePath) {
|
|
|
77
88
|
|
|
78
89
|
// Find YAML code blocks
|
|
79
90
|
const yamlBlockRegex = /```ya?ml\n([\s\S]*?)\n```/g;
|
|
91
|
+
let match;
|
|
92
|
+
const replacements = [];
|
|
80
93
|
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
while ((match = yamlBlockRegex.exec(newContent)) !== null) {
|
|
95
|
+
const [fullMatch, yamlContent] = match;
|
|
96
|
+
const formatted = await formatYamlContent(yamlContent, filePath);
|
|
97
|
+
if (formatted !== null) {
|
|
98
|
+
// Remove trailing newline that js-yaml adds
|
|
99
|
+
const trimmedFormatted = formatted.replace(/\n$/, '');
|
|
100
|
+
|
|
101
|
+
if (trimmedFormatted !== yamlContent) {
|
|
102
|
+
modified = true;
|
|
103
|
+
console.log(chalk.green(`✓ Formatted YAML in ${filePath}`));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
replacements.push({
|
|
107
|
+
start: match.index,
|
|
108
|
+
end: match.index + fullMatch.length,
|
|
109
|
+
replacement: `\`\`\`yaml\n${trimmedFormatted}\n\`\`\``
|
|
110
|
+
});
|
|
92
111
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Apply replacements in reverse order to maintain indices
|
|
115
|
+
for (let i = replacements.length - 1; i >= 0; i--) {
|
|
116
|
+
const { start, end, replacement } = replacements[i];
|
|
117
|
+
newContent = newContent.slice(0, start) + replacement + newContent.slice(end);
|
|
118
|
+
}
|
|
96
119
|
|
|
97
120
|
if (modified) {
|
|
98
121
|
fs.writeFileSync(filePath, newContent);
|
|
@@ -101,9 +124,10 @@ function processMarkdownFile(filePath) {
|
|
|
101
124
|
return false;
|
|
102
125
|
}
|
|
103
126
|
|
|
104
|
-
function processYamlFile(filePath) {
|
|
127
|
+
async function processYamlFile(filePath) {
|
|
128
|
+
await initializeModules();
|
|
105
129
|
const content = fs.readFileSync(filePath, 'utf8');
|
|
106
|
-
const formatted = formatYamlContent(content, filePath);
|
|
130
|
+
const formatted = await formatYamlContent(content, filePath);
|
|
107
131
|
|
|
108
132
|
if (formatted === null) {
|
|
109
133
|
return false; // Syntax error
|
|
@@ -116,7 +140,8 @@ function processYamlFile(filePath) {
|
|
|
116
140
|
return false;
|
|
117
141
|
}
|
|
118
142
|
|
|
119
|
-
function lintYamlFile(filePath) {
|
|
143
|
+
async function lintYamlFile(filePath) {
|
|
144
|
+
await initializeModules();
|
|
120
145
|
try {
|
|
121
146
|
// Use yaml-lint for additional validation
|
|
122
147
|
execSync(`npx yaml-lint "${filePath}"`, { stdio: 'pipe' });
|
|
@@ -128,7 +153,8 @@ function lintYamlFile(filePath) {
|
|
|
128
153
|
}
|
|
129
154
|
}
|
|
130
155
|
|
|
131
|
-
function main() {
|
|
156
|
+
async function main() {
|
|
157
|
+
await initializeModules();
|
|
132
158
|
const args = process.argv.slice(2);
|
|
133
159
|
const glob = require('glob');
|
|
134
160
|
|
|
@@ -170,13 +196,13 @@ function main() {
|
|
|
170
196
|
try {
|
|
171
197
|
let changed = false;
|
|
172
198
|
if (ext === '.md') {
|
|
173
|
-
changed = processMarkdownFile(filePath);
|
|
199
|
+
changed = await processMarkdownFile(filePath);
|
|
174
200
|
} else if (ext === '.yml' || ext === '.yaml' || basename.includes('roomodes') || basename.includes('.yml') || basename.includes('.yaml')) {
|
|
175
201
|
// Handle YAML files and special cases like .roomodes
|
|
176
|
-
changed = processYamlFile(filePath);
|
|
202
|
+
changed = await processYamlFile(filePath);
|
|
177
203
|
|
|
178
204
|
// Also run linting
|
|
179
|
-
const lintPassed = lintYamlFile(filePath);
|
|
205
|
+
const lintPassed = await lintYamlFile(filePath);
|
|
180
206
|
if (!lintPassed) hasErrors = true;
|
|
181
207
|
} else {
|
|
182
208
|
// Skip silently for unsupported files
|
|
@@ -205,7 +231,10 @@ function main() {
|
|
|
205
231
|
}
|
|
206
232
|
|
|
207
233
|
if (require.main === module) {
|
|
208
|
-
main()
|
|
234
|
+
main().catch(error => {
|
|
235
|
+
console.error('Error:', error);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
});
|
|
209
238
|
}
|
|
210
239
|
|
|
211
240
|
module.exports = { formatYamlContent, processMarkdownFile, processYamlFile };
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
# BMAD Agent Team Configuration Schema
|
|
2
|
-
# This schema defines the structure for BMAD agent team configuration files
|
|
3
|
-
# Teams bundle multiple agents and workflows for specific project types
|
|
4
|
-
|
|
5
|
-
type: object
|
|
6
|
-
required:
|
|
7
|
-
- bundle
|
|
8
|
-
- agents
|
|
9
|
-
- workflows
|
|
10
|
-
|
|
11
|
-
properties:
|
|
12
|
-
bundle:
|
|
13
|
-
type: object
|
|
14
|
-
description: Team bundle metadata and configuration
|
|
15
|
-
required:
|
|
16
|
-
- name
|
|
17
|
-
- description
|
|
18
|
-
properties:
|
|
19
|
-
name:
|
|
20
|
-
type: string
|
|
21
|
-
description: Human-friendly name of the team bundle
|
|
22
|
-
pattern: "^Team .+$"
|
|
23
|
-
examples:
|
|
24
|
-
- "Team Fullstack"
|
|
25
|
-
- "Team No UI"
|
|
26
|
-
- "Team All"
|
|
27
|
-
|
|
28
|
-
description:
|
|
29
|
-
type: string
|
|
30
|
-
description: Detailed description of the team's purpose, capabilities, and use cases
|
|
31
|
-
minLength: 20
|
|
32
|
-
maxLength: 500
|
|
33
|
-
|
|
34
|
-
agents:
|
|
35
|
-
type: array
|
|
36
|
-
description: List of agents included in this team bundle
|
|
37
|
-
minItems: 2
|
|
38
|
-
items:
|
|
39
|
-
type: string
|
|
40
|
-
description: Agent ID matching agents/{agent}.yml or special value '*' for all agents
|
|
41
|
-
pattern: "^([a-z-]+|\\*)$"
|
|
42
|
-
examples:
|
|
43
|
-
- "bmad"
|
|
44
|
-
- "analyst"
|
|
45
|
-
- "pm"
|
|
46
|
-
- "ux-expert"
|
|
47
|
-
- "architect"
|
|
48
|
-
- "po"
|
|
49
|
-
- "sm"
|
|
50
|
-
- "dev"
|
|
51
|
-
- "qa"
|
|
52
|
-
- "*"
|
|
53
|
-
uniqueItems: true
|
|
54
|
-
allOf:
|
|
55
|
-
- description: Must include 'bmad' as the orchestrator
|
|
56
|
-
contains:
|
|
57
|
-
const: "bmad"
|
|
58
|
-
|
|
59
|
-
workflows:
|
|
60
|
-
type: array
|
|
61
|
-
description: List of workflows this team can execute
|
|
62
|
-
minItems: 1
|
|
63
|
-
items:
|
|
64
|
-
type: string
|
|
65
|
-
description: Workflow ID matching bmad-core/workflows/{workflow}.yml
|
|
66
|
-
enum:
|
|
67
|
-
- "brownfield-fullstack"
|
|
68
|
-
- "brownfield-service"
|
|
69
|
-
- "brownfield-ui"
|
|
70
|
-
- "greenfield-fullstack"
|
|
71
|
-
- "greenfield-service"
|
|
72
|
-
- "greenfield-ui"
|
|
73
|
-
uniqueItems: true
|
|
74
|
-
|
|
75
|
-
# No additional properties allowed
|
|
76
|
-
additionalProperties: false
|
|
77
|
-
|
|
78
|
-
# Validation rules
|
|
79
|
-
allOf:
|
|
80
|
-
- if:
|
|
81
|
-
properties:
|
|
82
|
-
agents:
|
|
83
|
-
contains:
|
|
84
|
-
const: "*"
|
|
85
|
-
then:
|
|
86
|
-
properties:
|
|
87
|
-
agents:
|
|
88
|
-
maxItems: 2
|
|
89
|
-
description: When using wildcard '*', only 'bmad' and '*' should be present
|
|
90
|
-
|
|
91
|
-
- if:
|
|
92
|
-
properties:
|
|
93
|
-
bundle:
|
|
94
|
-
properties:
|
|
95
|
-
name:
|
|
96
|
-
const: "Team No UI"
|
|
97
|
-
then:
|
|
98
|
-
properties:
|
|
99
|
-
agents:
|
|
100
|
-
not:
|
|
101
|
-
contains:
|
|
102
|
-
const: "ux-expert"
|
|
103
|
-
workflows:
|
|
104
|
-
not:
|
|
105
|
-
contains:
|
|
106
|
-
enum: ["brownfield-ui", "greenfield-ui"]
|
|
107
|
-
|
|
108
|
-
# Examples showing valid team configurations
|
|
109
|
-
examples:
|
|
110
|
-
minimal_team:
|
|
111
|
-
bundle:
|
|
112
|
-
name: "Team Minimal"
|
|
113
|
-
description: "Minimal team for basic project planning and architecture without implementation"
|
|
114
|
-
agents:
|
|
115
|
-
- bmad
|
|
116
|
-
- analyst
|
|
117
|
-
- architect
|
|
118
|
-
workflows:
|
|
119
|
-
- greenfield-service
|
|
120
|
-
|
|
121
|
-
fullstack_team:
|
|
122
|
-
bundle:
|
|
123
|
-
name: "Team Fullstack"
|
|
124
|
-
description: "Comprehensive full-stack development team capable of handling both greenfield application development and brownfield enhancement projects. This team combines strategic planning, user experience design, and holistic system architecture to deliver complete solutions from concept to deployment."
|
|
125
|
-
agents:
|
|
126
|
-
- bmad
|
|
127
|
-
- analyst
|
|
128
|
-
- pm
|
|
129
|
-
- ux-expert
|
|
130
|
-
- architect
|
|
131
|
-
- po
|
|
132
|
-
workflows:
|
|
133
|
-
- brownfield-fullstack
|
|
134
|
-
- brownfield-service
|
|
135
|
-
- brownfield-ui
|
|
136
|
-
- greenfield-fullstack
|
|
137
|
-
- greenfield-service
|
|
138
|
-
- greenfield-ui
|
|
139
|
-
|
|
140
|
-
all_agents_team:
|
|
141
|
-
bundle:
|
|
142
|
-
name: "Team All"
|
|
143
|
-
description: "This is a full organization of agents and includes every possible agent. This will produce the largest bundle but give the most options for discussion in a single session"
|
|
144
|
-
agents:
|
|
145
|
-
- bmad
|
|
146
|
-
- "*"
|
|
147
|
-
workflows:
|
|
148
|
-
- brownfield-fullstack
|
|
149
|
-
- brownfield-service
|
|
150
|
-
- brownfield-ui
|
|
151
|
-
- greenfield-fullstack
|
|
152
|
-
- greenfield-service
|
|
153
|
-
- greenfield-ui
|