mirror of
https://github.com/bmad-code-org/BMAD-METHOD.git
synced 2026-09-19 08:11:52 +08:00
feat/polytoken-support
1976 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c52c9b5b0e |
feat(bmad-prd): new PRD skill + product-brief updates (#2378)
* feat(bmm): add bmad-prd skill and extend product-brief with external integrations
Consolidates the legacy create-prd/edit-prd/validate-prd trio into a single
lean facilitator with create/update/validate intent modes, following the
bmad-product-brief pattern. Both skills gain external_sources and
external_handoffs customize.toml fields for routing through corporate MCP
tools (Confluence, Jira, etc.) with graceful degradation, plus a File roles
constraint clarifying decision-log (audit trail) vs addendum (preserved
depth for downstream docs).
* refactor(bmad-prd): tighten SKILL.md and operationalize source-extractor pattern
- Compress Overview to remove coaching prose duplicated in Discovery
- Operationalize "Extract, don't ingest" with explicit subagent return contract; reference from Update, Validate, and Finalize input reconciliation instead of inline "read N documents"
- Fix Overview H1 -> H2 (was breaking pre-pass tooling)
- Move full headless JSON schemas to assets/headless-schemas.md; keep minimal example inline
- Compress File roles bullet; tighten Finalize step 1
SKILL.md: 124 -> 105 lines, ~4729 -> ~4467 tokens
* feat(bmad-prd): open-items gate, drop distillate, persona discipline, decision-log metadata
- Add Finalize "Open-items review" step (new step 4): counts OQs / [ASSUMPTION] / [NOTE FOR PM], walks them with user, flags high density as red flag against agreed stakes
- Validate now treats open-items density as a first-class finding category
- Resume / continuity surfaces open items deterministically as the first orientation step
- Drop the PRD's own distillate output and the bmad-distillator finalize step. Downstream workflows (UX, architecture, story creation) source-extract from prd.md directly via the canonical source-extractor pattern. Headless schemas, customize.toml comments, and template updated accordingly.
- Drop "status: draft" from PRD frontmatter and template; version/state transitions logged to decision-log.md instead. Finalize step 7 records the version transition entry.
- Add PRD Discipline bullet: personas must be research-grounded or marked [ILLUSTRATIVE]; must drive decisions; 2-4 personas max. Discipline pass enforces.
- Expand File roles bullet: competitive-analysis detail beyond a one-line landscape and operational/cost mechanics (rate-limiting, compression) belong in addendum
* feat(bmad-prd): outcome-driven trim, swappable validation checklist, HTML report
SKILL.md trim (4.7K -> ~3.2K tokens, 124 -> 93 lines):
- Cut anchor enumerations (HIPAA/PCI/NIST list, API/Mobile/Web list, hobby->regulated list, "fast/easy/scalable/intuitive", input enumerations, etc.) the LLM already knows
- Cut derivable reasoning (synonyms-cause-drift explanation, hobby-vs-enterprise examples, etc.)
- Cut good/bad examples that anchor LLM attention (password/SendGrid example, persona quote, "let me also add this nearby thing")
- Drop SMART-ceremony language from Measurable bullet (keep judgment-not-ritual; SMART principles fine)
Progressive disclosure to references/:
- Headless mode rules + JSON minimal example moved to references/headless.md (loaded only when invoked headless)
- On Activation step 6 gates mode detection: headless -> read references/headless.md and follow
Swappable validation checklist:
- New assets/prd-validation-checklist.md (15 items: Quality / Discipline / Structural / Stakes-gated, each one line)
- New customize.toml field validation_checklist (override per org)
- Used by Validate intent AND Finalize Step 3 -- same subagent, same checklist, two moments
- Replaces bmad-validate-prd's 13-step micro-file architecture; kept the valuable check dimensions (density, measurability, traceability, implementation leakage, etc.) and dropped the ceremony
HTML validation report:
- New scripts/render-validation-html.py (PEP 723, stdlib only, ~175 lines) renders structured findings JSON into a styled HTML report with pass/warn/fail grade, inline SVG score bar, category grouping
- New assets/validation-report-template.html (inline CSS, native <details>, no JS, no external deps) -- swappable via customize.toml validation_report_template
- New references/validation-render.md documents the subagent output contract and renderer invocation; loaded only when validate flow runs
- Auto-opens browser on interactive runs; headless skips the open
Mode flow consistency:
- Create and Update both now explicitly "proceed to ## Finalize"
- Validate / analyze is standalone -- explicit "does NOT enter ## Finalize"; renderer auto-opens the HTML
- analyze is a synonym for validate; intent detection routes both
- Update mode no longer has its own light-close validation step (Finalize Step 3 covers it)
* refactor(product-brief,bmad-prd): remove distillation from brief and PRD workflows
Drop bmad-distillator integration from bmad-product-brief (finalize step,
update mode, headless JSON, constraints) and clean up customize.toml comments.
Distillation is the wrong layer — story self-containment via epic solution
design docs is the right answer for downstream context.
Also commit pending bmad-prd changes: working mode selector (Express vs
Facilitative), open-items triage into phase-blocking/resolvable/deferred
buckets, persistence wording fix, and facilitation-guide reference.
* refactor(bmad-prd): aggressive SKILL.md compression, remove LLM-obvious content
* feat(bmad-prd,bmad-product-brief): surface party-mode and advanced-elicitation at opening
* refactor(bmm): retire bmad-create-prd/edit/validate, point docs and PM agent at bmad-prd
Removes the three separate PRD skills (create, edit, validate) in favor of the
unified bmad-prd skill. Updates module-help.csv, PM agent menu, workflow map,
getting-started tutorial, commands reference, customize/help SKILL.md examples,
and the website workflow-map diagram. Adds Recipe 6 (Advanced Integration
Patterns) to expand-bmad-for-your-org.md covering external_sources,
external_handoffs, doc_standards, and swappable templates.
* test(bmad-product-brief): drop distillate from evals
Distillate was removed from the product-brief workflow in
|
||
|
|
724867d48d |
fix(installer): descriptive error when module definition missing after clone (#2377)
* fix(installer): throw descriptive error when module definition missing after clone When a stable tag predates a module restructure (e.g. baut v1.14.0 had payload/source dirs, but the registry pointed to skills/module.yaml which only exists on main), findExternalModuleSource silently returned the configured but non-existent path. This caused a confusing ENOENT inside getFileList/copyModuleWithFiltering rather than a clear error. Now throws with the version that was cloned and a --next hint when the install channel was stable, so users know exactly how to recover. Closes #2372 * style: fix prettier formatting in external-manager.js * style: apply prettier formatting |
||
|
|
c48b6f3069 |
Merge pull request #2345 from bma-d/bma-d/add-automator
feat(installer): add BMad Automator module |
||
|
|
fd0018900e | Merge branch 'main' into bma-d/add-automator | ||
|
|
b5b33c08fa |
Merge pull request #2371 from bmad-code-org/brief-fixes
fix(bmad-product-brief): tighten update/validate rules and eval expectations |
||
|
|
c19f6cd72a |
fix(bmad-product-brief): tighten update/validate rules and eval expectations
- Update: audit trail (decision-log + addendum) is now mandatory before modifying brief.md in headless mode; distillate regeneration is required - Validate: always emits offer_to_update in headless JSON output - Headless: added validate example to JSON status block docs - Evals B8: add 900s timeout, replace hard 30%-smaller check with meaningful-condensation expectation - Eval B9: sharpen right-sized expectation wording |
||
|
|
24a81706ca |
feat(bmm): add bmad-investigate skill
feat(bmm): add bmad-investigate skill |
||
|
|
32258a53a6 | fix(bmad-investigate): collapse multi-line description to single line | ||
|
|
1c1abaa5b1 |
refactor(bmm): streamline bmad-product-brief into lean facilitator (#2370)
* refactor(bmm): streamline bmad-product-brief into lean facilitator
Rewrites bmad-product-brief as an outcome-driven, intent-routed
facilitator with a configurable reviewer panel.
- Replace scripted prompt files with a concise SKILL.md
- Add brief-shape detection and intent routing
- Make the reviewer panel config-driven via customize.toml
- Harden the required-reviewer gate
- Add helper scripts and tests for panel resolution
- Replace embedded resources with a single brief-template asset
- Register skill metadata in module.yaml
* refactor(bmm): tighten bmad-product-brief discovery and polish flow
- Discovery now invites a brain dump and source material upfront,
followed by "anything else?" before drilling
- Create and Update modes explicitly invoke Discovery before drafting
- Calibrate "make them sweat" to ease as the brief firms up
- Update mode regenerates distillate.md when changes apply
- Replace polish_skills with polish_passes: polymorphic entries
(skill:/file:/plain-text), parallel subagents, applied automatically
so the user sees a polished draft, not a polish review
- Default persistent_facts to empty with opt-in examples instead of an
unbounded project-context.md glob
- Remove research-librarian, field-researcher, and skeptic agents no
longer needed with this rework
* refactor(bmm): make persistence and resume explicit in bmad-product-brief
- Replace "Hold a working memory" with "Persistence is real-time": the
workspace exists on disk and the user knows the path the moment Create
intent is confirmed; decision-log.md is canonical memory so walk-away
leaves nothing in the conversation
- Add "Continuity across sessions": prior in-progress drafts for this
project surface a resume offer
* test(bmm): scaffold evals for bmad-product-brief
Adds an eval suite for bmad-product-brief following the Anthropic skill-creator
schema, plus a new "Extract, don't ingest" constraint on the skill itself.
Skill change:
- New constraint: source artifacts (user-provided or run-discovered) enter the
parent conversation as relevance-filtered extracts via subagents, not loaded
wholesale. Keeps the parent context lean against transcripts, brainstorms,
research reports, code, web results, and prior briefs.
Evals (evals/bmm-skills/bmad-product-brief/):
- evals.json: 8 artifact/behavioral evals covering Create one-shot,
source-memo ingest, Update with contradiction surfacing, Validate inline,
Headless mode, brainstorm filtering, research-report filtering, persona
filtering. All scenarios use fictional entities (InsuLens, Branfield CC,
Forkbird Kitchen, Mossridge Library, Sproutkeeper, Hatchet & Loop Studio,
Brightway, Pantry Bridge).
- triggers.json: 15 description-firing checks (7 should-fire, 8 should-not-fire)
to catch under-triggering and adjacent-skill poaching.
- files/: realistic fixtures including a brainstorm with the relevant idea
buried at the end, a 3000-word market research report with the relevant
section in the middle, and customer interviews with the target persona in
position 3 of 4 — each shaped to test that filtering happens against the
user's stated focus regardless of where the relevant material sits.
Eval directory placement: top-level evals/ outside src/, matching the convention
in anthropics/skills (zero of 17 production skills include an evals/ subdir;
their skill-creator places dev workspaces as siblings to skill folders). Keeps
evals out of any installer or marketplace.json distribution path.
* refactor(bmm): rename brief workflow knobs and resolve PR review
- polish_passes -> doc_standards (TOML key + SKILL.md reference). Name
generalizes for every doc-producing skill: encodes standards applied at
finalize, not options.
- {run_folder} -> {doc_workspace}. Bound in Create to
{workflow.output_dir}/{workflow.output_folder_name}/; reused by Update,
Validate, Headless, and Finalize as the active brief's folder.
- On Activation Step 4 now resolves {date} explicitly (used by
output_folder_name default).
- Headless Mode: ambiguous-intent fallback is a `blocked` JSON status with
a `reason` field, no prompting. Resolves the activation/headless
contradiction flagged in review.
* test(bmm): overhaul product-brief evals into A/B/C pattern split
Refactor evals from 8 numbered single-shot tests into 16 typed evals:
- Pattern A (A1-A8): artifact-correctness tests with headless prompts and
precise, falsifiable expectations (no invented facts, right-sized output,
file boundary enforcement)
- Pattern B (B1-B8): process-discipline tests verifying decision-log fidelity,
polish phase ordering, contradiction detection, and distillate generation
- Pattern C (C1): config-compliance test for custom output paths and
document_output_language
Also tighten SKILL.md: add dependencies frontmatter, clarify headless override
autonomy in Update (proceed when intent is clear; block when ambiguous), and
make distillate skip explicit when bmad-distillator is not installed.
|
||
|
|
a3e0545847 | feat(installer): register automator module | ||
|
|
697d92e355 |
fix(bmm): tighten bmad-investigate per review and quality findings
Maintainer review (PR #2364): - shorten frontmatter description - add customize.toml for case-file template, output subdir, filename, persistent_facts, prepend/append steps, on_complete - subagent delegation discipline for context-heavy investigation steps - replace ambiguous "Halt" closer at each outcome with self-documenting "Pause for user with the recap above; wait for direction." Workflow-builder quality findings: - move case-file-template.md to references/ (path standards) - align activation with sibling 4-implementation skills (customize.toml resolution, persistent_facts, greet) - operationalize promised flows: existing-case resume (Outcome 0), evidence-light branch (Outcome 1), refutation pass (Outcome 3), trivial-fix hand-off (Outcome 4) - define High/Medium/Low confidence in Outcome 5 - name concrete next-step skills at Outcome 5 (bmad-quick-dev, bmad-correct-course, bmad-create-story, bmad-code-review) - add Hand-off Brief and Side Findings to case-file template |
||
|
|
7b590b0a90 |
fix(bmm): unwrap case-file template, tighten PRD discovery glob
Two PR review fixes: - Strip the surrounding markdown code fence from case-file-template.md so initializing a case file doesn't nest the whole artifact inside a code block. The template is now the structure directly, with usage notes in an HTML comment that doesn't render. Matches the BMM idiom used by bmad-create-story/template.md. - Drop the stale `*-archaeology.md` reference from bmad-create-prd step-01 discovery. The single-procedure restructure removed archaeology as a distinct mode, so case files only carry the `*-investigation.md` suffix. Tighten the glob accordingly. |
||
|
|
380590aa8b |
feat(bmm): add bmad-investigate skill
Forensic case investigation under Amelia's menu (IN). Evidence-graded findings (Confirmed / Deduced / Hypothesized), hypothesis discipline, structured case-file artifact. Single procedure that calibrates between defect-chasing and area-exploration based on the input. Wires bmad-create-prd discovery to pick up case files as PRD input. Public explainer doc, workflow-map Phase 4 row, EN + FR. |
||
|
|
e36f219c81 |
refactor(catalog): rename after/before to preceded-by/followed-by (#2360)
* refactor(catalog): rename after/before columns to preceded-by/followed-by The bare prepositions `after` and `before` had no subject anchor, leaving the dependency direction ambiguous: "X has Y in its `after` column" reads plausibly as either "Y comes after X" or "X comes after Y". An LLM catalog consumer just got the direction wrong because of this. `preceded-by` / `followed-by` are passive-voice participles whose grammar locks the subject (the skill in this row) and forces a single reading: "X is preceded by Y" can only mean Y comes first. Rename applied to: - module-help.csv headers (bmm-skills, core-skills) - bmad-help SKILL.md schema doc + descriptions - installer.js mergeModuleHelpCatalogs header string - plugin-resolver.js _buildSynthesizedHelpCsv header string - bmad-manifest.json keys (bmad-product-brief, bmad-prfaq) - distillate-format-reference.md example manifest The separate `required` column continues to carry hard-gate semantics; the renamed columns are pure soft sequencing hints, as already documented in bmad-help. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * style(installer): wrap long header strings per prettier * feat(installer): warn on non-canonical module-help.csv headers mergeModuleHelpCatalogs now compares each per-module file's header against the canonical schema and emits a one-shot prompts.log.warn per module on drift, naming both the expected and actual header. Data continues to load positionally so external modules built against the old after/before schema still install cleanly — the warning is the maintainer signal to rename their columns. Centralize the canonical header in modules/module-help-schema.js so the merger and the synthesizer (PluginResolver._buildSynthesizedHelpCsv) read the same source of truth; future column renames are one edit. Verified by installing all four bmad-org external modules (bmb, cis, gds, tea) — every one ships the legacy after/before header today and now fires an advisory warning while still merging cleanly into _bmad/_config/bmad-help.csv with the canonical column names. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
9debc165aa |
fix(installer): remove bmad-help from Copilot Custom Agents picker (#2359)
* fix(installer): remove bmad-help from Copilot Custom Agents picker Per @BMadCode's feedback after #2324 merged: every persona agent's activation message already advertises bmad-help, so its picker entry is redundant AND confusing (looks like a peer agent when it's actually the meta-help). Removes the ALWAYS_AGENT_IDS allowlist exception that put it there. The toml-driven filter (the mechanism BMadCode endorsed in his PR review) remains the sole signal: a skill is a persona iff its source customize.toml has an [agent] section. bmad-help has no customize.toml, so under the cleaned-up filter it's correctly excluded. Tests: replaces the inclusion assertion in Suite 17 with an exclusion assertion. Suite still covers persona / non-conventional persona / workflow / meta-skill-with-`-agent-`-in-name cases. Refs #2324 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test: clarify Suite 17 fixture comment per PR review The fixture creates no customize.toml at all for bmad-help, so the exclusion path being exercised is the missing-file branch — not the file-without-[agent]-section branch. Reword the comment accordingly. Per @augmentcode review on #2359. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
65b810a11f |
fix(installer): generate slash-command and Agent pointer files (OpenCode + GitHub Copilot) (#2324)
* fix(installer): generate OpenCode /<skill> slash commands Adds .opencode/commands/<canonicalId>.md pointer files for each installed skill so users can invoke skills directly (e.g. /bmad-quick-dev) instead of going through the /skills menu. - platform-codes.yaml: add commands_target_dir field for opencode - _config-driven.js: installCommandPointers() with skip-if-exists default, reserved-name collision guard, YAML-safe description quoting - _config-driven.js: cleanupCommandPointers() for symmetric uninstall - test-installation-components.js: extend OpenCode suite with assertions covering pointer creation, content, and idempotency OpenCode-only and opt-in via the new yaml field; other adapters unchanged. Refs #2267 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer): address PR #2324 review feedback Six fixes from CodeRabbit + Augment review on the OpenCode command pointer generation: - skipTarget no longer suppresses installCommandPointers in multi-IDE shared-target_dir batches. Pointers live in a per-IDE directory and are not deduped across peers, so OpenCode must still generate them even when a peer (e.g. openhands) won the .agents/skills write race. - skipTarget no longer suppresses cleanupCommandPointers either, so partial uninstalls leave no stale pointers when a peer remains. - canonicalId is validated as a safe basename before being interpolated into a file path (defense in depth against a malformed manifest entry writing outside commands_target_dir). - yamlSafeSingleLine now quotes descriptions starting with `[` or `{` so YAML doesn't parse them as a sequence/map. - Per-record fs.writeFile failures are caught and counted (writeFailures) rather than aborting the whole IDE install — pointer files are a non-essential adjunct to the skill copy. - Generator-shaped pointer files are refreshed when the manifest description changes; hand-modified files (body diverges from the generator pattern) are still preserved unless forceCommands is set. Tests: extends Suite 8 with description-update propagation; adds new Suite 40c covering OpenCode + openhands batches in both orderings plus partial-IDE uninstall pointer cleanup. 308 tests pass (was 296). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer): address PR #2324 follow-up nitpicks Four nitpicks from CodeRabbit's original review that were missed in the first triage pass: - Hand-edited pointers now survive the production install flow. cleanupCommandPointers spares pointers for canonicalIds that are still in the new manifest when called from the install/update flow (signal: options.previousSkillIds is set). Uninstall and partial-IDE removal flows still wipe pointers as before. The previous behavior wiped every pointer in removalSet before installCommandPointers could run, so its skip-if-exists guard never fired and hand edits were lost on every reinstall — contradicting the docstring's preservation claim. - RESERVED_OPENCODE_COMMANDS is now gated on this.name === 'opencode' so future adapters opting into commands_target_dir don't silently inherit OpenCode's reserved-name set. - printSummary now surfaces results.commands so users see how many pointers were created/refreshed/skipped per install, plus a warning for any per-file write failures. - Dropped a dead `typeof entry !== 'string'` check; fs.readdir without withFileTypes always yields strings. Tests: extends Suite 8 with a hand-edit-preservation regression that calls setup with previousSkillIds (the production shape) and asserts a sentinel byte sequence in the pointer body survives. 310 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer): extend command-pointer generation to Copilot Custom Agents Re-scopes #2324 to cover the second user-facing pain: GitHub Copilot's Custom Agents picker, where installed BMAD skills currently don't show up even though slash commands work natively. Generalizes the per-platform pointer-file mechanism so the same installCommandPointers / cleanupCommandPointers code path serves both OpenCode (slash commands palette) and Copilot (Custom Agents picker), with all platform-specific shape pushed into platform-codes.yaml as data: - commands_target_dir — where pointer files live (existing) - commands_extension — file extension (default '.md'; Copilot uses '.agent.md' per VS Code Custom Agents docs) - commands_body_template — pointer body, supports {canonicalId} and {target_dir} placeholders. Default matches OpenCode's `@skills/<id>` resolver. Copilot has no such resolver, so its template uses the {project-root}/<target_dir>/<id>/SKILL.md LOAD pattern (consistent with PR #1769). OpenCode behavior is unchanged. Copilot users now get a per-skill .github/agents/<canonicalId>.agent.md file that surfaces the skill in the Custom Agents picker — addressing the "agents being gone" complaint flagged by enterprise users. Tests: extends Suite 17 with assertions for Copilot agent pointer creation, body content (LOAD pattern with {project-root}-rooted path), and idempotency. 318 tests pass (was 310). Refs #2267 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer): filter Copilot Custom Agents picker to persona agents only Earlier commit naively wrote a `.github/agents/<id>.agent.md` for every installed skill, which would clutter the Custom Agents picker with 90+ workflow/tool entries that don't belong there. Adds an `agents-only` filter that gates the per-skill emission on whether the canonical id signals a persona agent: - Primary rule: id contains `-agent-` (e.g. `bmad-agent-pm`, `gds-agent-game-dev`, `wds-agent-freya-ux`, `bmad-cis-agent-storyteller`). - Allowlist: `bmad-tea` — TEA's Murat persona uses the bare module code rather than the `-agent-` convention. Listed explicitly so the rule still surfaces it. Verified against the full installed manifest (114 skills): catches all 20 description-confirmed personas across BMM, CIS, GDS, WDS, TEA; excludes all 94 workflows/tools. Wired through a new yaml field on github-copilot: commands_filter: agents-only OpenCode is unaffected — it has no `commands_filter` set, so the loop behaves as before (every skill becomes a slash command). Tests: extends Suite 17 with a multi-skill manifest fixture covering persona/agent + bmad-tea + workflow cases; asserts persona agents and bmad-tea get .agent.md files while workflows do not. 322 tests pass. Refs #2267 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer): detect personas via customize.toml [agent] section Per maintainer review on PR #2324: the `-agent-` naming convention isn't a load-bearing contract anywhere else in the codebase, and the bmad-tea allowlist already shows it starting to break. A future persona that doesn't follow the convention would silently disappear from the Copilot Custom Agents picker. Replaces the name-based filter with a behavior-based signal: read each skill's source `customize.toml` and check for an `[agent]` section. This is the actual configuration source of truth — every BMAD persona is configured under `[agent]`, every workflow under `[workflow]`, every standalone skill has no customize.toml. Verified on disk against the full installed manifest (114 skills): - 20 personas detected — exactly the description-confirmed count across BMM, CIS, GDS, WDS, TEA. bmad-tea is caught natively (no allowlist). - 94 workflows/tools correctly excluded. - `bmad-agent-builder` (meta-skill that builds agent skills) is now CORRECTLY excluded — its canonical id contains `-agent-` but its customize.toml has [workflow], not [agent], because it isn't a persona itself. The previous naming-based filter was including it in the agents picker, which would have been a silent UX bug. `NON_CONVENTIONAL_AGENT_IDS` constant is removed entirely — the toml signal subsumes it. Tests: extends Suite 17 with a 4-skill fixture that covers persona + non-conventional persona + workflow + meta-skill cases. 388 tests pass. Refs #2267 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer): always include bmad-help in Copilot agents picker Adds a single, deliberate exception to the toml-based agents-only filter: `bmad-help` is the structural meta-skill across BMAD — the orientation helper that points users at every other skill. Users invoke it persona-style ("ask the helper") even though it has no `[agent]` customize.toml of its own (it isn't a configurable persona). Implemented as a one-element ALWAYS_AGENT_IDS set rather than a hardcode in the function body so the exception is named, documented, and discoverable. The skill is structurally unique — there is no second meta-help skill — so this is not the start of a growing allowlist; it's a one-off for the one orientation surface BMAD ships. Verified on disk: agents picker now shows 21 entries (20 personas via [agent] in customize.toml + bmad-help). bmad-agent-builder stays correctly excluded (its customize.toml has [workflow], not [agent]). Tests: extends Suite 17 with a `bmad-help` fixture (no customize.toml, must still appear in agents picker). 389 tests pass. Refs #2267 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
e6cdc93b79 | chore(release): v6.6.0 [skip ci] v6.6.0 | ||
|
|
e174bebc60 | chore(release): draft v6.6.0 changelog and bump marketplace plugins (#2356) | ||
|
|
fcf20f1c7b |
Fix/azure devops url parsing (#2269)
* fix(installer): handle deep-path URLs in custom module source parser Rewrite parseSource() from host-specific regex to generic URL-based parser so Azure DevOps _git paths and other multi-segment repo URLs are preserved in cloneUrl and cacheKey. Closes #2268 * test(installer): add Azure DevOps URL tests and wire into CI - Add 18 assertions for dev.azure.com and visualstudio.com URLs - Cover modern ADO, legacy ADO, .git suffix, ?path= subdir variants - Add test:urls script to test and quality npm chains --------- Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
e011192525 |
docs(zh-cn): complete missing translations and localize ecosystem sidebar (#2355)
Add Chinese translations for the two remaining untranslated docs (named-agents, expand-bmad-for-your-org) and add i18n translations for the BMad Ecosystem sidebar group and its items across all locales. Co-authored-by: leon <leon.liang@hairobotics.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
91a57499e9 |
feat(installer): add --set and --list-options for non-interactive config (#2354)
Closes #1663. Adds two installer flags so module config options can be set without interactive prompts. Designed for CI scripts, Dockerfiles, and enterprise rollouts where the user wants to bake answers into the install command rather than answer prompts. `--set <module>.<key>=<value>` (repeatable) sets any module config option. `--list-options [module]` lists every key the installer can discover locally — built-in modules (`core`, `bmm`) plus any cached official modules. One flag scales to every module without growing the CLI surface per option. ```bash npx bmad-method install --yes \ --modules bmm --tools claude-code \ --set bmm.project_knowledge=research \ --set bmm.user_skill_level=expert \ --set core.user_name=Brian ``` ## How it works `--set` is a post-install patch. The installer runs its normal flow untouched, then `applySetOverrides` upserts each value into the relevant config files: - `_bmad/config.toml` (team scope, default) - `_bmad/config.user.toml` (user scope, when the key already lives there — so user-scope keys like `core.user_name` and `bmm.user_skill_level` keep their proper file) - `_bmad/<module>/config.yaml` (so declared schema keys carry forward via the existingValue path on the next install) A module without `_bmad/<module>/config.yaml` is skipped silently — no orphan sections in `config.toml` for uninstalled modules. ## Tradeoffs documented in install-bmad.md - **Verbatim values.** `--set bmm.project_knowledge=research` writes `"research"`, not `"{project-root}/research"`. The `result:` template is not applied. Pass it explicitly if you want the rendered form: `--set bmm.project_knowledge='{project-root}/research'`. - **Carry-forward, declared keys.** Free — values land in the per-module `config.yaml`, so the next install reads them as `existingValue` and they become the prompt default (accepted under `--yes`). - **Carry-forward, undeclared keys.** Best-effort. The value lives in `config.toml` for the current install but won't be re-emitted on the next install (the manifest writer's schema-strict partition drops unknown keys). Re-pass `--set` if needed. - **No "key not in schema" validation.** Whatever you assert is written. ## Security Prototype-pollution defense: `--set __proto__.x=1` would otherwise reach `overrides.__proto__[x] = 1` and pollute `Object.prototype`, cascading into every plain-object lookup in the process. Defense-in- depth via parser-level reserved-name rejection (`__proto__`, `prototype`, `constructor`) AND `Object.create(null)` for the override maps. Verified the attack reproduces without the guard and is blocked with it. ## What's intentionally NOT integrated `--set` deliberately does not touch the prompt / template / schema collection flow. No pre-seeding answers, no question filtering, no function-default evaluation, no schema-strict partition exemption. That earlier integration approach was tried and scrapped: it spread state across `Config`, `OfficialModules`, `manifest-generator`, both collection helpers, and required parallel plumbing for quick-update — every bug fix touched a different layer. The post-install patch model covers the actual user need (set a config value from CI) in ~330 lines of `set-overrides.js` without the schema gymnastics. ## Files - `tools/installer/set-overrides.js` (new): parser, prototype-pollution guard, `applySetOverrides` post-install patch, `upsertTomlKey` / `tomlString` / `tomlHasKey` line-based TOML helpers - `tools/installer/list-options.js` (new): module.yaml discovery + formatter for `--list-options` - `tools/installer/commands/install.js`: register `--set` / `--list-options` flags, early validation, `--list-options` exit-code handling (await `stream.write` callback then `process.exitCode` to avoid truncating piped output), thread `setOverrides` through to quick-update - `tools/installer/core/config.js`: carry `setOverrides` field for the post-install patch step - `tools/installer/core/installer.js`: invoke `applySetOverrides` after `writeCentralConfig` (covers regular install + quick-update via the shared install path) - `tools/installer/ui.js`: parse `--set` for early validation, warn about overrides targeting modules not in `--modules`, drop those entries before threading - `docs/how-to/install-bmad.md`, `README.md`: usage, routing rules, carry-forward semantics, tradeoffs ## Test plan Suite 44 (24 cases): parser, prototype-pollution guard, `tomlString` escaping, `upsertTomlKey` across insert/replace/missing-section/ empty-file/preserved-newline cases, `applySetOverrides` happy path + uninstalled-module skip + missing-user-toml-creation + empty-input no-op, `discoverOfficialModuleYamls` / `formatOptionsList` sanity (hermetic via `BMAD_EXTERNAL_MODULES_CACHE` temp dir). 355 total passing. Lint + prettier + markdownlint clean. E2E smoke verified across: - [x] `--set` writes correct files (team toml / user toml / per-module yaml) for declared and undeclared keys - [x] Quick-update without `--set` carries forward declared keys via `existingValue` path - [x] Quick-update WITH `--set` applies cleanly (uniform behavior across action types) - [x] `--set` for unselected module: warned, no orphan section - [x] Prototype pollution: rejected with non-zero exit - [x] `--list-options bmm` exit 0 with full output through pipe; `--list-options nope` exit 1 - [x] Translated docs (`docs/{cs,fr,vi-vn,zh-cn}/`) intentionally not touched — they'll lag behind English until the translation pipeline runs |
||
|
|
48a7ec8bff |
fix: align bmad-help.csv with documented schema and clean up source rows (#2278) (#2349)
* fix(installer): preserve module-help.csv schema in merged bmad-help.csv (#2278) The installer's mergeModuleHelpCatalogs was rewriting the merged catalog under a different schema (module,phase,name,code,sequence,workflow-file,...) than the documented source schema in every module's module-help.csv (module,skill,display-name,menu-code,description,action,args,phase,...). Worse, the parsing assumed the wrong source column order, so column data was scrambled in the merged output. SKILL.md docs the source schema, so the bmad-help skill was navigating a catalog whose actual columns no longer matched its mental model. Drop the transformation and the agent enrichment columns (which had no consumers anywhere in the codebase). Emit rows verbatim in the source schema, padding short rows and filling empty module fields. Sort by module then phase, stable within phase to preserve authored order. Closes #2278 * fix(catalog): normalize module-help.csv rows to documented 13-column schema Many rows in core-skills/module-help.csv and bmm-skills/module-help.csv were missing one column between description and phase, leaving them at 12 fields instead of 13. CSV consumers that read by header position were silently mapping data into the wrong columns (description into action, phase into args, required into before, etc). Inserted an empty cell at column index 5 across all 31 affected rows to restore alignment with the documented header (module,skill,display-name,menu-code,description,action,args,phase, after,before,required,output-location,outputs). |
||
|
|
3da984a491 |
fix(config): promote project_name to core (closes #2279) (#2348)
* fix(config): promote project_name to core, fixes #2279 project_name was a bmm-specific prompt despite being a universal project-level concept used by every module — including core skills like bmad-brainstorming, which loads from _bmad/core/config.yaml and was silently broken because project_name lived under bmm. Users without bmm installed could not run brainstorming at all. Move: - src/core-skills/module.yaml: declare project_name with prompt "What is your project called?" and default {directory_name}, matching what bmm previously had. - src/bmm-skills/module.yaml: remove the bmm definition; add project_name to the "Variables from Core Config inserted" header comment so contributors can see what's inherited. Migration for existing installs: - tools/installer/modules/official-modules.js: after loadExistingConfig reads each per-module config.yaml, hoist any keys that are now declared in core but appear under non-core modules. Without this, the partition logic in writeCentralConfig (which strips core keys from non-core buckets) would silently drop the user's prior project_name on the next quick-update. Generic — handles project_name today and any future module→core promotions. - The hoist preserves precedence: an existing core value beats a stale module-side copy. --yes seed: - tools/installer/ui.js: add project_name to the hardcoded core seed (using path.basename(directory) to match the {directory_name} default) so non-interactive fresh installs populate it. Without this the seed silently omits project_name and core skills fall back to literals. Tests: - test/test-installation-components.js Suite 43 (9 assertions) covers the schema move, the loadExistingConfig hoist, and the precedence rule. - Suite 35 fixture updated: project_name moved from bmm bucket to core, with a stale bmm copy left in place to verify it gets stripped. Verified manually: - Fresh install -y: project_name lands in [core] of config.toml. - Existing install with project_name in bmm/config.yaml: quick-update hoists it to [core] and strips it from [modules.bmm]. * fix(installer): harden config-load against malformed config.yaml Per augment review on #2348: loadExistingConfig stored any truthy yaml.parse result (including scalars like '42'), which would later crash _hoistCoreKeysFromLegacyModuleConfigs at \`key in cfg\` with "Cannot use 'in' operator to search for ... in 42". - loadExistingConfig: only keep parses that are plain objects (not scalars or arrays). A corrupt config.yaml is now treated the same as a parse error — skipped, not crashed-on. - _hoistCoreKeysFromLegacyModuleConfigs: belt-and-suspenders type guards on _existingConfig.core (in case it's populated by some other path) and on each module cfg in the loop. - Test Suite 43 adds 2 assertions covering a scalar core/config.yaml: loadExistingConfig must not crash, and bmm.project_name must still hoist into a clean core bucket. |
||
|
|
815600e4ca |
fix(create-architecture): unprime step-07 validation checklist (#2292) (#2347)
step-07-validation template shipped with all 16 completeness checkboxes pre-checked and Overall Status hard-coded to READY FOR IMPLEMENTATION, defeating the gate. Reset checkboxes to unchecked, replace status with a templated choice tied to the checklist and gap analysis, and instruct the agent to only mark items the validation actually confirms. Closes #2292 |
||
|
|
7ee5fa313b |
fix(installer): require --tools for fresh --yes installs; remove --tools none (#2346)
* fix(installer): require --tools for fresh --yes installs; remove --tools none (closes #2326) 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. * fix(installer): address review for #2326 — single source of truth, drop dead code, add tests - Refactor formatPlatformList to use IdeManager so --list-tools and --tools validation see the same set of platforms. Eliminates the drift where suspended platforms appeared in --list-tools but were rejected at validation. - Drop unused getValidPlatformIds export. - Flatten redundant block scope around the throw in the --yes-without-tools branch (refactor leftover). - Drop dead String() defensive cast (Commander always passes a string). - Add Test Suite 42: 8 unit tests covering _parseToolsFlag empty/whitespace/ unknown/typo cases plus an integration check that --list-tools output and --tools validation agree on the ID set. * fix(installer): close --tools "" bypass and drop hardcoded tool count - Replace truthy `if (options.tools)` guard with `!== undefined` in both upgrade and fresh-install branches. Empty string now reaches _parseToolsFlag and produces the specific "passed empty" error instead of falling through to a generic message (fresh-install) or being silently ignored (existing-install). - Drop the hardcoded "42 supported tools" count from the prereqs in install-bmad.md so the doc doesn't drift as platform-codes.yaml changes. Addresses augment / coderabbit review on #2346. |
||
|
|
3e89b30b3c |
fix: use full update path when --custom-source is passed with --yes (#2336)
* fix: use full update path when --custom-source is passed with --yes When --yes is used on an existing install, the installer auto-selects quick-update. However, quick-update never re-clones custom module repos — it only reads whatever is already in the cache. This means --custom-source with a new version tag (e.g. @1.1.0) is silently ignored and the previously cached version (e.g. 1.0.1) is reported as "already up to date". Default to the full update path when --custom-source is present, so the custom repo gets re-cloned at the requested version. Also ensure all installed modules are included in the selection when --yes is combined with --custom-source, preventing previously installed modules from being removed. * fix: address review feedback on choices.find() and comment clarity * style: prettier fix for empty-body methods in custom-module-manager --------- Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
b4d73b7daf |
Fix installer custom modules http (#2344)
* fix(installer): preserve http protocol in custom module clone URLs Previously, parseSource() hardcoded 'https://' when building cloneUrl, forcing http:// Git URLs (e.g., internal LAN hosts) to upgrade to https. This broke cloning for self-hosted Git servers that only serve over HTTP. - Capture the protocol from the regex match instead of discarding it - Update JSDoc and inline comments to document HTTP support - Update install-custom-modules docs (EN, ZH, VN) to list HTTP URL type Fixes the --custom-source flag for http:// addresses. * docs(installer): update JSDoc to mention HTTP support in cloneRepo Add HTTP to the cloneRepo method's JSDoc param description. Also fixes minor spacing in empty arrow functions (formatting). * docs(installer): fix JSDoc annotation for cloneRepo param Correct @param backtick escaping in cloneRepo JSDoc. Also documents HTTP as a supported protocol alongside HTTPS and SSH. --------- Co-authored-by: 关惠民 <9155544@qq.com> |
||
|
|
6ff74ba662 |
fix(installer): route community installs through PluginResolver when marketplace.json ships (#2331)
* fix(installer): route community installs through PluginResolver when marketplace.json ships Community-catalog installs ignored .claude-plugin/marketplace.json, so modules that nest module.yaml inside a setup skill's assets/ directory (e.g. Strategy 2 in PluginResolver) ended up half-installed: only module-help.csv and the generated config.yaml landed in _bmad/<code>/, while the actual skill source trees and module.yaml never got copied. The install would silently emit "could not locate module.yaml" warnings and leave .agents/skills/ without the module's skills. The fix wires the existing PluginResolver onto the community path: - CommunityModuleManager.cloneModule now detects marketplace.json after the clone+ref-checkout completes and runs PluginResolver. The resolution is stamped with channel/sha/registryApprovedTag/registryApprovedSha and cached in _pluginResolutions, mirroring the existing _resolutions cache. - OfficialModules.install consults the community plugin resolution and delegates to installFromResolution (the same code path custom-source installs already use). installFromResolution branches on communitySource to write source: 'community' with the registry's approved tag/sha and channel. - resolveInstalledModuleYaml now searches the community-modules cache root in addition to the external-modules cache, and the BMB setup-skill detector walks src/skills/ and skills/ (not just the repo root) so collectAgents FromModuleYaml and writeCentralConfig can find module.yaml in nested marketplace-plugin layouts. Backward compatibility: repos without marketplace.json (e.g. WDS, which declares module_definition: src/module.yaml at the root) continue through the legacy findModuleSource path with no behavior change. Verified against the live zarlor/suno-band-manager community module and a 23-check fixture suite covering Suno-shape, WDS-shape, and bare-repo layouts. * fix(installer): harden community marketplace.json resolution path Address review feedback on the community marketplace.json install path: - Wrap PluginResolver.resolve() in try/catch so a malformed plugin entry falls through to the legacy install path with a warn instead of crashing cloneModule. - Stop mutating the resolver's return object; shallow-clone before stamping community provenance so install state cannot leak back into resolver-owned objects. - Warn when _selectPluginForModule lands on the single-plugin fallback with a name that doesn't match the registry code or module_definition hint, so a misconfigured marketplace.json can't silently install the wrong plugin. - Add CommunityModuleManager.resolveFromCache() and call it from OfficialModules.install() when the in-process plugin cache is empty, so callers that reach install() without pre-cloning still get the marketplace-aware path. Reuses an existing channel resolution when present, otherwise synthesizes a stable-channel stub from the registry entry plus the cached repo's HEAD. - Align installFromResolution()'s returned versionInfo.version with manifestEntry.version precedence (communityVersion || cloneRef || ...) so downstream summaries match what was written to the manifest. Tests: lint, format:check, lint:md, test:install (290), test:channels (83), test:refs (7) all green. |
||
|
|
1ad1f91e38 |
feat(workflows): add brownfield epic scoping to detect file churn (#1823) (#1826)
Add design completeness gate, file overlap check, and validation to prevent unnecessary file churn when epics target the same component. |
||
|
|
350688df67 |
fix(installer): resolve url-source custom modules from custom-modules cache (#2323)
* fix(installer): resolve url-source custom modules from custom-modules cache resolveInstalledModuleYaml previously only searched ~/.bmad/cache/external-modules/, so modules installed via --custom-source <git-url> (cached at ~/.bmad/cache/custom-modules/<host>/<owner>/<repo>/) could not be located on re-install runs. This caused warnings during npx bmad-method install: [warn] collectAgentsFromModuleYaml: could not locate module.yaml for '<name>' [warn] writeCentralConfig: could not locate module.yaml for '<name>' Adds a fallback that walks the custom-modules cache via _findCacheRepoRoots (identifying repo roots by .bmad-source.json or .claude-plugin/, not marketplace.json, so direct-mode modules are also covered), reuses the same searchRoot candidate-path logic, and matches by the discovered yaml's code or name field. Works without needing _resolutionCache to be populated, which fixes the re-install scenario where no --custom-source flag is passed. Closes #2312 * fix(installer): enumerate all module.yamls when walking custom-modules cache A url-source custom-modules repo can host multiple plugins in discovery mode (e.g. skills/module-a/module.yaml and skills/module-b/module.yaml). The previous walk used searchRoot which returned only the first match, so asking for module-b would surface module-a's yaml, fail the code/name check, and skip the repo entirely — never inspecting module-b. Splits the candidate-path traversal into searchRootAll (returns every module.yaml in priority order) and a thin searchRoot wrapper for the existing single-module fallbacks. The custom-modules walk now iterates every yaml per repo and matches each against code or name. |
||
|
|
be85e5b4a0 |
fix(installer): support local custom-source modules in resolveInstalledModuleYaml and TOML key (#2316)
- resolveInstalledModuleYaml: fall back to CustomModuleManager._resolutionCache for local custom-source modules (external cache path doesn't exist for these); refactor candidate-path search into shared searchRoot() helper; add *-setup/assets/module.yaml BMB standard path - manifest-generator: use module code field (not display name) as TOML section key [modules.X] Co-authored-by: cidemaxio <cidemaxio@users.noreply.github.com> |
||
|
|
04cfde1454 |
fix(installer): mirror launch channel as default for external modules (#2321)
* fix(installer): mirror launch channel as default for external modules When the user runs `npx bmad-method@next install`, the installer itself runs from a prerelease, but the interactive channel gate previously hardcoded "(all stable)" — defaulting tea/community modules to stable while bmad-method itself was on next. The bleeding-edge launch did not flow through. Detect the installer's own version via semver.prerelease() and default the gate (and per-module picker) to match — "all next" for prerelease launches, "all stable" for stable. Users keep full control: hit "n" to customize per module, or pass explicit --channel / --pin / --next flags to override. * fix(installer): seed channelOptions before module picker, not gate CodeRabbit caught a label/install mismatch in the previous approach: the module picker resolves version labels via decideChannelForModule, which runs before _interactiveChannelGate. With channelOptions.global still null at picker time, labels rendered from stable tags — then the gate flipped global to 'next' and externals installed from main HEAD. Net effect on @next launches: "tea (v1.6.0)" in the picker, but install pulled HEAD. Move the launch detection up into promptInstall, immediately after parseChannelOptions. Seeding channelOptions.global = 'next' before the picker makes labels resolve from main HEAD (matching the install) and lets the existing gate's haveFlagIntent check skip cleanly — the @next user already declared their intent by typing it. Per-module customization remains available via --pin / --next / --channel flags, same as for any pre-set global. |
||
|
|
7baa30c567 |
fix(publish): advance @next dist-tag after stable release (#2320)
* fix(publish): advance @next dist-tag after stable release When a stable release publishes via workflow_dispatch, @latest can leapfrog the existing @next prerelease (e.g. latest=6.5.0 while next=6.4.1-next.0), turning `npx bmad-method@next install` into a silent downgrade until the next qualifying push to main republishes a fresh -next.0. - publish.yaml: after stable publish, repoint @next at the just-published stable version. The existing derive-prerelease step picks max(latest, next) as its base, so subsequent push-driven prereleases bump from there. - bmad-cli.js: checkForUpdate was querying the @beta dist-tag (which this package does not use). Replace string-matching with semver.prerelease() and query @next for prerelease users. * fix(publish): harden next-tag advance step and broaden path filter - continue-on-error on the dist-tag advance: failure leaves @next stale until the next push-driven prerelease, which is recoverable; failing the job after a successful publish + git tag + GH release is not. - Status echo so release-log triage can confirm the advance ran. - Add removals.txt to the push-trigger path filter. Installer-affecting changes outside src/** (like the post-6.5.0 removals.txt fix) should still trigger a fresh -next.0 publish. |
||
|
|
88b9a1c842 |
fix(installer): remove pre-v6.2.0 wrapper skills on update (closes #2309) (#2315)
Adds 32 entries to removals.txt covering the module-prefixed wrapper skill names used pre-v6.2.0 (bmad-bmm-* and bmad-agent-bmm-*). Users upgrading from v6.0.x / v6.1.x had these installed in their IDE skill directories, but the v6.2.0 architecture switch dropped the module prefix and the cleanup never knew the old names. Stale wrappers stayed behind alongside the new self-contained skills, causing duplicates and broken-file errors when invoked (referenced files no longer exist). The removals.txt entries get added to the cleanup removalSet on every install/update, so the next install run for an upgrading user removes the stale wrappers automatically. |
||
|
|
69cbeb4d07 | chore(release): v6.5.0 [skip ci] v6.5.0 | ||
|
|
1d35acfd84 | docs: add v6.5.0 changelog entry (#2314) | ||
|
|
01cc32540b |
feat(installer): expand to 42 platforms with shared target_dir coordination (#2313)
* refactor(installer): replace legacy_targets auto-cleanup with upgrade warnings Removes the legacy_targets YAML field and its install-time auto-migration of pre-v6.1.0 directories (.claude/commands, .opencode/agents, etc.). On install, surface a warning instead: read manifest version and scan 24 known legacy paths, then print rm -rf commands the user can run themselves. Also deletes orphan tools/platform-codes.yaml (never loaded by any code) and fixes a stale URL in the cs translation. * feat(installer): consolidate to .agents/skills and add global_target_dir for all platforms Updates platform-codes.yaml against verified primary docs for all 24 supported platforms. 14 platforms (auggie, codex, crush, cursor, gemini, github-copilot, kilo, kimi-code, opencode, pi, roo, rovo-dev, windsurf) move their project target_dir to the cross-tool .agents/skills/ standard. Junie moves from the broken .agents/skills/ to its own .junie/skills/ per JetBrains docs. Adds global_target_dir to every platform: 11 share ~/.agents/skills/, Crush uses XDG ~/.config/agents/skills/, Codex global stays ~/.codex/skills/, the rest are tool-specific. Ona and Trae omit global (no documented home path). Note: installer logic does not yet dedupe writes for platforms sharing a target_dir — users installing multiple .agents/skills/ tools together will overwrite the same files (harmless on install, but uninstalling one clears the dir for the others). Coordination logic is the next step. * feat(installer): add 18 new platforms, dedup shared target_dir, ownership-aware cleanup Adds 18 platforms from the verified Vercel list (adal, amp, bob, command-code, cortex, droid, firebender, goose, kode, mistral-vibe, mux, neovate, openclaw, openhands, pochi, replit, warp, zencoder). Marks codex and github-copilot as preferred alongside claude-code and cursor. Coordination for platforms sharing a target_dir: - IdeManager.setupBatch dedups skill writes when multiple selected platforms point at the same target_dir (e.g. .agents/skills/). The first platform writes, peers skip the redundant wipe-and-rewrite. Result reports the same count and target dir for every member so the install summary is consistent. - IdeManager.cleanupByList accepts remainingIdes; when removing one platform from a shared dir while another co-installed platform still owns it, the target_dir wipe is skipped. Platform-specific hooks (copilot markers, kilo modes, rovodev prompts) still run. - _setupIdes uses setupBatch; _removeDeselectedIdes passes remainingIdes so partial reconfigure preserves shared skills. Skill ownership now uses skill-manifest.csv canonicalIds, not the bmad- prefix. This unblocks custom modules that ship skills with non-bmad names (e.g. fred-cool-skill). Affected sites: - _config-driven.detect: reads canonicalIds from the project's bmadDir - _config-driven.findAncestorConflict: reads canonicalIds from the ancestor's own bmadDir, falling back to the prefix only when no manifest exists - legacy-warnings.findStaleLegacyDirs: same canonicalId-based detection Migration warnings: LEGACY_SKILL_PATHS adds 12 skill dirs that moved to the .agents/skills/ standard (cursor, gemini, github-copilot, kimi, opencode, pi, roo, rovodev, windsurf, plus their globals). Users with stale skills in those locations get a one-line warning with the rm command per dir. New shared helper tools/installer/ide/shared/installed-skills.js exposes getInstalledCanonicalIds(bmadDir) and isBmadOwnedEntry(entry, canonicalIds). Tests: 9 new assertions across two suites covering dedup, partial uninstall preservation, and custom-module skill detection. All 286 tests pass. * fix(installer): setupBatch must not claim a shared target_dir on failure If the first platform's setup throws or returns success: false, the dedup map previously still recorded the claim with skillCount: 0, causing every peer sharing the target_dir to skip its install — leaving the dir empty/broken behind a cascade of misleading "shares with X" rows. Now the claim is only recorded when the install succeeded and wrote skills. On failure, the next peer becomes the new first writer and recovers. Adds Suite 40b regression test that monkey-patches cursor.setup to throw and verifies gemini still populates the shared dir. * fix(installer): address PR #2313 review findings Three issues raised by augmentcode and coderabbit bot reviewers: 1. _removeDeselectedIdes silently swallowed cleanup failures after the refactor to cleanupByList. The old per-IDE try/catch logged a warning; the new path discarded the result array. Now logs a warning per failed ide so failures stay visible. 2. The legacy-dir cleanup hint printed `rm -rf "<path>"/bmad*` which both matched bmad-os-* utility skills the user should keep AND missed the custom-module skills (e.g. fred-cool-skill) that the new canonical-id detection now finds. Findings now carry the exact entry names from the scan, and the warning prints one precise rm line per entry. 3. warnPreNativeSkillsLegacy did unguarded fs reads at install start. A permission/IO error would have aborted the whole install. Wrapped the call site in try/catch so legacy-scan failures only emit a warning. |
||
|
|
1197122001 | chore(release): v6.4.0 [skip ci] v6.4.0 | ||
|
|
314fe69d14 | docs: add v6.4.0 changelog entry (#2310) | ||
|
|
9ff9d6f8f3 |
feat: add Kimi Code CLI support (#2302)
Adds kimi-code to both platform-codes.yaml files so Kimi Code CLI is available as an install target via the config-driven installer. Skills are installed to .kimi/skills/, which is the project-level skills directory per the official Kimi Code CLI documentation. Closes #1630 Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
c29b72ecc0 |
fix(create-story): read UPDATE files before generating dev notes (#2274)
When a story modifies existing files, create-story must read those files before generating dev notes. Without this, dev agents improvise design decisions without knowing the current state of the code, leading to regressions caught only at review time. Adds a step at the end of Step 3 (Architecture analysis) that reads every file marked UPDATE in the architecture directory structure and documents its current state, what the story changes, and what must be preserved. Fixes #2273 Co-authored-by: Brian Madison <bmadcode@gmail.com> |
||
|
|
e7a213ed07 |
feat: uniform customize.toml support across all BMM workflows (#2308)
* feat: extend customize.toml to all 6 developer-execution workflows (#2303) Add uniform customization support to dev-story, code-review, sprint-planning, sprint-status, quick-dev, and checkpoint-preview, matching the same 4 extension points (activation_steps_prepend, activation_steps_append, persistent_facts, on_complete) already available on 17 BMM workflows from PR #2287. - Create customize.toml for each workflow - Add 6-step activation block to SKILL.md (merge workflow.md content in, delete workflow.md per PR #2287 pattern) - Wire on_complete at terminal steps (inline <action> for XML workflows, ## On Complete section for step-file workflows) - Fix pre-existing step number reference in dev-story (Step 6 → 9) * fix: correct goto step="6" → step="9" in dev-story The XML goto at line 203 still pointed to step 6 ("Author comprehensive tests") instead of step 9 ("Story completion and mark for review"), which is the actual completion gate. This was the same class of pre-existing bug fixed in the text (M-1) but missed in the XML action. --------- Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
0533976753 |
fix: installer live version for external modules (#2307)
* resolved merge conflict * fix: addressed PR comments * fix: use git tags for installer module versions |
||
|
|
3d824d4c0f |
feat(installer): channel-based version resolution + interactive channel management (#2305)
* feat(installer): channel-based version resolution for external modules Adds stable/next/pinned channel resolution so external/community modules install at released git tags by default instead of tracking main HEAD. Manifest now records channel, resolved version, and SHA per module for reproducible installs. CLI flags: --channel, --all-stable, --all-next, --next=CODE (repeatable), --pin CODE=TAG (repeatable). Precedence: pin > next > channel > registry default > stable. --yes accepts patch/minor upgrades but refuses majors. Interactive "Ready to install (all stable)?" gate with a per-module picker (stable/next/pin) when declined. Re-install prompts classify tag diffs as patch/minor/major with semver-class-dependent defaults. Legacy version:null manifests get a one-time migration prompt. Custom modules gain an optional @<ref> URL suffix for pinning (https, ssh, /tree/<ref>/subdir forms supported; local paths rejected). Community modules honor --next/--pin overrides with a curator-bypass warning; default path still enforces the approved SHA. Quick-update now reads the manifest's recorded channel per module so pinned installs don't silently roll forward. * feat(installer): interactive channel switch, upgrade refusal, unified docs Builds on the channel-resolution foundation. The installer now lets users flip a module between stable, next, and pinned after install — either interactively via a "Review channel assignments?" gate, or by flag. Quick and modify re-installs classify stable upgrades; under non-interactive flows, patches and minors apply automatically but majors are refused with a pointer to --pin. Fallback behavior for GitHub rate-limit / network failures is now cache- aware: re-installs reuse the recorded ref silently; fresh installs abort with actionable guidance (set GITHUB_TOKEN or use --next/--pin). Bundled modules (core, bmm) warn when targeted by --pin or --next so users aren't left wondering why the flag had no effect. Install summary labels no longer mangle "main" into "vmain"; next-channel entries render as "main @ <short-sha>" instead. Bundled modules are now correctly skipped from all channel prompts and tag-API lookups. Docs consolidated into a single how-to. install-bmad.md now covers the interactive flow, the channel model (stable/next/pinned plus the npm dist-tag axis for core/bmm), the re-install upgrade prompts, the full flag reference, copy-paste recipes, and troubleshooting. The old non-interactive-installation.md is reduced to a redirect stub. * fix(installer): review fixes + unit tests for channel resolution - ui.js: import parseGitHubRepo; fixes ReferenceError in the interactive channel picker's stable-tag pre-resolve path. - community-manager: pinned modules now fetch+checkout the pin tag on cache refresh instead of resetting to origin/HEAD (was silently drifting to main on re-install). - channel-plan: parseChannelOptions returns acceptBypass so --yes auto-confirms the curator-bypass prompt; headless --next/--pin installs of community modules no longer hang. - community-manager: simplify recordedVersion (dead ternary branch). - custom-module-manager: drop "or sha" from the @<ref> comment (git clone --branch rejects raw SHAs); update-path fetches origin <ref> so /tree/<branch>/ URLs work too. - install-bmad.md: rename "Headless / CI installs" to "Headless CI installs" so the stub's #headless-ci-installs anchor resolves. - test/test-installer-channels.js: 83 unit tests for channel-plan and channel-resolver pure modules; wired into npm test as test:channels. * fix(installer): address CodeRabbit review findings - ui.js: skip stable-channel upgrade classification when the user has already declared intent via --pin/--next=/--channel or the review gate. Prevents the decline / major-refused / fetch-error branches from silently overwriting an explicit pin with prev.version. - external-manager.js: short-circuit cloneExternalModule when the requested plan matches an existing in-process resolution and the cache is valid. Avoids redundant resolveChannel() + git fetch on every same-plan lookup in a single install. - installer.js: fall back to CommunityModuleManager.getResolution() when no external resolution exists, so community module result rows carry newChannel/newSha instead of null under --next/--pin. - installer.js: don't label a module as "no change" when its version string is 'main'/'HEAD' — the SHA may have moved and preVersions doesn't track the prior SHA. Show "(refreshed)" instead. - official-modules.js: match versionInfo.version to the manifest's cloneRef || (hasGitClone ? 'main' : version) expression so summary lines report the cloned ref for git-backed custom installs. - install-bmad.md: clarify that sha is only written for git-backed modules and that rerunning the same --modules on another machine does not reproduce stable-channel installs — convert recorded tags into explicit --pin flags for cross-machine reproducibility. |
||
|
|
2395b0e2ed |
fix: bmad tea instal version (#2298)
* fix: bmad tea instal version * fix: addressed review comments |
||
|
|
914c4edd6b |
fix(installer): resolve external-module agents from cache during manifest write (#2295)
External official modules (bmb, cis, gds, tea, wds) are cloned to ~/.bmad/cache/external-modules/<name>/ and never copied into src/modules/, so collectAgentsFromModuleYaml silently skipped them and their agents never reached config.toml. Swap the hardcoded src/modules lookup for a resolveInstalledModuleYaml() helper that also searches the external cache (handling src/, skills/, nested, and root layouts) and warns instead of silently skipping when a module.yaml can't be found. |
||
|
|
16c9976d7e |
docs(vi-vn): sync and update Vietnamese documentation (#2291)
Co-authored-by: miendinh <miendinh@users.noreply.github.com> |
||
|
|
87292cd86a |
feat(skills): wire on_complete into terminal steps; add full customize.toml comments (#2290)
All 16 bare workflow customize.toml files now have the same thorough comment block as the well-documented ones, with skill-specific on_complete descriptions that name the exact terminal step and exit condition. on_complete is now executed at the true end of each workflow's terminal step rather than lazily referenced in SKILL.md: - Linear workflows: ## On Complete block appended to the final step file (create-prd step-12, create-ux-design step-14, create-architecture step-08, generate-project-context step-03, check-implementation-readiness step-06, epics-and-stories step-04, all three research step-06 files, prfaq verdict, document-project both sub-workflow instruction files) - Multi-path workflows: on_complete inline on each true exit path only (edit-prd fires on [S] Summary and [X] Exit, not on [V] Validate or [E] Edit; validate-prd fires on [X] Exit only, not on [R], [E], or [F]) - Inline XML workflows: <action> tag at the close of the final step (correct-course step-6, create-story step-6, retrospective step-12, qa-generate-e2e-tests appended to SKILL.md) |
||
|
|
b63086f22e |
feat(core-skills): add bmad-customize — guided authoring for _bmad/custom overrides (#2289)
* feat(core-skills): add bmad-customize for authoring _bmad/custom overrides A conversational guide skill that helps users author or update TOML overrides in _bmad/custom/ for customizable BMad agents and workflows. Covers per-skill agent and workflow surfaces; central config is out of scope for v1. - SKILL.md: six-step flow (intent, discover, route, compose, team-vs-user, show-confirm-write-verify) with baked-in agent-vs-workflow routing heuristic and a template-swap subroutine - scripts/list_customizable_skills.py: stdlib-only scanner that enumerates customizable skills across standard IDE install paths, reports surface type and override status, PEP 723, 10 unit tests - Reuses _bmad/scripts/resolve_customization.py for post-write verification - Registered in core-skills/module-help.csv with menu code BC * refactor(bmad-customize): apply QA pass (top 3 recommendations) Applies the three highest-payoff themes from the quality analysis: - Labeling + completion contracts: rename ## Purpose to ## Overview, add domain framing (what customization means in BMad, typical user arrival shapes), add an explicit Completion block with testable conditions for "skill run is done" - Hostile-environment robustness: add On-Activation preflight that classifies no-BMad / BMad-without-resolver / full-install states, instruct Step 2 to surface scanner errors[] and scanned_roots on empty results, add resolver-missing fallback to Step 6.4, add a re-enter-Step-4 recovery loop when verify shows the override didn't take effect - Returning-user and iteration experience: add "Audit / iterate" intent class in Step 1, lead discovery with already-overridden skills for that intent, read existing overrides in Step 3 before composing, frame Step 4 as additive-on-top rather than fresh authoring, give Cross-cutting intent an explicit Step 3 branch that walks agent-vs-workflow with the user Resolves 12 of 18 observations from the quality report. Lint clean (scan-path-standards and scan-scripts both 0 findings). Unit tests still 10/10. * refactor(bmad-customize): derive skills root from install location Previously the scanner hardcoded a list of IDE skill directories (.claude/skills, .cursor/skills, .cline/skills, .continue/skills) and scanned them relative to the project root. That was wrong: skills can be installed either project-local or user-global, the IDE determines the convention, and the set of valid locations is open-ended. The scanner now derives its primary skills root from __file__ — the running skill's own install directory is the authoritative location for finding siblings. --skills-root overrides the default; --extra-root (repeatable) adds additional locations for the rare mixed-install case. Changes: - list_customizable_skills.py: remove SKILL_ROOTS constant, add default_skills_root() derived from __file__, rename scan_project to scan_skills(skills_roots, project_root), add --skills-root and --extra-root flags, de-dupe skills when the same name appears in multiple roots (first wins) - SKILL.md: update Step 2 to describe the scanner's derive-from-install behavior and when to use --extra-root; drop the hardcoded IDE path list from Notes - tests: refactor setUp to place skills under a generic skills root (not .claude/skills), add 3 new tests for multiple-roots merge, duplicate-name precedence, and missing-root error reporting * docs(customization): point users at bmad-customize as the guided path Surface the new bmad-customize skill across the three customization docs so users know they don't need to hand-author TOML to benefit from the surface: - customize-bmad.md: prominent tip at the top introducing the skill as the guided authoring helper; updated the "Need to see what's customizable?" troubleshooting tip to recommend the skill first - expand-bmad-for-your-org.md: tip under prereqs noting every recipe can be applied via the skill, with the recipes remaining the reference for what to override - named-agents.md: short paragraph in the customization section and a link entry under the references list Hand-authoring still works the same way; the skill is additive. Central-config overrides are flagged as the current exception. * docs(bmad-customize): steer users at bmad-builder instead of 'forking' * fix(bmad-customize): reword description to pass file-ref validator * refactor(bmad-customize): tighten description and expand module-help entry - SKILL.md description: drop the catch-all 'or asks how to change the behavior of a specific BMad skill' trigger clause that would fire in casual discussion; keep the four explicit phrase triggers. - module-help.csv: rewrite the description so bmad-help has real routing material — names the concrete capabilities (persistent facts, template swaps, activation hooks, menus), the scope routing, and the value prop (no TOML hand-authoring). Matches the 'Use when...' pattern other Core entries use. * fix(module-help): quote bmad-customize description field that contains commas * fix(bmad-customize): address PR #2289 review findings - SKILL.md preflight: load root config from _bmad/config.toml and config.user.toml (not .yaml) — the installer emits TOML; the YAML references would have made the skill silently miss real user config - SKILL.md resolver fallback (Step 6.4): read all three merge layers when present (base / team / user) and describe the merge in base → team → user order; the prior wording could describe the wrong effective merge when the user wrote .user.toml on top of an existing team .toml - SKILL.md: replace bare 'docs/how-to/customize-bmad.md' references (3 locations) with the public docs URL so users installing the skill aren't pointed at a path they don't have locally - list_customizable_skills.py: catch UnicodeDecodeError in read_frontmatter_description so a non-UTF-8 SKILL.md can't abort the whole scan - list_customizable_skills.py: clarify exit-code contract in the module docstring — errors[] is non-fatal by design, exit 2 is reserved for invocation errors - customize-bmad.md: tighten the tip to scope bmad-customize to the per-skill surface; central-config is out of scope v1 - expand-bmad-for-your-org.md: same scoping — Recipes 1-4 can be applied by the skill; Recipe 5 (central config) stays hand-authored * fix(bmad-customize): markdownlint MD034 and validate-file-refs - Wrap the three docs.bmad-method.org references as [text](url) markdown links instead of bare URLs (MD034) - Drop the {project-root}/ prefix on line 41's config.toml references. validate-file-refs strips the template prefix and tries to resolve 'config.toml' as 'src/config.toml'; sibling skills (party-mode, retrospective, advanced-elicitation) all reference '_bmad/config.toml' bare and pass CI — match that pattern. The '(root level under {project-root}, installer-owned)' parenthetical preserves the disambiguation. * refactor(bmad-customize): cut token-wasting prose from SKILL.md Down from 175 lines to 110. Removed: - 'What customization means in BMad' architecture backgrounder — the LLM reads the live customize.toml in Step 3; doesn't need the lore - 'Desired Outcomes' section — retrospective narration of what the 6 steps already instruct - 'Role' section — fluff; the flow itself defines the role - 'Notes' section — sparse-override rule already in Step 4, IDE-path note is commentary, docs link duplicates the out-of-scope section - 'The scanner derives its skills directory from...' and 'returns JSON with...' — commentary the LLM doesn't need; it runs the script and sees the output - 'that file IS the schema' and similar editorial asides throughout - Explanatory clauses like 'silently drifts on every release' and 'trust the user's domain knowledge' Kept everything that's load-bearing: preflight conditionals, intent classification, routing heuristic, merge semantics, template-swap subroutine, team-vs-user defaults, verify fallback and recovery loop, completion conditions, out-of-scope list. |
||
|
|
ffdd9bc69e |
feat(skills): add TOML workflow customization to 17 bmm-skills (#2287)
* feat(skills): add TOML workflow customization to 17 bmm-skills
Flattens each skill's workflow.md into SKILL.md and adds a customize.toml
surface with a 6-step activation block (resolve_customization, prepend,
persistent_facts, config, greet, append). Core-skills and developer
execution skills (dev-story, code-review, sprint-planning, sprint-status,
quick-dev, checkpoint-preview) are intentionally excluded.
Customized: document-project, prfaq, domain/market/technical-research,
create-prd, create-ux-design, edit-prd, validate-prd,
check-implementation-readiness, create-architecture,
create-epics-and-stories, generate-project-context, correct-course,
create-story, qa-generate-e2e-tests, retrospective.
* fix(skills): address PR review findings on workflow customization
- bmad-create-story: drop stale {project_context} variable reference
from step 2 note; content is already loaded via persistent_facts
- research skills (market/domain/technical): derive research_topic_slug
before writing output filename to prevent path injection and invalid
filesystem characters
- bmad-correct-course: reconcile step 1 verify list and HALT with the
"Missing documents" rule — Architecture and UI/UX are optional, HALT
only fires when PRD or Epics are missing
- fix grammar in Micro-file Design bullets across 5 migrated skills
(self contained → self-contained, adhere too 1 file → adhere to one
file at a time)
- docs/how-to/customize-bmad.md: document workflow activation order
and frame the baseline fields as a stable initial pass with targeted
per-workflow customization points coming later
|