Replace GitHub-only custom module installation with support for any Git
host (GitHub, GitLab, Bitbucket, self-hosted) and local file paths.
- Add parseSource() universal input parser (local paths, SSH, HTTPS with
deep path/subdir extraction for GitHub, GitLab, Gitea)
- Add resolveSource() coordinator: parse -> clone if URL -> detect
discovery vs direct mode (marketplace.json present or not)
- Clone-first approach eliminates host-specific raw URL fetching
- 3-level cache structure (host/owner/repo) with .bmad-source.json
metadata for URL reconstruction
- Local paths install directly without caching; localPath persisted in
manifest for quick-update source lookup
- Direct mode scans target directory for SKILL.md when no marketplace.json
- Fix version display bug where walk-up found parent repo marketplace.json
and reported wrong version for custom modules
ManifestGenerator rebuilds the entire manifest via getModuleVersionInfo
for every module. For custom modules, this returned null for version and
repoUrl because it only checked _readMarketplaceVersion (which searches
for marketplace.json on disk) and hardcoded repoUrl to null. Now checks
the resolution cache first to get the correct version and repo URL.
* feat(installer): add community module browser and custom URL support
Three-tier module selection: official, community (category drill-down
with featured/search), and custom GitHub URL.
- Add RegistryClient shared fetch utility
- Add CommunityModuleManager with SHA-pinned cloning (refuses install
if approved SHA cannot be reached; uses HEAD when no SHA set)
- Add CustomModuleManager for arbitrary GitHub repo installation
- Extend findModuleSource chain with community and custom fallthrough
- Extend manifest to detect community and custom source types
- Add Config.customModulesMeta for custom module metadata
* fix: resolve review findings for community/custom module support
- Remove redundant CommunityModuleManager instantiation in UI display
- Remove dead customModulesMeta field from Config (never populated)
- Add 35 unit tests for CustomModuleManager and CommunityModuleManager
pure functions: URL validation, normalization, search, featured, categories
* fix: preserve installed community/custom modules in modify flow
When a user does "Modify Installation" and declines to browse community
modules, previously installed community/custom modules are now auto-kept.
If the user does browse, their selections are trusted (they can deselect).
Also fix stale docs: class doc for SHA pinning, JSDoc return type.
* fix: include community and custom modules in quick update
Quick update now checks community registry and custom cache so installed
community/custom modules are updated instead of skipped.
* fix: use defaults for new config fields during quick update
When quick update encounters new config fields (e.g., from a newly
supported community module), use schema defaults silently instead of
prompting the user. Quick update should be non-interactive.
* test: add unit tests for SHA pinning, category filtering, and URL edge cases
Cover SHA normalization (set vs null/trusted), listByCategory,
getModuleByCode, and URL validation edge cases (HTTP, trailing slash,
SSH without .git). Total: 243 tests.
* refactor(installer): remove custom content installation feature
Remove the entire local filesystem custom content feature from the
installer to make way for marketplace-based plugin installation.
Deleted: custom-handler.js, custom-module-cache.js, custom-modules.js
Removed: --custom-content CLI flag, interactive custom content prompts,
custom module caching, manifest tracking, missing-source resolution,
and related test suites. Updated docs across all translations.
* fix: address review findings from Augment
Fix admonition syntax (remove accidental space in :::note) across 4
translated docs files, and update stale JSDoc on listAvailable().
* feat(installer): overhaul branding, versioning, and skill cleanup
Logo and branding:
- Responsive logo: full "BMAD METHOD" at >=95 cols, "BMAD" for narrower terminals
- Color scheme updated from yellow to blue (matching bmadcode.com brand)
- Added copyright notice and tagline in white for contrast
- Removed version number from logo (individual module versions shown in summary)
- Added ™ to both wide and narrow logo variants
Installer start message:
- Replaced outdated V6 launch announcement with clean welcome
- Consolidated redundant module/platform messaging into single intro
- Tightened open source manifesto (same spirit, fewer words)
- Merged speaking/media into support section with contact email
- Added full social links: Website, Discord, YouTube, X, Facebook
- Replaced docs.bmad-method.org and changelog links with bmadcode.com hub
Install summary improvements:
- Module names now show full display names from module.yaml (not abbreviations)
- All module versions sourced from .claude-plugin/marketplace.json exclusively
- Summary shows version transitions: "v6.2.2 -> v6.3.0", "v6.3.0, no change",
or "v6.3.0, installed" for fresh installs
- Switched summary from clack note() to box() for full-brightness text
- Removed dim/gray styling that was hard to read on dark terminals
- Links styled with color.blue instead of color.dim
- Get started section leads with actionable steps (launch agent, run bmad-help)
- Removed redundant social links (already shown in start message)
Version source unification:
- All module versions now come from .claude-plugin/marketplace.json only
- Removed package.json as version source for core/bmm modules
- Updated manifest.js getModuleVersionInfo() to use marketplace.json
- Updated installer.js _getMarketplaceVersion() helper
- Updated ui.js getMarketplaceVersion() for module selection display
- Quick Update menu no longer shows misleading version (was using package.json)
- Module selection list now shows versions next to each module name
Skill cleanup overhaul:
- Replaced blunt-force bmad-* prefix deletion with surgical removal system
- Added removals.txt support: optional per-project file listing skills to remove
- Created initial removals.txt with all skills removed since v6.2.0
- Install/update: captures previously installed skill IDs from skill-manifest.csv
before manifest regeneration, then removes those + removals.txt entries
- Uninstall: removes all installed skills via skill-manifest.csv + removals.txt
- Deselecting modules now correctly removes their skills from IDE directories
- User-created bmad-* skills in IDE directories are no longer destroyed
- Legacy directory cleanup retains prefix matching (those dirs are abandoned)
Bug fixes:
- Fixed duplicate "CORE module already up to date" during quick update
- Fixed version display showing package.json version instead of actual module version
- Updated test fixture for bmad-os-* preservation test to use skill-manifest.csv
* fix(installer): address Augment review findings
- Fix plugins[0] fragility: extract highest version across all plugins
in marketplace.json instead of assuming first entry (ui.js, installer.js,
manifest.js)
- Fix _readMarketplaceVersion ignoring moduleSourcePath: custom modules
can now source their own marketplace.json by walking up from source path
- Hard-exclude bmad-os-* utility skills in both surgical and legacy cleanup
modes, preventing accidental deletion if tracked in manifests
- Distinguish missing file vs parse error in skill-manifest.csv reading:
warn on corrupt CSV instead of silently skipping cleanup
* fix(installer): resolve module source before reading marketplace version
Move _readMarketplaceVersion call after source type resolution so custom
modules use their own source path instead of falling back to the external
module cache, which could match a different module with the same code.
* refactor(installer): restructure installer with clean separation of concerns
Move tools/cli/ to tools/installer/ with major structural cleanup:
- InstallPaths async factory for path resolution and directory creation
- Config value object (frozen) replaces mutable config bag
- ExistingInstall value object replaces stateful Detector class
- OfficialModules + CustomModules + ExternalModuleManager replace monolithic ModuleManager
- install() is prompt-free; all user interaction in ui.js
- Update state returned explicitly instead of mutating customConfig
- Delete dead code: dependency-resolver, _base-ide, IdeConfigManager,
platform-codes helpers, npx wrapper, xml-utils
- Flatten directory structure: custom/handler → custom-handler,
tools/cli/ → tools/installer/, lib/ directories removed
- Update all path references in package.json, tests, CI, and docs
* fix(installer): guard ExistingInstall.version and surface module.yaml errors
Guard ExistingInstall.version access with .installed check in
uninstall.js, ui.js, and installer.js to prevent throwing on
empty/partial _bmad dirs. Surface invalid module.yaml parse errors
as warnings instead of silently returning empty results.