* feat(installer): add plugin resolution strategies for custom URL installs When installing from a custom GitHub URL, the installer now analyzes marketplace.json plugin structures to determine how to locate module registration files (module.yaml, module-help.csv). Five strategies are tried in cascade: 1. Root module files at the common parent of listed skills 2. A -setup skill with registration files in its assets/ 3. Single standalone skill with registration files in assets/ 4. Multiple standalone skills, each with their own registration files 5. Fallback: synthesize registration from marketplace.json metadata and SKILL.md frontmatter Also changes the custom URL flow from confirm-all to multiselect, letting users pick which plugins to install. Already-installed modules are pre-checked for update; new modules are unchecked for opt-in. New file: tools/installer/modules/plugin-resolver.js Modified: custom-module-manager.js, official-modules.js, ui.js * fix(installer): address PR review findings for plugin resolver - Guard against path traversal in plugin-resolver.js: skill paths from unverified marketplace.json are now constrained to the repo root using path.resolve() + startsWith check - Skip npm install during browsing phase: cloneRepo() accepts skipInstall option, used in ui.js before user confirms selection, preventing arbitrary lifecycle script execution from untrusted repos - Add createModuleDirectories() call to installFromResolution() so modules with declarative directory config are fully set up - Fix ESLint: use replaceAll instead of replace with global regex * fix(installer): pass version and repoUrl to manifest for custom plugins installFromResolution was passing empty strings for version and repoUrl, which the manifest stores as null. Now threads the repo URL from ui.js through resolvePlugin into each ResolvedModule, and passes the plugin version and URL to the manifest correctly. * fix(installer): manifest-generator overwrites custom module version/repoUrl 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. * fix(installer): resolve custom modules from disk cache on quick update When the resolution cache is empty (fresh CLI process, e.g. quick update), findModuleSourceByCode only matched plugin.name against the module code. This failed for modules like "sam" and "dw" where the code comes from module.yaml inside a setup/standalone skill, not from the plugin name in marketplace.json. Now runs the PluginResolver on cached repos when the direct name match fails, finding the correct module source and re-populating the cache for the install pipeline. * feat(installer): universal source support for custom modules 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 * fix(installer): harden readMarketplaceJsonFromDisk and hoist require - Add try/catch to readMarketplaceJsonFromDisk so malformed JSON returns null instead of throwing an unhandled parse error - Hoist CustomModuleManager require outside the per-module loop in _installOfficialModules * fix(installer): restore validateGitHubUrl strictness and fix prettier - Restore original GitHub-only regex in deprecated validateGitHubUrl wrapper so existing tests pass (rejects non-GitHub URLs, trailing slashes) - Run prettier to fix formatting in custom-module-manager.js * feat(installer): add --custom-source CLI flag for non-interactive installs Allows installing custom modules from Git URLs or local paths directly from the command line without interactive prompts: npx bmad-method install --custom-source /path/to/module npx bmad-method install --custom-source https://gitlab.com/org/repo npx bmad-method install --custom-source /path/one,https://host/org/repo Works alongside --modules and --yes flags. All discovered modules from each source are auto-selected. * docs: add custom and community module installation guide New how-to page covering community module browsing, custom sources (any Git host, local paths), discovery vs direct mode, local development workflow, and the --custom-source CLI flag. Clarifies that .claude-plugin/ is a cross-tool convention, not Claude-specific. Also updates non-interactive installation docs with the new flag and examples, bumps sidebar ordering, and fixes --custom-source to install only core + custom modules when --modules is not specified.
7.3 KiB
title, description, sidebar
| title | description | sidebar | ||
|---|---|---|---|---|
| Install Custom and Community Modules | Install third-party modules from the community registry, Git repositories, or local paths |
|
Use the BMad installer to add modules from the community registry, third-party Git repositories, or local file paths.
When to Use This
- Installing a community-contributed module from the BMad registry
- Installing a module from a third-party Git repository (GitHub, GitLab, Bitbucket, self-hosted)
- Testing a module you are developing locally with BMad Builder
- Installing modules from a private or self-hosted Git server
:::note[Prerequisites]
Requires Node.js v20+ and npx (included with npm). Custom and community modules can be selected during a fresh install or added to an existing installation.
:::
Community Modules
Community modules are curated in the BMad plugins marketplace. They are organized by category and are pinned to an approved commit for safety.
1. Run the Installer
npx bmad-method install
2. Browse the Community Catalog
After selecting official modules, the installer asks:
Would you like to browse community modules?
Select Yes to enter the catalog browser. You can:
- Browse by category
- View featured modules
- View all available modules
- Search by keyword
3. Select Modules
Pick modules from any category. The installer shows descriptions, versions, and trust tiers. Already-installed modules are pre-checked for update.
4. Continue with Installation
After selecting community modules, the installer proceeds to custom sources, then tool/IDE configuration and the rest of the install flow.
Custom Sources (Git URLs and Local Paths)
Custom modules can come from any Git repository or a local directory on your machine. The installer resolves the source, analyzes the module structure, and installs it alongside your other modules.
Interactive Installation
During installation, after the community module step, the installer asks:
Would you like to install from a custom source (Git URL or local path)?
Select Yes, then provide a source:
| Input Type | Example |
|---|---|
| HTTPS URL (any host) | https://github.com/org/repo |
| HTTPS URL with subdir | https://github.com/org/repo/tree/main/my-module |
| SSH URL | git@github.com:org/repo.git |
| Local path | /Users/me/projects/my-module |
| Local path with tilde | ~/projects/my-module |
The installer clones the repository (for URLs) or reads directly from disk (for local paths), then presents the discovered modules for selection.
Non-Interactive Installation
Use the --custom-source flag to install custom modules from the command line:
npx bmad-method install \
--directory . \
--custom-source /path/to/my-module \
--tools claude-code \
--yes
When --custom-source is provided without --modules, only core and the custom modules are installed. To include official modules as well, add --modules:
npx bmad-method install \
--directory . \
--modules bmm \
--custom-source https://gitlab.com/myorg/my-module \
--tools claude-code \
--yes
Multiple sources can be comma-separated:
--custom-source /path/one,https://github.com/org/repo,/path/two
How Module Discovery Works
The installer uses two modes to find installable modules in a source:
| Mode | Trigger | Behavior |
|---|---|---|
| Discovery | Source contains .claude-plugin/marketplace.json |
Lists all plugins from the manifest; you pick which to install |
| Direct | No marketplace.json found | Scans the directory for skills (subdirectories with SKILL.md), resolves as a single module |
Discovery mode is typical for published modules. Direct mode is convenient when pointing at a skills directory during local development.
:::note[About .claude-plugin/]
The .claude-plugin/marketplace.json path is a standard convention adopted across multiple AI tool installers for plugin discoverability. It does not require Claude, does not use Claude APIs, and has no effect on which AI tool you use. Any module with this file can be discovered by any installer that follows the convention.
:::
Local Development Workflow
If you are building a module with BMad Builder, you can install it directly from your working directory:
npx bmad-method install \
--directory ~/my-project \
--custom-source ~/my-module-repo/skills \
--tools claude-code \
--yes
Local sources are referenced by path, not copied to a cache. When you update your module source and reinstall, the installer picks up the latest changes.
:::caution[Source Removal]
If you delete the local source directory after installation, the installed module files in _bmad/ are preserved. The module will be skipped during updates until the source path is restored.
:::
What You Get
After installation, custom modules appear in _bmad/ alongside official modules:
your-project/
├── _bmad/
│ ├── core/ # Built-in core module
│ ├── bmm/ # Official module (if selected)
│ ├── my-module/ # Your custom module
│ │ ├── my-skill/
│ │ │ └── SKILL.md
│ │ └── module-help.csv
│ └── _config/
│ └── manifest.yaml # Tracks all modules, versions, and sources
└── ...
The manifest records the source of each custom module (repoUrl for Git sources, localPath for local sources) so that quick updates can locate the source again.
Updating Custom Modules
Custom modules participate in the normal update flow:
- Quick update (
--action quick-update): Refreshes all modules from their original sources. Git-based modules are re-fetched; local modules are re-read from their source path. - Full update: Re-runs module selection so you can add or remove custom modules.
Creating Your Own Modules
Use BMad Builder to create modules that others can install:
- Run
bmad-module-builderto scaffold your module structure - Add skills, agents, and workflows with the various bmad builder tools
- Publish to a Git repository or share the folder collection
- Others install with
--custom-source <your-repo-url>
For modules to support discovery mode, include a .claude-plugin/marketplace.json in your repository root (this is a cross-tool convention, not Claude-specific). See the BMad Builder documentation for the marketplace.json format.
:::tip[Testing Locally First] During development, install your module with a local path to iterate quickly before publishing to a Git repository. :::