* feat: add custom GitHub Copilot installer handler
Adds a dedicated GitHub Copilot handler that generates:
- Agent files with .agent.md extension and enriched descriptions
- Prompt files (.prompt.md) for workflows, tasks, and agent activators
- copilot-instructions.md with project config and agent reference table
Replaces the generic config-driven handler with a custom one that
properly supports Copilot's agent/prompt file conventions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: escape YAML descriptions and preserve user copilot-instructions
- Escape single quotes in YAML frontmatter descriptions across all prompt
generators (createWorkflowPromptContent, createTechWriterPromptContent,
createAgentActivatorPromptContent) to match createAgentContent behavior
- Make copilot-instructions.md non-destructive using BMAD markers
(<!-- BMAD:START --> / <!-- BMAD:END -->) to preserve user content
- On cleanup, only remove content between markers; skip files without markers
- Back up existing unmarked files before overwriting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add error handling for CSV read/parse in loadAgentManifest and loadBmadHelp
Wrap file read and csv.parse in try/catch blocks so malformed or
unreadable CSV files gracefully degrade instead of aborting setup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use specific detection paths instead of .github configDir
Set configDir to null and use detectionPaths with
.github/copilot-instructions.md and .github/agents/ so the base
detect() doesn't false-positive on every GitHub repo.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add comments explaining hardcoded bmm/config.yaml in prompts
Clarify that bmm/config.yaml is safe to hardcode in generated prompt
content because these prompts are only created when bmm module data
(bmad-help.csv, agent artifacts) exists.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: guard against missing workflow-file in bmad-help.csv entries
Skip entries where workflow-file is empty/undefined to prevent
workflowFile.endsWith() from throwing during prompt generation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: guard escapeYamlSingleQuote against undefined input
Default to empty string when value is undefined/null to prevent
replaceAll from throwing on missing CSV fields.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: preserve customised tool permissions across reinstalls
Before this change, reinstalling would overwrite any user-customised
tools arrays in agent and prompt frontmatter with the hardcoded default.
Now the installer reads existing tool permissions from .agent.md and
.prompt.md files before cleanup, and re-applies them to the regenerated
files. Falls back to the default ['read', 'edit', 'search', 'execute']
for new files or files without prior customisation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: prevent cleanup from stripping copilot-instructions.md markers before generation
The cleanup() method was removing the BMAD marker section from
copilot-instructions.md, leaving user content without markers.
generateCopilotInstructions() then treated the markerless file as
legacy, backed it up, and overwrote user content.
Fix: remove the copilot-instructions.md block from cleanup() entirely.
generateCopilotInstructions() already handles marker-based replacement
in a single read-modify-write pass that correctly preserves user content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: update manager.js comments to include github-copilot.js
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: make agent capabilities data-driven via agent YAML metadata
Replace the hardcoded getAgentCapabilities() map with a data-driven
pipeline. Capabilities are now defined in each .agent.yaml source file,
compiled into the XML output, extracted into agent-manifest.csv by the
manifest generator, and read by the GitHub Copilot handler at install
time. New agents automatically get their capabilities without code
changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use this.bmadFolderName instead of hardcoded _bmad in template paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove redundant "None" skip option from module selection
The "None - Skip module installation" option was unnecessary since
core is always locked/selected, satisfying the required constraint.
Users can simply press Enter with only core selected to skip modules.
Also removes dead code: selectModules(), getExternalModuleChoices(),
and selectExternalModules() methods that were never called.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: support ESM and .cjs module installers in ModuleManager
Module installer loading now handles three cases:
- .cjs files loaded via require() (always CommonJS regardless of package type)
- .js files loaded via dynamic import() (works for both CJS and ESM)
- CJS default export unwrapped automatically for consistent API
This fixes errors when external modules set "type":"module" in their
package.json. Those modules must still rename installer.js to
installer.cjs if it uses require() internally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address code review findings from PR #1590
- Filter 'core' from CLI --modules in update path for consistency
- Update selectAllModules() JSDoc to reflect core exclusion
- Fix ESM default-export unwrap to handle function/class exports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: clarify module post-install script errors as non-fatal warnings
Change error display from log.error to log.warn and explain that the
module was installed successfully — only the optional post-install
script could not run. Prevents users from thinking the module
installation itself failed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: suppress non-fatal module post-install script errors
Post-install scripts fail due to CJS/ESM incompatibility but module
files are already copied successfully. Silently catch the error instead
of showing a warning that alarms users into thinking installation failed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove redundant modules and tools lines from install summary
The checkmark list already shows each installed module and IDE tool.
Keep only the install path and file-warning lines in the summary footer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Brian <bmadcode@gmail.com>
* feat(cli): complete @clack/prompts migration
Full migration of BMAD CLI installer from legacy terminal libraries
(chalk, ora, boxen, figlet, wrap-ansi, cli-table3, readline) to unified
@clack/prompts v1.0.0 visual system.
Foundation (prompts.js + cli-utils.js):
- Extended prompts.js wrapper with box, spinner, progress, taskLog,
path, autocomplete, selectKey, stream, color re-export
- Refactored cli-utils.js: displayLogo uses box(), sections use note(),
steps use log.step(), removed boxen/figlet/wrap-ansi/cli-table3
UI orchestration (ui.js):
- Replaced ~100 console.log+chalk calls with log.*, note(), box()
- Replaced ora spinner with @clack spinner
- Module selection: autocompleteMultiselect with locked core module,
bulleted post-selection display, maxItems for no-scroll
Spinner migration (installer.js):
- Replaced 40+ ora spinner calls with @clack spinner
- All spinner.stop() calls include meaningful messages
- Failure paths use spinner.error() (red cross) instead of stop()
Readline migration (agent/installer.js + config-collector.js):
- Migrated readline prompts to @clack text/confirm/select
- Fixed chalk.dim bug (chalk was never imported)
- Removed chalk from config-collector.js
IDE handlers + modules (7 files):
- Replaced chalk+ora across all IDE handlers and module manager
- Fixed options.installer undefined bug in manager.js update()
Cleanup:
- Removed ora, boxen, figlet, wrap-ansi, cli-table3 from dependencies
- chalk stays (used outside tools/cli/ scope)
- Replaced hand-drawn Unicode update box in bmad-cli.js with box()
- Added process.stdin.setMaxListeners(25) for sequential prompts
Spinner wrapper adds isSpinning state tracking (not native to @clack).
Removed dead groupMultiselect and sortKey sort calls.
Ref: tech-spec-installer-clack-migration-ui-enhancement.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(cli): consolidate installer output to single spinner + summary
Replace ~40 lines of output from 15+ spinner start/stop cycles with a
single animated spinner during installation and a final note() summary
block showing checkmarks per step.
Key changes:
- Add results collector pattern in install() method
- Replace spinner.stop/start pairs with addResult + spinner.message
- Add renderInstallSummary() using prompts.note() with colored output
- Propagate silent flag through IDE handlers and module manager
- Add spinner race condition guards (start while spinning, stop while stopped)
- Add no-op spinner pattern for silent external module cloning
- Fix stdin listener limit to be defensive with Math.max
- Add GIT_TERMINAL_PROMPT=0 for non-interactive git operations
- Merge locked values into initialValue for autocomplete prompts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(cli): resolve code review findings from @clack/prompts migration
Address 31 issues across 14 CLI files found during PR #1586 review
(Augment Code + CodeRabbit):
- Fix bmadDir ReferenceError by hoisting declaration before try block
- Wrap console.log monkey-patch in try/finally for safe restoration
- Fix transformWorkflowPath dead code and undefined return path
- Fix broken symlink crash in _config-driven.js and codex.js cleanup
- Pass installer instance through update() for agent recompilation
- Fix @clack/prompts API: defaultValue→default, initialValue→default
- Use nullish coalescing (??) instead of logical OR for falsy values
- Forward options in recursive promptToolSelection calls
- Remove no-op replaceAll('_bmad','_bmad') in manager and generator
- Remove unused confirm prompt in config-collector hasNoConfig branch
- Guard spinner.message() when spinner is not running
- Add missing methods to silent spinner stub (cancel, clear, isSpinning)
- Wrap install.js error handler with inner try/catch + console fallback
- Gate codex per-entry error log with silent flag
- Add return statements to all stream wrapper methods
- Remove dead variables (availableNames, hasCustomContentItems)
- Filter core module from update flow selection
- Replace borderColor ternary chain with object map
- Fix Kilo "agents" label to "modes" in IDE manager
- Normalize error return shape for unsupported IDEs
- Fix spinner message timing before dependency resolution
- Guard undefined moduleDir in dependency-resolver
- Fix workflowsInstalled counter inflation in custom handler
- Migrate console.warn calls to prompts.log.warn
- Replace console.log() with prompts.log.message('')
- Fix legacyBmadPath hardcoded to .bmad instead of entry.name
- Fix focusedValue never assigned breaking SPACE toggle and hints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Override _isActionKey to treat SPACE as an action key instead of search input,
and add key handler to toggle selections when not navigating
- update IDE selection prompt message from "Select tools:" to "Integrate with:".
* feat: add non-interactive installation support
Add command-line flags to support non-interactive installation for CI/CD
pipelines and automated deployments:
- --directory: Installation directory
- --modules: Comma-separated module IDs
- --tools: Tool/IDE IDs (use "none" to skip)
- --custom-content: Custom module paths
- --action: Action type for existing installations
- --user-name, --communication-language, --document-output-language, --output-folder: Core config
- -y, --yes: Accept all defaults
When flags are provided, prompts are skipped. Missing values gracefully
fall back to interactive prompts.
* fix: complete non-interactive installation support
- Fix validation checks using truthy instead of !== true
- Add skipPrompts flag to skip module config prompts with --yes
- Add getDefaultModules() for automatic module selection with --yes
- Fix IDE selection to use array check instead of length check
Co-Authored-By: AiderDesk <https://github.com/hotovo/aider-desk>
---------
Co-authored-by: Brian <bmadcode@gmail.com>
* fix: support CRLF line endings and add task/tool templates for all IDEs
* fix: preserve file extensions in IDE task/tool paths and update BMAD branding
* fix: double extension issue in wrapper filename generation
* fix: correct path handling and variable reference in task/tool command generator
* fix: change default BMAD folder name from 'bmad' to '_bmad' across all IDE components
* refactor: centralize BMAD_FOLDER_NAME constant in path-utils
* fix: Replace the rest of BMAD_FOLDER magic values
* fix: add safety checks for setBmadFolderName method calls in IdeManager
* fix: convert absolute paths to relative in task-tool-command-generator
* fix: support .xml task files in bmad-artifacts task discovery
* fix: skip internal tasks in manifest generation and IDE command discovery
* fix: skip empty artifact_types targets and remove unused vscode_settings target
* fix: skip internal tools in manifest generation and improve Windows path handling in command generator
* fix: use csv-parse library for proper CSV handling in manifest generation
* refactor: extract CSV text cleaning to reusable method in manifest generator
* fix: normalize path separators to forward slashes in agent file copying for cross-platform compatibility
---------
Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com>
Co-authored-by: Brian <bmadcode@gmail.com>
* fix: correct malformed XML syntax and remove hardcoded path
- Fix missing opening quote in activation-steps.txt: `n={HELP_STEP}"` → `n="{HELP_STEP}"`
- Remove spurious hyphen: `-Let` → `Let`
- Replace hardcoded `/Users/brianmadison/...` path with relative path
Fixes#1435
* fix: add missing HELP_STEP placeholder replacement
The activation-steps.txt template includes a {HELP_STEP} placeholder,
but activation-builder.js never calculated or replaced it. This caused
the literal string "{HELP_STEP}" to appear in compiled agent files.
Added helpStep calculation between menuStep and haltStep, and adjusted
subsequent step numbers accordingly.
Fixes#1441
* Update src/bmm/workflows/2-plan-workflows/create-prd/validation-report-prd-workflow.md
---------
Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com>
* docs: radical reduction of documentation scope for v6 beta
Archive and basement unreviewed content to ship a focused, minimal doc set.
Changes:
- Archive stale how-to workflow guides (will rewrite for v6)
- Archive outdated explanation and reference content
- Move unreviewed content to basement for later review
- Reorganize TEA docs into dedicated /tea/ section
- Add workflow-map visual reference page
- Simplify getting-started tutorial and sidebar navigation
- Add explanation pages: brainstorming, adversarial-review, party-mode,
quick-flow, advanced-elicitation
- Fix base URL handling for subdirectory deployments (GitHub Pages forks)
The goal is a minimal, accurate doc set for beta rather than
comprehensive but potentially misleading content.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: restructure BMM and agents documentation by consolidating and flattening index files.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix(cli): replace inquirer with @clack/prompts for Windows compatibility
- Add new prompts.js wrapper around @clack/prompts to fix Windows arrow
key navigation issues (libuv #852)
- Fix validation logic in github-copilot.js that always returned true
- Add support for primitive choice values (string/number) in select/multiselect
- Add 'when' property support for conditional questions in prompt()
- Update all IDE installers to use new prompts module
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(cli): address code review feedback for prompts migration
- Move @clack/prompts from devDependencies to dependencies (critical)
- Remove unused inquirer dependency
- Fix potential crash in multiselect when initialValues is undefined
- Add async validator detection with explicit error message
- Extract validateCustomContentPathSync method in ui.js
- Extract promptInstallLocation methods in claude-code.js and antigravity.js
- Fix moduleId -> missing.id in installer.js remove flow
- Update multiselect to support native clack API (options/initialValues)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update comments to reference @clack/prompts instead of inquirer
- Update bmad-cli.js comment about CLI prompts
- Update config-collector.js JSDoc comments
- Rename inquirer variable to choiceUtils in ui.js
- Update JSDoc returns and calls documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(cli): add spacing between prompts and installation progress
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(cli): add multiselect usage hints for inexperienced users
Add inline navigation hints to all multiselect prompts showing
(↑/↓ navigate, SPACE select, ENTER confirm) to help users
unfamiliar with terminal multiselect controls.
Also restore detailed warning when no tools are selected,
explaining that SPACE must be pressed to select items.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(cli): restore IDE grouping using groupMultiselect
Replace flat multiselect with native @clack/prompts groupMultiselect
component to restore visual grouping of IDE/tool options:
- "Previously Configured" - pre-selected IDEs from existing install
- "Recommended Tools" - starred preferred options
- "Additional Tools" - other available options
This restores the grouped UX that was lost during the Inquirer.js
to @clack/prompts migration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Inquirer v9+ is ESM-only, causing ERR_REQUIRE_ESM when loaded via
require() in CommonJS. Convert all require('inquirer') calls to
dynamic import('inquirer') across 8 CLI files.
Fixes#1197
* feat: add documentation website with Docusaurus build pipeline
* feat(docs): add AI discovery meta tags for llms.txt files
- Add global headTags with ai-terms, llms, llms-full meta tags
- Update landing page link to clarify AI context purpose
* fix(docs): restore accidentally deleted faq.md and glossary.md
Files were removed in 12dd97fe during path restructuring.
* fix(docs): update broken project-readme links to GitHub URL
* feat(schema): add compound trigger format validation