bmad-method 6.2.3-next.8 → 6.3.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/.claude-plugin/marketplace.json +0 -3
- package/README.md +8 -9
- package/README_CN.md +1 -1
- package/README_VN.md +110 -0
- package/package.json +1 -1
- package/removals.txt +17 -0
- package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/steps/step-13-responsive-accessibility.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/data/prd-purpose.md +197 -0
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +1 -1
- package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +1 -3
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/workflow.md +1 -1
- package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/workflow.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-agent-dev/SKILL.md +5 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/SKILL.md +29 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/generate-trail.md +38 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-01-orientation.md +105 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-02-walkthrough.md +89 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-03-detail-pass.md +106 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-04-testing.md +74 -0
- package/src/bmm-skills/4-implementation/bmad-checkpoint-preview/step-05-wrapup.md +24 -0
- package/src/bmm-skills/4-implementation/bmad-code-review/steps/step-01-gather-context.md +38 -15
- package/src/bmm-skills/4-implementation/bmad-correct-course/checklist.md +2 -2
- package/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md +8 -8
- package/src/bmm-skills/4-implementation/bmad-qa-generate-e2e-tests/checklist.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-quick-dev/compile-epic-context.md +62 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/spec-template.md +1 -1
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md +33 -6
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md +20 -8
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-03-implement.md +2 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +16 -4
- package/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md +1 -5
- package/src/bmm-skills/4-implementation/bmad-retrospective/workflow.md +134 -134
- package/src/bmm-skills/4-implementation/bmad-sprint-planning/sprint-status-template.yaml +1 -1
- package/src/bmm-skills/4-implementation/bmad-sprint-planning/workflow.md +3 -3
- package/src/bmm-skills/4-implementation/bmad-sprint-status/workflow.md +2 -2
- package/src/bmm-skills/module-help.csv +2 -0
- package/src/core-skills/bmad-help/SKILL.md +4 -2
- package/src/core-skills/bmad-party-mode/SKILL.md +121 -2
- package/src/core-skills/module-help.csv +1 -0
- package/tools/installer/cli-utils.js +18 -9
- package/tools/installer/commands/install.js +1 -1
- package/tools/installer/core/existing-install.js +2 -8
- package/tools/installer/core/install-paths.js +0 -3
- package/tools/installer/core/installer.js +180 -463
- package/tools/installer/core/manifest-generator.js +8 -14
- package/tools/installer/core/manifest.js +94 -102
- package/tools/installer/ide/_config-driven.js +149 -38
- package/tools/installer/ide/shared/skill-manifest.js +1 -16
- package/tools/installer/install-messages.yaml +19 -26
- package/tools/installer/modules/community-manager.js +377 -0
- package/tools/installer/modules/custom-module-manager.js +644 -0
- package/tools/installer/modules/external-manager.js +65 -49
- package/tools/installer/modules/official-modules.js +117 -65
- package/tools/installer/modules/plugin-resolver.js +398 -0
- package/tools/installer/modules/registry-client.js +66 -0
- package/tools/installer/{external-official-modules.yaml → modules/registry-fallback.yaml} +3 -12
- package/tools/installer/ui.js +549 -666
- package/src/bmm-skills/4-implementation/bmad-agent-qa/SKILL.md +0 -61
- package/src/bmm-skills/4-implementation/bmad-agent-qa/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/4-implementation/bmad-agent-quick-flow-solo-dev/SKILL.md +0 -53
- package/src/bmm-skills/4-implementation/bmad-agent-quick-flow-solo-dev/bmad-skill-manifest.yaml +0 -11
- package/src/bmm-skills/4-implementation/bmad-agent-sm/SKILL.md +0 -55
- package/src/bmm-skills/4-implementation/bmad-agent-sm/bmad-skill-manifest.yaml +0 -11
- package/src/core-skills/bmad-party-mode/steps/step-01-agent-loading.md +0 -138
- package/src/core-skills/bmad-party-mode/steps/step-02-discussion-orchestration.md +0 -187
- package/src/core-skills/bmad-party-mode/steps/step-03-graceful-exit.md +0 -167
- package/src/core-skills/bmad-party-mode/workflow.md +0 -183
- package/tools/installer/core/custom-module-cache.js +0 -260
- package/tools/installer/custom-handler.js +0 -112
- package/tools/installer/modules/custom-modules.js +0 -197
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
const path = require('node:path');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const yaml = require('yaml');
|
|
4
|
-
const prompts = require('./prompts');
|
|
5
|
-
/**
|
|
6
|
-
* Handler for custom content (custom.yaml)
|
|
7
|
-
* Discovers custom agents and workflows in the project
|
|
8
|
-
*/
|
|
9
|
-
class CustomHandler {
|
|
10
|
-
/**
|
|
11
|
-
* Find all custom.yaml files in the project
|
|
12
|
-
* @param {string} projectRoot - Project root directory
|
|
13
|
-
* @returns {Array} List of custom content paths
|
|
14
|
-
*/
|
|
15
|
-
async findCustomContent(projectRoot) {
|
|
16
|
-
const customPaths = [];
|
|
17
|
-
|
|
18
|
-
// Helper function to recursively scan directories
|
|
19
|
-
async function scanDirectory(dir, excludePaths = []) {
|
|
20
|
-
try {
|
|
21
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
22
|
-
|
|
23
|
-
for (const entry of entries) {
|
|
24
|
-
const fullPath = path.join(dir, entry.name);
|
|
25
|
-
|
|
26
|
-
// Skip hidden directories and common exclusions
|
|
27
|
-
if (
|
|
28
|
-
entry.name.startsWith('.') ||
|
|
29
|
-
entry.name === 'node_modules' ||
|
|
30
|
-
entry.name === 'dist' ||
|
|
31
|
-
entry.name === 'build' ||
|
|
32
|
-
entry.name === '.git' ||
|
|
33
|
-
entry.name === 'bmad'
|
|
34
|
-
) {
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Skip excluded paths
|
|
39
|
-
if (excludePaths.some((exclude) => fullPath.startsWith(exclude))) {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (entry.isDirectory()) {
|
|
44
|
-
// Recursively scan subdirectories
|
|
45
|
-
await scanDirectory(fullPath, excludePaths);
|
|
46
|
-
} else if (entry.name === 'custom.yaml') {
|
|
47
|
-
// Found a custom.yaml file
|
|
48
|
-
customPaths.push(fullPath);
|
|
49
|
-
} else if (
|
|
50
|
-
entry.name === 'module.yaml' && // Check if this is a custom module (in root directory)
|
|
51
|
-
// Skip if it's in src/modules (those are standard modules)
|
|
52
|
-
!fullPath.includes(path.join('src', 'modules'))
|
|
53
|
-
) {
|
|
54
|
-
customPaths.push(fullPath);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
} catch {
|
|
58
|
-
// Ignore errors (e.g., permission denied)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Scan the entire project, but exclude source directories
|
|
63
|
-
await scanDirectory(projectRoot, [path.join(projectRoot, 'src'), path.join(projectRoot, 'tools'), path.join(projectRoot, 'test')]);
|
|
64
|
-
|
|
65
|
-
return customPaths;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Get custom content info from a custom.yaml or module.yaml file
|
|
70
|
-
* @param {string} configPath - Path to config file
|
|
71
|
-
* @param {string} projectRoot - Project root directory for calculating relative paths
|
|
72
|
-
* @returns {Object|null} Custom content info
|
|
73
|
-
*/
|
|
74
|
-
async getCustomInfo(configPath, projectRoot = null) {
|
|
75
|
-
try {
|
|
76
|
-
const configContent = await fs.readFile(configPath, 'utf8');
|
|
77
|
-
|
|
78
|
-
// Try to parse YAML with error handling
|
|
79
|
-
let config;
|
|
80
|
-
try {
|
|
81
|
-
config = yaml.parse(configContent);
|
|
82
|
-
} catch (parseError) {
|
|
83
|
-
await prompts.log.warn('YAML parse error in ' + configPath + ': ' + parseError.message);
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Check if this is an module.yaml (module) or custom.yaml (custom content)
|
|
88
|
-
const isInstallConfig = configPath.endsWith('module.yaml');
|
|
89
|
-
const configDir = path.dirname(configPath);
|
|
90
|
-
|
|
91
|
-
// Use provided projectRoot or fall back to process.cwd()
|
|
92
|
-
const basePath = projectRoot || process.cwd();
|
|
93
|
-
const relativePath = path.relative(basePath, configDir);
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
id: config.code || 'unknown-code',
|
|
97
|
-
name: config.name,
|
|
98
|
-
description: config.description || '',
|
|
99
|
-
path: configDir,
|
|
100
|
-
relativePath: relativePath,
|
|
101
|
-
defaultSelected: config.default_selected === true,
|
|
102
|
-
config: config,
|
|
103
|
-
isInstallConfig: isInstallConfig, // Track which type this is
|
|
104
|
-
};
|
|
105
|
-
} catch (error) {
|
|
106
|
-
await prompts.log.warn('Failed to read ' + configPath + ': ' + error.message);
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
module.exports = { CustomHandler };
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
const path = require('node:path');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const yaml = require('yaml');
|
|
4
|
-
const { CustomHandler } = require('../custom-handler');
|
|
5
|
-
const { Manifest } = require('../core/manifest');
|
|
6
|
-
const prompts = require('../prompts');
|
|
7
|
-
|
|
8
|
-
class CustomModules {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.paths = new Map();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
has(moduleCode) {
|
|
14
|
-
return this.paths.has(moduleCode);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
get(moduleCode) {
|
|
18
|
-
return this.paths.get(moduleCode);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
set(moduleId, sourcePath) {
|
|
22
|
-
this.paths.set(moduleId, sourcePath);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Install a custom module from its source path.
|
|
27
|
-
* @param {string} moduleName - Module identifier
|
|
28
|
-
* @param {string} bmadDir - Target bmad directory
|
|
29
|
-
* @param {Function} fileTrackingCallback - Optional callback to track installed files
|
|
30
|
-
* @param {Object} options - Install options
|
|
31
|
-
* @param {Object} options.moduleConfig - Pre-collected module configuration
|
|
32
|
-
* @returns {Object} Install result
|
|
33
|
-
*/
|
|
34
|
-
async install(moduleName, bmadDir, fileTrackingCallback = null, options = {}) {
|
|
35
|
-
const sourcePath = this.paths.get(moduleName);
|
|
36
|
-
if (!sourcePath) {
|
|
37
|
-
throw new Error(`No source path for custom module '${moduleName}'`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (!(await fs.pathExists(sourcePath))) {
|
|
41
|
-
throw new Error(`Source for custom module '${moduleName}' not found at: ${sourcePath}`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const targetPath = path.join(bmadDir, moduleName);
|
|
45
|
-
|
|
46
|
-
// Read custom.yaml and merge into module config
|
|
47
|
-
let moduleConfig = options.moduleConfig ? { ...options.moduleConfig } : {};
|
|
48
|
-
const customConfigPath = path.join(sourcePath, 'custom.yaml');
|
|
49
|
-
if (await fs.pathExists(customConfigPath)) {
|
|
50
|
-
try {
|
|
51
|
-
const content = await fs.readFile(customConfigPath, 'utf8');
|
|
52
|
-
const customConfig = yaml.parse(content);
|
|
53
|
-
if (customConfig) {
|
|
54
|
-
moduleConfig = { ...moduleConfig, ...customConfig };
|
|
55
|
-
}
|
|
56
|
-
} catch (error) {
|
|
57
|
-
await prompts.log.warn(`Failed to read custom.yaml for ${moduleName}: ${error.message}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Remove existing installation
|
|
62
|
-
if (await fs.pathExists(targetPath)) {
|
|
63
|
-
await fs.remove(targetPath);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Copy files with filtering
|
|
67
|
-
await this._copyWithFiltering(sourcePath, targetPath, fileTrackingCallback);
|
|
68
|
-
|
|
69
|
-
// Add to manifest
|
|
70
|
-
const manifest = new Manifest();
|
|
71
|
-
const versionInfo = await manifest.getModuleVersionInfo(moduleName, bmadDir, sourcePath);
|
|
72
|
-
await manifest.addModule(bmadDir, moduleName, {
|
|
73
|
-
version: versionInfo.version,
|
|
74
|
-
source: versionInfo.source,
|
|
75
|
-
npmPackage: versionInfo.npmPackage,
|
|
76
|
-
repoUrl: versionInfo.repoUrl,
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
return { success: true, module: moduleName, path: targetPath, moduleConfig };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Copy module files, filtering out install-time-only artifacts.
|
|
84
|
-
* @param {string} sourcePath - Source module directory
|
|
85
|
-
* @param {string} targetPath - Target module directory
|
|
86
|
-
* @param {Function} fileTrackingCallback - Optional callback to track installed files
|
|
87
|
-
*/
|
|
88
|
-
async _copyWithFiltering(sourcePath, targetPath, fileTrackingCallback = null) {
|
|
89
|
-
const files = await this._getFileList(sourcePath);
|
|
90
|
-
|
|
91
|
-
for (const file of files) {
|
|
92
|
-
if (file.startsWith('sub-modules/')) continue;
|
|
93
|
-
|
|
94
|
-
const isInSidecar = path
|
|
95
|
-
.dirname(file)
|
|
96
|
-
.split('/')
|
|
97
|
-
.some((dir) => dir.toLowerCase().endsWith('-sidecar'));
|
|
98
|
-
if (isInSidecar) continue;
|
|
99
|
-
|
|
100
|
-
if (file === 'module.yaml') continue;
|
|
101
|
-
if (file === 'config.yaml') continue;
|
|
102
|
-
|
|
103
|
-
const sourceFile = path.join(sourcePath, file);
|
|
104
|
-
const targetFile = path.join(targetPath, file);
|
|
105
|
-
|
|
106
|
-
// Skip web-only agents
|
|
107
|
-
if (file.startsWith('agents/') && file.endsWith('.md')) {
|
|
108
|
-
const content = await fs.readFile(sourceFile, 'utf8');
|
|
109
|
-
if (/<agent[^>]*\slocalskip="true"[^>]*>/.test(content)) {
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
await fs.ensureDir(path.dirname(targetFile));
|
|
115
|
-
await fs.copy(sourceFile, targetFile, { overwrite: true });
|
|
116
|
-
|
|
117
|
-
if (fileTrackingCallback) {
|
|
118
|
-
fileTrackingCallback(targetFile);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Recursively list all files in a directory.
|
|
125
|
-
* @param {string} dir - Directory to scan
|
|
126
|
-
* @param {string} baseDir - Base directory for relative paths
|
|
127
|
-
* @returns {string[]} Relative file paths
|
|
128
|
-
*/
|
|
129
|
-
async _getFileList(dir, baseDir = dir) {
|
|
130
|
-
const files = [];
|
|
131
|
-
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
132
|
-
|
|
133
|
-
for (const entry of entries) {
|
|
134
|
-
const fullPath = path.join(dir, entry.name);
|
|
135
|
-
if (entry.isDirectory()) {
|
|
136
|
-
files.push(...(await this._getFileList(fullPath, baseDir)));
|
|
137
|
-
} else {
|
|
138
|
-
files.push(path.relative(baseDir, fullPath));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return files;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Discover custom module source paths from all available sources.
|
|
147
|
-
* @param {Object} config - Installation configuration
|
|
148
|
-
* @param {Object} paths - InstallPaths instance
|
|
149
|
-
* @returns {Map<string, string>} Map of module ID to source path
|
|
150
|
-
*/
|
|
151
|
-
async discoverPaths(config, paths) {
|
|
152
|
-
this.paths = new Map();
|
|
153
|
-
|
|
154
|
-
if (config._quickUpdate) {
|
|
155
|
-
if (config._customModuleSources) {
|
|
156
|
-
for (const [moduleId, customInfo] of config._customModuleSources) {
|
|
157
|
-
this.paths.set(moduleId, customInfo.sourcePath);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return this.paths;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// From UI: selectedFiles
|
|
164
|
-
if (config.customContent && config.customContent.selected && config.customContent.selectedFiles) {
|
|
165
|
-
const customHandler = new CustomHandler();
|
|
166
|
-
for (const customFile of config.customContent.selectedFiles) {
|
|
167
|
-
const customInfo = await customHandler.getCustomInfo(customFile, paths.projectRoot);
|
|
168
|
-
if (customInfo && customInfo.id) {
|
|
169
|
-
this.paths.set(customInfo.id, customInfo.path);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// From UI: sources
|
|
175
|
-
if (config.customContent && config.customContent.sources) {
|
|
176
|
-
for (const source of config.customContent.sources) {
|
|
177
|
-
this.paths.set(source.id, source.path);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// From UI: cachedModules
|
|
182
|
-
if (config.customContent && config.customContent.cachedModules) {
|
|
183
|
-
const selectedCachedIds = config.customContent.selectedCachedModules || [];
|
|
184
|
-
const shouldIncludeAll = selectedCachedIds.length === 0 && config.customContent.selected;
|
|
185
|
-
|
|
186
|
-
for (const cachedModule of config.customContent.cachedModules) {
|
|
187
|
-
if (cachedModule.id && cachedModule.cachePath && (shouldIncludeAll || selectedCachedIds.includes(cachedModule.id))) {
|
|
188
|
-
this.paths.set(cachedModule.id, cachedModule.cachePath);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return this.paths;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
module.exports = { CustomModules };
|