bmad-method 6.0.0-Beta.0 → 6.0.0-Beta.2
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/CHANGELOG.md +8 -1
- package/package.json +1 -1
- package/src/bmm/module-help.csv +31 -31
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +1 -1
- package/src/core/module-help.csv +8 -8
- package/tools/cli/installers/install-messages.yaml +11 -10
- package/tools/cli/installers/lib/core/installer.js +26 -40
- package/tools/cli/installers/lib/ide/_config-driven.js +423 -0
- package/tools/cli/installers/lib/ide/codex.js +40 -12
- package/tools/cli/installers/lib/ide/manager.js +65 -38
- package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
- package/tools/cli/installers/lib/ide/platform-codes.yaml +241 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +19 -5
- package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +5 -0
- package/tools/cli/installers/lib/ide/shared/path-utils.js +166 -50
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +7 -5
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +21 -3
- package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
- package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/gemini/body.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/gemini/header.toml +2 -0
- package/tools/cli/installers/lib/ide/templates/split/opencode/body.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/opencode/header.md +4 -0
- package/tools/cli/lib/ui.js +19 -75
- package/tools/cli/installers/lib/ide/STANDARDIZATION_PLAN.md +0 -208
- package/tools/cli/installers/lib/ide/antigravity.js +0 -474
- package/tools/cli/installers/lib/ide/auggie.js +0 -244
- package/tools/cli/installers/lib/ide/claude-code.js +0 -506
- package/tools/cli/installers/lib/ide/cline.js +0 -272
- package/tools/cli/installers/lib/ide/crush.js +0 -149
- package/tools/cli/installers/lib/ide/cursor.js +0 -160
- package/tools/cli/installers/lib/ide/gemini.js +0 -301
- package/tools/cli/installers/lib/ide/github-copilot.js +0 -383
- package/tools/cli/installers/lib/ide/iflow.js +0 -191
- package/tools/cli/installers/lib/ide/opencode.js +0 -257
- package/tools/cli/installers/lib/ide/qwen.js +0 -372
- package/tools/cli/installers/lib/ide/roo.js +0 -273
- package/tools/cli/installers/lib/ide/rovo-dev.js +0 -290
- package/tools/cli/installers/lib/ide/trae.js +0 -313
- package/tools/cli/installers/lib/ide/windsurf.js +0 -258
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const yaml = require('yaml');
|
|
4
|
+
|
|
5
|
+
const PLATFORM_CODES_PATH = path.join(__dirname, 'platform-codes.yaml');
|
|
6
|
+
|
|
7
|
+
let _cachedPlatformCodes = null;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Load the platform codes configuration from YAML
|
|
11
|
+
* @returns {Object} Platform codes configuration
|
|
12
|
+
*/
|
|
13
|
+
async function loadPlatformCodes() {
|
|
14
|
+
if (_cachedPlatformCodes) {
|
|
15
|
+
return _cachedPlatformCodes;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!(await fs.pathExists(PLATFORM_CODES_PATH))) {
|
|
19
|
+
throw new Error(`Platform codes configuration not found at: ${PLATFORM_CODES_PATH}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const content = await fs.readFile(PLATFORM_CODES_PATH, 'utf8');
|
|
23
|
+
_cachedPlatformCodes = yaml.parse(content);
|
|
24
|
+
return _cachedPlatformCodes;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get platform information by code
|
|
29
|
+
* @param {string} platformCode - Platform code (e.g., 'claude-code', 'cursor')
|
|
30
|
+
* @returns {Object|null} Platform info or null if not found
|
|
31
|
+
*/
|
|
32
|
+
function getPlatformInfo(platformCode) {
|
|
33
|
+
if (!_cachedPlatformCodes) {
|
|
34
|
+
throw new Error('Platform codes not loaded. Call loadPlatformCodes() first.');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return _cachedPlatformCodes.platforms[platformCode] || null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get all preferred platforms
|
|
42
|
+
* @returns {Promise<Array>} Array of preferred platform codes
|
|
43
|
+
*/
|
|
44
|
+
async function getPreferredPlatforms() {
|
|
45
|
+
const config = await loadPlatformCodes();
|
|
46
|
+
return Object.entries(config.platforms)
|
|
47
|
+
.filter(([_, info]) => info.preferred)
|
|
48
|
+
.map(([code, _]) => code);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get all platform codes by category
|
|
53
|
+
* @param {string} category - Category to filter by (ide, cli, tool, etc.)
|
|
54
|
+
* @returns {Promise<Array>} Array of platform codes in the category
|
|
55
|
+
*/
|
|
56
|
+
async function getPlatformsByCategory(category) {
|
|
57
|
+
const config = await loadPlatformCodes();
|
|
58
|
+
return Object.entries(config.platforms)
|
|
59
|
+
.filter(([_, info]) => info.category === category)
|
|
60
|
+
.map(([code, _]) => code);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get all platforms with installer config
|
|
65
|
+
* @returns {Promise<Array>} Array of platform codes that have installer config
|
|
66
|
+
*/
|
|
67
|
+
async function getConfigDrivenPlatforms() {
|
|
68
|
+
const config = await loadPlatformCodes();
|
|
69
|
+
return Object.entries(config.platforms)
|
|
70
|
+
.filter(([_, info]) => info.installer)
|
|
71
|
+
.map(([code, _]) => code);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get platforms that use custom installers (no installer config)
|
|
76
|
+
* @returns {Promise<Array>} Array of platform codes with custom installers
|
|
77
|
+
*/
|
|
78
|
+
async function getCustomInstallerPlatforms() {
|
|
79
|
+
const config = await loadPlatformCodes();
|
|
80
|
+
return Object.entries(config.platforms)
|
|
81
|
+
.filter(([_, info]) => !info.installer)
|
|
82
|
+
.map(([code, _]) => code);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Clear the cached platform codes (useful for testing)
|
|
87
|
+
*/
|
|
88
|
+
function clearCache() {
|
|
89
|
+
_cachedPlatformCodes = null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = {
|
|
93
|
+
loadPlatformCodes,
|
|
94
|
+
getPlatformInfo,
|
|
95
|
+
getPreferredPlatforms,
|
|
96
|
+
getPlatformsByCategory,
|
|
97
|
+
getConfigDrivenPlatforms,
|
|
98
|
+
getCustomInstallerPlatforms,
|
|
99
|
+
clearCache,
|
|
100
|
+
};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# BMAD Platform Codes Configuration
|
|
2
|
+
# Central configuration for all platform/IDE codes used in the BMAD system
|
|
3
|
+
#
|
|
4
|
+
# This file defines:
|
|
5
|
+
# 1. Platform metadata (name, preferred status, category, description)
|
|
6
|
+
# 2. Installer configuration (target directories, templates, artifact types)
|
|
7
|
+
#
|
|
8
|
+
# Format:
|
|
9
|
+
# code: Platform identifier used internally
|
|
10
|
+
# name: Display name shown to users
|
|
11
|
+
# preferred: Whether this platform is shown as a recommended option on install
|
|
12
|
+
# category: Type of platform (ide, cli, tool, service)
|
|
13
|
+
# description: Brief description of the platform
|
|
14
|
+
# installer: Installation configuration (optional - omit for custom installers)
|
|
15
|
+
|
|
16
|
+
platforms:
|
|
17
|
+
# ============================================================================
|
|
18
|
+
# CLI Tools
|
|
19
|
+
# ============================================================================
|
|
20
|
+
|
|
21
|
+
claude-code:
|
|
22
|
+
name: "Claude Code"
|
|
23
|
+
preferred: true
|
|
24
|
+
category: cli
|
|
25
|
+
description: "Anthropic's official CLI for Claude"
|
|
26
|
+
installer:
|
|
27
|
+
target_dir: .claude/commands
|
|
28
|
+
template_type: default
|
|
29
|
+
|
|
30
|
+
auggie:
|
|
31
|
+
name: "Auggie"
|
|
32
|
+
preferred: false
|
|
33
|
+
category: cli
|
|
34
|
+
description: "AI development tool"
|
|
35
|
+
installer:
|
|
36
|
+
target_dir: .augment/commands
|
|
37
|
+
template_type: default
|
|
38
|
+
|
|
39
|
+
gemini:
|
|
40
|
+
name: "Gemini CLI"
|
|
41
|
+
preferred: false
|
|
42
|
+
category: cli
|
|
43
|
+
description: "Google's CLI for Gemini"
|
|
44
|
+
installer:
|
|
45
|
+
target_dir: .gemini/commands
|
|
46
|
+
template_type: gemini
|
|
47
|
+
|
|
48
|
+
# ============================================================================
|
|
49
|
+
# IDEs
|
|
50
|
+
# ============================================================================
|
|
51
|
+
|
|
52
|
+
cursor:
|
|
53
|
+
name: "Cursor"
|
|
54
|
+
preferred: true
|
|
55
|
+
category: ide
|
|
56
|
+
description: "AI-first code editor"
|
|
57
|
+
installer:
|
|
58
|
+
target_dir: .cursor/commands
|
|
59
|
+
template_type: default
|
|
60
|
+
|
|
61
|
+
windsurf:
|
|
62
|
+
name: "Windsurf"
|
|
63
|
+
preferred: true
|
|
64
|
+
category: ide
|
|
65
|
+
description: "AI-powered IDE with cascade flows"
|
|
66
|
+
installer:
|
|
67
|
+
target_dir: .windsurf/workflows
|
|
68
|
+
template_type: windsurf
|
|
69
|
+
|
|
70
|
+
cline:
|
|
71
|
+
name: "Cline"
|
|
72
|
+
preferred: false
|
|
73
|
+
category: ide
|
|
74
|
+
description: "AI coding assistant"
|
|
75
|
+
installer:
|
|
76
|
+
target_dir: .clinerules/workflows
|
|
77
|
+
template_type: windsurf
|
|
78
|
+
|
|
79
|
+
roo:
|
|
80
|
+
name: "Roo Cline"
|
|
81
|
+
preferred: false
|
|
82
|
+
category: ide
|
|
83
|
+
description: "Enhanced Cline fork"
|
|
84
|
+
installer:
|
|
85
|
+
target_dir: .roo/commands
|
|
86
|
+
template_type: default
|
|
87
|
+
|
|
88
|
+
github-copilot:
|
|
89
|
+
name: "GitHub Copilot"
|
|
90
|
+
preferred: false
|
|
91
|
+
category: ide
|
|
92
|
+
description: "GitHub's AI pair programmer"
|
|
93
|
+
installer:
|
|
94
|
+
targets:
|
|
95
|
+
- target_dir: .github/agents
|
|
96
|
+
template_type: copilot_agents
|
|
97
|
+
artifact_types: [agents]
|
|
98
|
+
- target_dir: .vscode
|
|
99
|
+
template_type: vscode_settings
|
|
100
|
+
artifact_types: []
|
|
101
|
+
|
|
102
|
+
opencode:
|
|
103
|
+
name: "OpenCode"
|
|
104
|
+
preferred: false
|
|
105
|
+
category: ide
|
|
106
|
+
description: "OpenCode terminal coding assistant"
|
|
107
|
+
installer:
|
|
108
|
+
target_dir: .opencode/command
|
|
109
|
+
template_type: opencode
|
|
110
|
+
|
|
111
|
+
crush:
|
|
112
|
+
name: "Crush"
|
|
113
|
+
preferred: false
|
|
114
|
+
category: ide
|
|
115
|
+
description: "AI development assistant"
|
|
116
|
+
installer:
|
|
117
|
+
target_dir: .crush/commands
|
|
118
|
+
template_type: default
|
|
119
|
+
|
|
120
|
+
iflow:
|
|
121
|
+
name: "iFlow"
|
|
122
|
+
preferred: false
|
|
123
|
+
category: ide
|
|
124
|
+
description: "AI workflow automation"
|
|
125
|
+
installer:
|
|
126
|
+
target_dir: .iflow/commands
|
|
127
|
+
template_type: default
|
|
128
|
+
|
|
129
|
+
qwen:
|
|
130
|
+
name: "QwenCoder"
|
|
131
|
+
preferred: false
|
|
132
|
+
category: ide
|
|
133
|
+
description: "Qwen AI coding assistant"
|
|
134
|
+
installer:
|
|
135
|
+
target_dir: .qwen/commands
|
|
136
|
+
template_type: default
|
|
137
|
+
|
|
138
|
+
rovo-dev:
|
|
139
|
+
name: "Rovo Dev"
|
|
140
|
+
preferred: false
|
|
141
|
+
category: ide
|
|
142
|
+
description: "Atlassian's Rovo development environment"
|
|
143
|
+
installer:
|
|
144
|
+
target_dir: .rovodev/workflows
|
|
145
|
+
template_type: rovodev
|
|
146
|
+
|
|
147
|
+
trae:
|
|
148
|
+
name: "Trae"
|
|
149
|
+
preferred: false
|
|
150
|
+
category: ide
|
|
151
|
+
description: "AI coding tool"
|
|
152
|
+
installer:
|
|
153
|
+
target_dir: .trae/rules
|
|
154
|
+
template_type: trae
|
|
155
|
+
|
|
156
|
+
antigravity:
|
|
157
|
+
name: "Google Antigravity"
|
|
158
|
+
preferred: false
|
|
159
|
+
category: ide
|
|
160
|
+
description: "Google's AI development environment"
|
|
161
|
+
installer:
|
|
162
|
+
target_dir: .agent/workflows
|
|
163
|
+
template_type: antigravity
|
|
164
|
+
# Note: Antigravity uses .agent/workflows/ directory (not .antigravity/)
|
|
165
|
+
|
|
166
|
+
# ============================================================================
|
|
167
|
+
# Custom Installers (no installer config - use custom file)
|
|
168
|
+
# These have unique installation logic that doesn't fit the config-driven model
|
|
169
|
+
# ============================================================================
|
|
170
|
+
|
|
171
|
+
codex:
|
|
172
|
+
name: "Codex"
|
|
173
|
+
preferred: false
|
|
174
|
+
category: cli
|
|
175
|
+
description: "OpenAI Codex integration"
|
|
176
|
+
# No installer config - uses custom codex.js
|
|
177
|
+
|
|
178
|
+
kilo:
|
|
179
|
+
name: "KiloCoder"
|
|
180
|
+
preferred: false
|
|
181
|
+
category: ide
|
|
182
|
+
description: "AI coding platform"
|
|
183
|
+
# No installer config - uses custom kilo.js (creates .kilocodemodes file)
|
|
184
|
+
|
|
185
|
+
kiro-cli:
|
|
186
|
+
name: "Kiro CLI"
|
|
187
|
+
preferred: false
|
|
188
|
+
category: cli
|
|
189
|
+
description: "Kiro command-line interface"
|
|
190
|
+
# No installer config - uses custom kiro-cli.js (YAML→JSON conversion)
|
|
191
|
+
|
|
192
|
+
# ============================================================================
|
|
193
|
+
# Installer Config Schema
|
|
194
|
+
# ============================================================================
|
|
195
|
+
#
|
|
196
|
+
# installer:
|
|
197
|
+
# target_dir: string # Directory where artifacts are installed
|
|
198
|
+
# template_type: string # Default template type to use
|
|
199
|
+
# header_template: string (optional) # Override for header/frontmatter template
|
|
200
|
+
# body_template: string (optional) # Override for body/content template
|
|
201
|
+
# targets: array (optional) # For multi-target installations
|
|
202
|
+
# - target_dir: string
|
|
203
|
+
# template_type: string
|
|
204
|
+
# artifact_types: [agents, workflows, tasks, tools]
|
|
205
|
+
# artifact_types: array (optional) # Filter which artifacts to install (default: all)
|
|
206
|
+
# skip_existing: boolean (optional) # Skip files that already exist (default: false)
|
|
207
|
+
|
|
208
|
+
# ============================================================================
|
|
209
|
+
# Platform Categories
|
|
210
|
+
# ============================================================================
|
|
211
|
+
|
|
212
|
+
categories:
|
|
213
|
+
ide:
|
|
214
|
+
name: "Integrated Development Environment"
|
|
215
|
+
description: "Full-featured code editors with AI assistance"
|
|
216
|
+
|
|
217
|
+
cli:
|
|
218
|
+
name: "Command Line Interface"
|
|
219
|
+
description: "Terminal-based tools"
|
|
220
|
+
|
|
221
|
+
tool:
|
|
222
|
+
name: "Development Tool"
|
|
223
|
+
description: "Standalone development utilities"
|
|
224
|
+
|
|
225
|
+
service:
|
|
226
|
+
name: "Cloud Service"
|
|
227
|
+
description: "Cloud-based development platforms"
|
|
228
|
+
|
|
229
|
+
extension:
|
|
230
|
+
name: "Editor Extension"
|
|
231
|
+
description: "Plugins for existing editors"
|
|
232
|
+
|
|
233
|
+
# ============================================================================
|
|
234
|
+
# Naming Conventions and Rules
|
|
235
|
+
# ============================================================================
|
|
236
|
+
|
|
237
|
+
conventions:
|
|
238
|
+
code_format: "lowercase-kebab-case"
|
|
239
|
+
name_format: "Title Case"
|
|
240
|
+
max_code_length: 20
|
|
241
|
+
allowed_characters: "a-z0-9-"
|
|
@@ -31,11 +31,23 @@ class AgentCommandGenerator {
|
|
|
31
31
|
const launcherContent = await this.generateLauncherContent(agent);
|
|
32
32
|
// Use relativePath if available (for nested agents), otherwise just name with .md
|
|
33
33
|
const agentPathInModule = agent.relativePath || `${agent.name}.md`;
|
|
34
|
+
// Calculate the relative agent path (e.g., bmm/agents/pm.md)
|
|
35
|
+
let agentRelPath = agent.path;
|
|
36
|
+
// Remove _bmad/ prefix if present to get relative path from project root
|
|
37
|
+
// Handle both absolute paths (/path/to/_bmad/...) and relative paths (_bmad/...)
|
|
38
|
+
if (agentRelPath.includes('_bmad/')) {
|
|
39
|
+
const parts = agentRelPath.split(/_bmad\//);
|
|
40
|
+
if (parts.length > 1) {
|
|
41
|
+
agentRelPath = parts.slice(1).join('/');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
34
44
|
artifacts.push({
|
|
35
45
|
type: 'agent-launcher',
|
|
36
|
-
module: agent.module,
|
|
37
46
|
name: agent.name,
|
|
38
|
-
|
|
47
|
+
description: agent.description || `${agent.name} agent`,
|
|
48
|
+
module: agent.module,
|
|
49
|
+
relativePath: path.join(agent.module, 'agents', agentPathInModule), // For command filename
|
|
50
|
+
agentPath: agentRelPath, // Relative path to actual agent file
|
|
39
51
|
content: launcherContent,
|
|
40
52
|
sourcePath: agent.path,
|
|
41
53
|
});
|
|
@@ -119,8 +131,10 @@ class AgentCommandGenerator {
|
|
|
119
131
|
}
|
|
120
132
|
|
|
121
133
|
/**
|
|
122
|
-
* Write agent launcher artifacts using
|
|
123
|
-
* Creates flat files like:
|
|
134
|
+
* Write agent launcher artifacts using dash format (NEW STANDARD)
|
|
135
|
+
* Creates flat files like: bmad-bmm-pm.agent.md
|
|
136
|
+
*
|
|
137
|
+
* The .agent.md suffix distinguishes agents from workflows/tasks/tools.
|
|
124
138
|
*
|
|
125
139
|
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
|
126
140
|
* @param {Array} artifacts - Agent launcher artifacts
|
|
@@ -131,7 +145,7 @@ class AgentCommandGenerator {
|
|
|
131
145
|
|
|
132
146
|
for (const artifact of artifacts) {
|
|
133
147
|
if (artifact.type === 'agent-launcher') {
|
|
134
|
-
// Convert relativePath to
|
|
148
|
+
// Convert relativePath to dash format: bmm/agents/pm.md → bmad-bmm-pm.agent.md
|
|
135
149
|
const flatName = toDashPath(artifact.relativePath);
|
|
136
150
|
const launcherPath = path.join(baseCommandsDir, flatName);
|
|
137
151
|
await fs.ensureDir(path.dirname(launcherPath));
|
|
@@ -86,6 +86,11 @@ async function getAgentsFromDir(dirPath, moduleName, relativePath = '') {
|
|
|
86
86
|
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
87
87
|
|
|
88
88
|
for (const entry of entries) {
|
|
89
|
+
// Skip if entry.name is undefined or not a string
|
|
90
|
+
if (!entry.name || typeof entry.name !== 'string') {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
|
|
89
94
|
const fullPath = path.join(dirPath, entry.name);
|
|
90
95
|
const newRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
91
96
|
|