Address automated review findings on PR #2482:
- source.mjs: validate URL-derived subdir with safePathInsideRoot so a
../ subdir can't copy out of the shared clone cache; run cleanup() if
the terminal copyDir throws so the temp working dir never leaks.
- install.mjs: reject unknown --channel values (e.g. a 'stabl' typo)
instead of silently treating them as the 'next' default.
- remove.mjs / update.mjs: containment-check manifest/CLI-derived paths
before destructive fs.rm / atomic swap, reusing safePathInsideRoot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The acme-devlog fixture's .mcp.json was swallowed by the global
.gitignore '.mcp.json' rule, so it was never committed. The skill's
install test asserts _bmad/devlog/.mcp.json exists, which passed
locally (file on disk) but failed on CI's clean checkout. Add a
negation for the test-fixtures path and commit the fixture.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* Add configurable parties to bmad-party-mode
Party mode gains a customize.toml config surface and a guided
authoring flow, while the out-of-the-box default room is unchanged.
- customize.toml: party_members (custom personas), party_groups
(named rooms with an optional freeform `scene`), default_party,
and party_mode (auto/session/subagent/agent-team). Universal
hooks wired (activation steps, persistent_facts, on_complete).
- Roster model: collective = installed agents + custom members
(the pool, summonable by name). Default room stays installed-only
so customs never crowd it. Groups curate subsets; open-cast groups
(no members) are cast from the scene on the fly.
- scripts/resolve_party.py: lazy roster resolver (installed-only
default, group menu by name, one group's detail on demand,
alias/override merge) + unit tests.
- references/create-party.md: create/edit parties, distill personas
from data for focus groups, persist ad-hoc casts; writes overrides
via bmad-customize.
- Ships a "Code Review Crew" group (5 adversarial review lenses),
available via --party but absent from the default room.
* Rework party-mode modes + rewrite the docs explainer
Skill:
- How It Runs is now a compact router; one mode active per session,
runtime --mode wins over the customize default, all degrade to session
- Default mode is `session`; `auto`/`subagent`/`agent-team` carved to
references/mode-*.md, loaded only when that mode is active
- Add references/mode-auto.md (spawn-vs-voice rubric), mode-subagent.md,
mode-agent-team.md
- resolve_party.py fallback default auto -> session
- customize.toml: party_mode default session; trim duplicated mode gloss
- Trim restated script-contract prose; collapse "Following the User's Lead";
add scene/persona-binding and web-search rules; offer an HTML keepsake
at wrap-up
Docs:
- Full rewrite of docs/explanation/party-mode.md: the four modes, custom
parties (personas, scenes, shapes), the shipped Code Review Crew as one
example beside the module-based default, launch examples, party ideas,
and the multi-group bonus tip
* Keep party energy up and route the keepsake to a config output dir
- SKILL.md: add "Keep It Feeling Like a Party" guidance so the room stays
fun and engaging and doesn't drift into Q&A or a report
- Keepsake now writes to {workflow.output_dir}; step 2 resolves
{output_folder} and {date}
- customize.toml: add output_dir = {output_folder}/party-mode, overridable
in team/user TOML (matches the bmad-brainstorming output pattern)
Retrospective Step 12 appends agreed action items to a new action_items
section in sprint-status.yaml and updates the previous epic's entries from
the Step 4 follow-through. Sprint-status parses the section, validates its
statuses, and surfaces open items in the summary and data mode.
Sprint-planning preserves the section when regenerating the file.
* bmad-architecture: breadth coverage + lean directives; reviewer reports to subfolder
- Inline forward-readiness (inherit upstream silently; thin input -> suggest bmad-spec or hybrid-capture) and brownfield (ratify, don't re-tell) directives in place of a standalone spine-checklist
- Use {workflow.persistent_facts} instead of hardcoded project-context.md
- Reviewer gate writes per-reviewer reports to reviews/ subfolder so the deliverable folder stays clean
- Require breadth coverage at distill and in the gate rubric: every altitude-owned dimension decided/deferred/open, flagging the operational/environmental envelope a domain-focused draft skips
- Trim repeated directives and human-facing justification prose
* Redesign spine template and move stack pinning to a body table
Rework spine-template.md so it stops forcing fixed structure: guidance
moves into single-line HTML comments (stripped at distill), the always-two
diagrams and empty-mermaid render bugs are gone, and the structural-seed
framing opens up so the operational/environmental envelope isn't skipped.
Stack moves from nested frontmatter into a ## Stack | Name | Version | table.
lint_spine.py drops the frontmatter dep check for find_unpinned_stack, which
parses the Stack table and flags real-name/blank-version rows while skipping
{token} skeletons. Tests reworked to match; 24 passing.
SKILL.md Finalize tightened to act-then-strip template comments and sweep
altitude-owned breadth.
* Harden find_unpinned_stack: blank fences, locate columns, looser heading
Address PR review (CodeRabbit + Augment): find_unpinned_stack scanned raw
body, so pipe-rows or ## headings inside a fenced block could be misread as
live Stack content and misreport version_pin. Now blanks fences first, like
find_placeholders and find_ad_issues, honoring the linter's fences-are-non-live
contract.
Also locate both Name and Version columns from the header (a reordered table
now pairs name to version correctly) and match the heading on a word boundary
(## Stack & Versions still counts). Add regression tests for fenced rows,
fenced headings, renamed heading, and reordered columns (28 passing).
Reword stale 'unpinned deps' / 'unpinned dependency versions' to 'unpinned
Stack versions' to match the body-table model.
* Rework solutioning architecture skill into bmad-architecture (spine)
- Rename canonical skill bmad-tech-plan -> bmad-architecture; output is ARCHITECTURE-SPINE.md
- Convert bmad-create-architecture to a deprecated husk forwarding to bmad-architecture (create intent); strip steps/data/template
- Finalize: spine is the default, then offers fuller renderings + a self-contained HTML view; doc_standards polish applies to prose docs only
- Reviewer Gate: add adversarial divergence-hunter, on by default at high/regulated/cross-team stakes
- Fix references in module-help.csv, bmad-prd, bmad-ux, bmad-agent-architect; reword help entry for when-to-offer
- bmad-spec: flag recognized-but-unaddressed domain implications as open_questions
* bmad-architecture: extract Finalize/reviewer-menu to references, add grade_spine script
- Move the Finalize sequence out of SKILL.md into references/finalize.md
- Make references/validate.md own the canonical reviewer menu and prompts
- Add scripts/grade_spine.py (+ tests) so validation grade is computed
deterministically instead of derived by hand
- Tighten SKILL.md spine/memlog framing
* bmad-architecture: outcome-driven rewrite + spawned reviewer gate
Re-express SKILL.md as goals/outcomes rather than procedure: intent is read
from the input (raw idea, large doc, codebase, feature slice, existing spine)
instead of a Create/Update/Validate x mode matrix. Restore the counter-default
coaching invariants that over-compression had stripped — Guided is the default,
load-bearing calls are shown with alternatives and the user chooses, recommend a
known starter when the stack is open, investigate brownfield before deciding.
Adopt the bmad-prd/product-brief shape: a dedicated Reviewer Gate that always
spawns finalize_reviewers as parallel subagents against the spine (lint floor
first; ad-hoc lenses scaled to rigor/altitude/criticality), and a numbered
Finalize that calls it. Headless runs the full gate non-interactively.
Reframe the structural seed as the living source of truth for shape (code owns
detail; evolve on shape change; memlog keeps history). Fix template mermaid
(C4 -> flowchart, valid one-attr-per-line erDiagram). Ship two default
finalize_reviewers (currency/reality check, adversarial divergence hunter).
Remove grade_spine.py and the inlined discovery/inputs/validate/finalize refs.
* bmad-architecture: review fixes — shared memlog, epic altitude, lint hardening
Pre-PR review fixes for the new architecture-spine skill:
- Adopt the shared canonical memlog (#2462); drop the vendored copy and the
status-flag lifecycle in favor of `event` entries
- Wire epic-altitude inheritance: parent-spine load+bind, Inherited Invariants
template section, epic-scoped run folder, parent-contradiction lens; state
that per-story detail is deferred to bmad-create-story
- Add the Update intent; honor a forwarded-activation handoff from the
deprecated bmad-create-architecture shim
- Rename modes to Coaching path / Fast path (suite-consistent with prd/brief)
and sequence the offer as an activation step
- Fix the brownfield project-context.md default path ({output_folder} no-op)
- lint_spine: line-exact frontmatter, fence-blanking (AD-in-fence + accurate
line numbers), map-form key_deps, AD-0 fix; soften template-token severity;
add 8 tests
- Carve the Reviewer Gate to references/ to stay under the SKILL.md token budget
- Template: entities-only ERD, scale-down guidance, softened seed framing;
gitignore .memlog.md
* bmad-architecture: address PR review (augment + coderabbit)
- REF-03: use canonical "invoke the `skill` skill" language for all cross-skill
references in SKILL.md (was "route to / offer / hand to / Next:")
- lint_spine: scan frontmatter for unfilled template tokens / TBD (paradigm,
scope, date were uncatchable in the body-only pass)
- lint_spine: guard read_text() so a bad-encoding/unreadable spine returns error
JSON and exit 0, honoring the documented contract
- reviewer-gate: resolve the "always run" vs "may skip" ambiguity — the gate
scales/skips by stakes, but finalize_reviewers always run once it does
- tests: +3 (frontmatter token, frontmatter TBD, unreadable spine); use next()
* bmad-architecture: align finalize-reviewers wording + headless blocked output
- customize.toml: reword finalize_reviewers comment to match reviewer-gate.md —
the gate is stakes-gated, but its reviewers always run once it does (coderabbit)
- headless.md: state explicitly that a blocked run omits spine/memlog/companions,
matching the "omit keys for artifacts not produced" contract (coderabbit)
* bmad-architecture: ask deliverable purpose up front, offer presentable renderings, lead next-steps with bmad-spec
* feat: installer detects Python version and warns when 3.11+ (tomllib) is missing
Several BMAD features need Python at runtime: memlog (3.8+) and the TOML
config resolution scripts (3.11+ for stdlib tomllib). Users install into
varied environments (Linux, Windows, WSL, Docker) where Python may be
missing or too old, and previously only found out via runtime errors.
The installer now probes PATH at startup (py -3 / python3 / python) and
classifies the result: 3.11+ passes silently with a success line; 3.8-3.10
or missing/too-old Python gets a warning naming exactly which features
degrade, plus per-platform install hints. The warning requires an explicit
ack — continue (fix later, no reinstall needed) or quit and re-run after
installing Python. Warn-don't-block: most of BMAD works without Python, so
the install is never refused. In --yes mode the warning logs and continues
without prompting.
* fix: align Python check with runtime truth (python3) and harden edge cases
Review fixes for the installer Python check:
- Probe python3 first on all platforms: every runtime call site invokes a
literal python3, so only that command vouches for BMAD features. Python
found via py/python now gets an explicit mismatch warning instead of a
false "all BMAD features supported".
- Treat closed/piped stdin as non-interactive (in addition to --yes) so
scripted installs no longer silently exit 0 via clack's cancel path.
- Retry probes with shell:true on win32 EINVAL (CVE-2024-27980 hardening
rejects .bat/.cmd shims like pyenv-win's without a shell).
- Add Suite 46 branch tests for checkPythonEnvironment with stubbed
detection, prompts, and process.exit.
* fix: remove empty skill-group dirs left in _bmad after install
Skill cleanup removed each skill's own directory but never pruned the
now-empty grouping folders above it (e.g. _bmad/bmm/1-analysis), leaving
empty dirs behind after every install. Walk up from each removed skill
dir and drop empty parents, stopping at the bmad root.
* fix: harden empty-parent pruning boundary and cleanup
Use a path-boundary check instead of a string prefix so sibling dirs
(e.g. _bmad2) can't match the bmad root, and make the walk best-effort
so a dir that vanishes or fills in mid-walk never aborts the install.
Move the test fixture cleanup into finally so failures don't leak temp
dirs.
---------
Co-authored-by: Brian <bmadcode@gmail.com>
* bmad-spec: make the memlog canonical, SPEC.md a derived view
Replace the bespoke .decision-log.md with the shared memlog script
(_bmad/scripts/memlog.py, same location as resolve_customization.py).
The append-only memlog becomes the single source of truth; SPEC.md and
spec-authored companions are re-derived from it (plus cited sources for
raw content) on each run instead of hand-patched. This makes bmad-spec
the sole writer of the spec and lets the surrounding steps (PRD, UX,
architecture, epics) feed one spec in any order without merge drift.
- New "Memory and derivation" section: memlog canonical, SPEC.md a
projection, single-writer rule, append/init via the shared script,
no status field (terminal moments are event entries).
- Operation reads the prior memlog (not the rendered SPEC.md) as the
authority on decisions and capability IDs on update.
- Conflict-surfacing: live sources/companions that disagree on a field
are raised to the user, resolution logged as a new entry.
- Rename .decision-log.md -> .memlog.md across SKILL.md and assets.
* core: add shared canonical memlog.py in src/scripts
Single source-of-truth memlog: append-only, chronological working-memory
log for skills. Installs to _bmad/scripts/memlog.py via the existing
src/scripts sync (beside resolve_customization.py), so any skill can call
it at runtime — bmad-spec is the first consumer.
Merges the neutral API (--workspace, free-form --type/--by, generic set)
with crash-safe fsync atomic writes. No lifecycle status by design: a
memory log records completion as an event entry, never a frontmatter flag.
Also accepts --path for callers that hold the file path directly. 30 tests.
* bmad-spec: include event in memlog --type list
The documented append --type set omitted event while the next line
requires --type event for terminal moments. Align the list.
* Fix memlog Python floor and exclude tests from install
- memlog.py: add 'from __future__ import annotations' so PEP 585/604
hints stay lazy; the script runs on Python 3.8+ instead of crashing
below 3.10. Correct the requires-python header to >=3.8.
- installer.js: filter tests/, __pycache__/, .pytest_cache/, and *.pyc
out of _installSharedScripts so dev-only files never ship to users.
The Blind Hunter subagent intentionally has no tool access, but the
review steps never said how {diff_output} should be delivered. Orchestrators
typically wrote the diff to a temp file and asked the agent to read it,
which silently fails (0 tool calls), and the 10-finding requirement then
pushes the agent to hallucinate findings against code it never saw.
State explicitly that the diff is passed inline in the subagent prompt,
in both bmad-code-review step 2 and bmad-quick-dev step 4.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* docs(fr): translation of install-custom-modules
Reference commit 97d32405
* docs(fr): refinement of forensic-investigation
* docs(fr): translation of customize-bmad TOML customization rewrite
Reference commits 0dbfae67, 4405b817, ffdd9bc6, b63086f2"
* fix(docs): handle non-ASCII anchors in link validator
Anchor validation failed for links containing accented characters
(e.g. ./customize-bmad.md#dépannage) because the raw anchor didn't
match the slugified version produced by extractAnchors.
Normalize anchors through decodeURIComponent + headingToAnchor before
comparing, and guard against malformed URI components.
* docs(fr): translation of install-bmad channel and config rewrite
Reference commits 3d824d4c, 91a57499, 0f852a38
* docs(fr): translation of expand-bmad-for-your-org organizational customization patterns
Reference commits c52c9b5b, b63086f2, 4405b817, 0dbfae67
* docs(fr): update install-custom-modules
Reference commit 231a2036
* docs(fr): consolidate non-interactive installation into unified install-bmad guide
Replace standalone non-interactive-installation.md with a redirect stub
pointing to the Installations CI non interactives section in install-bmad.md.
* docs(fr): translation of named-agents
Reference commits 0dbfae67, 4405b817, b63086f2
* docs(fr): refinement of upgrade-to-v6
* docs(fr): refine agents.md
* docs(fr): refine commands.md
rename bmad-create-prd to bmad-prd and update skill descriptions
* docs(fr): refine workflow-map-diagram
Reference commit c52c9b5b
rename create-prd to prd, create-product-brief to product-brief
add prfaq workflow, update agent labels and output names
refine French wording throughout
* docs(fr): update and refine workflow-map
Reference commits: 380590ac52c9b5
* docs(fr): update and refine getting-started
Reference commits c52c9b5b, 0f852a38
rename bmad-create-prd to bmad-prd, add PRD intents section
update Quick Reference table, refine French wording throughout
* docs(fr): refine index.md
Reference commit 0dbfae67
refine French wording throughout, improve phrasing and table formatting
* docs(fr): apply French typographic conventions across all docs
regex-based pass followed by AI + manual review of all 34 source files
Rules applied:
- Apostrophe: ASCII ' → curly ’ (U+2019) in all French prose
- Guillemets: ASCII "..." → « … » with narrow no-break space (U+202F) on both sides
- Narrow no-break space (U+202F): before ; ? ! and after « / before »
- No-break space (U+00A0): before : in French prose
- Thousands separator: narrow no-break space (U+202F) in 4+ digit numbers
Additional review fixes: remaining ASCII quotes in _STYLE_GUIDE.md
checklist items, testing.md, and party-mode.md numbering.
Preserved exclusions: YAML frontmatter delimiters, code blocks,
backtick inline code, URLs, footnote syntax, and English UI text.
* docs(fr): align sidebar ordering with current English docs
Update sidebar order values across all French explanation and how-to
pages to match the live English documentation structure.
* docs(fr): fix omission in quick-dev from english
* docs(fr): style guide formatting
* docs(fr): use quick-dev wording in workflow-map-diagram-fr
* docs(fr): fix typos
* docs(fr): add bmad-investigate / IN trigger to agent tables
The forensic investigation feature added the IN menu trigger and
bmad-investigate skill, but the French docs that enumerate triggers
and agent capabilities were not updated.
- agents.md: add IN trigger and Enquête de code to Amelia's row
- named-agents.md: add Enquête de code to Amelia's capabilities
* docs(fr): fix agent skill identifiers to use bmad-agent-* prefix
The agent skill identifiers in agents.md and commands.md were missing
the -agent- segment of the namespace (e.g. bmad-pm instead of
bmad-agent-pm). All agent launchers use the bmad-agent-* naming
convention since the installer generates skill directories under that
prefix.
- agents.md: fix bmad-dev, bmad-analyst, bmad-pm, bmad-architect,
bmad-ux-designer, bmad-tech-writer
- commands.md: fix bmad-pm, bmad-architect
* docs(fr): rename bmad-create-ux-design to bmad-ux (#2413)
Apply ee47e30c (refactor(bmad-ux): spine-based UX skill) to French docs.
Rename skill bmad-create-ux-design → bmad-ux and update outputs
from ux-spec.md to DESIGN.md + EXPERIENCE.md.
* docs(fr): translate bmad-spec section
French translation of the bmad-spec section introduced in aa6dece
(feat(bmad-spec): introduce Spec kernel distiller skill (#2417)).
* docs(fr): improve core-tools locution, phrasing and typography
Broader pass across all sections of core-tools.md for more idiomatic
French: consistent section headers (À utiliser quand, Fonctionnement),
natural verb choices, fluid sentence construction and corrected
punctuation.
* docs(fr): apply French typography and table formatting pass
Continuation of 27002100. Systematic pass across all French documentation
assisted by an automated French typography linter:
- Replace regular space with NBSP (U+00A0) before colons per French
typographic convention
- Align table separator rows to match column widths
- Fix thousands separator in install-bmad.md (5000 → 5 000)
- Correct glossary example code block rendering in _STYLE_GUIDE.md
* docs(fr): fix missing french typography on roadmap.mdx
* docs(fr): translate web-bundles explanation and how-to
French translation of:
- docs/explanation/web-bundles.md
- docs/how-to/use-web-bundles.md
Reference commits: 7729ad46, d659a03d, 3bc2ad30
* docs(fr): refresh skill metadata references
Fixes#2437 for French.
- agents.md: update PM triggers CP/VP/EP → PRD, remove stale US trigger
from Technical Writer, align PRD description to create/update/validate
- commands.md: fix Cursor/Windsurf skill paths to .agents/skills/,
update core tools count to 12, align PRD description
- core-tools.md: add missing bmad-customize tool entry and section with
link to customize-bmad how-to
- party-mode.md: replace stale "BMad Master orchestre" with "Le Party
Mode orchestre la discussion"
---------
Co-authored-by: Brian <bmadcode@gmail.com>
Close the remaining capability gaps where the skill's custom-module install was
narrower than the canonical installer (tools/installer/modules/custom-module-manager.js
+ channel-resolver.js). The new-spec install path was already shared code and the
legacy resolver a faithful port, so this targets only the independently-implemented
source/channel/cache plumbing.
- source.mjs parseSource: accept `owner/repo@ref`, and browser-style deep-path
git URLs (tree/blob, GitLab `-/tree`, Gitea `src/branch`, `?path=`), extracting
the embedded ref + repo subdirectory — so a module in a monorepo subfolder
installs directly. URL-based parsing handles Azure DevOps `_git`, nested
groups, and dotted repo names.
- lib/cache.mjs: shared clone cache at ~/.bmad/cache/custom-modules/<host>/<owner>/<repo>/
with .bmad-source.json/.bmad-channel.json metadata, matching the installer
(reuse on matching ref, fetch/refresh otherwise, keep stale copy on fetch
failure). materializeSource copies the module root out of the cache into a
throwaway temp tree so the cache is never mutated.
- lib/channel-resolver.mjs: node:-only port of resolveChannel (stable/next/pinned);
`stable` resolves the latest non-prerelease GitHub tag, falling back to next.
semver-lite gains prerelease/compare/rcompare so it stays registry-free.
- install.mjs/update.mjs: resolve channel+ref before clone; update re-resolves the
channel the module was installed with.
Tests + CI:
- test/test-bmad-module-source.mjs: unit coverage for parseSource, semver-lite, and
channel-resolver, at parity with the installer's test-parse-source-urls.js /
test-installer-channels.js.
- Wire the skill's unit test (test:skill-source) and its end-to-end integration
test (test:skill) into npm test, npm run quality, and the quality.yaml CI job —
the integration test was previously committed but only ever run by hand.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The standalone bmad-module skill only understood the new plugin.json#bmad
spec, so installing a legacy repo (marketplace.json + module.yaml, e.g.
bmad-code-org/bmad-module-game-dev-studio) failed with exit 20. Legacy
support existed only in the full installer's PluginResolver, which the
skill can't import (it ships self-contained under .claude/skills/).
Port that resolver into lib/legacy-resolver.mjs (strategies 1-5): when a
repo has no plugin.json#bmad but has a marketplace.json, resolve it into a
synthetic manifest of the same shape readAndValidateManifest produces, then
run it through the existing buildCopyPlan -> rewrite -> stage -> swap
pipeline unchanged. buildCopyPlan already copies marketplace.json verbatim,
flattens arbitrary skill paths to skills/<basename>, and flattens
moduleDefinition/moduleHelpCsv, so almost no downstream change is needed.
- plugin-json.mjs: extract validateManifestObject(m, {allowReserved}) and
add hasBmadPluginJson(dir). Legacy installs pass allowReserved:true so
first-party codes (gds, bmm, ...) install; new-spec authors still get
exit 21.
- install.mjs: detect new-spec -> legacy -> neither in §3; write
synthesized module.yaml/module-help.csv into the temp clone for the
strategy-5 fallback.
- cli.mjs: add --module <code> to disambiguate a multi-module marketplace
(otherwise exit 20 lists the available codes).
- help-catalog.mjs: export MODULE_HELP_CSV_HEADER for the synthesizer.
- tests: legacy fixtures (strategy-1, reserved code, synthesize fallback)
+ integration assertions. SKILL.md/README updated.
Verified: full install of the real game-dev-studio repo resolves gds and
lands 250 files under _bmad/gds/. Integration suite 97/0, installer
component tests 374/0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Remove EXIT.FILE_OVERLAP (40): never thrown anywhere; its docs
described code 70 (path traversal). Dropped from exit.mjs and the
cli.mjs --help listing.
- Document --channel on the update verb (already wired through the
scripts for both install and update).
- Trim the SKILL.md exit-code table to the codes that change what the
agent tells the user (5, 10, 80, 90); defer the full list to the
script's --help, removing the triplicated/drifting table.
- Lightly tighten the intro and script-path prose loaded on every
skill activation; no behavioral change.
Integration suite 73 pass / 0 fail; validate:refs clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the ancestor walk added in the previous commit finds more than one
module.yaml + module-help.csv pair between the skills' common parent and
the repo root, the deepest one was chosen silently. That could surprise a
user whose repo legitimately carries module definitions at multiple levels.
PluginResolver.resolve now accepts an optional chooseModuleDefinition
callback. When >1 candidate is found it is invoked with each candidate
enriched with its relativePath + module.yaml code/name/description, and its
selection wins. Headless callers (the --custom-source CLI flow, tests,
re-resolution lookups) omit the callback and keep the deterministic
deepest-first default, so nothing blocks. The interactive custom-module
flow supplies a prompt, pausing/resuming its spinner around the choice.
Threads options through CustomModuleManager.resolvePlugin and wires the
prompt into both resolve sites of _addCustomUrlModules. Adds tests for the
deepest-first default, candidate enrichment, and chooser override.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PluginResolver strategy 1 only checked the skills' common parent for
module.yaml + module-help.csv. For the canonical BMad layout (module
files at src/, skills under src/skills/<name>/) the common parent is
src/skills, so the files were missed and the resolver fell through to
strategy 5 — synthesizing a degenerate module named after the marketplace
plugin (e.g. bmad-creative-intelligence-suite) and discarding the real
`code` (cis) and `agents:` roster. That mismatch then made
resolveInstalledModuleYaml fail, emitting the collectAgentsFromModuleYaml
and writeCentralConfig "could not locate module.yaml" warnings.
Strategy 1 now walks up from the skills' common parent to the repo root
(bounded, deepest-first) and uses the first directory with both files, so
src/module.yaml resolves correctly. Also match on `pluginName` in
resolveInstalledModuleYaml's resolution-cache fallback so a module tracked
under its marketplace plugin name still resolves. Adds a regression test
mirroring the bmad-creative-intelligence-suite layout.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Initial draft: brainstorming improved
* bmad-brainstorming: apply quality-analysis fixes
- Add ## Overview heading (prose was already present)
- Fix resume scan to glob output_dir/*/session.md (per-session subfolders);
handle multiple in-progress sessions
- Anchor brain_methods to {skill-root} and always pass --file to brain.py
(--file before subcommand); drop the unreliable conditional
- Log decisions, dismissed E3 false positive, verified tests (15 passed)
* bmad-brainstorming: memlog session memory + facilitation refinements
Replace the running-log concept with a generic, append-only memlog
(scripts/memlog.py): a flat, chronological, write-only session memory any
skill can reuse. Entries land at the end in the order they happen; --type
tags the kind (idea/insight/question/decision/technique); nothing is
grouped, reordered, or rewritten. The file is .memlog.md, read only on resume.
- scripts/memlog.py (init/append/set) + test_memlog.py (20 tests)
- SKILL.md: reordered into framing + flow; lean Memlog framing; batch
technique model (Facilitator Chosen / Browse / Category / Inventive Flow);
Progressive removed; facilitation stance preserved
- references/finalize.md: two-move synthesis + opt-in artifacts, each derived
from the memlog via subagent
- references/headless.md, customize.toml: memlog wiring + per-topic folders
* bmad-brainstorming: gate technique-flow choice and stop full-catalog dumps
- brain.py: `list` now requires --category or --all; a bare `list` is refused so the full ~100-technique catalog can no longer flood context. --all is the deliberate full-dump escape hatch.
- SKILL.md: technique-flow selection is now a hard gate (present the four ways, wait for the user's pick) instead of a soft default that got skipped; Stance "no multiple-choice" rule scoped to generation, with an explicit carve-out for that one process menu.
- headless.md: use `list --all` deliberately, passing --file.
- customize.toml: fix stale "progressive flows" wording to match the four real flows.
- test_brain.py: regression tests for the list guard (bare refused, --all dumps all).
* bmad-brainstorming: remove .decision-log.md build-time artifact
The workflow-builder writes .decision-log.md to track its own build session; it is a build-time artifact, not part of the shipped skill, so it should not be committed to the project.
* bmad-brainstorming: facilitation modes, attributed memlog, and the selection composer
- Three facilitation modes chosen up front (Facilitator / Creative Partner / Ideate for me), each a loaded frame; SKILL.md routes mode + technique selection primarily through the selection page, with the in-chat menus as fallback.
- memlog: optional --by user|coach attribution (required in Creative Partner) so authorship stays visible in the log.
- brain.py: generates a self-contained "browse all" selection page (brain-selector.html) - a session composer with facilitation mode, a hand-picked + Random + Invent + AI-picks technique strategy, category toggle-chips and a category-aware filter, and a copy-to-clipboard prompt with a paste-back banner. Category-tinted cards, 13 crafted category icons, and a hand-assigned icon for each of the 100 techniques. `html` writes to a file (never dumps the catalog into context); a snapshot test keeps the shipped page in sync with the CSV.
- Drop the now-unused Six Thinking Hats detail file; the catalog needs no detail files.
- finalize.md: synthesis is mode-aware and the "hand them the mirror" step reads the by-attribution tags.
* bmad-brainstorming: fix code-review findings
memlog.py
- Parse frontmatter by the first line that is exactly `---`, so a `---` inside a
topic/goal value no longer truncates the block, drops `status`, and breaks resume
forever. Neutralize newlines in field values on render too.
brain.py (selector page + CLI)
- Composer: category toggles now define session scope; the text filter is a pure
browse aid. checked() and the random pool both key off scope (offCats), so hidden
cards are never silently copied and a stray filter term can't starve a random draw.
- Clipboard: only show the "Copied!" banner when the copy actually succeeds; on
failure show a warning and a prefilled prompt() so the text is never lost.
- category_style: fall back to the neutral glyph instead of KeyError if the hue/glyph
dicts ever desync.
- random: clamp -n so a negative/oversized value returns cleanly instead of crashing.
- --extra: merge a JSON overlay of additional_techniques into every command, so the
browse page and category draws include custom techniques/categories as advertised.
docs
- SKILL.md: fix dangling `## Choosing Your Mode` anchor and the "Copy selection"
button label; document --extra in the regen instructions.
- mode-autonomous.md: persist the mode flip when handing off from autonomous, so a
resume restores the new stance.
- finalize.md: grammar/typo fixes (CodeRabbit).
tests
- Regression tests for the memlog `---` fix, --extra merge, negative -n, and the
category fallback; regenerated the snapshot-tested selection page. Renamed the
shadowing `type`/`l` locals flagged by CodeRabbit. 52 passing.
* bmad-brainstorming: composer header polish + dark mode
- Center header content (.hwrap) so it aligns with the card column on wide screens.
- Replace the text filter with jump-nav: category chips smooth-scroll to their
section (offset for the sticky header); drop the category exclude-toggle, so
Random/AI draw from the whole catalog.
- Fix narrow-screen crowding between the chips and the Copy prompt button.
- Move Copy prompt to the end of the Techniques row, anchored to the Total readout.
- Add a per-mode hint line that explains the selected facilitation stance.
- Dark mode: refactor all colors to CSS variables + a dark palette, with a header
toggle (☾/☀) that defaults to system preference and persists in localStorage; an
inline head script applies the theme before first paint to avoid a flash. Category
hues are lifted toward white on dark surfaces to stay legible.
Regenerated the snapshot-tested selection page; SKILL.md wording updated (chips are
jump-nav, not a filter). 52 Python tests passing.
* bmad-brainstorming: condense SKILL.md, extract resume + in-chat technique frames
- Rewrite SKILL.md: consolidate framing, merge session setup into Run a
Session, descriptive (non-imperative) Overview true across all 3 stances
(~2,790 -> ~2,070 tokens)
- Extract Resuming to references/resume.md (loads only on resume)
- Extract in-chat technique selection to references/in-chat-techniques.md
(loads only when the composer page is declined)
- Add HTML-open recovery guidance to the composer-page step
- Ideate-for-me now auto-produces the HTML keepsake (finalize.md +
mode-autonomous.md) instead of asking first
* Enhance bmad-brainstorming: goal facet, proven grouping, convergence, icon sidecar
Catalog (brain-methods.csv -> 108 methods):
- Add provenance / good_for / audience columns (additive, backward-compatible)
- Add 8 researched classic methods: How Might We, Job to Be Done, Empathy Map,
Backcasting, TRIZ Contradiction, Fishbone Diagram, Build on What Works, Scenario Cross
Selector page (brain.py generator):
- "Proven & Professional" lead group (29 named methods, cross-category)
- Super-group ordering (Structured/Creative/Wild/Introspective) replacing alphabetical
- "Great for" goal filter driven by good_for tags
- Per-category "Invent a ... technique" cards reusing the invent flow
Convergence:
- New references/converge.md (diverge -> converge -> finalize); wired into SKILL.md
Maintainability:
- Extract category + technique icons to assets/brain-icons.json; brain.py loads the
sidecar, with logic and fallbacks staying in code (8 new icons added, full coverage)
Docs:
- Add analysis/ (catalog-analysis.md + method-matrix.csv): the 4-axis review behind these changes
All 52 tests pass.
This work was developed in a separate bmad-marketplace repo and is now
landing directly in BMAD-METHOD, so the migration framing is obsolete:
- remove links to docs/spec.md (only existed in the temp repo) and the
bmad-marketplace / 'upstream patch' / 'sibling checkout' references in
README, the integration test, and the acme-md-lint fixture
- drop dead 'spec §N' pointers in install.mjs, install-plan.mjs, and
plugin-json.mjs (including a user-facing reserved-code error message)
- reword the manifest-generator 'patch' note as in-repo behavior
- correct the documented install path from _bmad/ to the IDE skills
directories the installer now distributes skills to (.claude/skills/, etc.)
No behavior change. Integration suite: 73 pass / 0 fail.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Step 4 pointed at _bmad/core/skills/bmad-module/, but the new module
system distributes skills verbatim into the selected IDE directories
(.claude/skills/, .agents/skills/, etc.). Resolve the script relative
to SKILL.md instead, and route the missing-script case to the existing
exit-code-5 reinstall guidance.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add Strategy 0 to PluginResolver: detect a .claude-plugin/plugin.json
carrying a bmad{} block at the module root and resolve+validate it via
the bmad-module skill's own libs (new bmad-module-lib bridge), so the
installer and runtime skill agree on what a module is. Every resolved
module now carries a format discriminator ('plugin-json' | 'legacy').
OfficialModules routes 'plugin-json' resolutions through a new
_installFromPluginJson path that reuses the skill's copy-plan/flatten/
rewrite/atomic-swap libs, producing an on-disk layout byte-identical to
a bmad-module install while leaving legacy installs untouched. Direct
mode in ui.js prefers a root plugin.json#bmad manifest over SKILL.md
scanning. Adds Test Suite 45 covering detection, legacy fall-through,
and end-to-end install.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The skill validator walks all of src/ recursively, so the bmad-module skill's
reference and negative example modules under tests/fixtures/ (intentionally
non-bmad-* names and deliberately-malformed fixtures) were validated as
production skills and tripped HIGH SKILL-04 name-format findings, failing
`validate:skills --strict`.
Exclude a `fixtures/` directory whose parent is `tests/` from discovery so the
validator judges only real skills. No production skill lives under tests/fixtures/.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The bmad-module skill copied a module's files and distributed skills to IDEs,
but skipped four post-copy steps the full `bmad install --custom-source` path
performs, leaving modules incompletely installed:
- Merge each module's module-help.csv into _bmad/_config/bmad-help.csv (the
catalog bmad-help reads) — new lib/help-catalog.mjs
- Generate [modules.<code>] / [agents.<code>] blocks in config.toml /
config.user.toml from module.yaml (defaults + --set overrides), via a
targeted merge that preserves [core] and sibling modules — new lib/config-gen.mjs
- Create the working directories a module declares under `directories:`
(with move-on-path-change and wds_folders) — new lib/module-dirs.mjs
- Run `npm install --omit=dev` in place when a module ships package.json
(opt out via bmad.install.skipNpm) — new lib/npm-deps.mjs
All four run as a shared finishModuleInstall step wired into install, update,
and remove; every step is non-fatal so a module already committed to _bmad/
isn't lost to a post-copy hiccup. Adds a repeatable --set <code>.<key>=<value>
flag mirroring the installer.
Also fixes two latent issues in the manifest-driven copy that the new steps
depend on:
- moduleDefinition / moduleHelpCsv are now flattened to the module root even
when they live inside a declared skill dir (the setup-skill assets pattern);
previously claimedSrc dedup skipped them and the rewritten plugin.json
pointed at a non-existent ./module.yaml.
- package.json / package-lock.json are now copied so npm deps can install.
Tests: extends the integration suite with config/agent-roster, --set,
directory-creation, help-catalog, removal-cleanup, and npm assertions
(73/73 pass); adds a minimal-npm fixture and rewrites the comprehensive
fixture's module-help.csv to the canonical schema.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reframes the party-mode skill around outcomes instead of a rigid
subagent script, addressing issue #2280.
- Voicing the room is the default; subagents become opt-in (--subagents)
for rounds that genuinely need independent thinking.
- Removes the lossy 400-word context cap and the 'Do NOT use tools'
constraint that drove subagents to fabricate on grounded questions.
- Adds a 'What Good Feels Like' bar: short in-character turns, real
drama over consensus, brevity by default.
- Adds orchestrator weaving so independently-produced turns read as one
conversation without altering what any persona actually argued.
- Slims SKILL.md from 128 to 75 lines.
The bmad-module skill staged community modules under _bmad/<code>/ but never
pushed their skills out to the coding assistants the user selected at
`bmad install` time, so a freshly installed module was invisible to Claude
Code / Cursor / Copilot / etc. until a full reinstall; remove left skills
orphaned in the IDE dirs.
install/update/remove now distribute (or prune) skills to every IDE listed in
_bmad/_config/manifest.yaml and clean the redundant skill dirs from _bmad/,
matching how official modules end up.
Single engine, three callers — no fork:
- New tools/installer/core/ide-sync.js (syncIdes) wraps the real
IdeManager.setupBatch + platform-codes engine. The full installer
(_setupIdes/_cleanupSkillDirs), the new `bmad ide-sync` command, and the
skill all route through it, so new IDEs and engine changes propagate
everywhere automatically.
Local, dependency-free delivery — no npx/network at runtime:
- build-ide-sync.mjs esbuild-bundles the engine into vendor/ide-sync.mjs
(+ platform-codes.yaml), aliasing ../prompts and ../project-root to small
shims so @clack and the installer graph are dropped. The bundle ships inside
the skill tree (like yaml.mjs); the skill execs it locally. It's
generated-from-source and gated by vendor:check, refreshed on every install.
update/remove pass --prune with the module's canonicalIds so skills dropped
between versions (or on uninstall) are removed from IDE dirs + command
pointers. Graceful degradation: if the bundle is unreachable, the verb still
succeeds and points the user at `bmad ide-sync`.
Tests: new test/test-ide-sync.js drift-guard (engine == bundle, incl. prune),
integration.test.sh IDE-distribution section (offline), bundle self-check in
the build. All gates green (vendor:check, lint, format, test:install 349/349).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Formatting-only; no content changes. Brings both docs in line with the
repo's prettier config (a leftover from the .js→.mjs migration).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The suite resolved its reference modules from `<repo>/examples`, which
existed only in the sibling bmad-marketplace checkout — so after the
skill moved into BMAD-METHOD core every install/list/remove assertion
failed with "local source not a directory".
Vendor the two reference modules (acme-md-lint, acme-devlog) under
tests/fixtures/examples/ and point EXAMPLES there; drop the now-unused
REPO_DIR. Also correct the comprehensive-install assertion: hooks are
flattened to the canonical root slot (hooks.json), matching .mcp.json
and rewriteManifestPaths — not a hooks/ subdir.
Suite now passes 41/41.
Note: these fixtures are copies of the bmad-marketplace examples and
must be re-synced if those reference modules change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The copy planner treated every skills/agents/commands entry as a
directory and ran it through addDirRecursive, which lists files *under*
the path. For a subagent declared as a file (e.g.
`"agents": ["./agents/foo.md"]` — a standard Claude-Code shape) that
listed nothing, so the agent was silently dropped from the install even
though rewriteManifestPaths already remapped it to `./agents/foo.md`.
Stat each entry and branch: directories recurse as before, files are
queued directly (honoring the ignore matcher). Verified by the
comprehensive fixture's changelog-archivist.md agent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The bmad-module skill installed but was absent from the core help
registry, so it never surfaced in the bmad-help menu (every other core
skill has a row). Add it as menu-code MM ("Manage Modules").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the flat copy-list staging with a manifest-driven copy plan:
- buildCopyPlan maps declared skills/agents/commands and string-typed
Claude-Code surfaces into canonical install slots, copies conventional
top-level metadata, and drops anything not covered (no more leaking of
tools/, website/, .github/, etc.).
- rewriteManifestPaths emits a plugin.json whose paths point at the
canonical post-install locations, keeping the on-disk manifest
self-consistent inside _bmad/<code>/.
- stageCopyPlan stages the plan plus synthesized files (rewritten
plugin.json) into the tmp dir for the atomic swap.
install.mjs and update.mjs switch to the new plan/skillDestDirs flow and
drop the now-unused copy-list helpers.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
With shallow clones (--depth 1), `origin/HEAD` becomes stale after the
initial clone. The update path used `git reset --hard origin/HEAD` which
never picked up new commits pushed to the default branch.
Resolve the default branch name via `git symbolic-ref refs/remotes/origin/HEAD`,
then fetch and reset against `origin/<branch>` explicitly. Falls back to
`main` if origin/HEAD is not set.
Co-authored-by: Brian <bmadcode@gmail.com>
loadExistingConfig only read from legacy _bmad/<module>/config.yaml files, but
the installer writes user-scoped answers (user_name, communication_language, etc.)
to _bmad/config.user.toml. On every subsequent reinstall those values were not
loaded back, so the user got re-prompted instead of seeing their prior answers as
defaults.
Adds parseCentralToml — a lightweight line scanner matching the installer's own
TOML output format — and updates loadExistingConfig to read config.toml and
config.user.toml first (merging both into the same section buckets). Legacy
per-module config.yaml files are kept as a fallback for pre-v6 installations.
Co-authored-by: RobertOcsko <robert.ocsko@;seon.io>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Brian <bmadcode@gmail.com>