bmad-method 6.3.1-next.2 → 6.3.1-next.20
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 +1 -2
- package/src/bmm-skills/1-analysis/bmad-agent-analyst/SKILL.md +51 -36
- package/src/bmm-skills/1-analysis/bmad-agent-analyst/customize.toml +90 -0
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/SKILL.md +50 -33
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.toml +81 -0
- package/src/bmm-skills/1-analysis/bmad-document-project/SKILL.md +57 -1
- package/src/bmm-skills/1-analysis/bmad-document-project/customize.toml +41 -0
- package/src/bmm-skills/1-analysis/bmad-document-project/workflows/deep-dive-instructions.md +1 -0
- package/src/bmm-skills/1-analysis/bmad-document-project/workflows/full-scan-instructions.md +1 -0
- package/src/bmm-skills/1-analysis/bmad-prfaq/SKILL.md +48 -9
- package/src/bmm-skills/1-analysis/bmad-prfaq/customize.toml +41 -0
- package/src/bmm-skills/1-analysis/bmad-prfaq/references/verdict.md +4 -0
- package/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md +44 -9
- package/src/bmm-skills/1-analysis/bmad-product-brief/customize.toml +47 -0
- package/src/bmm-skills/1-analysis/bmad-product-brief/prompts/contextual-discovery.md +8 -7
- package/src/bmm-skills/1-analysis/bmad-product-brief/prompts/draft-and-review.md +6 -5
- package/src/bmm-skills/1-analysis/bmad-product-brief/prompts/finalize.md +4 -1
- package/src/bmm-skills/1-analysis/bmad-product-brief/prompts/guided-elicitation.md +3 -2
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/SKILL.md +91 -1
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/customize.toml +41 -0
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +6 -0
- package/src/bmm-skills/1-analysis/research/bmad-market-research/SKILL.md +91 -1
- package/src/bmm-skills/1-analysis/research/bmad-market-research/customize.toml +41 -0
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +6 -0
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/SKILL.md +91 -1
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/customize.toml +41 -0
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +6 -0
- package/src/bmm-skills/2-plan-workflows/bmad-agent-pm/SKILL.md +50 -35
- package/src/bmm-skills/2-plan-workflows/bmad-agent-pm/customize.toml +85 -0
- package/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/SKILL.md +50 -31
- package/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/customize.toml +60 -0
- package/src/bmm-skills/2-plan-workflows/bmad-create-prd/SKILL.md +99 -1
- package/src/bmm-skills/2-plan-workflows/bmad-create-prd/customize.toml +41 -0
- package/src/bmm-skills/2-plan-workflows/bmad-create-prd/steps-c/step-08-scoping.md +70 -23
- package/src/bmm-skills/2-plan-workflows/bmad-create-prd/steps-c/step-11-polish.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-create-prd/steps-c/step-12-complete.md +6 -0
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/SKILL.md +70 -1
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/customize.toml +41 -0
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-14-complete.md +6 -0
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/SKILL.md +97 -1
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/customize.toml +42 -0
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +2 -0
- package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/SKILL.md +99 -1
- package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/customize.toml +42 -0
- package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/steps-v/step-v-13-report-complete.md +1 -0
- package/src/bmm-skills/3-solutioning/bmad-agent-architect/SKILL.md +50 -30
- package/src/bmm-skills/3-solutioning/bmad-agent-architect/customize.toml +65 -0
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/SKILL.md +86 -1
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/customize.toml +41 -0
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +6 -0
- package/src/bmm-skills/3-solutioning/bmad-create-architecture/SKILL.md +69 -1
- package/src/bmm-skills/3-solutioning/bmad-create-architecture/customize.toml +41 -0
- package/src/bmm-skills/3-solutioning/bmad-create-architecture/steps/step-08-complete.md +6 -0
- package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/SKILL.md +88 -1
- package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/customize.toml +41 -0
- package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/steps/step-04-final-validation.md +6 -0
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/SKILL.md +76 -1
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/customize.toml +41 -0
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-03-complete.md +6 -0
- package/src/bmm-skills/4-implementation/bmad-agent-dev/SKILL.md +48 -43
- package/src/bmm-skills/4-implementation/bmad-agent-dev/customize.toml +90 -0
- package/src/bmm-skills/4-implementation/bmad-correct-course/SKILL.md +296 -1
- package/src/bmm-skills/4-implementation/bmad-correct-course/customize.toml +41 -0
- package/src/bmm-skills/4-implementation/bmad-create-story/SKILL.md +412 -1
- package/src/bmm-skills/4-implementation/bmad-create-story/customize.toml +41 -0
- package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/SKILL.md +171 -1
- package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/customize.toml +41 -0
- package/src/bmm-skills/4-implementation/bmad-retrospective/SKILL.md +1507 -1
- package/src/bmm-skills/4-implementation/bmad-retrospective/customize.toml +41 -0
- package/src/bmm-skills/module.yaml +49 -0
- package/src/core-skills/bmad-advanced-elicitation/SKILL.md +7 -1
- package/src/core-skills/bmad-customize/SKILL.md +111 -0
- package/src/core-skills/bmad-customize/scripts/list_customizable_skills.py +231 -0
- package/src/core-skills/bmad-customize/scripts/tests/test_list_customizable_skills.py +249 -0
- package/src/core-skills/bmad-distillator/resources/distillate-format-reference.md +1 -1
- package/src/core-skills/bmad-party-mode/SKILL.md +13 -10
- package/src/core-skills/module-help.csv +1 -0
- package/src/core-skills/module.yaml +3 -0
- package/src/scripts/resolve_config.py +176 -0
- package/src/scripts/resolve_customization.py +230 -0
- package/tools/installer/cli-utils.js +0 -137
- package/tools/installer/commands/status.js +1 -1
- package/tools/installer/commands/uninstall.js +1 -1
- package/tools/installer/core/existing-install.js +1 -1
- package/tools/installer/core/install-paths.js +12 -6
- package/tools/installer/core/installer.js +88 -88
- package/tools/installer/core/manifest-generator.js +331 -189
- package/tools/installer/core/manifest.js +24 -642
- package/tools/installer/file-ops.js +1 -1
- package/tools/installer/fs-native.js +116 -0
- package/tools/installer/ide/_config-driven.js +1 -1
- package/tools/installer/ide/platform-codes.js +1 -1
- package/tools/installer/ide/shared/path-utils.js +0 -145
- package/tools/installer/ide/shared/skill-manifest.js +1 -1
- package/tools/installer/message-loader.js +1 -1
- package/tools/installer/modules/community-manager.js +11 -6
- package/tools/installer/modules/custom-module-manager.js +1 -28
- package/tools/installer/modules/external-manager.js +5 -44
- package/tools/installer/modules/official-modules.js +5 -53
- package/tools/installer/modules/plugin-resolver.js +1 -1
- package/tools/installer/modules/registry-client.js +133 -12
- package/tools/installer/modules/version-resolver.js +336 -0
- package/tools/installer/project-root.js +55 -1
- package/tools/installer/prompts.js +0 -106
- package/tools/installer/ui.js +50 -48
- package/tools/migrate-custom-module-paths.js +1 -1
- package/src/bmm-skills/1-analysis/bmad-agent-analyst/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/1-analysis/bmad-document-project/workflow.md +0 -25
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/workflow.md +0 -51
- package/src/bmm-skills/1-analysis/research/bmad-market-research/workflow.md +0 -51
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/workflow.md +0 -52
- package/src/bmm-skills/2-plan-workflows/bmad-agent-pm/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/2-plan-workflows/bmad-create-prd/workflow.md +0 -61
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/workflow.md +0 -35
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/workflow.md +0 -62
- package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/workflow.md +0 -61
- package/src/bmm-skills/3-solutioning/bmad-agent-architect/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/workflow.md +0 -47
- package/src/bmm-skills/3-solutioning/bmad-create-architecture/workflow.md +0 -32
- package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/workflow.md +0 -51
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/workflow.md +0 -39
- package/src/bmm-skills/4-implementation/bmad-agent-dev/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md +0 -267
- package/src/bmm-skills/4-implementation/bmad-create-story/workflow.md +0 -380
- package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/workflow.md +0 -136
- package/src/bmm-skills/4-implementation/bmad-retrospective/workflow.md +0 -1479
- package/tools/installer/ide/shared/agent-command-generator.js +0 -180
- package/tools/installer/ide/shared/bmad-artifacts.js +0 -208
- package/tools/installer/ide/shared/module-injections.js +0 -136
- package/tools/installer/ide/templates/agent-command-template.md +0 -14
- package/tools/installer/ide/templates/combined/antigravity.md +0 -8
- package/tools/installer/ide/templates/combined/default-agent.md +0 -15
- package/tools/installer/ide/templates/combined/default-task.md +0 -10
- package/tools/installer/ide/templates/combined/default-tool.md +0 -10
- package/tools/installer/ide/templates/combined/default-workflow.md +0 -6
- package/tools/installer/ide/templates/combined/gemini-agent.toml +0 -14
- package/tools/installer/ide/templates/combined/gemini-task.toml +0 -11
- package/tools/installer/ide/templates/combined/gemini-tool.toml +0 -11
- package/tools/installer/ide/templates/combined/gemini-workflow-yaml.toml +0 -16
- package/tools/installer/ide/templates/combined/gemini-workflow.toml +0 -14
- package/tools/installer/ide/templates/combined/kiro-agent.md +0 -16
- package/tools/installer/ide/templates/combined/kiro-task.md +0 -9
- package/tools/installer/ide/templates/combined/kiro-tool.md +0 -9
- package/tools/installer/ide/templates/combined/kiro-workflow.md +0 -7
- package/tools/installer/ide/templates/combined/opencode-agent.md +0 -15
- package/tools/installer/ide/templates/combined/opencode-task.md +0 -13
- package/tools/installer/ide/templates/combined/opencode-tool.md +0 -13
- package/tools/installer/ide/templates/combined/opencode-workflow-yaml.md +0 -16
- package/tools/installer/ide/templates/combined/opencode-workflow.md +0 -16
- package/tools/installer/ide/templates/combined/rovodev.md +0 -9
- package/tools/installer/ide/templates/combined/trae.md +0 -9
- package/tools/installer/ide/templates/combined/windsurf-workflow.md +0 -10
- package/tools/installer/ide/templates/split/.gitkeep +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Drop-in replacement for fs-extra using native node:fs APIs.
|
|
2
|
+
// Eliminates graceful-fs monkey-patching that causes non-deterministic
|
|
3
|
+
// file loss during multi-module installs on macOS (issue #1779).
|
|
4
|
+
const fsp = require('node:fs/promises');
|
|
5
|
+
const fs = require('node:fs');
|
|
6
|
+
const path = require('node:path');
|
|
7
|
+
|
|
8
|
+
async function pathExists(p) {
|
|
9
|
+
try {
|
|
10
|
+
await fsp.access(p);
|
|
11
|
+
return true;
|
|
12
|
+
} catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function ensureDir(dir) {
|
|
18
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function remove(p) {
|
|
22
|
+
await fsp.rm(p, { recursive: true, force: true });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function copy(src, dest, options = {}) {
|
|
26
|
+
const filterFn = options.filter;
|
|
27
|
+
const overwrite = options.overwrite !== false;
|
|
28
|
+
const srcStat = await fsp.stat(src);
|
|
29
|
+
|
|
30
|
+
if (srcStat.isFile()) {
|
|
31
|
+
if (filterFn && !(await filterFn(src, dest))) return;
|
|
32
|
+
await fsp.mkdir(path.dirname(dest), { recursive: true });
|
|
33
|
+
if (!overwrite) {
|
|
34
|
+
try {
|
|
35
|
+
await fsp.access(dest);
|
|
36
|
+
if (options.errorOnExist) throw new Error(`${dest} already exists`);
|
|
37
|
+
return;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error.message.includes('already exists')) throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
await fsp.copyFile(src, dest);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (srcStat.isDirectory()) {
|
|
47
|
+
if (filterFn && !(await filterFn(src, dest))) return;
|
|
48
|
+
await fsp.mkdir(dest, { recursive: true });
|
|
49
|
+
const entries = await fsp.readdir(src, { withFileTypes: true });
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
await copy(path.join(src, entry.name), path.join(dest, entry.name), options);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function move(src, dest) {
|
|
57
|
+
try {
|
|
58
|
+
await fsp.rename(src, dest);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (error.code === 'EXDEV') {
|
|
61
|
+
await copy(src, dest);
|
|
62
|
+
await fsp.rm(src, { recursive: true, force: true });
|
|
63
|
+
} else {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readJsonSync(p) {
|
|
70
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function writeJson(p, data, options = {}) {
|
|
74
|
+
const spaces = options.spaces ?? 2;
|
|
75
|
+
await fsp.writeFile(p, JSON.stringify(data, null, spaces) + '\n', 'utf8');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
// Native async (node:fs/promises)
|
|
80
|
+
readFile: fsp.readFile,
|
|
81
|
+
writeFile: fsp.writeFile,
|
|
82
|
+
stat: fsp.stat,
|
|
83
|
+
readdir: fsp.readdir,
|
|
84
|
+
access: fsp.access,
|
|
85
|
+
realpath: fsp.realpath,
|
|
86
|
+
rename: fsp.rename,
|
|
87
|
+
rmdir: fsp.rmdir,
|
|
88
|
+
unlink: fsp.unlink,
|
|
89
|
+
chmod: fsp.chmod,
|
|
90
|
+
mkdir: fsp.mkdir,
|
|
91
|
+
mkdtemp: fsp.mkdtemp,
|
|
92
|
+
copyFile: fsp.copyFile,
|
|
93
|
+
rm: fsp.rm,
|
|
94
|
+
|
|
95
|
+
// fs-extra compatible helpers (native implementations)
|
|
96
|
+
pathExists,
|
|
97
|
+
ensureDir,
|
|
98
|
+
remove,
|
|
99
|
+
copy,
|
|
100
|
+
move,
|
|
101
|
+
readJsonSync,
|
|
102
|
+
writeJson,
|
|
103
|
+
|
|
104
|
+
// Sync methods from core node:fs
|
|
105
|
+
existsSync: fs.existsSync.bind(fs),
|
|
106
|
+
readFileSync: fs.readFileSync.bind(fs),
|
|
107
|
+
writeFileSync: fs.writeFileSync.bind(fs),
|
|
108
|
+
statSync: fs.statSync.bind(fs),
|
|
109
|
+
accessSync: fs.accessSync.bind(fs),
|
|
110
|
+
readdirSync: fs.readdirSync.bind(fs),
|
|
111
|
+
createReadStream: fs.createReadStream.bind(fs),
|
|
112
|
+
pathExistsSync: fs.existsSync.bind(fs),
|
|
113
|
+
|
|
114
|
+
// Constants
|
|
115
|
+
constants: fs.constants,
|
|
116
|
+
};
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
* - standalone/agents/fred.md → bmad-agent-standalone-fred.md
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
// Type segments - agents are included in naming, others are filtered out
|
|
19
|
-
const TYPE_SEGMENTS = ['workflows', 'tasks', 'tools'];
|
|
20
18
|
const AGENT_SEGMENT = 'agents';
|
|
21
19
|
|
|
22
20
|
// BMAD installation folder name - centralized constant for all installers
|
|
@@ -194,125 +192,6 @@ function parseDashName(filename) {
|
|
|
194
192
|
};
|
|
195
193
|
}
|
|
196
194
|
|
|
197
|
-
// ============================================================================
|
|
198
|
-
// LEGACY FUNCTIONS (underscore format) - kept for backward compatibility
|
|
199
|
-
// ============================================================================
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Convert hierarchical path to flat underscore-separated name (LEGACY)
|
|
203
|
-
* @deprecated Use toDashName instead
|
|
204
|
-
*/
|
|
205
|
-
function toUnderscoreName(module, type, name) {
|
|
206
|
-
const isAgent = type === AGENT_SEGMENT;
|
|
207
|
-
if (module === 'core') {
|
|
208
|
-
return isAgent ? `bmad_agent_${name}.md` : `bmad_${name}.md`;
|
|
209
|
-
}
|
|
210
|
-
if (module === 'standalone') {
|
|
211
|
-
return isAgent ? `bmad_agent_standalone_${name}.md` : `bmad_standalone_${name}.md`;
|
|
212
|
-
}
|
|
213
|
-
return isAgent ? `bmad_${module}_agent_${name}.md` : `bmad_${module}_${name}.md`;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Convert relative path to flat underscore-separated name (LEGACY)
|
|
218
|
-
* @deprecated Use toDashPath instead
|
|
219
|
-
*/
|
|
220
|
-
function toUnderscorePath(relativePath) {
|
|
221
|
-
// Strip common file extensions (same as toDashPath for consistency)
|
|
222
|
-
const withoutExt = relativePath.replace(/\.(md|yaml|yml|json|xml|toml)$/i, '');
|
|
223
|
-
const parts = withoutExt.split(/[/\\]/);
|
|
224
|
-
|
|
225
|
-
const module = parts[0];
|
|
226
|
-
const type = parts[1];
|
|
227
|
-
const name = parts.slice(2).join('_');
|
|
228
|
-
|
|
229
|
-
return toUnderscoreName(module, type, name);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Create custom agent underscore name (LEGACY)
|
|
234
|
-
* @deprecated Use customAgentDashName instead
|
|
235
|
-
*/
|
|
236
|
-
function customAgentUnderscoreName(agentName) {
|
|
237
|
-
return `bmad_custom_${agentName}.md`;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Check if a filename uses underscore format (LEGACY)
|
|
242
|
-
* @deprecated Use isDashFormat instead
|
|
243
|
-
*/
|
|
244
|
-
function isUnderscoreFormat(filename) {
|
|
245
|
-
return filename.startsWith('bmad_') && filename.includes('_');
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Extract parts from an underscore-formatted filename (LEGACY)
|
|
250
|
-
* @deprecated Use parseDashName instead
|
|
251
|
-
*/
|
|
252
|
-
function parseUnderscoreName(filename) {
|
|
253
|
-
const withoutExt = filename.replace('.md', '');
|
|
254
|
-
const parts = withoutExt.split('_');
|
|
255
|
-
|
|
256
|
-
if (parts.length < 2 || parts[0] !== 'bmad') {
|
|
257
|
-
return null;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const agentIndex = parts.indexOf('agent');
|
|
261
|
-
|
|
262
|
-
if (agentIndex !== -1) {
|
|
263
|
-
if (agentIndex === 1) {
|
|
264
|
-
// bmad_agent_... - check for standalone
|
|
265
|
-
if (parts.length >= 4 && parts[2] === 'standalone') {
|
|
266
|
-
return {
|
|
267
|
-
prefix: parts[0],
|
|
268
|
-
module: 'standalone',
|
|
269
|
-
type: 'agents',
|
|
270
|
-
name: parts.slice(3).join('_'),
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
prefix: parts[0],
|
|
275
|
-
module: 'core',
|
|
276
|
-
type: 'agents',
|
|
277
|
-
name: parts.slice(agentIndex + 1).join('_'),
|
|
278
|
-
};
|
|
279
|
-
} else {
|
|
280
|
-
return {
|
|
281
|
-
prefix: parts[0],
|
|
282
|
-
module: parts[1],
|
|
283
|
-
type: 'agents',
|
|
284
|
-
name: parts.slice(agentIndex + 1).join('_'),
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (parts.length === 2) {
|
|
290
|
-
return {
|
|
291
|
-
prefix: parts[0],
|
|
292
|
-
module: 'core',
|
|
293
|
-
type: 'workflows',
|
|
294
|
-
name: parts[1],
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Check for standalone non-agent: bmad_standalone_name
|
|
299
|
-
if (parts[1] === 'standalone') {
|
|
300
|
-
return {
|
|
301
|
-
prefix: parts[0],
|
|
302
|
-
module: 'standalone',
|
|
303
|
-
type: 'workflows',
|
|
304
|
-
name: parts.slice(2).join('_'),
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return {
|
|
309
|
-
prefix: parts[0],
|
|
310
|
-
module: parts[1],
|
|
311
|
-
type: 'workflows',
|
|
312
|
-
name: parts.slice(2).join('_'),
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
195
|
/**
|
|
317
196
|
* Resolve the skill name for an artifact.
|
|
318
197
|
* Prefers canonicalId from a bmad-skill-manifest.yaml sidecar when available,
|
|
@@ -328,37 +207,13 @@ function resolveSkillName(artifact) {
|
|
|
328
207
|
return toDashPath(artifact.relativePath);
|
|
329
208
|
}
|
|
330
209
|
|
|
331
|
-
// Backward compatibility aliases (colon format was same as underscore)
|
|
332
|
-
const toColonName = toUnderscoreName;
|
|
333
|
-
const toColonPath = toUnderscorePath;
|
|
334
|
-
const customAgentColonName = customAgentUnderscoreName;
|
|
335
|
-
const isColonFormat = isUnderscoreFormat;
|
|
336
|
-
const parseColonName = parseUnderscoreName;
|
|
337
|
-
|
|
338
210
|
module.exports = {
|
|
339
|
-
// New standard (dash-based)
|
|
340
211
|
toDashName,
|
|
341
212
|
toDashPath,
|
|
342
213
|
resolveSkillName,
|
|
343
214
|
customAgentDashName,
|
|
344
215
|
isDashFormat,
|
|
345
216
|
parseDashName,
|
|
346
|
-
|
|
347
|
-
// Legacy (underscore-based) - kept for backward compatibility
|
|
348
|
-
toUnderscoreName,
|
|
349
|
-
toUnderscorePath,
|
|
350
|
-
customAgentUnderscoreName,
|
|
351
|
-
isUnderscoreFormat,
|
|
352
|
-
parseUnderscoreName,
|
|
353
|
-
|
|
354
|
-
// Backward compatibility aliases
|
|
355
|
-
toColonName,
|
|
356
|
-
toColonPath,
|
|
357
|
-
customAgentColonName,
|
|
358
|
-
isColonFormat,
|
|
359
|
-
parseColonName,
|
|
360
|
-
|
|
361
|
-
TYPE_SEGMENTS,
|
|
362
217
|
AGENT_SEGMENT,
|
|
363
218
|
BMAD_FOLDER_NAME,
|
|
364
219
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
const fs = require('fs-
|
|
1
|
+
const fs = require('../fs-native');
|
|
2
2
|
const os = require('node:os');
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const { execSync } = require('node:child_process');
|
|
5
5
|
const prompts = require('../prompts');
|
|
6
6
|
const { RegistryClient } = require('./registry-client');
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
8
|
+
const MARKETPLACE_OWNER = 'bmad-code-org';
|
|
9
|
+
const MARKETPLACE_REPO = 'bmad-plugins-marketplace';
|
|
10
|
+
const MARKETPLACE_REF = 'main';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Manages community modules from the BMad marketplace registry.
|
|
@@ -33,7 +33,12 @@ class CommunityModuleManager {
|
|
|
33
33
|
if (this._cachedIndex) return this._cachedIndex;
|
|
34
34
|
|
|
35
35
|
try {
|
|
36
|
-
const config = await this._client.
|
|
36
|
+
const config = await this._client.fetchGitHubYaml(
|
|
37
|
+
MARKETPLACE_OWNER,
|
|
38
|
+
MARKETPLACE_REPO,
|
|
39
|
+
'registry/community-index.yaml',
|
|
40
|
+
MARKETPLACE_REF,
|
|
41
|
+
);
|
|
37
42
|
if (config?.modules?.length) {
|
|
38
43
|
this._cachedIndex = config;
|
|
39
44
|
return config;
|
|
@@ -54,7 +59,7 @@ class CommunityModuleManager {
|
|
|
54
59
|
if (this._cachedCategories) return this._cachedCategories;
|
|
55
60
|
|
|
56
61
|
try {
|
|
57
|
-
const config = await this._client.
|
|
62
|
+
const config = await this._client.fetchGitHubYaml(MARKETPLACE_OWNER, MARKETPLACE_REPO, 'categories.yaml', MARKETPLACE_REF);
|
|
58
63
|
if (config?.categories) {
|
|
59
64
|
this._cachedCategories = config;
|
|
60
65
|
return config;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const fs = require('fs-
|
|
1
|
+
const fs = require('../fs-native');
|
|
2
2
|
const os = require('node:os');
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const { execSync } = require('node:child_process');
|
|
@@ -155,33 +155,6 @@ class CustomModuleManager {
|
|
|
155
155
|
};
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
/**
|
|
159
|
-
* @deprecated Use parseSource() instead. Kept for backward compatibility.
|
|
160
|
-
* Parse and validate a GitHub repository URL.
|
|
161
|
-
* @param {string} url - GitHub URL to validate
|
|
162
|
-
* @returns {Object} { owner, repo, isValid, error }
|
|
163
|
-
*/
|
|
164
|
-
validateGitHubUrl(url) {
|
|
165
|
-
if (!url || typeof url !== 'string') {
|
|
166
|
-
return { owner: null, repo: null, isValid: false, error: 'URL is required' };
|
|
167
|
-
}
|
|
168
|
-
const trimmed = url.trim();
|
|
169
|
-
|
|
170
|
-
// HTTPS format: https://github.com/owner/repo[.git] (strict, no trailing path)
|
|
171
|
-
const httpsMatch = trimmed.match(/^https?:\/\/github\.com\/([^/]+)\/([^/.]+?)(?:\.git)?$/);
|
|
172
|
-
if (httpsMatch) {
|
|
173
|
-
return { owner: httpsMatch[1], repo: httpsMatch[2], isValid: true, error: null };
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// SSH format: git@github.com:owner/repo[.git]
|
|
177
|
-
const sshMatch = trimmed.match(/^git@github\.com:([^/]+)\/([^/.]+?)(?:\.git)?$/);
|
|
178
|
-
if (sshMatch) {
|
|
179
|
-
return { owner: sshMatch[1], repo: sshMatch[2], isValid: true, error: null };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return { owner: null, repo: null, isValid: false, error: 'Not a valid GitHub URL (expected https://github.com/owner/repo)' };
|
|
183
|
-
}
|
|
184
|
-
|
|
185
158
|
// ─── Marketplace JSON ─────────────────────────────────────────────────────
|
|
186
159
|
|
|
187
160
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const fs = require('fs-
|
|
1
|
+
const fs = require('../fs-native');
|
|
2
2
|
const os = require('node:os');
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const { execSync } = require('node:child_process');
|
|
@@ -6,7 +6,9 @@ const yaml = require('yaml');
|
|
|
6
6
|
const prompts = require('../prompts');
|
|
7
7
|
const { RegistryClient } = require('./registry-client');
|
|
8
8
|
|
|
9
|
-
const
|
|
9
|
+
const MARKETPLACE_OWNER = 'bmad-code-org';
|
|
10
|
+
const MARKETPLACE_REPO = 'bmad-plugins-marketplace';
|
|
11
|
+
const MARKETPLACE_REF = 'main';
|
|
10
12
|
const FALLBACK_CONFIG_PATH = path.join(__dirname, 'registry-fallback.yaml');
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -33,8 +35,7 @@ class ExternalModuleManager {
|
|
|
33
35
|
|
|
34
36
|
// Try remote registry first
|
|
35
37
|
try {
|
|
36
|
-
const
|
|
37
|
-
const config = yaml.parse(content);
|
|
38
|
+
const config = await this._client.fetchGitHubYaml(MARKETPLACE_OWNER, MARKETPLACE_REPO, 'registry/official.yaml', MARKETPLACE_REF);
|
|
38
39
|
if (config?.modules?.length) {
|
|
39
40
|
this.cachedModules = config;
|
|
40
41
|
return config;
|
|
@@ -109,46 +110,6 @@ class ExternalModuleManager {
|
|
|
109
110
|
return modules.find((m) => m.code === code) || null;
|
|
110
111
|
}
|
|
111
112
|
|
|
112
|
-
/**
|
|
113
|
-
* Get module info by key
|
|
114
|
-
* @param {string} key - The module key (e.g., 'bmad-creative-intelligence-suite')
|
|
115
|
-
* @returns {Object|null} Module info or null if not found
|
|
116
|
-
*/
|
|
117
|
-
async getModuleByKey(key) {
|
|
118
|
-
const modules = await this.listAvailable();
|
|
119
|
-
return modules.find((m) => m.key === key) || null;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Check if a module code exists in external modules
|
|
124
|
-
* @param {string} code - The module code to check
|
|
125
|
-
* @returns {boolean} True if the module exists
|
|
126
|
-
*/
|
|
127
|
-
async hasModule(code) {
|
|
128
|
-
const module = await this.getModuleByCode(code);
|
|
129
|
-
return module !== null;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Get the URL for a module by code
|
|
134
|
-
* @param {string} code - The module code
|
|
135
|
-
* @returns {string|null} The URL or null if not found
|
|
136
|
-
*/
|
|
137
|
-
async getModuleUrl(code) {
|
|
138
|
-
const module = await this.getModuleByCode(code);
|
|
139
|
-
return module ? module.url : null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Get the module definition path for a module by code
|
|
144
|
-
* @param {string} code - The module code
|
|
145
|
-
* @returns {string|null} The module definition path or null if not found
|
|
146
|
-
*/
|
|
147
|
-
async getModuleDefinition(code) {
|
|
148
|
-
const module = await this.getModuleByCode(code);
|
|
149
|
-
return module ? module.moduleDefinition : null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
113
|
/**
|
|
153
114
|
* Get the cache directory for external modules
|
|
154
115
|
* @returns {string} Path to the external modules cache directory
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const path = require('node:path');
|
|
2
|
-
const fs = require('fs-
|
|
2
|
+
const fs = require('../fs-native');
|
|
3
3
|
const yaml = require('yaml');
|
|
4
4
|
const prompts = require('../prompts');
|
|
5
5
|
const { getProjectRoot, getSourcePath, getModulePath } = require('../project-root');
|
|
@@ -12,6 +12,8 @@ class OfficialModules {
|
|
|
12
12
|
// Config collection state (merged from ConfigCollector)
|
|
13
13
|
this.collectedConfig = {};
|
|
14
14
|
this._existingConfig = null;
|
|
15
|
+
// Tracked during interactive config collection so {directory_name}
|
|
16
|
+
// placeholder defaults can be resolved in buildQuestion().
|
|
15
17
|
this.currentProjectDir = null;
|
|
16
18
|
}
|
|
17
19
|
|
|
@@ -500,32 +502,6 @@ class OfficialModules {
|
|
|
500
502
|
}
|
|
501
503
|
}
|
|
502
504
|
|
|
503
|
-
/**
|
|
504
|
-
* Find all .md agent files recursively in a directory
|
|
505
|
-
* @param {string} dir - Directory to search
|
|
506
|
-
* @returns {Array} List of .md agent file paths
|
|
507
|
-
*/
|
|
508
|
-
async findAgentMdFiles(dir) {
|
|
509
|
-
const agentFiles = [];
|
|
510
|
-
|
|
511
|
-
async function searchDirectory(searchDir) {
|
|
512
|
-
const entries = await fs.readdir(searchDir, { withFileTypes: true });
|
|
513
|
-
|
|
514
|
-
for (const entry of entries) {
|
|
515
|
-
const fullPath = path.join(searchDir, entry.name);
|
|
516
|
-
|
|
517
|
-
if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
518
|
-
agentFiles.push(fullPath);
|
|
519
|
-
} else if (entry.isDirectory()) {
|
|
520
|
-
await searchDirectory(fullPath);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
await searchDirectory(dir);
|
|
526
|
-
return agentFiles;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
505
|
/**
|
|
530
506
|
* Create directories declared in module.yaml's `directories` key
|
|
531
507
|
* This replaces the security-risky module installer pattern with declarative config
|
|
@@ -699,29 +675,6 @@ class OfficialModules {
|
|
|
699
675
|
return { createdDirs, movedDirs, createdWdsFolders };
|
|
700
676
|
}
|
|
701
677
|
|
|
702
|
-
/**
|
|
703
|
-
* Private: Process module configuration
|
|
704
|
-
* @param {string} modulePath - Path to installed module
|
|
705
|
-
* @param {string} moduleName - Module name
|
|
706
|
-
*/
|
|
707
|
-
async processModuleConfig(modulePath, moduleName) {
|
|
708
|
-
const configPath = path.join(modulePath, 'config.yaml');
|
|
709
|
-
|
|
710
|
-
if (await fs.pathExists(configPath)) {
|
|
711
|
-
try {
|
|
712
|
-
let configContent = await fs.readFile(configPath, 'utf8');
|
|
713
|
-
|
|
714
|
-
// Replace path placeholders
|
|
715
|
-
configContent = configContent.replaceAll('{project-root}', `bmad/${moduleName}`);
|
|
716
|
-
configContent = configContent.replaceAll('{module}', moduleName);
|
|
717
|
-
|
|
718
|
-
await fs.writeFile(configPath, configContent, 'utf8');
|
|
719
|
-
} catch (error) {
|
|
720
|
-
await prompts.log.warn(`Failed to process module config: ${error.message}`);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
|
|
725
678
|
/**
|
|
726
679
|
* Private: Sync module files (preserving user modifications)
|
|
727
680
|
* @param {string} sourcePath - Source module path
|
|
@@ -867,10 +820,10 @@ class OfficialModules {
|
|
|
867
820
|
let foundAny = false;
|
|
868
821
|
const entries = await fs.readdir(bmadDir, { withFileTypes: true });
|
|
869
822
|
|
|
823
|
+
const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']);
|
|
870
824
|
for (const entry of entries) {
|
|
871
825
|
if (entry.isDirectory()) {
|
|
872
|
-
|
|
873
|
-
if (entry.name === '_config' || entry.name === '_memory') {
|
|
826
|
+
if (nonModuleDirs.has(entry.name)) {
|
|
874
827
|
continue;
|
|
875
828
|
}
|
|
876
829
|
|
|
@@ -1091,7 +1044,6 @@ class OfficialModules {
|
|
|
1091
1044
|
*/
|
|
1092
1045
|
async collectModuleConfigQuick(moduleName, projectDir, silentMode = true) {
|
|
1093
1046
|
this.currentProjectDir = projectDir;
|
|
1094
|
-
|
|
1095
1047
|
// Load existing config if not already loaded
|
|
1096
1048
|
if (!this._existingConfig) {
|
|
1097
1049
|
await this.loadExistingConfig(projectDir);
|