bmad-method 4.24.0 → 4.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +11 -5
- package/CHANGELOG.md +17 -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/{core-config.yml → core-config.yaml} +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/dist/agents/analyst.txt +5 -5
- package/dist/agents/architect.txt +5 -5
- package/dist/agents/bmad-master.txt +18 -18
- package/dist/agents/bmad-orchestrator.txt +7 -7
- package/dist/agents/dev.txt +1 -1
- package/dist/agents/pm.txt +4 -4
- package/dist/agents/po.txt +3 -3
- package/dist/agents/sm.txt +4 -4
- package/dist/agents/ux-expert.txt +1 -1
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +1 -1
- package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +3 -3
- package/dist/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.txt +10 -10
- package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +2 -2
- package/dist/teams/team-all.txt +19 -19
- package/dist/teams/team-fullstack.txt +14 -14
- package/dist/teams/team-ide-minimal.txt +15 -15
- package/dist/teams/team-no-ui.txt +14 -14
- 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-2d-phaser-game-dev/{config.yml → config.yaml} +1 -1
- package/expansion-packs/bmad-creator-tools/{config.yml → config.yaml} +1 -1
- 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/{config.yml → config.yaml} +1 -1
- 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/.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/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/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/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
|
@@ -286,7 +286,7 @@ IMPORTANT: Only proceed after plan.md is approved
|
|
|
286
286
|
expansion-packs/
|
|
287
287
|
└── {pack-name}/
|
|
288
288
|
├── plan.md (ALREADY CREATED)
|
|
289
|
-
├── manifest.
|
|
289
|
+
├── manifest.yaml
|
|
290
290
|
├── README.md
|
|
291
291
|
├── agents/
|
|
292
292
|
│ ├── {pack-name}-orchestrator.md (REQUIRED - Custom themed orchestrator)
|
|
@@ -309,13 +309,13 @@ expansion-packs/
|
|
|
309
309
|
├── workflows/
|
|
310
310
|
│ └── {domain}-workflow.md (REQUIRED if multiple agents)
|
|
311
311
|
└── agent-teams/
|
|
312
|
-
└── {domain}-team.
|
|
312
|
+
└── {domain}-team.yaml (REQUIRED if multiple agents)
|
|
313
313
|
|
|
314
314
|
```
|
|
315
315
|
|
|
316
316
|
#### 3.2 Create Manifest
|
|
317
317
|
|
|
318
|
-
Create `manifest.
|
|
318
|
+
Create `manifest.yaml`:
|
|
319
319
|
|
|
320
320
|
```yaml
|
|
321
321
|
name: {pack-name}
|
|
@@ -358,7 +358,7 @@ files:
|
|
|
358
358
|
- {domain}-workflow.md # REQUIRED if multiple agents - decision trees
|
|
359
359
|
|
|
360
360
|
agent-teams:
|
|
361
|
-
- {domain}-team.
|
|
361
|
+
- {domain}-team.yaml # REQUIRED if multiple agents - team config
|
|
362
362
|
|
|
363
363
|
# Data files users must provide (in their bmad-core/data/ directory)
|
|
364
364
|
required_user_data:
|
|
@@ -494,7 +494,7 @@ cp common/utils/workflow-management.md expansion-packs/{pack-name}/utils/
|
|
|
494
494
|
1. Design decision trees for workflow branching
|
|
495
495
|
2. Create handoff protocols to specialist agents
|
|
496
496
|
3. Implement validation loops and quality checkpoints
|
|
497
|
-
4. **If multiple agents**: Create team configuration in `agent-teams/{domain}-team.
|
|
497
|
+
4. **If multiple agents**: Create team configuration in `agent-teams/{domain}-team.yaml`
|
|
498
498
|
5. **If multiple agents**: Create workflow in `workflows/{domain}-workflow.md`
|
|
499
499
|
6. Ensure orchestrator references workflow-management utility
|
|
500
500
|
7. Verify ALL referenced tasks exist (including core utilities)
|
|
@@ -665,7 +665,7 @@ Before declaring complete:
|
|
|
665
665
|
|
|
666
666
|
1. [ ] Decision trees and workflow orchestration complete
|
|
667
667
|
2. [ ] Knowledge base files embedded (best practices, terminology, standards)
|
|
668
|
-
3. [ ] Manifest.
|
|
668
|
+
3. [ ] Manifest.yaml reflects all components and dependencies
|
|
669
669
|
4. [ ] All items in plan.md marked complete
|
|
670
670
|
5. [ ] No orphaned tasks or templates
|
|
671
671
|
|
|
@@ -772,7 +772,7 @@ These files are automatically available to all agents and don't require user set
|
|
|
772
772
|
```text
|
|
773
773
|
healthcare/
|
|
774
774
|
├── plan.md (Created first for approval)
|
|
775
|
-
├── manifest.
|
|
775
|
+
├── manifest.yaml (with dependency mapping and character descriptions)
|
|
776
776
|
├── README.md (featuring character introductions and numbered options)
|
|
777
777
|
├── agents/
|
|
778
778
|
│ ├── healthcare-orchestrator.md (Dr. Sarah Chen - YAML-in-Markdown)
|
|
@@ -798,7 +798,7 @@ healthcare/
|
|
|
798
798
|
│ ├── clinical-trial-workflow.md (decision trees with Mermaid diagrams)
|
|
799
799
|
│ └── compliance-audit-workflow.md (handoff protocols and quality gates)
|
|
800
800
|
└── agent-teams/
|
|
801
|
-
└── healthcare-team.
|
|
801
|
+
└── healthcare-team.yaml (coordinated team configurations)
|
|
802
802
|
|
|
803
803
|
Required user data files (bmad-core/data/):
|
|
804
804
|
- medical-terminology.md (institution-specific terms and abbreviations)
|
|
@@ -1009,7 +1009,7 @@ Embedded knowledge (automatic):
|
|
|
1009
1009
|
- [ ] All agent references verified (tasks, templates, data, checklists)
|
|
1010
1010
|
- [ ] Data requirements documented with validation criteria and examples
|
|
1011
1011
|
- [ ] README includes character introductions and numbered options explanation
|
|
1012
|
-
- [ ] manifest.
|
|
1012
|
+
- [ ] manifest.yaml reflects actual files with dependency mapping and character descriptions
|
|
1013
1013
|
|
|
1014
1014
|
**Advanced Quality Gates:**
|
|
1015
1015
|
|
|
@@ -150,5 +150,5 @@ workflows: null
|
|
|
150
150
|
3. Replace all placeholders with actual values
|
|
151
151
|
4. Ensure agent names match available agents in the system
|
|
152
152
|
5. Verify workflow names match available workflows
|
|
153
|
-
6. Save as team-[descriptor].
|
|
153
|
+
6. Save as team-[descriptor].yaml or [domain]-team.yaml
|
|
154
154
|
7. Place in the agent-teams directory of the appropriate location]]
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
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:
|
|
12
12
|
|
|
13
|
-
```
|
|
13
|
+
```yaml
|
|
14
14
|
activation-instructions:
|
|
15
15
|
- Follow all instructions in this file -> this defines you, your persona and more importantly what you can do. STAY IN CHARACTER!
|
|
16
16
|
- Only read the files/tasks listed here when user selects them for execution to minimize context usage
|
|
@@ -28,7 +28,7 @@ Install this expansion pack when your project requires:
|
|
|
28
28
|
|
|
29
29
|
### Agents
|
|
30
30
|
|
|
31
|
-
- `devops.
|
|
31
|
+
- `devops.yaml` - DevOps and Platform Engineering agent configuration
|
|
32
32
|
|
|
33
33
|
### Personas
|
|
34
34
|
|
|
@@ -116,8 +116,8 @@ Before deployment:
|
|
|
116
116
|
|
|
117
117
|
The DevOps agent can be added to team configurations:
|
|
118
118
|
|
|
119
|
-
- `team-technical.
|
|
120
|
-
- `team-full-org.
|
|
119
|
+
- `team-technical.yaml` - For technical implementation teams
|
|
120
|
+
- `team-full-org.yaml` - For complete organizational teams
|
|
121
121
|
|
|
122
122
|
## Dependencies
|
|
123
123
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require("node:fs").promises;
|
|
2
2
|
const path = require("node:path");
|
|
3
3
|
const DependencyResolver = require("../lib/dependency-resolver");
|
|
4
|
+
const yamlUtils = require("../lib/yaml-utils");
|
|
4
5
|
|
|
5
6
|
class WebBuilder {
|
|
6
7
|
constructor(options = {}) {
|
|
@@ -111,10 +112,12 @@ class WebBuilder {
|
|
|
111
112
|
|
|
112
113
|
processAgentContent(content) {
|
|
113
114
|
// First, replace content before YAML with the template
|
|
115
|
+
const yamlContent = yamlUtils.extractYamlFromAgent(content);
|
|
116
|
+
if (!yamlContent) return content;
|
|
117
|
+
|
|
114
118
|
const yamlMatch = content.match(/```ya?ml\n([\s\S]*?)\n```/);
|
|
115
119
|
if (!yamlMatch) return content;
|
|
116
|
-
|
|
117
|
-
const yamlContent = yamlMatch[1];
|
|
120
|
+
|
|
118
121
|
const yamlStartIndex = content.indexOf(yamlMatch[0]);
|
|
119
122
|
const yamlEndIndex = yamlStartIndex + yamlMatch[0].length;
|
|
120
123
|
|
|
@@ -259,7 +262,7 @@ class WebBuilder {
|
|
|
259
262
|
const agentTeamsDir = path.join(packDir, "agent-teams");
|
|
260
263
|
try {
|
|
261
264
|
const teamFiles = await fs.readdir(agentTeamsDir);
|
|
262
|
-
const teamFile = teamFiles.find((f) => f.endsWith(".
|
|
265
|
+
const teamFile = teamFiles.find((f) => f.endsWith(".yaml"));
|
|
263
266
|
|
|
264
267
|
if (teamFile) {
|
|
265
268
|
console.log(` Building team bundle for ${packName}`);
|
|
@@ -272,7 +275,7 @@ class WebBuilder {
|
|
|
272
275
|
for (const outputDir of outputDirs) {
|
|
273
276
|
const teamsOutputDir = path.join(outputDir, "teams");
|
|
274
277
|
await fs.mkdir(teamsOutputDir, { recursive: true });
|
|
275
|
-
const outputFile = path.join(teamsOutputDir, teamFile.replace(".
|
|
278
|
+
const outputFile = path.join(teamsOutputDir, teamFile.replace(".yaml", ".txt"));
|
|
276
279
|
await fs.writeFile(outputFile, bundle, "utf8");
|
|
277
280
|
console.log(` ✓ Created bundle: ${path.relative(this.rootDir, outputFile)}`);
|
|
278
281
|
}
|
|
@@ -294,11 +297,11 @@ class WebBuilder {
|
|
|
294
297
|
sections.push(this.formatSection(`agents#${agentName}`, agentContent));
|
|
295
298
|
|
|
296
299
|
// Resolve and add agent dependencies
|
|
297
|
-
const
|
|
298
|
-
if (
|
|
300
|
+
const yamlContent = yamlUtils.extractYamlFromAgent(agentContent);
|
|
301
|
+
if (yamlContent) {
|
|
299
302
|
try {
|
|
300
303
|
const yaml = require("js-yaml");
|
|
301
|
-
const agentConfig = yaml.load(
|
|
304
|
+
const agentConfig = yaml.load(yamlContent);
|
|
302
305
|
|
|
303
306
|
if (agentConfig.dependencies) {
|
|
304
307
|
// Add resources, first try expansion pack, then core
|
|
@@ -306,7 +309,7 @@ class WebBuilder {
|
|
|
306
309
|
if (Array.isArray(resources)) {
|
|
307
310
|
for (const resourceName of resources) {
|
|
308
311
|
let found = false;
|
|
309
|
-
const extensions = [".md", ".
|
|
312
|
+
const extensions = [".md", ".yaml"];
|
|
310
313
|
|
|
311
314
|
// Try expansion pack first
|
|
312
315
|
for (const ext of extensions) {
|
|
@@ -391,7 +394,7 @@ class WebBuilder {
|
|
|
391
394
|
|
|
392
395
|
// Add team configuration and parse to get agent list
|
|
393
396
|
const teamContent = await fs.readFile(teamConfigPath, "utf8");
|
|
394
|
-
const teamFileName = path.basename(teamConfigPath, ".
|
|
397
|
+
const teamFileName = path.basename(teamConfigPath, ".yaml");
|
|
395
398
|
const teamConfig = this.parseYaml(teamContent);
|
|
396
399
|
sections.push(this.formatSection(`agent-teams#${teamFileName}`, teamContent));
|
|
397
400
|
|
|
@@ -416,9 +419,9 @@ class WebBuilder {
|
|
|
416
419
|
try {
|
|
417
420
|
const resourceFiles = await fs.readdir(resourcePath);
|
|
418
421
|
for (const resourceFile of resourceFiles.filter(
|
|
419
|
-
(f) => f.endsWith(".md") || f.endsWith(".
|
|
422
|
+
(f) => f.endsWith(".md") || f.endsWith(".yaml")
|
|
420
423
|
)) {
|
|
421
|
-
const fileName = resourceFile.replace(/\.(md|
|
|
424
|
+
const fileName = resourceFile.replace(/\.(md|yaml)$/, "");
|
|
422
425
|
expansionResources.set(`${resourceDir}#${fileName}`, true);
|
|
423
426
|
}
|
|
424
427
|
} catch (error) {
|
|
@@ -474,13 +477,9 @@ class WebBuilder {
|
|
|
474
477
|
sections.push(this.formatSection(`agents#${agentId}`, coreAgentContent));
|
|
475
478
|
|
|
476
479
|
// Parse and collect dependencies from core agent
|
|
477
|
-
const
|
|
478
|
-
if (
|
|
480
|
+
const yamlContent = yamlUtils.extractYamlFromAgent(coreAgentContent, true);
|
|
481
|
+
if (yamlContent) {
|
|
479
482
|
try {
|
|
480
|
-
// Clean up the YAML to handle command descriptions after dashes
|
|
481
|
-
let yamlContent = agentYaml[1];
|
|
482
|
-
yamlContent = yamlContent.replace(/^(\s*-)(\s*"[^"]+")(\s*-\s*.*)$/gm, "$1$2");
|
|
483
|
-
|
|
484
483
|
const agentConfig = this.parseYaml(yamlContent);
|
|
485
484
|
if (agentConfig.dependencies) {
|
|
486
485
|
for (const [resourceType, resources] of Object.entries(agentConfig.dependencies)) {
|
|
@@ -508,7 +507,7 @@ class WebBuilder {
|
|
|
508
507
|
// Always prefer expansion pack versions if they exist
|
|
509
508
|
for (const [key, dep] of allDependencies) {
|
|
510
509
|
let found = false;
|
|
511
|
-
const extensions = [".md", ".
|
|
510
|
+
const extensions = [".md", ".yaml"];
|
|
512
511
|
|
|
513
512
|
// Always check expansion pack first, even if the dependency came from a core agent
|
|
514
513
|
if (expansionResources.has(key)) {
|
|
@@ -568,11 +567,11 @@ class WebBuilder {
|
|
|
568
567
|
try {
|
|
569
568
|
const resourceFiles = await fs.readdir(resourcePath);
|
|
570
569
|
for (const resourceFile of resourceFiles.filter(
|
|
571
|
-
(f) => f.endsWith(".md") || f.endsWith(".
|
|
570
|
+
(f) => f.endsWith(".md") || f.endsWith(".yaml")
|
|
572
571
|
)) {
|
|
573
572
|
const filePath = path.join(resourcePath, resourceFile);
|
|
574
573
|
const fileContent = await fs.readFile(filePath, "utf8");
|
|
575
|
-
const fileName = resourceFile.replace(/\.(md|
|
|
574
|
+
const fileName = resourceFile.replace(/\.(md|yaml)$/, "");
|
|
576
575
|
|
|
577
576
|
// Only add if not already included as a dependency
|
|
578
577
|
const resourceKey = `${resourceDir}#${fileName}`;
|
|
@@ -32,7 +32,7 @@ async function bumpAllVersions() {
|
|
|
32
32
|
const updatedItems = [];
|
|
33
33
|
|
|
34
34
|
// First, bump the core version
|
|
35
|
-
const coreConfigPath = path.join(__dirname, '..', 'bmad-core', 'core-config.
|
|
35
|
+
const coreConfigPath = path.join(__dirname, '..', 'bmad-core', 'core-config.yaml');
|
|
36
36
|
try {
|
|
37
37
|
const coreConfigContent = fs.readFileSync(coreConfigPath, 'utf8');
|
|
38
38
|
const coreConfig = yaml.load(coreConfigContent);
|
|
@@ -59,7 +59,7 @@ async function bumpAllVersions() {
|
|
|
59
59
|
for (const entry of entries) {
|
|
60
60
|
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'README.md') {
|
|
61
61
|
const packId = entry.name;
|
|
62
|
-
const configPath = path.join(expansionPacksDir, packId, 'config.
|
|
62
|
+
const configPath = path.join(expansionPacksDir, packId, 'config.yaml');
|
|
63
63
|
|
|
64
64
|
if (fs.existsSync(configPath)) {
|
|
65
65
|
try {
|
|
@@ -30,7 +30,7 @@ function bumpVersion(currentVersion, type) {
|
|
|
30
30
|
|
|
31
31
|
async function bumpCoreVersion() {
|
|
32
32
|
try {
|
|
33
|
-
const coreConfigPath = path.join(__dirname, '..', 'bmad-core', 'core-config.
|
|
33
|
+
const coreConfigPath = path.join(__dirname, '..', 'bmad-core', 'core-config.yaml');
|
|
34
34
|
|
|
35
35
|
const coreConfigContent = fs.readFileSync(coreConfigPath, 'utf8');
|
|
36
36
|
const coreConfig = yaml.load(coreConfigContent);
|
|
@@ -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();
|