Fresh non-interactive installs without --tools previously produced a
config-only install (~35 files vs ~1400 in the manifest) with no warning
and a "BMAD is ready to use" success card, leaving slash commands
unreachable. --tools none was an explicit opt-in for the same broken
state.
Now: fresh install + -y without --tools throws a helpful error pointing
at --list-tools. --tools none is rejected as an unknown ID. Empty and
typo'd tool IDs are also rejected. Existing-install paths (--action
update, quick-update, modify) are unchanged - they continue to reuse
previously-configured tools when --tools is omitted.
Adds --list-tools flag that prints all 42 supported tool IDs (id, name,
target_dir, preferred star) sourced from platform-codes.yaml.
English docs updated; localized docs (vi-vn, fr, cs, etc.) will sync via
the normal translation pass.
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
* 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.