bmad-method 6.2.3-next.0 → 6.2.3-next.1
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/package.json +8 -8
- package/src/core-skills/bmad-distillator/resources/distillate-format-reference.md +1 -1
- package/tools/{cli → installer}/bmad-cli.js +3 -1
- package/tools/{cli/lib → installer}/cli-utils.js +3 -4
- package/tools/{cli → installer}/commands/install.js +3 -3
- package/tools/{cli → installer}/commands/status.js +4 -4
- package/tools/{cli → installer}/commands/uninstall.js +5 -5
- package/tools/installer/core/config.js +52 -0
- package/tools/{cli/installers/lib → installer}/core/custom-module-cache.js +1 -1
- package/tools/installer/core/existing-install.js +127 -0
- package/tools/installer/core/install-paths.js +129 -0
- package/tools/installer/core/installer.js +1790 -0
- package/tools/{cli/installers/lib → installer}/core/manifest-generator.js +3 -3
- package/tools/{cli/installers/lib → installer}/core/manifest.js +2 -2
- package/tools/{cli/installers/lib/custom/handler.js → installer/custom-handler.js} +1 -1
- package/tools/{cli/installers/lib → installer}/ide/_config-driven.js +30 -397
- package/tools/{cli/installers/lib → installer}/ide/manager.js +1 -53
- package/tools/installer/ide/platform-codes.js +37 -0
- package/tools/installer/ide/platform-codes.yaml +190 -0
- package/tools/{cli/installers/lib → installer}/ide/shared/module-injections.js +1 -1
- package/tools/{cli/installers/lib → installer}/message-loader.js +2 -2
- package/tools/installer/modules/custom-modules.js +197 -0
- package/tools/installer/modules/external-manager.js +323 -0
- package/tools/{cli/installers/lib/core/config-collector.js → installer/modules/official-modules.js} +714 -43
- package/tools/{cli/lib → installer}/ui.js +65 -299
- package/tools/javascript-conventions.md +5 -0
- package/tools/bmad-npx-wrapper.js +0 -38
- package/tools/cli/installers/lib/core/dependency-resolver.js +0 -743
- package/tools/cli/installers/lib/core/detector.js +0 -223
- package/tools/cli/installers/lib/core/ide-config-manager.js +0 -157
- package/tools/cli/installers/lib/core/installer.js +0 -3002
- package/tools/cli/installers/lib/ide/_base-ide.js +0 -657
- package/tools/cli/installers/lib/ide/platform-codes.js +0 -100
- package/tools/cli/installers/lib/ide/platform-codes.yaml +0 -341
- package/tools/cli/installers/lib/modules/external-manager.js +0 -136
- package/tools/cli/installers/lib/modules/manager.js +0 -928
- package/tools/cli/lib/config.js +0 -213
- package/tools/cli/lib/platform-codes.js +0 -116
- package/tools/lib/xml-utils.js +0 -13
- /package/tools/{cli → installer}/README.md +0 -0
- /package/tools/{cli → installer}/external-official-modules.yaml +0 -0
- /package/tools/{cli/lib → installer}/file-ops.js +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/shared/agent-command-generator.js +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/shared/bmad-artifacts.js +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/shared/path-utils.js +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/shared/skill-manifest.js +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/agent-command-template.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/antigravity.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-agent.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-task.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-tool.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-workflow.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-agent.toml +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-task.toml +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-tool.toml +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-workflow-yaml.toml +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-workflow.toml +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-agent.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-task.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-tool.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-workflow.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-agent.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-task.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-tool.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-workflow-yaml.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-workflow.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/rovodev.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/trae.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/combined/windsurf-workflow.md +0 -0
- /package/tools/{cli/installers/lib → installer}/ide/templates/split/.gitkeep +0 -0
- /package/tools/{cli/installers → installer}/install-messages.yaml +0 -0
- /package/tools/{cli/lib → installer}/project-root.js +0 -0
- /package/tools/{cli/lib → installer}/prompts.js +0 -0
- /package/tools/{cli/lib → installer}/yaml-format.js +0 -0
|
@@ -1,100 +0,0 @@
|
|
|
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
|
-
};
|
|
@@ -1,341 +0,0 @@
|
|
|
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
|
-
antigravity:
|
|
18
|
-
name: "Google Antigravity"
|
|
19
|
-
preferred: false
|
|
20
|
-
category: ide
|
|
21
|
-
description: "Google's AI development environment"
|
|
22
|
-
installer:
|
|
23
|
-
legacy_targets:
|
|
24
|
-
- .agent/workflows
|
|
25
|
-
target_dir: .agent/skills
|
|
26
|
-
template_type: antigravity
|
|
27
|
-
skill_format: true
|
|
28
|
-
|
|
29
|
-
auggie:
|
|
30
|
-
name: "Auggie"
|
|
31
|
-
preferred: false
|
|
32
|
-
category: cli
|
|
33
|
-
description: "AI development tool"
|
|
34
|
-
installer:
|
|
35
|
-
legacy_targets:
|
|
36
|
-
- .augment/commands
|
|
37
|
-
target_dir: .augment/skills
|
|
38
|
-
template_type: default
|
|
39
|
-
skill_format: true
|
|
40
|
-
|
|
41
|
-
claude-code:
|
|
42
|
-
name: "Claude Code"
|
|
43
|
-
preferred: true
|
|
44
|
-
category: cli
|
|
45
|
-
description: "Anthropic's official CLI for Claude"
|
|
46
|
-
installer:
|
|
47
|
-
legacy_targets:
|
|
48
|
-
- .claude/commands
|
|
49
|
-
target_dir: .claude/skills
|
|
50
|
-
template_type: default
|
|
51
|
-
skill_format: true
|
|
52
|
-
ancestor_conflict_check: true
|
|
53
|
-
|
|
54
|
-
cline:
|
|
55
|
-
name: "Cline"
|
|
56
|
-
preferred: false
|
|
57
|
-
category: ide
|
|
58
|
-
description: "AI coding assistant"
|
|
59
|
-
installer:
|
|
60
|
-
legacy_targets:
|
|
61
|
-
- .clinerules/workflows
|
|
62
|
-
target_dir: .cline/skills
|
|
63
|
-
template_type: default
|
|
64
|
-
skill_format: true
|
|
65
|
-
|
|
66
|
-
codex:
|
|
67
|
-
name: "Codex"
|
|
68
|
-
preferred: false
|
|
69
|
-
category: cli
|
|
70
|
-
description: "OpenAI Codex integration"
|
|
71
|
-
installer:
|
|
72
|
-
legacy_targets:
|
|
73
|
-
- .codex/prompts
|
|
74
|
-
- ~/.codex/prompts
|
|
75
|
-
target_dir: .agents/skills
|
|
76
|
-
template_type: default
|
|
77
|
-
skill_format: true
|
|
78
|
-
ancestor_conflict_check: true
|
|
79
|
-
artifact_types: [agents, workflows, tasks]
|
|
80
|
-
|
|
81
|
-
codebuddy:
|
|
82
|
-
name: "CodeBuddy"
|
|
83
|
-
preferred: false
|
|
84
|
-
category: ide
|
|
85
|
-
description: "Tencent Cloud Code Assistant - AI-powered coding companion"
|
|
86
|
-
installer:
|
|
87
|
-
legacy_targets:
|
|
88
|
-
- .codebuddy/commands
|
|
89
|
-
target_dir: .codebuddy/skills
|
|
90
|
-
template_type: default
|
|
91
|
-
skill_format: true
|
|
92
|
-
|
|
93
|
-
crush:
|
|
94
|
-
name: "Crush"
|
|
95
|
-
preferred: false
|
|
96
|
-
category: ide
|
|
97
|
-
description: "AI development assistant"
|
|
98
|
-
installer:
|
|
99
|
-
legacy_targets:
|
|
100
|
-
- .crush/commands
|
|
101
|
-
target_dir: .crush/skills
|
|
102
|
-
template_type: default
|
|
103
|
-
skill_format: true
|
|
104
|
-
|
|
105
|
-
cursor:
|
|
106
|
-
name: "Cursor"
|
|
107
|
-
preferred: true
|
|
108
|
-
category: ide
|
|
109
|
-
description: "AI-first code editor"
|
|
110
|
-
installer:
|
|
111
|
-
legacy_targets:
|
|
112
|
-
- .cursor/commands
|
|
113
|
-
target_dir: .cursor/skills
|
|
114
|
-
template_type: default
|
|
115
|
-
skill_format: true
|
|
116
|
-
|
|
117
|
-
gemini:
|
|
118
|
-
name: "Gemini CLI"
|
|
119
|
-
preferred: false
|
|
120
|
-
category: cli
|
|
121
|
-
description: "Google's CLI for Gemini"
|
|
122
|
-
installer:
|
|
123
|
-
legacy_targets:
|
|
124
|
-
- .gemini/commands
|
|
125
|
-
target_dir: .gemini/skills
|
|
126
|
-
template_type: default
|
|
127
|
-
skill_format: true
|
|
128
|
-
|
|
129
|
-
github-copilot:
|
|
130
|
-
name: "GitHub Copilot"
|
|
131
|
-
preferred: false
|
|
132
|
-
category: ide
|
|
133
|
-
description: "GitHub's AI pair programmer"
|
|
134
|
-
installer:
|
|
135
|
-
legacy_targets:
|
|
136
|
-
- .github/agents
|
|
137
|
-
- .github/prompts
|
|
138
|
-
target_dir: .github/skills
|
|
139
|
-
template_type: default
|
|
140
|
-
skill_format: true
|
|
141
|
-
|
|
142
|
-
iflow:
|
|
143
|
-
name: "iFlow"
|
|
144
|
-
preferred: false
|
|
145
|
-
category: ide
|
|
146
|
-
description: "AI workflow automation"
|
|
147
|
-
installer:
|
|
148
|
-
legacy_targets:
|
|
149
|
-
- .iflow/commands
|
|
150
|
-
target_dir: .iflow/skills
|
|
151
|
-
template_type: default
|
|
152
|
-
skill_format: true
|
|
153
|
-
|
|
154
|
-
kilo:
|
|
155
|
-
name: "KiloCoder"
|
|
156
|
-
preferred: false
|
|
157
|
-
category: ide
|
|
158
|
-
description: "AI coding platform"
|
|
159
|
-
suspended: "Kilo Code does not yet support the Agent Skills standard. Support is paused until they implement it. See https://github.com/kilocode/kilo-code/issues for updates."
|
|
160
|
-
installer:
|
|
161
|
-
legacy_targets:
|
|
162
|
-
- .kilocode/workflows
|
|
163
|
-
target_dir: .kilocode/skills
|
|
164
|
-
template_type: default
|
|
165
|
-
skill_format: true
|
|
166
|
-
|
|
167
|
-
kiro:
|
|
168
|
-
name: "Kiro"
|
|
169
|
-
preferred: false
|
|
170
|
-
category: ide
|
|
171
|
-
description: "Amazon's AI-powered IDE"
|
|
172
|
-
installer:
|
|
173
|
-
legacy_targets:
|
|
174
|
-
- .kiro/steering
|
|
175
|
-
target_dir: .kiro/skills
|
|
176
|
-
template_type: kiro
|
|
177
|
-
skill_format: true
|
|
178
|
-
|
|
179
|
-
ona:
|
|
180
|
-
name: "Ona"
|
|
181
|
-
preferred: false
|
|
182
|
-
category: ide
|
|
183
|
-
description: "Ona AI development environment"
|
|
184
|
-
installer:
|
|
185
|
-
target_dir: .ona/skills
|
|
186
|
-
template_type: default
|
|
187
|
-
skill_format: true
|
|
188
|
-
|
|
189
|
-
opencode:
|
|
190
|
-
name: "OpenCode"
|
|
191
|
-
preferred: false
|
|
192
|
-
category: ide
|
|
193
|
-
description: "OpenCode terminal coding assistant"
|
|
194
|
-
installer:
|
|
195
|
-
legacy_targets:
|
|
196
|
-
- .opencode/agents
|
|
197
|
-
- .opencode/commands
|
|
198
|
-
- .opencode/agent
|
|
199
|
-
- .opencode/command
|
|
200
|
-
target_dir: .opencode/skills
|
|
201
|
-
template_type: opencode
|
|
202
|
-
skill_format: true
|
|
203
|
-
ancestor_conflict_check: true
|
|
204
|
-
|
|
205
|
-
pi:
|
|
206
|
-
name: "Pi"
|
|
207
|
-
preferred: false
|
|
208
|
-
category: cli
|
|
209
|
-
description: "Provider-agnostic terminal-native AI coding agent"
|
|
210
|
-
installer:
|
|
211
|
-
target_dir: .pi/skills
|
|
212
|
-
template_type: default
|
|
213
|
-
skill_format: true
|
|
214
|
-
|
|
215
|
-
qoder:
|
|
216
|
-
name: "Qoder"
|
|
217
|
-
preferred: false
|
|
218
|
-
category: ide
|
|
219
|
-
description: "Qoder AI coding assistant"
|
|
220
|
-
installer:
|
|
221
|
-
target_dir: .qoder/skills
|
|
222
|
-
template_type: default
|
|
223
|
-
skill_format: true
|
|
224
|
-
|
|
225
|
-
qwen:
|
|
226
|
-
name: "QwenCoder"
|
|
227
|
-
preferred: false
|
|
228
|
-
category: ide
|
|
229
|
-
description: "Qwen AI coding assistant"
|
|
230
|
-
installer:
|
|
231
|
-
legacy_targets:
|
|
232
|
-
- .qwen/commands
|
|
233
|
-
target_dir: .qwen/skills
|
|
234
|
-
template_type: default
|
|
235
|
-
skill_format: true
|
|
236
|
-
|
|
237
|
-
roo:
|
|
238
|
-
name: "Roo Code"
|
|
239
|
-
preferred: false
|
|
240
|
-
category: ide
|
|
241
|
-
description: "Enhanced Cline fork"
|
|
242
|
-
installer:
|
|
243
|
-
legacy_targets:
|
|
244
|
-
- .roo/commands
|
|
245
|
-
target_dir: .roo/skills
|
|
246
|
-
template_type: default
|
|
247
|
-
skill_format: true
|
|
248
|
-
|
|
249
|
-
rovo-dev:
|
|
250
|
-
name: "Rovo Dev"
|
|
251
|
-
preferred: false
|
|
252
|
-
category: ide
|
|
253
|
-
description: "Atlassian's Rovo development environment"
|
|
254
|
-
installer:
|
|
255
|
-
legacy_targets:
|
|
256
|
-
- .rovodev/workflows
|
|
257
|
-
target_dir: .rovodev/skills
|
|
258
|
-
template_type: default
|
|
259
|
-
skill_format: true
|
|
260
|
-
|
|
261
|
-
trae:
|
|
262
|
-
name: "Trae"
|
|
263
|
-
preferred: false
|
|
264
|
-
category: ide
|
|
265
|
-
description: "AI coding tool"
|
|
266
|
-
installer:
|
|
267
|
-
legacy_targets:
|
|
268
|
-
- .trae/rules
|
|
269
|
-
target_dir: .trae/skills
|
|
270
|
-
template_type: default
|
|
271
|
-
skill_format: true
|
|
272
|
-
|
|
273
|
-
windsurf:
|
|
274
|
-
name: "Windsurf"
|
|
275
|
-
preferred: false
|
|
276
|
-
category: ide
|
|
277
|
-
description: "AI-powered IDE with cascade flows"
|
|
278
|
-
installer:
|
|
279
|
-
legacy_targets:
|
|
280
|
-
- .windsurf/workflows
|
|
281
|
-
target_dir: .windsurf/skills
|
|
282
|
-
template_type: windsurf
|
|
283
|
-
skill_format: true
|
|
284
|
-
|
|
285
|
-
# ============================================================================
|
|
286
|
-
# Installer Config Schema
|
|
287
|
-
# ============================================================================
|
|
288
|
-
#
|
|
289
|
-
# installer:
|
|
290
|
-
# target_dir: string # Directory where artifacts are installed
|
|
291
|
-
# template_type: string # Default template type to use
|
|
292
|
-
# header_template: string (optional) # Override for header/frontmatter template
|
|
293
|
-
# body_template: string (optional) # Override for body/content template
|
|
294
|
-
# legacy_targets: array (optional) # Old target dirs to clean up on reinstall (migration)
|
|
295
|
-
# - string # Relative path, e.g. .opencode/agent
|
|
296
|
-
# targets: array (optional) # For multi-target installations
|
|
297
|
-
# - target_dir: string
|
|
298
|
-
# template_type: string
|
|
299
|
-
# artifact_types: [agents, workflows, tasks, tools]
|
|
300
|
-
# artifact_types: array (optional) # Filter which artifacts to install (default: all)
|
|
301
|
-
# skip_existing: boolean (optional) # Skip files that already exist (default: false)
|
|
302
|
-
# skill_format: boolean (optional) # Use directory-per-skill output: <name>/SKILL.md
|
|
303
|
-
# # with clean frontmatter (name + description, unquoted)
|
|
304
|
-
# ancestor_conflict_check: boolean (optional) # Refuse install when ancestor dir has BMAD files
|
|
305
|
-
# # in the same target_dir (for IDEs that inherit
|
|
306
|
-
# # skills from parent directories)
|
|
307
|
-
|
|
308
|
-
# ============================================================================
|
|
309
|
-
# Platform Categories
|
|
310
|
-
# ============================================================================
|
|
311
|
-
|
|
312
|
-
categories:
|
|
313
|
-
ide:
|
|
314
|
-
name: "Integrated Development Environment"
|
|
315
|
-
description: "Full-featured code editors with AI assistance"
|
|
316
|
-
|
|
317
|
-
cli:
|
|
318
|
-
name: "Command Line Interface"
|
|
319
|
-
description: "Terminal-based tools"
|
|
320
|
-
|
|
321
|
-
tool:
|
|
322
|
-
name: "Development Tool"
|
|
323
|
-
description: "Standalone development utilities"
|
|
324
|
-
|
|
325
|
-
service:
|
|
326
|
-
name: "Cloud Service"
|
|
327
|
-
description: "Cloud-based development platforms"
|
|
328
|
-
|
|
329
|
-
extension:
|
|
330
|
-
name: "Editor Extension"
|
|
331
|
-
description: "Plugins for existing editors"
|
|
332
|
-
|
|
333
|
-
# ============================================================================
|
|
334
|
-
# Naming Conventions and Rules
|
|
335
|
-
# ============================================================================
|
|
336
|
-
|
|
337
|
-
conventions:
|
|
338
|
-
code_format: "lowercase-kebab-case"
|
|
339
|
-
name_format: "Title Case"
|
|
340
|
-
max_code_length: 20
|
|
341
|
-
allowed_characters: "a-z0-9-"
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('node:path');
|
|
3
|
-
const yaml = require('yaml');
|
|
4
|
-
const prompts = require('../../../lib/prompts');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Manages external official modules defined in external-official-modules.yaml
|
|
8
|
-
* These are modules hosted in external repositories that can be installed
|
|
9
|
-
*
|
|
10
|
-
* @class ExternalModuleManager
|
|
11
|
-
*/
|
|
12
|
-
class ExternalModuleManager {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.externalModulesConfigPath = path.join(__dirname, '../../../external-official-modules.yaml');
|
|
15
|
-
this.cachedModules = null;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Load and parse the external-official-modules.yaml file
|
|
20
|
-
* @returns {Object} Parsed YAML content with modules object
|
|
21
|
-
*/
|
|
22
|
-
async loadExternalModulesConfig() {
|
|
23
|
-
if (this.cachedModules) {
|
|
24
|
-
return this.cachedModules;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const content = await fs.readFile(this.externalModulesConfigPath, 'utf8');
|
|
29
|
-
const config = yaml.parse(content);
|
|
30
|
-
this.cachedModules = config;
|
|
31
|
-
return config;
|
|
32
|
-
} catch (error) {
|
|
33
|
-
await prompts.log.warn(`Failed to load external modules config: ${error.message}`);
|
|
34
|
-
return { modules: {} };
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Get list of available external modules
|
|
40
|
-
* @returns {Array<Object>} Array of module info objects
|
|
41
|
-
*/
|
|
42
|
-
async listAvailable() {
|
|
43
|
-
const config = await this.loadExternalModulesConfig();
|
|
44
|
-
const modules = [];
|
|
45
|
-
|
|
46
|
-
for (const [key, moduleConfig] of Object.entries(config.modules || {})) {
|
|
47
|
-
modules.push({
|
|
48
|
-
key,
|
|
49
|
-
url: moduleConfig.url,
|
|
50
|
-
moduleDefinition: moduleConfig['module-definition'],
|
|
51
|
-
code: moduleConfig.code,
|
|
52
|
-
name: moduleConfig.name,
|
|
53
|
-
header: moduleConfig.header,
|
|
54
|
-
subheader: moduleConfig.subheader,
|
|
55
|
-
description: moduleConfig.description || '',
|
|
56
|
-
defaultSelected: moduleConfig.defaultSelected === true,
|
|
57
|
-
type: moduleConfig.type || 'community', // bmad-org or community
|
|
58
|
-
npmPackage: moduleConfig.npmPackage || null, // Include npm package name
|
|
59
|
-
isExternal: true,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return modules;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Get module info by code
|
|
68
|
-
* @param {string} code - The module code (e.g., 'cis')
|
|
69
|
-
* @returns {Object|null} Module info or null if not found
|
|
70
|
-
*/
|
|
71
|
-
async getModuleByCode(code) {
|
|
72
|
-
const modules = await this.listAvailable();
|
|
73
|
-
return modules.find((m) => m.code === code) || null;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Get module info by key
|
|
78
|
-
* @param {string} key - The module key (e.g., 'bmad-creative-intelligence-suite')
|
|
79
|
-
* @returns {Object|null} Module info or null if not found
|
|
80
|
-
*/
|
|
81
|
-
async getModuleByKey(key) {
|
|
82
|
-
const config = await this.loadExternalModulesConfig();
|
|
83
|
-
const moduleConfig = config.modules?.[key];
|
|
84
|
-
|
|
85
|
-
if (!moduleConfig) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
key,
|
|
91
|
-
url: moduleConfig.url,
|
|
92
|
-
moduleDefinition: moduleConfig['module-definition'],
|
|
93
|
-
code: moduleConfig.code,
|
|
94
|
-
name: moduleConfig.name,
|
|
95
|
-
header: moduleConfig.header,
|
|
96
|
-
subheader: moduleConfig.subheader,
|
|
97
|
-
description: moduleConfig.description || '',
|
|
98
|
-
defaultSelected: moduleConfig.defaultSelected === true,
|
|
99
|
-
type: moduleConfig.type || 'community', // bmad-org or community
|
|
100
|
-
npmPackage: moduleConfig.npmPackage || null, // Include npm package name
|
|
101
|
-
isExternal: true,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Check if a module code exists in external modules
|
|
107
|
-
* @param {string} code - The module code to check
|
|
108
|
-
* @returns {boolean} True if the module exists
|
|
109
|
-
*/
|
|
110
|
-
async hasModule(code) {
|
|
111
|
-
const module = await this.getModuleByCode(code);
|
|
112
|
-
return module !== null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Get the URL for a module by code
|
|
117
|
-
* @param {string} code - The module code
|
|
118
|
-
* @returns {string|null} The URL or null if not found
|
|
119
|
-
*/
|
|
120
|
-
async getModuleUrl(code) {
|
|
121
|
-
const module = await this.getModuleByCode(code);
|
|
122
|
-
return module ? module.url : null;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Get the module definition path for a module by code
|
|
127
|
-
* @param {string} code - The module code
|
|
128
|
-
* @returns {string|null} The module definition path or null if not found
|
|
129
|
-
*/
|
|
130
|
-
async getModuleDefinition(code) {
|
|
131
|
-
const module = await this.getModuleByCode(code);
|
|
132
|
-
return module ? module.moduleDefinition : null;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
module.exports = { ExternalModuleManager };
|