bmad-method 4.24.0 → 4.24.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/.vscode/settings.json +11 -5
- package/CHANGELOG.md +10 -1
- package/README.md +1 -1
- package/bmad-core/agents/bmad-master.md +1 -1
- package/bmad-core/agents/dev.md +2 -2
- package/bmad-core/agents/pm.md +1 -1
- package/bmad-core/agents/po.md +1 -1
- package/bmad-core/data/bmad-kb.md +4 -4
- package/bmad-core/tasks/create-brownfield-story.md +1 -1
- package/bmad-core/tasks/create-next-story.md +4 -4
- package/bmad-core/tasks/shard-doc.md +3 -3
- package/bmad-core/tasks/update-workflow-plan.md +1 -1
- package/bmad-core/templates/architecture-tmpl.md +1 -1
- package/bmad-core/templates/fullstack-architecture-tmpl.md +3 -3
- package/bmad-core/utils/plan-management.md +1 -1
- package/common/tasks/create-doc.md +1 -1
- package/docs/agentic-tools/roo-code-guide.md +1 -1
- package/docs/core-architecture.md +12 -12
- package/docs/user-guide.md +6 -6
- package/expansion-packs/bmad-creator-tools/tasks/generate-expansion-pack.md +9 -9
- package/expansion-packs/bmad-creator-tools/templates/agent-teams-tmpl.md +1 -1
- package/expansion-packs/bmad-creator-tools/templates/agent-tmpl.md +1 -1
- package/expansion-packs/bmad-infrastructure-devops/README.md +3 -3
- package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.md +0 -0
- package/package.json +1 -1
- package/tools/builders/web-builder.js +19 -20
- package/tools/bump-all-versions.js +2 -2
- package/tools/bump-core-version.js +1 -1
- package/tools/bump-expansion-version.js +1 -1
- package/tools/installer/README.md +1 -1
- package/tools/installer/bin/bmad.js +2 -2
- package/tools/installer/lib/config-loader.js +13 -12
- package/tools/installer/lib/file-manager.js +5 -5
- package/tools/installer/lib/ide-setup.js +14 -13
- package/tools/installer/lib/installer.js +24 -26
- package/tools/installer/package.json +1 -1
- package/tools/lib/dependency-resolver.js +8 -12
- package/tools/lib/yaml-utils.js +29 -0
- package/tools/update-expansion-version.js +3 -3
- package/tools/yaml-format.js +1 -1
- package/dist/agents/analyst.txt +0 -2731
- package/dist/agents/architect.txt +0 -3923
- package/dist/agents/bmad-master.txt +0 -10026
- package/dist/agents/bmad-orchestrator.txt +0 -2062
- package/dist/agents/dev.txt +0 -298
- package/dist/agents/pm.txt +0 -2249
- package/dist/agents/po.txt +0 -1511
- package/dist/agents/qa.txt +0 -262
- package/dist/agents/sm.txt +0 -726
- package/dist/agents/ux-expert.txt +0 -1101
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +0 -2378
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-developer.txt +0 -1584
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-sm.txt +0 -809
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +0 -7475
- package/dist/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.txt +0 -1960
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +0 -2073
- package/dist/teams/team-all.txt +0 -11952
- package/dist/teams/team-fullstack.txt +0 -11115
- package/dist/teams/team-ide-minimal.txt +0 -4365
- package/dist/teams/team-no-ui.txt +0 -9596
- /package/.github/{FUNDING.yml → FUNDING.yaml} +0 -0
- /package/.github/workflows/{release.yml → release.yaml} +0 -0
- /package/bmad-core/agent-teams/{team-all.yml → team-all.yaml} +0 -0
- /package/bmad-core/agent-teams/{team-fullstack.yml → team-fullstack.yaml} +0 -0
- /package/bmad-core/agent-teams/{team-ide-minimal.yml → team-ide-minimal.yaml} +0 -0
- /package/bmad-core/agent-teams/{team-no-ui.yml → team-no-ui.yaml} +0 -0
- /package/bmad-core/{core-config.yml → core-config.yaml} +0 -0
- /package/bmad-core/workflows/{brownfield-fullstack.yml → brownfield-fullstack.yaml} +0 -0
- /package/bmad-core/workflows/{brownfield-service.yml → brownfield-service.yaml} +0 -0
- /package/bmad-core/workflows/{brownfield-ui.yml → brownfield-ui.yaml} +0 -0
- /package/bmad-core/workflows/{greenfield-fullstack.yml → greenfield-fullstack.yaml} +0 -0
- /package/bmad-core/workflows/{greenfield-service.yml → greenfield-service.yaml} +0 -0
- /package/bmad-core/workflows/{greenfield-ui.yml → greenfield-ui.yaml} +0 -0
- /package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/{phaser-2d-nodejs-game-team.yml → phaser-2d-nodejs-game-team.yaml} +0 -0
- /package/expansion-packs/bmad-2d-phaser-game-dev/{config.yml → config.yaml} +0 -0
- /package/expansion-packs/bmad-2d-phaser-game-dev/workflows/{game-dev-greenfield.yml → game-dev-greenfield.yaml} +0 -0
- /package/expansion-packs/bmad-2d-phaser-game-dev/workflows/{game-prototype.yml → game-prototype.yaml} +0 -0
- /package/expansion-packs/bmad-creator-tools/{config.yml → config.yaml} +0 -0
- /package/expansion-packs/bmad-infrastructure-devops/{config.yml → config.yaml} +0 -0
- /package/tools/installer/config/{ide-agent-config.yml → ide-agent-config.yaml} +0 -0
- /package/tools/installer/config/{install.config.yml → install.config.yaml} +0 -0
|
@@ -38,7 +38,7 @@ function bumpVersion(currentVersion, type) {
|
|
|
38
38
|
|
|
39
39
|
async function updateVersion() {
|
|
40
40
|
try {
|
|
41
|
-
const configPath = path.join(__dirname, '..', 'expansion-packs', packId, 'config.
|
|
41
|
+
const configPath = path.join(__dirname, '..', 'expansion-packs', packId, 'config.yaml');
|
|
42
42
|
|
|
43
43
|
if (!fs.existsSync(configPath)) {
|
|
44
44
|
console.error(`Error: Expansion pack '${packId}' not found`);
|
|
@@ -16,7 +16,7 @@ installer/
|
|
|
16
16
|
│ ├── ide-setup.js # IDE-specific setup
|
|
17
17
|
│ └── prompts.js # Interactive CLI prompts
|
|
18
18
|
├── config/ # Configuration files
|
|
19
|
-
│ └── install.config.
|
|
19
|
+
│ └── install.config.yaml # Installation profiles
|
|
20
20
|
├── templates/ # IDE template files
|
|
21
21
|
│ ├── cursor-rules.md # Cursor template
|
|
22
22
|
│ ├── claude-commands.md # Claude Code template
|
|
@@ -158,7 +158,7 @@ async function promptInstallation() {
|
|
|
158
158
|
const choices = [];
|
|
159
159
|
|
|
160
160
|
// Load core config to get short-title
|
|
161
|
-
const coreConfigPath = path.join(__dirname, '..', '..', '..', 'bmad-core', 'core-config.
|
|
161
|
+
const coreConfigPath = path.join(__dirname, '..', '..', '..', 'bmad-core', 'core-config.yaml');
|
|
162
162
|
const coreConfig = yaml.load(await fs.readFile(coreConfigPath, 'utf8'));
|
|
163
163
|
const coreShortTitle = coreConfig['short-title'] || 'BMad Agile Core System';
|
|
164
164
|
|
|
@@ -166,7 +166,7 @@ async function promptInstallation() {
|
|
|
166
166
|
let bmadOptionText;
|
|
167
167
|
if (state.type === 'v4_existing') {
|
|
168
168
|
const currentVersion = state.manifest?.version || 'unknown';
|
|
169
|
-
const newVersion = coreConfig.version || 'unknown'; // Use version from core-config.
|
|
169
|
+
const newVersion = coreConfig.version || 'unknown'; // Use version from core-config.yaml
|
|
170
170
|
const versionInfo = currentVersion === newVersion
|
|
171
171
|
? `(v${currentVersion} - reinstall)`
|
|
172
172
|
: `(v${currentVersion} → v${newVersion})`;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const yaml = require('js-yaml');
|
|
4
|
+
const { extractYamlFromAgent } = require('../../lib/yaml-utils');
|
|
4
5
|
|
|
5
6
|
class ConfigLoader {
|
|
6
7
|
constructor() {
|
|
7
|
-
this.configPath = path.join(__dirname, '..', 'config', 'install.config.
|
|
8
|
+
this.configPath = path.join(__dirname, '..', 'config', 'install.config.yaml');
|
|
8
9
|
this.config = null;
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -41,9 +42,9 @@ class ConfigLoader {
|
|
|
41
42
|
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
42
43
|
|
|
43
44
|
// Extract YAML block from agent file
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
const yamlContent = yaml.load(
|
|
45
|
+
const yamlContentText = extractYamlFromAgent(agentContent);
|
|
46
|
+
if (yamlContentText) {
|
|
47
|
+
const yamlContent = yaml.load(yamlContentText);
|
|
47
48
|
const agentConfig = yamlContent.agent || {};
|
|
48
49
|
|
|
49
50
|
agents.push({
|
|
@@ -79,10 +80,10 @@ class ConfigLoader {
|
|
|
79
80
|
for (const entry of entries) {
|
|
80
81
|
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
81
82
|
const packPath = path.join(expansionPacksDir, entry.name);
|
|
82
|
-
const configPath = path.join(packPath, 'config.
|
|
83
|
+
const configPath = path.join(packPath, 'config.yaml');
|
|
83
84
|
|
|
84
85
|
try {
|
|
85
|
-
// Read config.
|
|
86
|
+
// Read config.yaml
|
|
86
87
|
const configContent = await fs.readFile(configPath, 'utf8');
|
|
87
88
|
const config = yaml.load(configContent);
|
|
88
89
|
|
|
@@ -97,7 +98,7 @@ class ConfigLoader {
|
|
|
97
98
|
dependencies: config.dependencies?.agents || []
|
|
98
99
|
});
|
|
99
100
|
} catch (error) {
|
|
100
|
-
// Fallback if config.
|
|
101
|
+
// Fallback if config.yaml doesn't exist or can't be read
|
|
101
102
|
console.warn(`Failed to read config for expansion pack ${entry.name}: ${error.message}`);
|
|
102
103
|
|
|
103
104
|
// Try to derive info from directory name as fallback
|
|
@@ -180,7 +181,7 @@ class ConfigLoader {
|
|
|
180
181
|
const teams = [];
|
|
181
182
|
|
|
182
183
|
for (const entry of entries) {
|
|
183
|
-
if (entry.isFile() && entry.name.endsWith('.
|
|
184
|
+
if (entry.isFile() && entry.name.endsWith('.yaml')) {
|
|
184
185
|
const teamPath = path.join(teamsDir, entry.name);
|
|
185
186
|
|
|
186
187
|
try {
|
|
@@ -189,7 +190,7 @@ class ConfigLoader {
|
|
|
189
190
|
|
|
190
191
|
if (teamConfig.bundle) {
|
|
191
192
|
teams.push({
|
|
192
|
-
id: path.basename(entry.name, '.
|
|
193
|
+
id: path.basename(entry.name, '.yaml'),
|
|
193
194
|
name: teamConfig.bundle.name || entry.name,
|
|
194
195
|
description: teamConfig.bundle.description || 'Team configuration',
|
|
195
196
|
icon: teamConfig.bundle.icon || '📋'
|
|
@@ -209,7 +210,7 @@ class ConfigLoader {
|
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
getTeamPath(teamId) {
|
|
212
|
-
return path.join(this.getBmadCorePath(), 'agent-teams', `${teamId}.
|
|
213
|
+
return path.join(this.getBmadCorePath(), 'agent-teams', `${teamId}.yaml`);
|
|
213
214
|
}
|
|
214
215
|
|
|
215
216
|
async getTeamDependencies(teamId) {
|
|
@@ -224,7 +225,7 @@ class ConfigLoader {
|
|
|
224
225
|
const depPaths = [];
|
|
225
226
|
|
|
226
227
|
// Add team config file
|
|
227
|
-
depPaths.push(`.bmad-core/agent-teams/${teamId}.
|
|
228
|
+
depPaths.push(`.bmad-core/agent-teams/${teamId}.yaml`);
|
|
228
229
|
|
|
229
230
|
// Add all agents
|
|
230
231
|
for (const agent of teamDeps.agents) {
|
|
@@ -236,7 +237,7 @@ class ConfigLoader {
|
|
|
236
237
|
|
|
237
238
|
// Add all resolved resources
|
|
238
239
|
for (const resource of teamDeps.resources) {
|
|
239
|
-
const filePath = `.bmad-core/${resource.type}/${resource.id}.${resource.type === 'workflows' ? '
|
|
240
|
+
const filePath = `.bmad-core/${resource.type}/${resource.id}.${resource.type === 'workflows' ? 'yaml' : 'md'}`;
|
|
240
241
|
if (!depPaths.includes(filePath)) {
|
|
241
242
|
depPaths.push(filePath);
|
|
242
243
|
}
|
|
@@ -17,7 +17,7 @@ async function initializeModules() {
|
|
|
17
17
|
class FileManager {
|
|
18
18
|
constructor() {
|
|
19
19
|
this.manifestDir = ".bmad-core";
|
|
20
|
-
this.manifestFile = "install-manifest.
|
|
20
|
+
this.manifestFile = "install-manifest.yaml";
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
async copyFile(source, destination) {
|
|
@@ -83,15 +83,15 @@ class FileManager {
|
|
|
83
83
|
this.manifestFile
|
|
84
84
|
);
|
|
85
85
|
|
|
86
|
-
// Read version from core-config.
|
|
87
|
-
const coreConfigPath = path.join(__dirname, "../../../bmad-core/core-config.
|
|
86
|
+
// Read version from core-config.yaml
|
|
87
|
+
const coreConfigPath = path.join(__dirname, "../../../bmad-core/core-config.yaml");
|
|
88
88
|
let coreVersion = "unknown";
|
|
89
89
|
try {
|
|
90
90
|
const coreConfigContent = await fs.readFile(coreConfigPath, "utf8");
|
|
91
91
|
const coreConfig = yaml.load(coreConfigContent);
|
|
92
92
|
coreVersion = coreConfig.version || "unknown";
|
|
93
93
|
} catch (error) {
|
|
94
|
-
console.warn("Could not read version from core-config.
|
|
94
|
+
console.warn("Could not read version from core-config.yaml, using 'unknown'");
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
const manifest = {
|
|
@@ -178,7 +178,7 @@ class FileManager {
|
|
|
178
178
|
const filePath = path.join(installDir, file.path);
|
|
179
179
|
|
|
180
180
|
// Skip checking the manifest file itself - it will always be different due to timestamps
|
|
181
|
-
if (file.path.endsWith('install-manifest.
|
|
181
|
+
if (file.path.endsWith('install-manifest.yaml')) {
|
|
182
182
|
continue;
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -3,6 +3,7 @@ const fs = require("fs-extra");
|
|
|
3
3
|
const yaml = require("js-yaml");
|
|
4
4
|
const fileManager = require("./file-manager");
|
|
5
5
|
const configLoader = require("./config-loader");
|
|
6
|
+
const { extractYamlFromAgent } = require("../../lib/yaml-utils");
|
|
6
7
|
|
|
7
8
|
// Dynamic import for ES module
|
|
8
9
|
let chalk;
|
|
@@ -27,7 +28,7 @@ class IdeSetup {
|
|
|
27
28
|
if (this.ideAgentConfig) return this.ideAgentConfig;
|
|
28
29
|
|
|
29
30
|
try {
|
|
30
|
-
const configPath = path.join(__dirname, '..', 'config', 'ide-agent-config.
|
|
31
|
+
const configPath = path.join(__dirname, '..', 'config', 'ide-agent-config.yaml');
|
|
31
32
|
const configContent = await fs.readFile(configPath, 'utf8');
|
|
32
33
|
this.ideAgentConfig = yaml.load(configContent);
|
|
33
34
|
return this.ideAgentConfig;
|
|
@@ -98,11 +99,11 @@ class IdeSetup {
|
|
|
98
99
|
mdcContent += "## Agent Activation\n\n";
|
|
99
100
|
mdcContent +=
|
|
100
101
|
"CRITICAL: Read the full YML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:\n\n";
|
|
101
|
-
mdcContent += "```
|
|
102
|
+
mdcContent += "```yaml\n";
|
|
102
103
|
// Extract just the YAML content from the agent file
|
|
103
|
-
const
|
|
104
|
-
if (
|
|
105
|
-
mdcContent +=
|
|
104
|
+
const yamlContent = extractYamlFromAgent(agentContent);
|
|
105
|
+
if (yamlContent) {
|
|
106
|
+
mdcContent += yamlContent;
|
|
106
107
|
} else {
|
|
107
108
|
// If no YAML found, include the whole content minus the header
|
|
108
109
|
mdcContent += agentContent.replace(/^#.*$/m, "").trim();
|
|
@@ -180,11 +181,11 @@ class IdeSetup {
|
|
|
180
181
|
mdContent += "## Agent Activation\n\n";
|
|
181
182
|
mdContent +=
|
|
182
183
|
"CRITICAL: Read the full YML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:\n\n";
|
|
183
|
-
mdContent += "```
|
|
184
|
+
mdContent += "```yaml\n";
|
|
184
185
|
// Extract just the YAML content from the agent file
|
|
185
|
-
const
|
|
186
|
-
if (
|
|
187
|
-
mdContent +=
|
|
186
|
+
const yamlContent = extractYamlFromAgent(agentContent);
|
|
187
|
+
if (yamlContent) {
|
|
188
|
+
mdContent += yamlContent;
|
|
188
189
|
} else {
|
|
189
190
|
// If no YAML found, include the whole content minus the header
|
|
190
191
|
mdContent += agentContent.replace(/^#.*$/m, "").trim();
|
|
@@ -428,11 +429,11 @@ class IdeSetup {
|
|
|
428
429
|
mdContent += "## Role Definition\n\n";
|
|
429
430
|
mdContent +=
|
|
430
431
|
"When the user types `@" + agentId + "`, adopt this persona and follow these guidelines:\n\n";
|
|
431
|
-
mdContent += "```
|
|
432
|
+
mdContent += "```yaml\n";
|
|
432
433
|
// Extract just the YAML content from the agent file
|
|
433
|
-
const
|
|
434
|
-
if (
|
|
435
|
-
mdContent +=
|
|
434
|
+
const yamlContent = extractYamlFromAgent(agentContent);
|
|
435
|
+
if (yamlContent) {
|
|
436
|
+
mdContent += yamlContent;
|
|
436
437
|
} else {
|
|
437
438
|
// If no YAML found, include the whole content minus the header
|
|
438
439
|
mdContent += agentContent.replace(/^#.*$/m, "").trim();
|
|
@@ -2,6 +2,7 @@ const path = require("node:path");
|
|
|
2
2
|
const fileManager = require("./file-manager");
|
|
3
3
|
const configLoader = require("./config-loader");
|
|
4
4
|
const ideSetup = require("./ide-setup");
|
|
5
|
+
const { extractYamlFromAgent } = require("../../lib/yaml-utils");
|
|
5
6
|
|
|
6
7
|
// Dynamic imports for ES modules
|
|
7
8
|
let chalk, ora, inquirer;
|
|
@@ -19,13 +20,13 @@ class Installer {
|
|
|
19
20
|
async getCoreVersion() {
|
|
20
21
|
const yaml = require("js-yaml");
|
|
21
22
|
const fs = require("fs-extra");
|
|
22
|
-
const coreConfigPath = path.join(__dirname, "../../../bmad-core/core-config.
|
|
23
|
+
const coreConfigPath = path.join(__dirname, "../../../bmad-core/core-config.yaml");
|
|
23
24
|
try {
|
|
24
25
|
const coreConfigContent = await fs.readFile(coreConfigPath, "utf8");
|
|
25
26
|
const coreConfig = yaml.load(coreConfigContent);
|
|
26
27
|
return coreConfig.version || "unknown";
|
|
27
28
|
} catch (error) {
|
|
28
|
-
console.warn("Could not read version from core-config.
|
|
29
|
+
console.warn("Could not read version from core-config.yaml, using 'unknown'");
|
|
29
30
|
return "unknown";
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -185,7 +186,7 @@ class Installer {
|
|
|
185
186
|
|
|
186
187
|
// Check for V4 installation (has .bmad-core with manifest)
|
|
187
188
|
const bmadCorePath = path.join(installDir, ".bmad-core");
|
|
188
|
-
const manifestPath = path.join(bmadCorePath, "install-manifest.
|
|
189
|
+
const manifestPath = path.join(bmadCorePath, "install-manifest.yaml");
|
|
189
190
|
|
|
190
191
|
if (await fileManager.pathExists(manifestPath)) {
|
|
191
192
|
state.type = "v4_existing";
|
|
@@ -713,7 +714,7 @@ class Installer {
|
|
|
713
714
|
|
|
714
715
|
for (const file of filesToRestore) {
|
|
715
716
|
// Skip the manifest file itself
|
|
716
|
-
if (file.endsWith('install-manifest.
|
|
717
|
+
if (file.endsWith('install-manifest.yaml')) continue;
|
|
717
718
|
|
|
718
719
|
const relativePath = file.replace('.bmad-core/', '');
|
|
719
720
|
const destPath = path.join(installDir, file);
|
|
@@ -1009,7 +1010,7 @@ class Installer {
|
|
|
1009
1010
|
|
|
1010
1011
|
// Check if expansion pack already exists
|
|
1011
1012
|
let expansionDotFolder = path.join(installDir, `.${packId}`);
|
|
1012
|
-
const existingManifestPath = path.join(expansionDotFolder, 'install-manifest.
|
|
1013
|
+
const existingManifestPath = path.join(expansionDotFolder, 'install-manifest.yaml');
|
|
1013
1014
|
|
|
1014
1015
|
if (await fileManager.pathExists(existingManifestPath)) {
|
|
1015
1016
|
spinner.stop();
|
|
@@ -1151,12 +1152,12 @@ class Installer {
|
|
|
1151
1152
|
}
|
|
1152
1153
|
}
|
|
1153
1154
|
|
|
1154
|
-
// Copy config.
|
|
1155
|
-
const configPath = path.join(expansionPackDir, 'config.
|
|
1155
|
+
// Copy config.yaml
|
|
1156
|
+
const configPath = path.join(expansionPackDir, 'config.yaml');
|
|
1156
1157
|
if (await fileManager.pathExists(configPath)) {
|
|
1157
|
-
const configDestPath = path.join(expansionDotFolder, 'config.
|
|
1158
|
+
const configDestPath = path.join(expansionDotFolder, 'config.yaml');
|
|
1158
1159
|
if (await fileManager.copyFile(configPath, configDestPath)) {
|
|
1159
|
-
installedFiles.push(path.join(`.${packId}`, 'config.
|
|
1160
|
+
installedFiles.push(path.join(`.${packId}`, 'config.yaml'));
|
|
1160
1161
|
}
|
|
1161
1162
|
}
|
|
1162
1163
|
|
|
@@ -1222,10 +1223,10 @@ class Installer {
|
|
|
1222
1223
|
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
1223
1224
|
|
|
1224
1225
|
// Extract YAML frontmatter to check dependencies
|
|
1225
|
-
const
|
|
1226
|
-
if (
|
|
1226
|
+
const yamlContent = extractYamlFromAgent(agentContent);
|
|
1227
|
+
if (yamlContent) {
|
|
1227
1228
|
try {
|
|
1228
|
-
const agentConfig = yaml.parse(
|
|
1229
|
+
const agentConfig = yaml.parse(yamlContent);
|
|
1229
1230
|
const dependencies = agentConfig.dependencies || {};
|
|
1230
1231
|
|
|
1231
1232
|
// Check for core dependencies (those that don't exist in the expansion pack)
|
|
@@ -1268,7 +1269,7 @@ class Installer {
|
|
|
1268
1269
|
const fs = require('fs').promises;
|
|
1269
1270
|
|
|
1270
1271
|
// Find all team files in the expansion pack
|
|
1271
|
-
const teamFiles = glob.sync('agent-teams/*.
|
|
1272
|
+
const teamFiles = glob.sync('agent-teams/*.yaml', {
|
|
1272
1273
|
cwd: expansionDotFolder
|
|
1273
1274
|
});
|
|
1274
1275
|
|
|
@@ -1314,13 +1315,10 @@ class Installer {
|
|
|
1314
1315
|
|
|
1315
1316
|
// Now resolve this agent's dependencies too
|
|
1316
1317
|
const agentContent = await fs.readFile(coreAgentPath, 'utf8');
|
|
1317
|
-
const
|
|
1318
|
+
const yamlContent = extractYamlFromAgent(agentContent, true);
|
|
1318
1319
|
|
|
1319
|
-
if (
|
|
1320
|
+
if (yamlContent) {
|
|
1320
1321
|
try {
|
|
1321
|
-
// Clean up the YAML to handle command descriptions
|
|
1322
|
-
let yamlContent = yamlMatch[1];
|
|
1323
|
-
yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
|
|
1324
1322
|
|
|
1325
1323
|
const agentConfig = yaml.parse(yamlContent);
|
|
1326
1324
|
const dependencies = agentConfig.dependencies || {};
|
|
@@ -1330,7 +1328,7 @@ class Installer {
|
|
|
1330
1328
|
const deps = dependencies[depType] || [];
|
|
1331
1329
|
|
|
1332
1330
|
for (const dep of deps) {
|
|
1333
|
-
const depFileName = dep.endsWith('.md') || dep.endsWith('.
|
|
1331
|
+
const depFileName = dep.endsWith('.md') || dep.endsWith('.yaml') ? dep : `${dep}.md`;
|
|
1334
1332
|
const expansionDepPath = path.join(expansionDotFolder, depType, depFileName);
|
|
1335
1333
|
|
|
1336
1334
|
// Check if dependency exists in expansion pack
|
|
@@ -1360,7 +1358,7 @@ class Installer {
|
|
|
1360
1358
|
}
|
|
1361
1359
|
}
|
|
1362
1360
|
} else {
|
|
1363
|
-
console.warn(chalk.yellow(` Warning: Core agent ${agentId} not found for team ${path.basename(teamFile, '.
|
|
1361
|
+
console.warn(chalk.yellow(` Warning: Core agent ${agentId} not found for team ${path.basename(teamFile, '.yaml')}`));
|
|
1364
1362
|
}
|
|
1365
1363
|
}
|
|
1366
1364
|
}
|
|
@@ -1528,7 +1526,7 @@ class Installer {
|
|
|
1528
1526
|
|
|
1529
1527
|
if (stats) {
|
|
1530
1528
|
// Check if it has a manifest
|
|
1531
|
-
const manifestPath = path.join(folderPath, "install-manifest.
|
|
1529
|
+
const manifestPath = path.join(folderPath, "install-manifest.yaml");
|
|
1532
1530
|
if (await fileManager.pathExists(manifestPath)) {
|
|
1533
1531
|
const manifest = await fileManager.readExpansionPackManifest(installDir, folder.substring(1));
|
|
1534
1532
|
if (manifest) {
|
|
@@ -1539,8 +1537,8 @@ class Installer {
|
|
|
1539
1537
|
};
|
|
1540
1538
|
}
|
|
1541
1539
|
} else {
|
|
1542
|
-
// Check if it has a config.
|
|
1543
|
-
const configPath = path.join(folderPath, "config.
|
|
1540
|
+
// Check if it has a config.yaml (expansion pack without manifest)
|
|
1541
|
+
const configPath = path.join(folderPath, "config.yaml");
|
|
1544
1542
|
if (await fileManager.pathExists(configPath)) {
|
|
1545
1543
|
expansionPacks[folder.substring(1)] = {
|
|
1546
1544
|
path: folderPath,
|
|
@@ -1579,7 +1577,7 @@ class Installer {
|
|
|
1579
1577
|
|
|
1580
1578
|
for (const file of filesToRestore) {
|
|
1581
1579
|
// Skip the manifest file itself
|
|
1582
|
-
if (file.endsWith('install-manifest.
|
|
1580
|
+
if (file.endsWith('install-manifest.yaml')) continue;
|
|
1583
1581
|
|
|
1584
1582
|
const relativePath = file.replace(`.${packId}/`, '');
|
|
1585
1583
|
const sourcePath = path.join(pack.packPath, relativePath);
|
|
@@ -1645,7 +1643,7 @@ class Installer {
|
|
|
1645
1643
|
|
|
1646
1644
|
while (currentDir !== path.dirname(currentDir)) {
|
|
1647
1645
|
const bmadDir = path.join(currentDir, ".bmad-core");
|
|
1648
|
-
const manifestPath = path.join(bmadDir, "install-manifest.
|
|
1646
|
+
const manifestPath = path.join(bmadDir, "install-manifest.yaml");
|
|
1649
1647
|
|
|
1650
1648
|
if (await fileManager.pathExists(manifestPath)) {
|
|
1651
1649
|
return bmadDir;
|
|
@@ -1656,7 +1654,7 @@ class Installer {
|
|
|
1656
1654
|
|
|
1657
1655
|
// Also check if we're inside a .bmad-core directory
|
|
1658
1656
|
if (path.basename(process.cwd()) === ".bmad-core") {
|
|
1659
|
-
const manifestPath = path.join(process.cwd(), "install-manifest.
|
|
1657
|
+
const manifestPath = path.join(process.cwd(), "install-manifest.yaml");
|
|
1660
1658
|
if (await fileManager.pathExists(manifestPath)) {
|
|
1661
1659
|
return process.cwd();
|
|
1662
1660
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs').promises;
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const yaml = require('js-yaml');
|
|
4
|
+
const { extractYamlFromAgent } = require('./yaml-utils');
|
|
4
5
|
|
|
5
6
|
class DependencyResolver {
|
|
6
7
|
constructor(rootDir) {
|
|
@@ -14,17 +15,12 @@ class DependencyResolver {
|
|
|
14
15
|
const agentPath = path.join(this.bmadCore, 'agents', `${agentId}.md`);
|
|
15
16
|
const agentContent = await fs.readFile(agentPath, 'utf8');
|
|
16
17
|
|
|
17
|
-
// Extract YAML from markdown content
|
|
18
|
-
const
|
|
19
|
-
if (!
|
|
18
|
+
// Extract YAML from markdown content with command cleaning
|
|
19
|
+
const yamlContent = extractYamlFromAgent(agentContent, true);
|
|
20
|
+
if (!yamlContent) {
|
|
20
21
|
throw new Error(`No YAML configuration found in agent ${agentId}`);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
// Clean up the YAML to handle command descriptions after dashes
|
|
24
|
-
let yamlContent = yamlMatch[1];
|
|
25
|
-
// Fix commands section: convert "- command - description" to just "- command"
|
|
26
|
-
yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
|
|
27
|
-
|
|
28
24
|
const agentConfig = yaml.load(yamlContent);
|
|
29
25
|
|
|
30
26
|
const dependencies = {
|
|
@@ -53,7 +49,7 @@ class DependencyResolver {
|
|
|
53
49
|
}
|
|
54
50
|
|
|
55
51
|
async resolveTeamDependencies(teamId) {
|
|
56
|
-
const teamPath = path.join(this.bmadCore, 'agent-teams', `${teamId}.
|
|
52
|
+
const teamPath = path.join(this.bmadCore, 'agent-teams', `${teamId}.yaml`);
|
|
57
53
|
const teamContent = await fs.readFile(teamPath, 'utf8');
|
|
58
54
|
const teamConfig = yaml.load(teamContent);
|
|
59
55
|
|
|
@@ -120,7 +116,7 @@ class DependencyResolver {
|
|
|
120
116
|
}
|
|
121
117
|
|
|
122
118
|
try {
|
|
123
|
-
const extensions = ['.md', '.
|
|
119
|
+
const extensions = ['.md', '.yaml'];
|
|
124
120
|
let content = null;
|
|
125
121
|
let filePath = null;
|
|
126
122
|
|
|
@@ -183,8 +179,8 @@ class DependencyResolver {
|
|
|
183
179
|
try {
|
|
184
180
|
const files = await fs.readdir(path.join(this.bmadCore, 'agent-teams'));
|
|
185
181
|
return files
|
|
186
|
-
.filter(f => f.endsWith('.
|
|
187
|
-
.map(f => f.replace('.
|
|
182
|
+
.filter(f => f.endsWith('.yaml'))
|
|
183
|
+
.map(f => f.replace('.yaml', ''));
|
|
188
184
|
} catch (error) {
|
|
189
185
|
return [];
|
|
190
186
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for YAML extraction from agent files
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Extract YAML content from agent markdown files
|
|
7
|
+
* @param {string} agentContent - The full content of the agent file
|
|
8
|
+
* @param {boolean} cleanCommands - Whether to clean command descriptions (default: false)
|
|
9
|
+
* @returns {string|null} - The extracted YAML content or null if not found
|
|
10
|
+
*/
|
|
11
|
+
function extractYamlFromAgent(agentContent, cleanCommands = false) {
|
|
12
|
+
// Remove carriage returns and match YAML block
|
|
13
|
+
const yamlMatch = agentContent.replace(/\r/g, "").match(/```ya?ml\n([\s\S]*?)\n```/);
|
|
14
|
+
if (!yamlMatch) return null;
|
|
15
|
+
|
|
16
|
+
let yamlContent = yamlMatch[1].trim();
|
|
17
|
+
|
|
18
|
+
// Clean up command descriptions if requested
|
|
19
|
+
// Converts "- command - description" to just "- command"
|
|
20
|
+
if (cleanCommands) {
|
|
21
|
+
yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, '$1$2');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return yamlContent;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
extractYamlFromAgent
|
|
29
|
+
};
|
|
@@ -22,8 +22,8 @@ if (!/^\d+\.\d+\.\d+$/.test(newVersion)) {
|
|
|
22
22
|
|
|
23
23
|
async function updateVersion() {
|
|
24
24
|
try {
|
|
25
|
-
// Update in config.
|
|
26
|
-
const configPath = path.join(__dirname, '..', 'expansion-packs', packId, 'config.
|
|
25
|
+
// Update in config.yaml
|
|
26
|
+
const configPath = path.join(__dirname, '..', 'expansion-packs', packId, 'config.yaml');
|
|
27
27
|
|
|
28
28
|
if (!fs.existsSync(configPath)) {
|
|
29
29
|
console.error(`Error: Expansion pack '${packId}' not found`);
|
|
@@ -39,7 +39,7 @@ async function updateVersion() {
|
|
|
39
39
|
const updatedYaml = yaml.dump(config, { indent: 2 });
|
|
40
40
|
fs.writeFileSync(configPath, updatedYaml);
|
|
41
41
|
|
|
42
|
-
console.log(`✓ Updated ${packId}/config.
|
|
42
|
+
console.log(`✓ Updated ${packId}/config.yaml: ${oldVersion} → ${newVersion}`);
|
|
43
43
|
console.log(`\n✓ Successfully updated ${packId} to version ${newVersion}`);
|
|
44
44
|
console.log('\nNext steps:');
|
|
45
45
|
console.log('1. Test the changes');
|
package/tools/yaml-format.js
CHANGED
|
@@ -197,7 +197,7 @@ async function main() {
|
|
|
197
197
|
let changed = false;
|
|
198
198
|
if (ext === '.md') {
|
|
199
199
|
changed = await processMarkdownFile(filePath);
|
|
200
|
-
} else if (ext === '.
|
|
200
|
+
} else if (ext === '.yaml' || ext === '.yml' || basename.includes('roomodes') || basename.includes('.yaml') || basename.includes('.yml')) {
|
|
201
201
|
// Handle YAML files and special cases like .roomodes
|
|
202
202
|
changed = await processYamlFile(filePath);
|
|
203
203
|
|