mirror of
https://github.com/bmad-code-org/BMAD-METHOD.git
synced 2026-09-19 08:11:52 +08:00
skill-customization
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9ffb5b80ab |
fix(installer): stop skill scanner from recursing into discovered skills
Skills don't nest. Once the manifest generator finds a valid SKILL.md in a directory, it should not recurse into that skill's subdirectories looking for more skills. Template files (like bmb's setup-skill-template) inside a skill's assets/ would be incorrectly scanned and produce spurious errors. |
||
|
|
a6d075bd0b |
fix(installer): replace fs-extra with native node:fs to prevent file loss
fs-extra routes all operations through graceful-fs, which globally monkey-patches node:fs with a deferred retry queue. During multi-module installs (~500+ file ops), retried unlink operations from one module's remove phase can fire after the next module's copy phase has written files, silently deleting them non-deterministically. Replace fs-extra with a thin fs-native.js wrapper over node:fs/promises and node:fs. All 21 consumers now use native APIs with no global monkey-patching, eliminating the retry-queue race condition entirely. Closes #1779 |
||
|
|
ea99b7ece5 |
chore(installer): remove 1,683 lines of dead code (#2247)
* chore(installer): remove dead code across installer modules
Delete 3 entirely dead files (agent-command-generator, bmad-artifacts,
module-injections) and remove ~50 unused exports from manifest.js,
cli-utils.js, prompts.js, path-utils.js, official-modules.js,
external-manager.js, custom-module-manager.js, and registry-client.js.
Removes corresponding dead tests.
* fix(installer): restore currentProjectDir writes for placeholder expansion
The previous commit removed the three assignments to
OfficialModules.currentProjectDir as dead code, but buildQuestion()
still reads the property to resolve {directory_name} placeholders in
module config defaults during interactive collection. Without the
writes, any module default containing {directory_name} would surface
the literal placeholder to users.
|
||
|
|
97d32405d0 |
feat(installer): universal source support for custom module installs (#2233)
* 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. |
||
|
|
59b07c33e2 |
feat(bmad-help): llms.txt support for general questions (#2230)
* feat(bmad-help): add _meta rows and llms.txt support for general questions Register llms.txt URLs in module-help.csv via _meta rows so bmad-help can fetch module documentation when users ask questions that don't map to a specific skill. * refactor(bmad-help): streamline llms.txt docs into existing skill sections |
||
|
|
b744408783 |
feat(installer): community module browser and custom URL support (#2229)
* 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. |
||
|
|
5dbfb588ee |
refactor(installer): remove custom content installation feature (#2227)
* 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(). |
||
|
|
6cecab2626 |
chore(install): stop copying skill prompts to _bmad by default (#2182)
* chore(install): stop copying skill prompts to _bmad by default Flip install_to_bmad default from true to false so skill directories are cleaned from _bmad/ after IDE install. Skills are self-contained in their IDE directories (.claude/skills/, etc.) and no longer need duplicate copies in _bmad/. Two skills (bmad-create-prd, bmad-validate-prd) opt back in via explicit manifests because bmad-edit-prd cross-references their data files. Also fixes broken bmm-skills/ path references and corrects the file-ref validator module-to-source mapping. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor(install): make edit-prd self-contained and remove install_to_bmad Give bmad-edit-prd its own copy of prd-purpose.md and replace the cross-skill validation workflow reference with a skill invocation, so all three PRD skills are fully self-contained. With no remaining consumers, remove the install_to_bmad flag from manifests, CSV output, the post-install cleanup loop, and the dedicated test file. * feat(install): clean up skill directories from _bmad after IDE install Skills are self-contained in IDE directories, so _bmad/ only needs module-level files (config.yaml, _config/). After all IDE setups complete, remove skill directories from _bmad/ via skill-manifest.csv. Also cleans up skill dirs left by older installer versions. * test(install): drop stale install_to_bmad column from suite 27 CSV row --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
c46502f640 |
feat(installer): overhaul branding, versioning, and skill cleanup (#2223)
* 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. |
||
|
|
1f99eb0496 |
fix: preserve local custom module sources during quick update (#2172)
* fix: preserve local custom module sources during quick update Keep customModules in the generated main manifest so local custom module source paths survive update runs. Load those preserved source paths during stock quick update before falling back to the custom cache directory. This fixes the case where BMAD would drop customModules, lose the original source path for a local module, and then skip the module or try to re-cache from _bmad/_config/custom/<module>, which could fail with ENOENT after the cache directory was removed. Also adds an installation component regression test to verify customModules and sourcePath are preserved in manifest generation. Fixes #1582 * fix: ensure consistent formatting * refactor: extract quick update custom source assembly Move quick-update custom module source collection out of Installer and into CustomModules as assembleQuickUpdateSources(). This keeps discoverPaths() focused on consuming prepared install inputs while making the quick-update source assembly step explicit and easier to evolve. Also: - preserve customModules metadata in manifest regeneration for installed modules - drop stale customModules entries when modules are no longer installed - cover manifest preservation and manifest-backed quick-update sources in tests |
||
|
|
513f440a23 |
refactor(installer): restructure installer with clean separation of concerns (#2129)
* 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. |