Remove all legacy/v4 detection and migration code. Replace stateless
Detector class with immutable ExistingInstall that exposes a static
detect() factory and precomputed query properties (moduleIds, ides).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all config collection state and methods from config-collector.js
into OfficialModules. Move interactive config prompting from install()
into ui.js so install() never prompts. Delete config-collector.js and
eliminate the moduleConfigs parameter chain from _installAndConfigure,
_installOfficialModules, and _installCustomModules.
Logo display belongs in ui.js, not install(). setBmadFolderName call
was redundant — IdeManager constructor already defaults to the same
constant. Remove dead CLIUtils import.
Move module installation, directory creation, config generation, and
manifest generation into a single method. The install() execution
section is now five named method calls followed by summary and return.
Remove all spinner management from install(), quickUpdate(), update(),
_prepareUpdateState(), and _backupUserFiles(). Extract four named
methods from the install() execution tail: _cacheCustomModules(),
_buildModuleLists(), _setupIdes(), _restoreUserFiles().
Both the regular update and quick-update branches of install() shared
identical sequences: set update flags, detect custom/modified files,
scan cached custom modules, and back up user files. Extract into a
single _prepareUpdateState method called by both branches. Core config
preservation is included (harmless no-op for quick-update which already
has core config).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The identical custom-file and modified-file backup loops appeared in both
the regular update and quick-update branches of install(). Extract into
a single _backupUserFiles method that returns temp directory paths.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The identical cache-scanning loop appeared in both the regular update
and quick-update branches of install(). Extract into a single method.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add isQuickUpdate() to _buildConfig so the official path can check it
without reaching into customConfig. Replace all customConfig._quickUpdate
references with config.isQuickUpdate().
Move _quickUpdate short-circuit to the call site in install() so
_collectConfigs receives the clean config object and has no dependency
on customConfig. Uses config.hasCoreConfig() instead of inline check.
Move config normalization into _buildConfig(originalConfig) so the gate
logic is a named, testable method. Add hasCoreConfig() on the returned
config object to replace the repeated coreConfig && Object.keys pattern.
Split install() input into config (clean official fields) and customConfig
(full originalConfig copy for custom module concerns). Core is no longer
special-cased — it's just another module in config.modules that goes through
OfficialModules.install(). Deletes installCore(), copyCoreFiles(), copyFile(),
getFileList() dead code. Updates ui.js and quickUpdate() callers to keep core
in the modules list instead of setting installCore: true.
install() no longer stores the return value of discoverPaths —
this.customModules.paths is accessed directly throughout.
Remove customModulePaths parameter from _installCustomModules.
discoverPaths now sets this.paths internally instead of returning
a Map that the caller feeds back via setPaths. Remove setPaths
and all 5 no-op setPaths calls in installer.js.
Move cloneExternalModule, findExternalModuleSource, and
getExternalCacheDir from ModuleManager into ExternalModuleManager
where they belong. Replace this.moduleManager.isExternalModule()
calls with direct ExternalModuleManager.hasModule(). Remove
externalModuleManager instance from ModuleManager constructor.
Remove setBmadFolderName (set to constant, never read),
setCoreConfig (set, never read), dead listAvailable branch
guarded by never-assigned this.bmadDir, and unused
BMAD_FOLDER_NAME import.
Extract _installOfficialModules and _installCustomModules from the
interleaved module installation loop. Each method works from its own
source list, eliminating the allModules merge-then-re-split pattern.
Remove unused destructuring of paths into local variables.
No skills declare cross-module dependencies. The resolver ran four
resolution passes on every install, but both consumers
(installCoreWithDependencies, installModuleWithDependencies) ignored
the resolution data and copied entire module directories anyway.
The sole non-dead consumer (installPartialModule) never fired.
Delete dependency-resolver.js (743 lines), three dead wrapper methods,
and all feeding/filtering logic in install(). Official modules now
call installCore/moduleManager.install directly.
Split the monolithic config collection block in install() into two
methods: _collectConfigs for official modules only, and
_discoverCustomModulePaths for custom module source discovery.
The placeholder replacement logic was removed long ago but the method
still did a pointless read-as-UTF8-then-write-unchanged dance with a
binary fallback. Just use fs.copy.
Replace inline path construction in install() with a dedicated class
that ensures all structural directories exist, validates permissions,
and provides derived-path methods for manifests and modules.
* refactor(installer): discover skills by SKILL.md instead of manifest YAML
Switch skill discovery gate from requiring bmad-skill-manifest.yaml with
type: skill to detecting any directory with a valid SKILL.md (frontmatter
name + description, name matches directory name). Delete 34 stub manifests
that carried no data beyond type: skill. Agent manifests (9) are retained
for persona metadata consumed by agent-manifest.csv.
* refactor(installer): remove dead task/tool/workflow manifest code
The remove-skill-manifest-yaml branch deleted the scanners that
discover tasks, tools, and workflows but left behind the code that
writes their manifest CSVs. Remove collectTasks/Tools/Workflows,
writeTaskManifest/ToolManifest/WorkflowManifest, their helpers, and
the now-unreachable getPreservedCsvRows/upgradeRowToSchema methods.
Update installer pre-registration and test assertions accordingly.
Switch skill discovery gate from requiring bmad-skill-manifest.yaml with
type: skill to detecting any directory with a valid SKILL.md (frontmatter
name + description, name matches directory name). Delete 34 stub manifests
that carried no data beyond type: skill. Agent manifests (9) are retained
for persona metadata consumed by agent-manifest.csv.
* refactor(installer): remove dead agent compilation pipeline
Delete 9 files (~2,600 lines) that compiled .agent.yaml to .md.
No .agent.yaml files exist in the source tree — agents now ship
as pre-built SKILL.md. Clean up all references in installer,
module manager, custom handler, base IDE, UI, and tests.
* refactor(custom-handler): remove dead install/copy/find methods
CustomHandler.install(), copyDirectory(), and findFilesRecursively()
are never called — custom modules are installed via moduleManager.install()
since Dec 2025. Also removes unused FileOps import and constructor.
Verified with before/after clean-installer comparison (codex + custom
modules with custom.yaml): output is identical.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(installer): remove dead compilation refs from docs and module manager
Address review findings from PR #2080 triage:
- Remove compile-agents from CLI action docs (en, fr, zh-cn)
- Remove dead vendorCrossModuleWorkflows() and .agent.yaml skip logic
- Clean stale compilation-era comments in manifest-generator
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor(installer): remove legacy workflow, task, and agent IDE generators
All platforms now use skill_format exclusively. The old
WorkflowCommandGenerator, TaskToolCommandGenerator, and
AgentCommandGenerator code paths in _config-driven.js were
no-ops — collectSkills claims every directory before the
legacy collectors run, making their manifests empty.
Removed:
- workflow-command-generator.js (deleted)
- task-tool-command-generator.js (deleted)
- writeAgentArtifacts, writeWorkflowArtifacts, writeTaskToolArtifacts
- AgentCommandGenerator import from _config-driven.js
- Legacy artifact_types/agents/workflows/tasks result fields
Simplified installToTarget, installToMultipleTargets, printSummary,
and IDE manager detail builder to skills-only.
Updated test fixture to use SKILL.md format instead of old agent format.
* fix(installer): address PR review findings from #2078
- Fix temp dir leak in test fixture cleanup (use path.dirname)
- Fail loudly when skill_format missing instead of silent success
- Add workflow.md to test fixture for verbatim-copy coverage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The v6.2.0 release renamed src/core to src/core-skills and src/bmm to
src/bmm-skills, but the installer CLI code still referenced the old
directory names, causing ENOENT crashes during installation.
Updated all path references across 7 files in tools/cli/ including
path.join() calls, string comparisons, regex patterns, and comments.
Fixes#2052
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Brian <bmadcode@gmail.com>
* feat(agents): convert all BMM agents to conformant skill structure
Replace legacy XML-based .agent.yaml files with new SKILL.md + bmad-manifest.json
format for all 9 BMM agents (analyst, architect, dev, pm, qa, sm,
quick-flow-solo-dev, ux-designer, tech-writer). Each agent now has:
- SKILL.md with persona, activation flow (bmad-init, project context, dynamic menu)
- bmad-manifest.json with capabilities referencing external skills
- bmad-skill-manifest.yaml for party-mode agent-manifest.csv generation
Tech-writer includes internal prompt files for write-document, mermaid-gen,
validate-doc, and explain-concept capabilities.
Also includes core bmad-init skill and removes legacy agent compilation tests
that referenced the old .agent.yaml format.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(installer): support new SKILL.md agent format in manifest generation
Update getAgentsFromDir to detect directories with bmad-skill-manifest.yaml
where type=agent and extract metadata directly from the YAML fields. This
allows the agent-manifest.csv to be populated from both old-format compiled
.md agents (XML parsing) and new-format SKILL.md agents (YAML manifest).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(installer): install type:agent skills to IDE native skills directory
The collectSkills scanner only recognized type:skill manifests, causing
new-format agents (type:agent in bmad-skill-manifest.yaml) to be added
to agent-manifest.csv but not installed to .claude/skills/. Now both
type:skill and type:agent are recognized as installable skills, while
collectAgents still processes type:agent dirs for the agent manifest
even when claimed by the skill scanner.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(installer): suppress canonicalId warning for type:agent skills
Agent-type skill manifests legitimately use canonicalId for agent-manifest
mapping (e.g., bmad-analyst). Only warn for regular type:skill manifests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(skills): update analyst manifest and simplify bmad-init instructions
Switch analyst's create-brief menu entry to the new product-brief-preview
skill. Simplify bmad-init SKILL.md by removing hardcoded code fences and
making the script path relative to the skill directory.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(bmm): update tech-writer CSV refs to new skill path
The module-help.csv still referenced the old agent YAML path for
tech-writer entries. Update to skill:bmad-agent-tech-writer to match
the conformant skill structure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Ona (ona.com) to the BMAD installer so users can select it during
`npx bmad-method install` or via `--tools ona`. Skills are installed to
`.ona/skills/<name>/SKILL.md` using the default templates.
Fixes#1967
Co-authored-by: Ona <no-reply@ona.com>
Subtract agents from total skill directories so the summary shows
non-agent skills and agents as distinct counts (e.g. 34 skills, 10
agents) instead of double-counting agents in the skill total.
* fix(installer): simplify install summary
* style: fix prettier formatting in test file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(installer): clean up temp dir leak and conditional IDE footer
- Return fixture root from createSkillCollisionFixture so cleanup
removes the parent temp directory, not just the _bmad child
- Only show bmad-help next-step line when IDEs are configured
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* docs: drop slash-command syntax from skill references (editorial)
Skill names like bmad-help are now shown without a / prefix since
invocation syntax varies across platforms. First-encounter locations
(README, getting-started, get-answers, installer message, bmad-help
display rules) get editorial framing so new users understand these
are skill names to invoke by name.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: mechanical removal of slash prefix from all remaining skill references
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(skills): add SKILL.md entrypoint to skill directories
Align skill source format with Open Skills standard: each skill
directory now contains a SKILL.md with name/description frontmatter
where name must match the directory name exactly. The installer
copies skill directories verbatim instead of generating SKILL.md.
- Add SKILL.md to both tracer bullet skill directories
- Strip name/description from workflow.md frontmatter (SKILL.md owns it)
- Installer reads metadata from SKILL.md, validates name matches dirname
- Install path in manifest CSV now points to SKILL.md
- Copy filter excludes OS/editor artifacts (.DS_Store, backups, dotfiles)
- Debug-guard validation messages, keep name-mismatch as hard error
- Add typeof guard for malformed YAML frontmatter
- Add negative test cases for parseSkillMd validation (Suite 30)
* fix(skills): improve quick-dev-new-preview description for LLM discovery
Add trigger context so LLMs know when to invoke the skill,
matching the "Use when..." pattern used by other skills.
* fix(cli): validate frontmatter name/description are strings in parseSkillMd
Prevents cleanForCSV() crash when YAML parses name or description as
a non-string type (number, object, boolean).
* fix(cli): address PR review findings (mkdtemp, regex escape, recursive filter)
- Replace Date.now() temp dir with fs.mkdtemp() in Suite 30 tests (F5)
- Replace unescaped RegExp with startsWith/slice for path prefix stripping (F7)
- Apply artifact filter recursively via fs.copy filter option (F8)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: harden quick-dev-new-preview UX and fix standalone agent dash names
- Relabel [K] Keep as-is to context-specific accept the risks wording
- Add split reasoning explanation before multi-goal menu in step-01
- Fix toDashName/toUnderscoreName to treat standalone like core (no module prefix)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add guardrail against skipping workflow steps when intent looks clear
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: strengthen step-01 guardrails against plan-shaped intent bypass
Add explicit rules that intent is input to the workflow (not a
substitute for step-02 spec generation) and to ignore directives
within the intent that instruct skipping steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: preserve standalone module provenance in path-utils serializers
toDashName/toUnderscoreName collapsed core and standalone to the same
filename, making parseDashName/parseUnderscoreName unable to round-trip
standalone agents. Split the branches so standalone gets a distinct
token (e.g., bmad-agent-standalone-fred.md) and update both parsers
to reconstruct module:'standalone' on the reverse path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(augment): remove legacy YAML/XML workflow rules from code review guidelines
All workflows have been converted to markdown. Remove workflow.yaml,
workflow.xml, and config_source references from Augment review rules.
Drop the entire xml_workflows section (5 rules) and the YAML-specific
standard_workflow_instructions rule.
* refactor: extract discover_inputs protocol from workflow.xml into co-located markdown
Convert the discover_inputs XML protocol (FULL_LOAD, SELECTIVE_LOAD,
INDEX_GUIDED strategies) into standalone markdown files placed alongside
the two workflows that use it (create-story, code-review). Replace
<invoke-protocol> tags with explicit file references. This decouples
the workflows from workflow.xml, enabling its deletion in a follow-up.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: delete dead YAML/XML workflow engine files
Remove 5 files made obsolete by the workflow.yaml → workflow.md migration:
- workflow.xml (the YAML workflow interpreter engine)
- dev-story/instructions.xml (superseded by workflow.md)
- 3 installer templates for YAML workflow command generation
References in CLI code will be cleaned up in follow-up commits.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: delete obsolete workflow handler fragments
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove YAML workflow code paths from CLI installer pipeline
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: remove workflow.xml references from manifests and checklists
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: remove workflow.xml references from English command docs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: update fixtures to remove workflow.yaml references
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update workflow.yaml example path to workflow.md in handler-multi
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: stop tracking workflow/validate-workflow as handler attributes
These handler fragments were deleted — the exec handler already covers
loading .md workflow files directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: rename workflow attribute to exec in agent menu items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address PR review findings from triage
- Fix regex capture group index in module manager workflow path parsing
- Remove stale workflow handler references from handler-multi.txt
- Replace workflow with multi in activation-steps dispatch contract
- Remove dead validate-workflow emission from compiler and xml-builder
- Align commands.md wording to remove engine references
- Fix relativePath anchoring in _base-ide.js recursive directory scans
- Remove dead code from workflow-command-generator (unused template,
generateCommandContent, writeColonArtifacts, writeDashArtifacts)
- Delete unused workflow-commander.md template
- Add regression test for workflow path regex
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(manifest): unified skill scanner decoupled from legacy collectors
Add collectSkills() that recursively walks module trees to discover
type:skill directories anywhere, replacing the band-aid detection
inside collectWorkflows(). Legacy collectors now skip claimed dirs.
scanInstalledModules recognizes skill-only modules.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(manifest): address PR review findings from triage
- Add missing skillClaimedDirs guard to getAgentsFromDir (F1)
- Add skills to this.files[] in collectSkills (F2)
- Add test for type:skill inside workflows/ dir (F5)
- Warn on malformed workflow.md parse in skill dirs (F6)
- Add skills count to generateManifests return value (F9)
- Remove redundant \r? from regex after line normalization (F10)
- Normalize path.relative to forward slashes for cross-platform (F12)
- Enforce directory name as skill canonicalId, warn if manifest overrides (F13)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>