From 31e44b110e355ce447d4b9f85005bfd0bb256b4e Mon Sep 17 00:00:00 2001 From: Benjamin Wiese <20987660+bnwe@users.noreply.github.com> Date: Thu, 14 Aug 2025 20:39:28 +0200 Subject: [PATCH 1/4] Remove bmad-core/bmad-core including empty file (#431) Co-authored-by: Ben Wiese --- bmad-core/bmad-core/user-guide.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 bmad-core/bmad-core/user-guide.md diff --git a/bmad-core/bmad-core/user-guide.md b/bmad-core/bmad-core/user-guide.md deleted file mode 100644 index e69de29b..00000000 From 3efcfd54d47f4c3cdc6527a438f86fc615a8700c Mon Sep 17 00:00:00 2001 From: Yongjip Kim Date: Fri, 15 Aug 2025 03:40:11 +0900 Subject: [PATCH 2/4] fix(docs): fix broken link in GUIDING-PRINCIPLES.md (#428) Co-authored-by: Brian --- docs/GUIDING-PRINCIPLES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/GUIDING-PRINCIPLES.md b/docs/GUIDING-PRINCIPLES.md index caee2f0c..98bea2ec 100644 --- a/docs/GUIDING-PRINCIPLES.md +++ b/docs/GUIDING-PRINCIPLES.md @@ -65,7 +65,7 @@ See [Expansion Packs Guide](../docs/expansion-packs.md) for detailed examples an ### Template Rules -Templates follow the [BMad Document Template](common/utils/bmad-doc-template.md) specification using YAML format: +Templates follow the [BMad Document Template](../common/utils/bmad-doc-template.md) specification using YAML format: 1. **Structure**: Templates are defined in YAML with clear metadata, workflow configuration, and section hierarchy 2. **Separation of Concerns**: Instructions for LLMs are in `instruction` fields, separate from content From d563266b9738b5d3c5ec1e31ab683aad517e2604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Kl=C3=BCmpers?= <102544568+stefankluempers@users.noreply.github.com> Date: Fri, 15 Aug 2025 05:23:44 +0200 Subject: [PATCH 3/4] feat: install Cursor rules to subdirectory (#438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: install Cursor rules to subdirectory Implement feature request #376 to avoid filename collisions and confusion between repo-specific and BMAD-specific rules. Changes: - Move Cursor rules from .cursor/rules/ to .cursor/rules/bmad/ - Update installer configuration to use new subdirectory structure - Update upgrader to reflect new rule directory path This keeps BMAD Method files separate from existing project rules, reducing chance of conflicts and improving organization. Fixes #376 * chore: correct formatting in cursor rules directory path --------- Co-authored-by: Stefan Klümpers --- tools/installer/config/install.config.yaml | 2 +- tools/installer/lib/ide-setup.js | 2 +- tools/upgraders/v3-to-v4-upgrader.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/installer/config/install.config.yaml b/tools/installer/config/install.config.yaml index 96e86aea..1da2e005 100644 --- a/tools/installer/config/install.config.yaml +++ b/tools/installer/config/install.config.yaml @@ -11,7 +11,7 @@ installation-options: ide-configurations: cursor: name: Cursor - rule-dir: .cursor/rules/ + rule-dir: .cursor/rules/bmad/ format: multi-file command-suffix: .mdc instructions: | diff --git a/tools/installer/lib/ide-setup.js b/tools/installer/lib/ide-setup.js index 4768a931..4dbc8e57 100644 --- a/tools/installer/lib/ide-setup.js +++ b/tools/installer/lib/ide-setup.js @@ -68,7 +68,7 @@ class IdeSetup extends BaseIdeSetup { } async setupCursor(installDir, selectedAgent) { - const cursorRulesDir = path.join(installDir, ".cursor", "rules"); + const cursorRulesDir = path.join(installDir, ".cursor", "rules", "bmad"); const agents = selectedAgent ? [selectedAgent] : await this.getAllAgentIds(installDir); await fileManager.ensureDirectory(cursorRulesDir); diff --git a/tools/upgraders/v3-to-v4-upgrader.js b/tools/upgraders/v3-to-v4-upgrader.js index cc535706..2a14b244 100644 --- a/tools/upgraders/v3-to-v4-upgrader.js +++ b/tools/upgraders/v3-to-v4-upgrader.js @@ -557,7 +557,7 @@ class V3ToV4Upgrader { try { const ideMessages = { - cursor: "Rules created in .cursor/rules/", + cursor: "Rules created in .cursor/rules/bmad/", "claude-code": "Commands created in .claude/commands/BMad/", windsurf: "Rules created in .windsurf/rules/", trae: "Rules created in.trae/rules/", From 9868437f10bb18503ae5421b83b5ba96e45dfaa3 Mon Sep 17 00:00:00 2001 From: Aaron Date: Thu, 14 Aug 2025 23:24:37 -0400 Subject: [PATCH 4/4] Add update-check command (#423) * Add update-check command * Adding additional information to update-check command and aligning with cli theme * Correct update-check message to exclude global --- tools/installer/bin/bmad.js | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tools/installer/bin/bmad.js b/tools/installer/bin/bmad.js index ff623239..51dff138 100755 --- a/tools/installer/bin/bmad.js +++ b/tools/installer/bin/bmad.js @@ -6,13 +6,17 @@ const fs = require('fs').promises; const yaml = require('js-yaml'); const chalk = require('chalk'); const inquirer = require('inquirer'); +const semver = require('semver'); +const https = require('https'); // Handle both execution contexts (from root via npx or from installer directory) let version; let installer; +let packageName; try { // Try installer context first (when run from tools/installer/) version = require('../package.json').version; + packageName = require('../package.json').name; installer = require('../lib/installer'); } catch (e) { // Fall back to root context (when run via npx from GitHub) @@ -86,6 +90,60 @@ program } }); +// Command to check if updates are available +program + .command('update-check') + .description('Check for BMad Update') + .action(async () => { + console.log('Checking for updates...'); + + // Make HTTP request to npm registry for latest version info + const req = https.get(`https://registry.npmjs.org/${packageName}/latest`, res => { + // Check for HTTP errors (non-200 status codes) + if (res.statusCode !== 200) { + console.error(chalk.red(`Update check failed: Received status code ${res.statusCode}`)); + return; + } + + // Accumulate response data chunks + let data = ''; + res.on('data', chunk => data += chunk); + + // Process complete response + res.on('end', () => { + try { + // Parse npm registry response and extract version + const latest = JSON.parse(data).version; + + // Compare versions using semver + if (semver.gt(latest, version)) { + console.log(chalk.bold.blue(`⚠️ ${packageName} update available: ${version} → ${latest}`)); + console.log(chalk.bold.blue('\nInstall latest by running:')); + console.log(chalk.bold.magenta(` npm install ${packageName}@latest`)); + console.log(chalk.dim(' or')); + console.log(chalk.bold.magenta(` npx ${packageName}@latest`)); + } else { + console.log(chalk.bold.blue(`✨ ${packageName} is up to date`)); + } + } catch (error) { + // Handle JSON parsing errors + console.error(chalk.red('Failed to parse npm registry data:'), error.message); + } + }); + }); + + // Handle network/connection errors + req.on('error', error => { + console.error(chalk.red('Update check failed:'), error.message); + }); + + // Set 30 second timeout to prevent hanging + req.setTimeout(30000, () => { + req.destroy(); + console.error(chalk.red('Update check timed out')); + }); + }); + program .command('list:expansions') .description('List available expansion packs')