bmad-method 4.33.1 → 4.35.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/CHANGELOG.md CHANGED
@@ -1,9 +1,21 @@
1
- ## [4.33.1](https://github.com/bmadcode/BMAD-METHOD/compare/v4.33.0...v4.33.1) (2025-07-29)
1
+ # [4.35.0](https://github.com/bmadcode/BMAD-METHOD/compare/v4.34.0...v4.35.0) (2025-08-04)
2
+
3
+
4
+ ### Features
5
+
6
+ * add qwen-code ide support to bmad installer. ([#392](https://github.com/bmadcode/BMAD-METHOD/issues/392)) ([a72b790](https://github.com/bmadcode/BMAD-METHOD/commit/a72b790f3be6c77355511ace2d63e6bec4d751f1))
2
7
 
8
+ # [4.34.0](https://github.com/bmadcode/BMAD-METHOD/compare/v4.33.1...v4.34.0) (2025-08-03)
9
+
10
+ ### Features
11
+
12
+ - add KiloCode integration support to BMAD installer ([#390](https://github.com/bmadcode/BMAD-METHOD/issues/390)) ([dcebe91](https://github.com/bmadcode/BMAD-METHOD/commit/dcebe91d5ea68e69aa27183411a81639d444efd7))
13
+
14
+ ## [4.33.1](https://github.com/bmadcode/BMAD-METHOD/compare/v4.33.0...v4.33.1) (2025-07-29)
3
15
 
4
16
  ### Bug Fixes
5
17
 
6
- * dev agent yaml syntax for develop-story command ([#362](https://github.com/bmadcode/BMAD-METHOD/issues/362)) ([bcb3728](https://github.com/bmadcode/BMAD-METHOD/commit/bcb3728f8868c0f83bca3d61fbd7e15c4e114526))
18
+ - dev agent yaml syntax for develop-story command ([#362](https://github.com/bmadcode/BMAD-METHOD/issues/362)) ([bcb3728](https://github.com/bmadcode/BMAD-METHOD/commit/bcb3728f8868c0f83bca3d61fbd7e15c4e114526))
7
19
 
8
20
  # [4.33.0](https://github.com/bmadcode/BMAD-METHOD/compare/v4.32.0...v4.33.0) (2025-07-28)
9
21
 
package/README.md CHANGED
@@ -40,7 +40,7 @@ This two-phase approach eliminates both **planning inconsistency** and **context
40
40
 
41
41
  - **[Install and Build software with Full Stack Agile AI Team](#quick-start)** → Quick Start Instruction
42
42
  - **[Learn how to use BMad](bmad-core/user-guide.md)** → Complete user guide and walkthrough
43
- - **[See available AI agents](#available-agents)** → Specialized roles for your team
43
+ - **[See available AI agents](/bmad-core/agents))** → Specialized roles for your team
44
44
  - **[Explore non-technical uses](#-beyond-software-development---expansion-packs)** → Creative writing, business, wellness, education
45
45
  - **[Create my own AI agents](#creating-your-own-expansion-pack)** → Build agents for your domain
46
46
  - **[Browse ready-made expansion packs](expansion-packs/)** → Game dev, DevOps, infrastructure and get inspired with ideas and examples
@@ -85,9 +85,9 @@ Once planning is complete and documents are sharded, BMad follows a structured d
85
85
  graph TD
86
86
  A["Development Phase Start"] --> B["SM: Reviews Previous Story Dev/QA Notes"]
87
87
  B --> B2["SM: Drafts Next Story from Sharded Epic + Architecture"]
88
- B2 --> B3{"QA: Review Story Draft (Optional)"}
89
- B3 -->|Review Requested| B4["QA: Review Story Against Artifacts"]
90
- B3 -->|Skip Review| C{"User Approval"}
88
+ B2 --> B3{"PO: Validate Story Draft (Optional)"}
89
+ B3 -->|Validation Requested| B4["PO: Validate Story Against Artifacts"]
90
+ B3 -->|Skip Validation| C{"User Approval"}
91
91
  B4 --> C
92
92
  C -->|Approved| D["Dev: Sequential Task Execution"]
93
93
  C -->|Needs Changes| B2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.33.1",
3
+ "version": "4.35.0",
4
4
  "description": "Breakthrough Method of Agile AI-driven Development",
5
5
  "main": "tools/cli.js",
6
6
  "bin": {
@@ -41,7 +41,7 @@ program
41
41
  .option('-f, --full', 'Install complete BMad Method')
42
42
  .option('-x, --expansion-only', 'Install only expansion packs (no bmad-core)')
43
43
  .option('-d, --directory <path>', 'Installation directory')
44
- .option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, trae, roo, cline, gemini, github-copilot, other)')
44
+ .option('-i, --ide <ide...>', 'Configure for specific IDE(s) - can specify multiple (cursor, claude-code, windsurf, trae, roo, kilo, cline, gemini, qwen-code, github-copilot, other)')
45
45
  .option('-e, --expansion-packs <packs...>', 'Install specific expansion packs (can specify multiple)')
46
46
  .action(async (options) => {
47
47
  try {
@@ -311,8 +311,10 @@ async function promptInstallation() {
311
311
  { name: 'Windsurf', value: 'windsurf' },
312
312
  { name: 'Trae', value: 'trae' }, // { name: 'Trae', value: 'trae'}
313
313
  { name: 'Roo Code', value: 'roo' },
314
+ { name: 'Kilo Code', value: 'kilo' },
314
315
  { name: 'Cline', value: 'cline' },
315
316
  { name: 'Gemini CLI', value: 'gemini' },
317
+ { name: 'Qwen Code', value: 'qwen-code' },
316
318
  { name: 'Github Copilot', value: 'github-copilot' }
317
319
  ]
318
320
  }
@@ -89,4 +89,25 @@ ide-configurations:
89
89
  # 3. The agent will adopt that persona for the conversation
90
90
  # 4. Requires VS Code 1.101+ with `chat.agent.enabled: true` in settings
91
91
  # 5. Agent files are stored in .github/chatmodes/
92
- # 6. Use `*help` to see available commands and agents
92
+ # 6. Use `*help` to see available commands and agents
93
+ kilo:
94
+ name: Kilo Code
95
+ format: custom-modes
96
+ file: .kilocodemodes
97
+ instructions: |
98
+ # To use BMAD agents in Kilo Code:
99
+ # 1. Open the mode selector in VSCode
100
+ # 2. Select a bmad-{agent} mode (e.g. "bmad-dev")
101
+ # 3. The AI adopts that agent's persona and capabilities
102
+
103
+ qwen-code:
104
+ name: Qwen Code
105
+ rule-dir: .qwen/bmad-method/
106
+ format: single-file
107
+ command-suffix: .md
108
+ instructions: |
109
+ # To use BMad agents with Qwen Code:
110
+ # 1. The installer creates a .qwen/bmad-method/ directory in your project.
111
+ # 2. It concatenates all agent files into a single QWEN.md file.
112
+ # 3. Simply mention the agent in your prompt (e.g., "As *dev, ...").
113
+ # 4. The Qwen Code CLI will automatically have the context for that agent.
@@ -53,10 +53,14 @@ class IdeSetup extends BaseIdeSetup {
53
53
  return this.setupRoo(installDir, selectedAgent);
54
54
  case "cline":
55
55
  return this.setupCline(installDir, selectedAgent);
56
+ case "kilo":
57
+ return this.setupKilocode(installDir, selectedAgent);
56
58
  case "gemini":
57
59
  return this.setupGeminiCli(installDir, selectedAgent);
58
60
  case "github-copilot":
59
61
  return this.setupGitHubCopilot(installDir, selectedAgent, spinner, preConfiguredSettings);
62
+ case "qwen-code":
63
+ return this.setupQwenCode(installDir, selectedAgent);
60
64
  default:
61
65
  console.log(chalk.yellow(`\nIDE ${ide} not yet supported`));
62
66
  return false;
@@ -675,11 +679,17 @@ class IdeSetup extends BaseIdeSetup {
675
679
  ? roleDefinitionMatch[1].trim()
676
680
  : `You are a ${title} specializing in ${title.toLowerCase()} tasks and responsibilities.`;
677
681
 
682
+
683
+ // Add permissions based on agent type
684
+ const permissions = agentPermissions[agentId];
678
685
  // Build mode entry with proper formatting (matching exact indentation)
679
686
  // Avoid double "bmad-" prefix for agents that already have it
680
687
  const slug = agentId.startsWith('bmad-') ? agentId : `bmad-${agentId}`;
681
688
  newModesContent += ` - slug: ${slug}\n`;
682
689
  newModesContent += ` name: '${icon} ${title}'\n`;
690
+ if (permissions) {
691
+ newModesContent += ` description: '${permissions.description}'\n`;
692
+ }
683
693
  newModesContent += ` roleDefinition: ${roleDefinition}\n`;
684
694
  newModesContent += ` whenToUse: ${whenToUse}\n`;
685
695
  // Get relative path from installDir to agent file
@@ -688,8 +698,6 @@ class IdeSetup extends BaseIdeSetup {
688
698
  newModesContent += ` groups:\n`;
689
699
  newModesContent += ` - read\n`;
690
700
 
691
- // Add permissions based on agent type
692
- const permissions = agentPermissions[agentId];
693
701
  if (permissions) {
694
702
  newModesContent += ` - - edit\n`;
695
703
  newModesContent += ` - fileRegex: ${permissions.fileRegex}\n`;
@@ -722,7 +730,98 @@ class IdeSetup extends BaseIdeSetup {
722
730
 
723
731
  return true;
724
732
  }
733
+
734
+ async setupKilocode(installDir, selectedAgent) {
735
+ const filePath = path.join(installDir, ".kilocodemodes");
736
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
737
+
738
+ let existingModes = [], existingContent = "";
739
+ if (await fileManager.pathExists(filePath)) {
740
+ existingContent = await fileManager.readFile(filePath);
741
+ for (const match of existingContent.matchAll(/- slug: ([\w-]+)/g)) {
742
+ existingModes.push(match[1]);
743
+ }
744
+ console.log(chalk.yellow(`Found existing .kilocodemodes file with ${existingModes.length} modes`));
745
+ }
746
+
747
+ const config = await this.loadIdeAgentConfig();
748
+ const permissions = config['roo-permissions'] || {}; // reuse same roo permissions block (Kilo Code understands same mode schema)
749
+
750
+ let newContent = "";
751
+
752
+ for (const agentId of agents) {
753
+ const slug = agentId.startsWith('bmad-') ? agentId : `bmad-${agentId}`;
754
+ if (existingModes.includes(slug)) {
755
+ console.log(chalk.dim(`Skipping ${agentId} - already exists in .kilocodemodes`));
756
+ continue;
757
+ }
758
+
759
+ const agentPath = await this.findAgentPath(agentId, installDir);
760
+ if (!agentPath) {
761
+ console.log(chalk.red(`✗ Could not find agent file for ${agentId}`));
762
+ continue;
763
+ }
764
+
765
+ const agentContent = await fileManager.readFile(agentPath);
766
+ const yamlMatch = agentContent.match(/```ya?ml\r?\n([\s\S]*?)```/);
767
+ if (!yamlMatch) {
768
+ console.log(chalk.red(`✗ Could not extract YAML block for ${agentId}`));
769
+ continue;
770
+ }
771
+
772
+ const yaml = yamlMatch[1];
773
+
774
+ // Robust fallback for title and icon
775
+ const title = (yaml.match(/title:\s*(.+)/)?.[1]?.trim()) || await this.getAgentTitle(agentId, installDir);
776
+ const icon = (yaml.match(/icon:\s*(.+)/)?.[1]?.trim()) || '🤖';
777
+ const whenToUse = (yaml.match(/whenToUse:\s*"(.+)"/)?.[1]?.trim()) || `Use for ${title} tasks`;
778
+ const roleDefinition = (yaml.match(/roleDefinition:\s*"(.+)"/)?.[1]?.trim()) ||
779
+ `You are a ${title} specializing in ${title.toLowerCase()} tasks and responsibilities.`;
780
+
781
+ const relativePath = path.relative(installDir, agentPath).replace(/\\/g, '/');
782
+ const customInstructions = `CRITICAL Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode`;
783
+
784
+ // Add permissions from config if they exist
785
+ const agentPermission = permissions[agentId];
786
+
787
+ // Begin .kilocodemodes block
788
+ newContent += ` - slug: ${slug}\n`;
789
+ newContent += ` name: '${icon} ${title}'\n`;
790
+ if (agentPermission) {
791
+ newContent += ` description: '${agentPermission.description}'\n`;
792
+ }
793
+
794
+ newContent += ` roleDefinition: ${roleDefinition}\n`;
795
+ newContent += ` whenToUse: ${whenToUse}\n`;
796
+ newContent += ` customInstructions: ${customInstructions}\n`;
797
+ newContent += ` groups:\n`;
798
+ newContent += ` - read\n`;
725
799
 
800
+
801
+ if (agentPermission) {
802
+ newContent += ` - - edit\n`;
803
+ newContent += ` - fileRegex: ${agentPermission.fileRegex}\n`;
804
+ newContent += ` description: ${agentPermission.description}\n`;
805
+ } else {
806
+ // Fallback to generic edit
807
+ newContent += ` - edit\n`;
808
+ }
809
+
810
+ console.log(chalk.green(`✓ Added Kilo mode: ${slug} (${icon} ${title})`));
811
+ }
812
+
813
+ const finalContent = existingContent
814
+ ? existingContent.trim() + "\n" + newContent
815
+ : "customModes:\n" + newContent;
816
+
817
+ await fileManager.writeFile(filePath, finalContent);
818
+ console.log(chalk.green("✓ Created .kilocodemodes file in project root"));
819
+ console.log(chalk.green(`✓ KiloCode setup complete!`));
820
+ console.log(chalk.dim("Custom modes will be available when you open this project in KiloCode"));
821
+
822
+ return true;
823
+ }
824
+
726
825
  async setupCline(installDir, selectedAgent) {
727
826
  const clineRulesDir = path.join(installDir, ".clinerules");
728
827
  const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
@@ -880,6 +979,106 @@ class IdeSetup extends BaseIdeSetup {
880
979
  return true;
881
980
  }
882
981
 
982
+ async setupQwenCode(installDir, selectedAgent) {
983
+ const qwenDir = path.join(installDir, ".qwen");
984
+ const bmadMethodDir = path.join(qwenDir, "bmad-method");
985
+ await fileManager.ensureDirectory(bmadMethodDir);
986
+
987
+ // Update logic for existing settings.json
988
+ const settingsPath = path.join(qwenDir, "settings.json");
989
+ if (await fileManager.pathExists(settingsPath)) {
990
+ try {
991
+ const settingsContent = await fileManager.readFile(settingsPath);
992
+ const settings = JSON.parse(settingsContent);
993
+ let updated = false;
994
+
995
+ // Handle contextFileName property
996
+ if (settings.contextFileName && Array.isArray(settings.contextFileName)) {
997
+ const originalLength = settings.contextFileName.length;
998
+ settings.contextFileName = settings.contextFileName.filter(
999
+ (fileName) => !fileName.startsWith("agents/")
1000
+ );
1001
+ if (settings.contextFileName.length !== originalLength) {
1002
+ updated = true;
1003
+ }
1004
+ }
1005
+
1006
+ if (updated) {
1007
+ await fileManager.writeFile(
1008
+ settingsPath,
1009
+ JSON.stringify(settings, null, 2)
1010
+ );
1011
+ console.log(chalk.green("✓ Updated .qwen/settings.json - removed agent file references"));
1012
+ }
1013
+ } catch (error) {
1014
+ console.warn(
1015
+ chalk.yellow("Could not update .qwen/settings.json"),
1016
+ error
1017
+ );
1018
+ }
1019
+ }
1020
+
1021
+ // Remove old agents directory
1022
+ const agentsDir = path.join(qwenDir, "agents");
1023
+ if (await fileManager.pathExists(agentsDir)) {
1024
+ await fileManager.removeDirectory(agentsDir);
1025
+ console.log(chalk.green("✓ Removed old .qwen/agents directory"));
1026
+ }
1027
+
1028
+ // Get all available agents
1029
+ const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir);
1030
+ let concatenatedContent = "";
1031
+
1032
+ for (const agentId of agents) {
1033
+ // Find the source agent file
1034
+ const agentPath = await this.findAgentPath(agentId, installDir);
1035
+
1036
+ if (agentPath) {
1037
+ const agentContent = await fileManager.readFile(agentPath);
1038
+
1039
+ // Create properly formatted agent rule content (similar to gemini)
1040
+ let agentRuleContent = `# ${agentId.toUpperCase()} Agent Rule\n\n`;
1041
+ agentRuleContent += `This rule is triggered when the user types \`*${agentId}\` and activates the ${await this.getAgentTitle(
1042
+ agentId,
1043
+ installDir
1044
+ )} agent persona.\n\n`;
1045
+ agentRuleContent += "## Agent Activation\n\n";
1046
+ agentRuleContent +=
1047
+ "CRITICAL: Read the full YAML, start activation to alter your state of being, follow startup section instructions, stay in this being until told to exit this mode:\n\n";
1048
+ agentRuleContent += "```yaml\n";
1049
+ // Extract just the YAML content from the agent file
1050
+ const yamlContent = extractYamlFromAgent(agentContent);
1051
+ if (yamlContent) {
1052
+ agentRuleContent += yamlContent;
1053
+ }
1054
+ else {
1055
+ // If no YAML found, include the whole content minus the header
1056
+ agentRuleContent += agentContent.replace(/^#.*$/m, "").trim();
1057
+ }
1058
+ agentRuleContent += "\n```\n\n";
1059
+ agentRuleContent += "## File Reference\n\n";
1060
+ const relativePath = path.relative(installDir, agentPath).replace(/\\/g, '/');
1061
+ agentRuleContent += `The complete agent definition is available in [${relativePath}](${relativePath}).\n\n`;
1062
+ agentRuleContent += "## Usage\n\n";
1063
+ agentRuleContent += `When the user types \`*${agentId}\`, activate this ${await this.getAgentTitle(
1064
+ agentId,
1065
+ installDir
1066
+ )} persona and follow all instructions defined in the YAML configuration above.\n`;
1067
+
1068
+ // Add to concatenated content with separator
1069
+ concatenatedContent += agentRuleContent + "\n\n---\n\n";
1070
+ console.log(chalk.green(`✓ Added context for *${agentId}`));
1071
+ }
1072
+ }
1073
+
1074
+ // Write the concatenated content to QWEN.md
1075
+ const qwenMdPath = path.join(bmadMethodDir, "QWEN.md");
1076
+ await fileManager.writeFile(qwenMdPath, concatenatedContent);
1077
+ console.log(chalk.green(`\n✓ Created QWEN.md in ${bmadMethodDir}`));
1078
+
1079
+ return true;
1080
+ }
1081
+
883
1082
  async setupGitHubCopilot(installDir, selectedAgent, spinner = null, preConfiguredSettings = null) {
884
1083
  // Configure VS Code workspace settings first to avoid UI conflicts with loading spinners
885
1084
  await this.configureVsCodeSettings(installDir, spinner, preConfiguredSettings);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bmad-method",
3
- "version": "4.33.1",
3
+ "version": "4.35.0",
4
4
  "description": "BMad Method installer - AI-powered Agile development framework",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {