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.
Files changed (78) hide show
  1. package/.vscode/settings.json +11 -5
  2. package/CHANGELOG.md +17 -1
  3. package/README.md +1 -1
  4. package/bmad-core/agents/bmad-master.md +1 -1
  5. package/bmad-core/agents/dev.md +2 -2
  6. package/bmad-core/agents/pm.md +1 -1
  7. package/bmad-core/agents/po.md +1 -1
  8. package/bmad-core/{core-config.yml → core-config.yaml} +1 -1
  9. package/bmad-core/data/bmad-kb.md +4 -4
  10. package/bmad-core/tasks/create-brownfield-story.md +1 -1
  11. package/bmad-core/tasks/create-next-story.md +4 -4
  12. package/bmad-core/tasks/shard-doc.md +3 -3
  13. package/bmad-core/tasks/update-workflow-plan.md +1 -1
  14. package/bmad-core/templates/architecture-tmpl.md +1 -1
  15. package/bmad-core/templates/fullstack-architecture-tmpl.md +3 -3
  16. package/bmad-core/utils/plan-management.md +1 -1
  17. package/common/tasks/create-doc.md +1 -1
  18. package/dist/agents/analyst.txt +5 -5
  19. package/dist/agents/architect.txt +5 -5
  20. package/dist/agents/bmad-master.txt +18 -18
  21. package/dist/agents/bmad-orchestrator.txt +7 -7
  22. package/dist/agents/dev.txt +1 -1
  23. package/dist/agents/pm.txt +4 -4
  24. package/dist/agents/po.txt +3 -3
  25. package/dist/agents/sm.txt +4 -4
  26. package/dist/agents/ux-expert.txt +1 -1
  27. package/dist/expansion-packs/bmad-2d-phaser-game-dev/agents/game-designer.txt +1 -1
  28. package/dist/expansion-packs/bmad-2d-phaser-game-dev/teams/phaser-2d-nodejs-game-team.txt +3 -3
  29. package/dist/expansion-packs/bmad-creator-tools/agents/bmad-the-creator.txt +10 -10
  30. package/dist/expansion-packs/bmad-infrastructure-devops/agents/infra-devops-platform.txt +2 -2
  31. package/dist/teams/team-all.txt +19 -19
  32. package/dist/teams/team-fullstack.txt +14 -14
  33. package/dist/teams/team-ide-minimal.txt +15 -15
  34. package/dist/teams/team-no-ui.txt +14 -14
  35. package/docs/agentic-tools/roo-code-guide.md +1 -1
  36. package/docs/core-architecture.md +12 -12
  37. package/docs/user-guide.md +6 -6
  38. package/expansion-packs/bmad-2d-phaser-game-dev/{config.yml → config.yaml} +1 -1
  39. package/expansion-packs/bmad-creator-tools/{config.yml → config.yaml} +1 -1
  40. package/expansion-packs/bmad-creator-tools/tasks/generate-expansion-pack.md +9 -9
  41. package/expansion-packs/bmad-creator-tools/templates/agent-teams-tmpl.md +1 -1
  42. package/expansion-packs/bmad-creator-tools/templates/agent-tmpl.md +1 -1
  43. package/expansion-packs/bmad-infrastructure-devops/README.md +3 -3
  44. package/expansion-packs/bmad-infrastructure-devops/{config.yml → config.yaml} +1 -1
  45. package/expansion-packs/bmad-infrastructure-devops/templates/infrastructure-platform-from-arch-tmpl.md +0 -0
  46. package/package.json +1 -1
  47. package/tools/builders/web-builder.js +19 -20
  48. package/tools/bump-all-versions.js +2 -2
  49. package/tools/bump-core-version.js +1 -1
  50. package/tools/bump-expansion-version.js +1 -1
  51. package/tools/installer/README.md +1 -1
  52. package/tools/installer/bin/bmad.js +2 -2
  53. package/tools/installer/lib/config-loader.js +13 -12
  54. package/tools/installer/lib/file-manager.js +5 -5
  55. package/tools/installer/lib/ide-setup.js +14 -13
  56. package/tools/installer/lib/installer.js +24 -26
  57. package/tools/installer/package.json +1 -1
  58. package/tools/lib/dependency-resolver.js +8 -12
  59. package/tools/lib/yaml-utils.js +29 -0
  60. package/tools/update-expansion-version.js +3 -3
  61. package/tools/yaml-format.js +1 -1
  62. /package/.github/{FUNDING.yml → FUNDING.yaml} +0 -0
  63. /package/.github/workflows/{release.yml → release.yaml} +0 -0
  64. /package/bmad-core/agent-teams/{team-all.yml → team-all.yaml} +0 -0
  65. /package/bmad-core/agent-teams/{team-fullstack.yml → team-fullstack.yaml} +0 -0
  66. /package/bmad-core/agent-teams/{team-ide-minimal.yml → team-ide-minimal.yaml} +0 -0
  67. /package/bmad-core/agent-teams/{team-no-ui.yml → team-no-ui.yaml} +0 -0
  68. /package/bmad-core/workflows/{brownfield-fullstack.yml → brownfield-fullstack.yaml} +0 -0
  69. /package/bmad-core/workflows/{brownfield-service.yml → brownfield-service.yaml} +0 -0
  70. /package/bmad-core/workflows/{brownfield-ui.yml → brownfield-ui.yaml} +0 -0
  71. /package/bmad-core/workflows/{greenfield-fullstack.yml → greenfield-fullstack.yaml} +0 -0
  72. /package/bmad-core/workflows/{greenfield-service.yml → greenfield-service.yaml} +0 -0
  73. /package/bmad-core/workflows/{greenfield-ui.yml → greenfield-ui.yaml} +0 -0
  74. /package/expansion-packs/bmad-2d-phaser-game-dev/agent-teams/{phaser-2d-nodejs-game-team.yml → phaser-2d-nodejs-game-team.yaml} +0 -0
  75. /package/expansion-packs/bmad-2d-phaser-game-dev/workflows/{game-dev-greenfield.yml → game-dev-greenfield.yaml} +0 -0
  76. /package/expansion-packs/bmad-2d-phaser-game-dev/workflows/{game-prototype.yml → game-prototype.yaml} +0 -0
  77. /package/tools/installer/config/{ide-agent-config.yml → ide-agent-config.yaml} +0 -0
  78. /package/tools/installer/config/{install.config.yml → install.config.yaml} +0 -0
@@ -1,5 +1,5 @@
1
1
  name: bmad-2d-phaser-game-dev
2
- version: 1.2.0
2
+ version: 1.3.0
3
3
  short-title: 2D game development with Phaser 3 & TypeScript
4
4
  description: >-
5
5
  2D Game Development expansion pack for BMAD Method - Phaser 3 & TypeScript
@@ -1,5 +1,5 @@
1
1
  name: bmad-creator-tools
2
- version: 1.1.0
2
+ version: 1.2.0
3
3
  short-title: Tools for creating BMAD framework components
4
4
  description: Tools for creating and extending BMAD framework components.
5
5
  author: Brian (BMad)
@@ -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.yml
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.yml (REQUIRED if multiple agents)
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.yml`:
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.yml # REQUIRED if multiple agents - team config
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.yml`
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.yml reflects all components and dependencies
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.yml (with dependency mapping and character descriptions)
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.yml (coordinated team configurations)
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.yml reflects actual files with dependency mapping and character descriptions
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].yml or [domain]-team.yml
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
- ```yml
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.yml` - DevOps and Platform Engineering agent configuration
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.yml` - For technical implementation teams
120
- - `team-full-org.yml` - For complete organizational teams
119
+ - `team-technical.yaml` - For technical implementation teams
120
+ - `team-full-org.yaml` - For complete organizational teams
121
121
 
122
122
  ## Dependencies
123
123
 
@@ -1,5 +1,5 @@
1
1
  name: bmad-infrastructure-devops
2
- version: 1.1.0
2
+ version: 1.2.0
3
3
  short-title: Infrastructure and DevOps capabilities
4
4
  description: >-
5
5
  This expansion pack extends BMAD Method with comprehensive infrastructure and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.24.0",
3
+ "version": "4.24.2",
4
4
  "description": "Breakthrough Method of Agile AI-driven Development",
5
5
  "main": "tools/cli.js",
6
6
  "bin": {
@@ -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(".yml"));
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(".yml", ".txt"));
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 agentYaml = agentContent.match(/```yaml\n([\s\S]*?)\n```/);
298
- if (agentYaml) {
300
+ const yamlContent = yamlUtils.extractYamlFromAgent(agentContent);
301
+ if (yamlContent) {
299
302
  try {
300
303
  const yaml = require("js-yaml");
301
- const agentConfig = yaml.load(agentYaml[1]);
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", ".yml", ".yaml"];
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, ".yml");
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(".yml")
422
+ (f) => f.endsWith(".md") || f.endsWith(".yaml")
420
423
  )) {
421
- const fileName = resourceFile.replace(/\.(md|yml)$/, "");
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 agentYaml = coreAgentContent.match(/```yaml\n([\s\S]*?)\n```/);
478
- if (agentYaml) {
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", ".yml", ".yaml"];
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(".yml")
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|yml)$/, "");
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.yml');
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.yml');
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.yml');
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.yml');
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.yml # Installation profiles
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.yml');
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.yml
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.yml');
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 yamlMatch = agentContent.match(/```yml\n([\s\S]*?)\n```/);
45
- if (yamlMatch) {
46
- const yamlContent = yaml.load(yamlMatch[1]);
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.yml');
83
+ const configPath = path.join(packPath, 'config.yaml');
83
84
 
84
85
  try {
85
- // Read config.yml
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.yml doesn't exist or can't be read
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('.yml')) {
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, '.yml'),
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}.yml`);
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}.yml`);
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' ? 'yml' : 'md'}`;
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.yml";
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.yml
87
- const coreConfigPath = path.join(__dirname, "../../../bmad-core/core-config.yml");
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.yml, using 'unknown'");
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.yml')) {
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.yml');
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 += "```yml\n";
102
+ mdcContent += "```yaml\n";
102
103
  // Extract just the YAML content from the agent file
103
- const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)```/);
104
- if (yamlMatch) {
105
- mdcContent += yamlMatch[1].trim();
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 += "```yml\n";
184
+ mdContent += "```yaml\n";
184
185
  // Extract just the YAML content from the agent file
185
- const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)```/);
186
- if (yamlMatch) {
187
- mdContent += yamlMatch[1].trim();
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 += "```yml\n";
432
+ mdContent += "```yaml\n";
432
433
  // Extract just the YAML content from the agent file
433
- const yamlMatch = agentContent.match(/```ya?ml\n([\s\S]*?)```/);
434
- if (yamlMatch) {
435
- mdContent += yamlMatch[1].trim();
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();