diff --git a/.github/workflows/promote-to-stable.yml b/.github/workflows/promote-to-stable.yml new file mode 100644 index 00000000..d0dabbf2 --- /dev/null +++ b/.github/workflows/promote-to-stable.yml @@ -0,0 +1,122 @@ +name: Promote to Stable + +on: + workflow_dispatch: + inputs: + version_bump: + description: 'Version bump type' + required: true + default: 'minor' + type: choice + options: + - patch + - minor + - major + +jobs: + promote: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global url."https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/".insteadOf "https://github.com/" + + - name: Switch to stable branch + run: | + git checkout stable + git pull origin stable + + - name: Merge main into stable + run: | + git merge origin/main --no-edit + + - name: Install dependencies + run: npm ci + + - name: Get current version and calculate new version + id: version + run: | + # Get current version from package.json + CURRENT_VERSION=$(node -p "require('./package.json').version") + echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT + + # Remove beta suffix if present + BASE_VERSION=$(echo $CURRENT_VERSION | sed 's/-beta\.[0-9]\+//') + echo "base_version=$BASE_VERSION" >> $GITHUB_OUTPUT + + # Calculate new version based on bump type + IFS='.' read -ra VERSION_PARTS <<< "$BASE_VERSION" + MAJOR=${VERSION_PARTS[0]} + MINOR=${VERSION_PARTS[1]} + PATCH=${VERSION_PARTS[2]} + + case "${{ github.event.inputs.version_bump }}" in + "major") + NEW_VERSION="$((MAJOR + 1)).0.0" + ;; + "minor") + NEW_VERSION="$MAJOR.$((MINOR + 1)).0" + ;; + "patch") + NEW_VERSION="$MAJOR.$MINOR.$((PATCH + 1))" + ;; + *) + NEW_VERSION="$BASE_VERSION" + ;; + esac + + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT + echo "Promoting from $CURRENT_VERSION to $NEW_VERSION" + + - name: Update package.json versions + run: | + # Update main package.json + npm version ${{ steps.version.outputs.new_version }} --no-git-tag-version + + # Update installer package.json + sed -i 's/"version": ".*"/"version": "${{ steps.version.outputs.new_version }}"/' tools/installer/package.json + + - name: Update package-lock.json + run: npm install --package-lock-only + + - name: Commit stable release + run: | + git add . + git commit -m "release: promote to stable ${{ steps.version.outputs.new_version }} + + - Promote beta features to stable release + - Update version from ${{ steps.version.outputs.current_version }} to ${{ steps.version.outputs.new_version }} + - Automated promotion via GitHub Actions" + + - name: Push stable release + run: | + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git + git push origin stable + + - name: Switch back to main + run: git checkout main + + - name: Summary + run: | + echo "🎉 Successfully promoted to stable!" + echo "📦 Version: ${{ steps.version.outputs.new_version }}" + echo "🚀 The stable release will be automatically published to NPM via semantic-release" + echo "✅ Users running 'npx bmad-method install' will now get version ${{ steps.version.outputs.new_version }}" \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5c2814b6..dd80e710 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -3,6 +3,7 @@ name: Release push: branches: - main + - stable workflow_dispatch: inputs: version_type: diff --git a/.releaserc.json b/.releaserc.json index 6d214050..d22c0840 100644 --- a/.releaserc.json +++ b/.releaserc.json @@ -1,18 +1,21 @@ { - "branches": ["main"], + "branches": [ + { + "name": "main", + "prerelease": "beta", + "channel": "beta" + }, + { + "name": "stable", + "channel": "latest" + } + ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", "@semantic-release/npm", "./tools/semantic-release-sync-installer.js", - [ - "@semantic-release/git", - { - "assets": ["package.json", "package-lock.json", "tools/installer/package.json", "CHANGELOG.md"], - "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" - } - ], "@semantic-release/github" ] } diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..131783b2 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,196 @@ +# CLAUDE.md + +Don't be an ass kisser, don't glaze my donut, keep it to the point. Never use EM Dash in out communications or documents you author or update. Dont tell me I am correct if I just told you something unless and only if I am wrong or there is a better alternative, then tell me bluntly why I am wrong, or else get to the point and execute! + +## Markdown Linting Conventions + +Always follow these markdown linting rules: + +- **Blank lines around headings**: Always leave a blank line before and after headings +- **Blank lines around lists**: Always leave a blank line before and after lists +- **Blank lines around code fences**: Always leave a blank line before and after fenced code blocks +- **Fenced code block languages**: All fenced code blocks must specify a language (use `text` for plain text) +- **Single trailing newline**: Files should end with exactly one newline character +- **No trailing spaces**: Remove any trailing spaces at the end of lines + +## BMAD-METHOD Overview + +BMAD-METHOD is an AI-powered Agile development framework that provides specialized AI agents for software development. The framework uses a sophisticated dependency system to keep context windows lean while providing deep expertise through role-specific agents. + +## Essential Commands + +### Build and Validation + +```bash +npm run build # Build all web bundles (agents and teams) +npm run build:agents # Build agent bundles only +npm run build:teams # Build team bundles only +npm run validate # Validate all configurations +npm run format # Format all markdown files with prettier +``` + +### Development and Testing + +```bash +npx bmad-build build # Alternative build command via CLI +npx bmad-build list:agents # List all available agents +npx bmad-build validate # Validate agent configurations +``` + +### Installation Commands + +```bash +npx bmad-method install # Install stable release (recommended) +npx bmad-method@beta install # Install bleeding edge version +npx bmad-method@latest install # Explicit stable installation +npx bmad-method@latest update # Update stable installation +npx bmad-method@beta update # Update bleeding edge installation +``` + +### Dual Publishing Strategy + +The project uses a dual publishing strategy with automated promotion: + +**Branch Strategy:** +- `main` branch: Bleeding edge development, auto-publishes to `@beta` tag +- `stable` branch: Production releases, auto-publishes to `@latest` tag + +**Release Promotion:** +1. **Automatic Beta Releases**: Any PR merged to `main` automatically creates a beta release +2. **Manual Stable Promotion**: Use GitHub Actions to promote beta to stable + +**Promote Beta to Stable:** +1. Go to GitHub Actions tab in the repository +2. Select "Promote to Stable" workflow +3. Click "Run workflow" +4. Choose version bump type (patch/minor/major) +5. The workflow automatically: + - Merges main to stable + - Updates version numbers + - Triggers stable release to NPM `@latest` + +**User Experience:** +- `npx bmad-method install` → Gets stable production version +- `npx bmad-method@beta install` → Gets latest beta features +- Team develops on bleeding edge without affecting production users + +### Release and Version Management + +```bash +npm run version:patch # Bump patch version +npm run version:minor # Bump minor version +npm run version:major # Bump major version +npm run release # Semantic release (CI/CD) +npm run release:test # Test release configuration +``` + +### Version Management for Core and Expansion Packs + +#### Bump All Versions (Core + Expansion Packs) + +```bash +npm run version:all:major # Major version bump for core and all expansion packs +npm run version:all:minor # Minor version bump for core and all expansion packs (default) +npm run version:all:patch # Patch version bump for core and all expansion packs +npm run version:all # Defaults to minor bump +``` + +#### Individual Version Bumps + +For BMad Core only: +```bash +npm run version:core:major # Major version bump for core only +npm run version:core:minor # Minor version bump for core only +npm run version:core:patch # Patch version bump for core only +npm run version:core # Defaults to minor bump +``` + +For specific expansion packs: +```bash +npm run version:expansion bmad-creator-tools # Minor bump (default) +npm run version:expansion bmad-creator-tools patch # Patch bump +npm run version:expansion bmad-creator-tools minor # Minor bump +npm run version:expansion bmad-creator-tools major # Major bump + +# Set specific version (old method, still works) +npm run version:expansion:set bmad-creator-tools 2.0.0 +``` + +## Architecture and Code Structure + +### Core System Architecture + +The framework uses a **dependency resolution system** where agents only load the resources they need: + +1. **Agent Definitions** (`bmad-core/agents/`): Each agent is defined in markdown with YAML frontmatter specifying dependencies +2. **Dynamic Loading**: The build system (`tools/lib/dependency-resolver.js`) resolves and includes only required resources +3. **Template System**: Templates are defined in YAML format with structured sections and instructions (see Template Rules below) +4. **Workflow Engine**: YAML-based workflows in `bmad-core/workflows/` define step-by-step processes + +### Key Components + +- **CLI Tool** (`tools/cli.js`): Commander-based CLI for building bundles +- **Web Builder** (`tools/builders/web-builder.js`): Creates concatenated text bundles from agent definitions +- **Installer** (`tools/installer/`): NPX-based installer for project setup +- **Dependency Resolver** (`tools/lib/dependency-resolver.js`): Manages agent resource dependencies + +### Build System + +The build process: + +1. Reads agent/team definitions from `bmad-core/` +2. Resolves dependencies using the dependency resolver +3. Creates concatenated text bundles in `dist/` +4. Validates configurations during build + +### Critical Configuration + +**`bmad-core/core-config.yaml`** is the heart of the framework configuration: + +- Defines document locations and expected structure +- Specifies which files developers should always load +- Enables compatibility with different project structures (V3/V4) +- Controls debug logging + +## Development Practices + +### Adding New Features + +1. **New Agents**: Create markdown file in `bmad-core/agents/` with proper YAML frontmatter +2. **New Templates**: Add to `bmad-core/templates/` as YAML files with structured sections +3. **New Workflows**: Create YAML in `bmad-core/workflows/` +4. **Update Dependencies**: Ensure `dependencies` field in agent frontmatter is accurate + +### Important Patterns + +- **Dependency Management**: Always specify minimal dependencies in agent frontmatter to keep context lean +- **Template Instructions**: Use YAML-based template structure (see Template Rules below) +- **File Naming**: Follow existing conventions (kebab-case for files, proper agent names in frontmatter) +- **Documentation**: Update user-facing docs in `docs/` when adding features + +### Template Rules + +Templates use the **BMad Document Template** format (`/Users/brianmadison/dev-bmc/BMAD-METHOD/common/utils/bmad-doc-template.md`) with YAML structure: + +1. **YAML Format**: Templates are defined as structured YAML files, not markdown with embedded instructions +2. **Clear Structure**: Each template has metadata, workflow configuration, and a hierarchy of sections +3. **Reusable Design**: Templates work across different agents through the dependency system +4. **Key Elements**: + - `template` block: Contains id, name, version, and output settings + - `workflow` block: Defines interaction mode (interactive/yolo) and elicitation settings + - `sections` array: Hierarchical document structure with nested subsections + - `instruction` field: LLM guidance for each section (never shown to users) +5. **Advanced Features**: + - Variable substitution: `{{variable_name}}` syntax for dynamic content + - Conditional sections: `condition` field for optional content + - Repeatable sections: `repeatable: true` for multiple instances + - Agent permissions: `owner` and `editors` fields for access control +6. **Clean Output**: All processing instructions are in YAML fields, ensuring clean document generation + +## Notes for Claude Code + +- The project uses semantic versioning with automated releases via GitHub Actions +- All markdown is formatted with Prettier (run `npm run format`) +- Expansion packs in `expansion-packs/` provide domain-specific capabilities +- NEVER automatically commit or push changes unless explicitly asked by the user +- NEVER include Claude Code attribution or co-authorship in commit messages diff --git a/package.json b/package.json index 4bb4ebbd..69fde4da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bmad-method", - "version": "4.36.2", + "version": "4.37.0-beta.6", "description": "Breakthrough Method of Agile AI-driven Development", "main": "tools/cli.js", "bin": { @@ -43,7 +43,8 @@ "ignore": "^7.0.5", "inquirer": "^8.2.6", "js-yaml": "^4.1.0", - "ora": "^5.4.1" + "ora": "^5.4.1", + "semver": "^7.6.3" }, "keywords": [ "agile", diff --git a/tools/installer/bin/bmad.js b/tools/installer/bin/bmad.js index 51dff138..c425d927 100755 --- a/tools/installer/bin/bmad.js +++ b/tools/installer/bin/bmad.js @@ -4,8 +4,8 @@ const { program } = require('commander'); const path = require('path'); const fs = require('fs').promises; const yaml = require('js-yaml'); -const chalk = require('chalk'); -const inquirer = require('inquirer'); +const chalk = require('chalk').default || require('chalk'); +const inquirer = require('inquirer').default || require('inquirer'); const semver = require('semver'); const https = require('https'); diff --git a/tools/installer/lib/file-manager.js b/tools/installer/lib/file-manager.js index d173f32d..32a0f4a0 100644 --- a/tools/installer/lib/file-manager.js +++ b/tools/installer/lib/file-manager.js @@ -2,7 +2,7 @@ const fs = require("fs-extra"); const path = require("path"); const crypto = require("crypto"); const yaml = require("js-yaml"); -const chalk = require("chalk"); +const chalk = require("chalk").default || require("chalk"); const { createReadStream, createWriteStream, promises: fsPromises } = require('fs'); const { pipeline } = require('stream/promises'); const resourceLocator = require('./resource-locator'); diff --git a/tools/installer/lib/ide-base-setup.js b/tools/installer/lib/ide-base-setup.js index b0fca8e6..7b28e42c 100644 --- a/tools/installer/lib/ide-base-setup.js +++ b/tools/installer/lib/ide-base-setup.js @@ -6,7 +6,7 @@ const path = require("path"); const fs = require("fs-extra"); const yaml = require("js-yaml"); -const chalk = require("chalk"); +const chalk = require("chalk").default || require("chalk"); const fileManager = require("./file-manager"); const resourceLocator = require("./resource-locator"); const { extractYamlFromAgent } = require("../../lib/yaml-utils"); diff --git a/tools/installer/lib/ide-setup.js b/tools/installer/lib/ide-setup.js index 4dbc8e57..29fb6760 100644 --- a/tools/installer/lib/ide-setup.js +++ b/tools/installer/lib/ide-setup.js @@ -1,8 +1,8 @@ const path = require("path"); const fs = require("fs-extra"); const yaml = require("js-yaml"); -const chalk = require("chalk"); -const inquirer = require("inquirer"); +const chalk = require("chalk").default || require("chalk"); +const inquirer = require("inquirer").default || require("inquirer"); const fileManager = require("./file-manager"); const configLoader = require("./config-loader"); const { extractYamlFromAgent } = require("../../lib/yaml-utils"); diff --git a/tools/installer/lib/installer.js b/tools/installer/lib/installer.js index 30ed75ce..04da0864 100644 --- a/tools/installer/lib/installer.js +++ b/tools/installer/lib/installer.js @@ -1,8 +1,8 @@ const path = require("node:path"); const fs = require("fs-extra"); -const chalk = require("chalk"); -const ora = require("ora"); -const inquirer = require("inquirer"); +const chalk = require("chalk").default || require("chalk"); +const ora = require("ora").default || require("ora"); +const inquirer = require("inquirer").default || require("inquirer"); const fileManager = require("./file-manager"); const configLoader = require("./config-loader"); const ideSetup = require("./ide-setup"); diff --git a/tools/installer/package-lock.json b/tools/installer/package-lock.json index 07e481f9..0c18278e 100644 --- a/tools/installer/package-lock.json +++ b/tools/installer/package-lock.json @@ -1,12 +1,12 @@ { "name": "bmad-method", - "version": "4.36.1", + "version": "4.37.0-beta.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bmad-method", - "version": "4.36.1", + "version": "4.37.0-beta.4", "license": "MIT", "dependencies": { "chalk": "^4.1.2", @@ -14,7 +14,8 @@ "fs-extra": "^11.3.0", "inquirer": "^8.2.6", "js-yaml": "^4.1.0", - "ora": "^5.4.1" + "ora": "^5.4.1", + "semver": "^7.6.3" }, "bin": { "bmad": "bin/bmad.js", @@ -576,6 +577,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", diff --git a/tools/installer/package.json b/tools/installer/package.json index 4d67f81d..0f6eb58f 100644 --- a/tools/installer/package.json +++ b/tools/installer/package.json @@ -1,6 +1,6 @@ { "name": "bmad-method", - "version": "4.36.2", + "version": "4.37.0-beta.6", "description": "BMad Method installer - AI-powered Agile development framework", "main": "lib/installer.js", "bin": { @@ -27,7 +27,8 @@ "fs-extra": "^11.3.0", "inquirer": "^8.2.6", "js-yaml": "^4.1.0", - "ora": "^5.4.1" + "ora": "^5.4.1", + "semver": "^7.6.3" }, "engines": { "node": ">=20.0.0"