Skip to content

feat(installer): auto-inject BMAD badge into README#2361

Closed
terryso wants to merge 2 commits intobmad-code-org:mainfrom
terryso:feat/badge-installer-integration
Closed

feat(installer): auto-inject BMAD badge into README#2361
terryso wants to merge 2 commits intobmad-code-org:mainfrom
terryso:feat/badge-installer-integration

Conversation

@terryso
Copy link
Copy Markdown

@terryso terryso commented May 1, 2026

Summary

Closes #2174

Lightweight installer integration that automatically adds a dynamic BMAD version badge to the project README during bmad install. The badge is powered by the existing bmad-badge.vercel.app service.

What it does

  • During bmad install / bmad update, the installer detects the project's git remote (owner/repo) and injects a [![BMAD](...) ](...) badge into the README — placed after the first heading, alongside any existing badges.
  • On bmad uninstall, the badge is automatically removed from the README.
  • Fully idempotent — re-running install/update skips if the badge is already present.
  • --no-badge flag available to opt out.

Files changed

File Change
tools/installer/core/badge.js New — resolves git remote, finds README, injects/removes badge markdown
tools/installer/core/installer.js Calls _injectBadgeIfNeeded() after install, before summary
tools/installer/commands/install.js Adds --no-badge CLI option
tools/installer/commands/uninstall.js Removes badge from README during uninstall

Design notes

  • No new skills — per @bmadcode's feedback in feat: Add Badge for Projects built with BMAD #2174, this avoids adding to IDE skill overhead.
  • Badge service — currently uses bmad-badge.vercel.app. If the BMAD team prefers to fork and deploy under an official domain, only the BADGE_URL constant in badge.js needs to change.
  • Minimal footprint — ~100 lines of new code, no changes to the core install flow beyond one additional step.

Test plan

  • Run bmad install on a project with a git remote and README → badge appears in README
  • Run bmad install again → badge not duplicated
  • Run bmad install --no-badge → no badge added
  • Run bmad uninstall → badge removed from README
  • Run bmad install on a project without git remote → graceful skip with warning

🤖 Generated with Claude Code
via Happy

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

This pull request adds automated BMAD badge management to the installer. The install command gains a --no-badge flag to control badge insertion, while a new badge utility module handles git remote resolution, README file detection, badge generation, and badge injection/removal. The installer and uninstall flows integrate these utilities to automatically update project READMEs with the BMAD badge during setup and remove it during teardown.

Changes

Cohort / File(s) Summary
Command-line Interface
tools/installer/commands/install.js
Adds --no-badge flag support; propagates flag state to config.noBadge to control badge insertion during installation.
Badge Utilities
tools/installer/core/badge.js
New module providing six exported functions: git remote resolution, README file discovery, badge detection via regex, badge markdown generation, badge injection after first heading, and badge removal from content.
Installer Integration
tools/installer/core/installer.js
Integrates badge injection into finalization phase; resolves git remote and README, checks existing badge state, and conditionally injects badge markdown when config.noBadge is enabled.
Uninstall Module
tools/installer/commands/uninstall.js
Extends uninstall flow to search for and remove BMAD badge from README during module/data removal phase.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Install as install.js
    participant Installer
    participant Badge as badge.js
    participant Git as Git Remote
    participant README as README File

    User->>Install: npm run install --no-badge
    Install->>Installer: initialize(config with noBadge: true)
    Note over Installer: ... installation proceeds ...
    Installer->>Installer: finalize()
    alt config.noBadge enabled
        Installer->>Badge: resolveGitRemote(projectDir)
        Badge->>Git: git config --get-regexp origin
        Git-->>Badge: git remote URL
        Badge-->>Installer: {owner, repo}
        Installer->>Badge: findReadme(projectDir)
        Badge-->>Installer: README file path
        Installer->>README: read content
        README-->>Installer: current content
        Installer->>Badge: hasBadge(content)
        Badge-->>Installer: boolean
        alt Badge not already present
            Installer->>Badge: injectBadge(content, owner, repo)
            Badge-->>Installer: updated content with badge
            Installer->>README: write updated content
            README-->>Installer: success
        else Badge already present
            Installer-->>Installer: record "already present"
        end
    else config.noBadge disabled or missing
        Installer-->>Installer: skip badge injection
    end
    Installer-->>User: installation complete
Loading
sequenceDiagram
    actor User
    participant Uninstall as uninstall.js
    participant Installer
    participant Badge as badge.js
    participant README as README File

    User->>Uninstall: npm run uninstall
    Uninstall->>Installer: uninstall flow
    Note over Installer: ... module removal phase ...
    Installer->>Uninstall: remove modules & data
    Uninstall->>Badge: findReadme(projectDir)
    Badge-->>Uninstall: README file path
    alt README exists
        Uninstall->>README: read content
        README-->>Uninstall: current content
        Uninstall->>Badge: hasBadge(content)
        Badge-->>Uninstall: boolean
        alt Badge found
            Uninstall->>Badge: removeBadge(content)
            Badge-->>Uninstall: content without badge
            Uninstall->>README: write updated content
            README-->>Uninstall: success
        else Badge not found
            Uninstall-->>Uninstall: skip removal
        end
    else README not found
        Uninstall-->>Uninstall: skip removal
    end
    Uninstall-->>User: uninstall complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(installer): auto-inject BMAD badge into README' clearly and concisely summarizes the main change: adding automatic BMAD badge injection to the installer workflow.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering the feature summary, implementation details, design notes, and test plan.
Linked Issues check ✅ Passed The implementation fully satisfies requirements from issue #2174: uses the specified badge format from bmad-badge.vercel.app, supports both installation and removal, automatically resolves owner/repo from git remote, and includes opt-out via --no-badge flag.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issue requirements: badge.js handles badge operations, installer.js integrates badge injection post-install, install.js adds the --no-badge flag, and uninstall.js removes the badge on uninstall.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/installer/commands/install.js`:
- Line 99: The quick-update flow rebuilds an installConfig without carrying over
config.noBadge so badge injection still runs; update Installer.quickUpdate()
(the place that constructs installConfig) to copy/preserve config.noBadge (or
the source config field) into the new installConfig so downstream badge
injection honors the --no-badge flag; locate the installConfig construction in
quickUpdate and add the noBadge property from the incoming config object.

In `@tools/installer/commands/uninstall.js`:
- Around line 143-151: The README badge cleanup block (using badge.findReadme,
badge.hasBadge, badge.removeBadge and fs.readFile/fs.writeFile) should be
best-effort: wrap the read/write sequence in a try/catch so any fs errors are
caught and do not propagate to fail the uninstall; inside the catch log or warn
the error (e.g., via processLogger or console.warn) and continue without
rethrowing so the overall uninstall exit code remains based on the primary _bmad
removal result.

In `@tools/installer/core/badge.js`:
- Around line 6-7: BADGE_PATTERN is hardcoded to bmad-badge.vercel.app, which
breaks hasBadge() and removeBadge() when BADGE_URL is changed; update the code
to build the badge-matching RegExp from the existing BADGE_URL constant (escape
any special regex chars) instead of the hardcoded host, then use that
constructed RegExp in BADGE_PATTERN (or replace BADGE_PATTERN with a
function/getter) so hasBadge() and removeBadge() always derive their matching
logic from BADGE_URL.
- Around line 18-20: The regex in the github remote parsing (the raw.match call
that assigns httpsMatch) uses ([^/.]+) for the repo capture which strips dots;
update that regex to allow dots (e.g., use ([^/]+) for the repo group) and
ensure any trailing .git is stripped later or by matching (so
functions/variables httpsMatch and the return { owner: ..., repo: ... } will
receive the full repo name including dots).

In `@tools/installer/core/installer.js`:
- Around line 106-109: Wrap the call to
this._injectBadgeIfNeeded(paths.projectRoot, addResult) so any thrown IO errors
are caught and handled non-fatally: inside the install flow where config.noBadge
is checked, add a try/catch around the _injectBadgeIfNeeded invocation, log a
warning (including the caught error and context like paths.projectRoot and
addResult) and continue without rethrowing so the installer does not abort on
README IO failures. Ensure you still skip the call when config.noBadge is true.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5ad7d03e-2829-4dbb-b88e-28c5d9640416

📥 Commits

Reviewing files that changed from the base of the PR and between 9debc16 and 707de90.

📒 Files selected for processing (4)
  • tools/installer/commands/install.js
  • tools/installer/commands/uninstall.js
  • tools/installer/core/badge.js
  • tools/installer/core/installer.js

Comment thread tools/installer/commands/install.js Outdated
Comment thread tools/installer/commands/uninstall.js Outdated
Comment thread tools/installer/core/badge.js Outdated
Comment thread tools/installer/core/badge.js Outdated
Comment thread tools/installer/core/installer.js
- Add badge.js module for git remote resolution, README detection, and badge injection
- Integrate badge prompt into install flow with --no-badge opt-out
- Support badge update when owner/repo changes on re-install
- Auto-create README.md with badge if missing
- Pass badge config through Config.build() for both install and quick-update paths

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@terryso terryso force-pushed the feat/badge-installer-integration branch from a955c86 to 4a4a7c9 Compare May 1, 2026 14:11
@alexeyv
Copy link
Copy Markdown
Collaborator

alexeyv commented May 4, 2026

This would irritate thousands of people. Thanks for the submission, but no, we are not doing this.

@alexeyv alexeyv closed this May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Add Badge for Projects built with BMAD

2 participants