mirror of
https://github.com/bmad-code-org/BMAD-METHOD.git
synced 2026-08-29 03:44:18 +08:00
docs/start-sidebar
687 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
7d68d38222 | docs: add Start documentation section | ||
|
|
825099b2cb |
fix(installer): ask about deprecated shims during Quick Update, and report the outcome (#2746)
* feat(installer): ask about shims during Quick Update Quick Update returned before the shim prompt, so anyone who only ever runs it carried their compatibility shims forward release after release without once being offered the chance to drop them. Quick Update now asks, defaulting to keeping the shims so pressing enter never removes a skill in active use. It stays quiet for an installation that already dropped its shims rather than re-asking every update. The prompt carries the recommendation to remove them and names the one case that justifies keeping them: a customized shim not yet migrated. Whenever an install retains shims, it now lists every one of them and what it forwards to. That notice is emitted where the policy is resolved rather than at the prompt, so it also reaches the paths that never prompt: --yes, --shims, and scripted quick updates. * fix(installer): never prompt for shims without a TTY, and report removal Two gaps in the Quick Update shim prompt. The prompt could be reached by a scripted run. `--action quick-update` is a documented scripting flag and is not tied to `--yes`, so a headless invocation on an install that still had shims fell through to a confirm. clack's confirm never resolves without a TTY: the process drained its event loop and exited silently, mid-install, with status 0. It now keeps the standing answer whenever stdin is not a TTY, leaving --shims and --no-shims as the way to change it from a script. Removing shims was also completely silent. Source filtering just skips the directories, and the IDE cleanup that deletes the stale skill dirs suppresses its logging on purpose, so nothing anywhere told the user that a skill they may still invoke had just gone. Any run that removes shims now lists them and says how to put them back, mirroring the retained notice. Between the two, every run that has shims either way reports which way it went, on interactive and headless paths alike. * feat(installer): carry the shim outcome into the final summary Both shim notices print before the install tasks start, so a long run buries them well above the fold. The summary box already repeats the uv warning for exactly this reason; the shim outcome now rides along the same way, as a single line next to the preserved/backed-up file counts. Retained reads "Deprecated shim skills retained: N (re-run to remove them)" in yellow, removed reads "Deprecated shim skills removed: N" in green, and an install with no shims either way adds no line at all. * fix(installer): say what an empty module selection installs The official module picker allows an empty selection on purpose: core is always installed and is not a row in the list, so selecting nothing is a valid core-only install. The prompt did not say so, and collapsed to a bare "0 items selected", which reads as though the install is about to do nothing. autocompleteMultiselect takes an optional emptyLabel, shown while selecting as "Nothing selected: installs core only" and on submit as "0 items selected (core only)". Pickers that pass no emptyLabel are unchanged. Also fixes the count to say "1 item" rather than "1 items". * refactor(installer): trim explanatory comments to what the code cannot say Cuts 35 comment lines added across this branch down to seven, keeping only the non-obvious constraints: clack's confirm hanging without a TTY, core not being a row in the module picker, and why the shim notices are emitted where they are. * fix(installer): report shims removed after they are retired from source Removal reporting was derived from the shims the incoming release ships, so a shim retired from source fell out of the report entirely: it was absent from discovery, yet the update cleanup still deleted its installed target using the previous manifest. The v7 cut is exactly that case, and it would have removed every shim in silence. Removal is now derived from what is installed, read back from skill-manifest.csv, and the retained/removed split moves into selectShimOutcome. This also covers the mixed run where one shim is retired while the rest stay enabled: both notices fire, and the summary carries both counts. The recovery line no longer offers --shims when the release cannot reinstall them. Raised by greptile and coderabbit on #2746. |
||
|
|
c96b7d1db2 |
feat(installer): add Grok as a tool target (#2732)
Install Grok skills to .agents/skills and ~/.grok/skills, matching the shared agents-skills path used by most CLIs. |
||
|
|
db7f96dd93 | feat(installer): make compatibility shims optional (#2728) | ||
|
|
401814f2de |
fix(installer): stop copying __pycache__ into IDE skill trees (#2695)
Fixes #2694. |
||
|
|
eeb6ad9cf4 |
feat: add ZCode as supported installer platform (#2613)
* feat: add ZCode as supported installer platform ZCode keeps a private skills tree (workspace `.zcode/skills`, global `~/.zcode/skills`) distinct from the cross-tool `.agents/skills` standard, so it needs its own platform entry. The installer is config-driven from platform-codes.yaml, so adding the platform is a config-only change — no new handler code. Follows the same pattern as the Antigravity CLI (AGY) addition (#2551): one platform-codes.yaml entry plus a Test Suite asserting the config and a real IdeManager.setup('zcode') install into a temp project. * test(installer): harden ZCode test cleanup with try/finally Move temp directory cleanup into a finally block with nullable guards so fixtures are removed even when setup throws mid-flight. Aligns Test Suite 6c with the existing pattern in Suite 28 (Pi) and Suite 32 (Ona). Addresses CodeRabbit review comment on PR #2613. --------- Co-authored-by: mindcarver <mindcarver@users.noreply.github.com> Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
ade7a966e9 |
fix(installer,skills): make uv a real requirement and stop assuming a system Python (#2704)
The installer told users uv was optional while bmad-build had already made it mandatory. uv-check.js called it "becoming the de facto standard", install-messages.yaml led with HEADS UP, and installer.js printed a Tip inside a box titled "BMAD is ready to use!" — while bmad-build and bmad-build-auto HALT on activation without `uv run`. The probe's result was discarded (`await checkUvEnvironment();`), so nothing branched on it. Messaging now names the consequence, and the post-install summary repeats the warning when it applies — the pre-install probe fires before every prompt, so by then it is far up the scrollback. Still warn-don't-block: core-only, docs-only, and CI installs never render a skill, so a missing uv must not fail the run. Adds a python3 probe used only when uv is absent, since that is the only case where the interpreter on PATH matters. It reports whether the direct-interpreter skills still work (3.11+) or nothing Python-backed will (below 3.11, or no python3 at all). Separately, 25 call sites still ran resolve_customization.py under a bare `python3`. That script requires 3.11+ for tomllib, so on macOS without Homebrew or Ubuntu 22.04 they fell through to their "if the script fails" path and hand-merged the TOML in-context — no error surfaced. All 25 now use `uv run`, which provisions a matching interpreter from the script's own requires-python. Four more spawned Python purely to open an HTML file: python3 -c "import webbrowser, pathlib; webbrowser.open(...)" Replaced with the platform opener bmad-brainstorming already uses — open / xdg-open / start. src/ now contains no bare Python invocation at all, so "Python 3.11+" leaves the user contract: uv provisions its own. docs/how-to/customize-bmad.md described a transition that this ends. Test suite 46 grows from 12 to 29 assertions: Python parsing, the 3.11 boundary in both directions, that uv-present skips the python3 probe, and all three missing-uv sub-branches. |
||
|
|
47bab7d15c |
refactor(project-context): conversational skill, no script, AGENTS.md block (#2698)
* feat(project-context): rewrite as prescriptive AGENTS.md generator Replace the kernel+bundle context system with a single product: a short verified agent guide (AGENTS.md). A field trial of the first version showed repo scanning produces polished-but-useless factoids; the rewrite fills a fixed section plan from ranked evidence channels (executable config and CI, targeted git history, session logs, human interview) and uses the repository only to verify claims, never as the source of knowledge. - Intents: bootstrap, refresh, record (capture an observed agent mistake), audit; query is gone with the bundle - Per-fact entry files, trust frontmatter, index, placement machinery, and the skill's context.py mechanics script are removed; accountability moves to one plain ledger file recording every candidate claim and its disposition - Skill directory only; docs, forwarding husks, and shared scripts untouched * refactor(project-context): per-section admission rules, two-tier guide Revisions from two end-to-end trials plus review: - Replace the global non-derivable test with per-section admission rules: brevity (orientation), authority (policy), universal need verified by execution (commands, verification), wrong-default-assumption (conventions), localization value (pointers), observed failure only (pitfalls) - Two-tier output: AGENTS.md (orientation + policy + pointer) for every session, AGENTS-dev.md for coding sessions; single file when tiny - Pitfalls can never be nominated by scans: sources are recorded lessons, maintainer recall, session evidence, and the writing session's own caught mistakes; retirement only when the guarded thing is gone or the human says so, since a working rule erases its own evidence - Interview ergonomics: recall questions, never review lists; testimony the repo contradicts is surfaced with evidence, never written or dropped - Trial-driven fixes: guide-to-filesystem link check, mutating-command go-ahead as the interview's first question, plain-English rewrite throughout * fix(project-context): bidirectional coverage trace, history-evidenced pitfalls Round-3 trial findings: an unsourced pitfall entered the guide at composition time because coverage only checked ledger-to-guide; and repeat-fix git history, the strongest pitfall evidence observed, was not an explicitly admitted source. * refactor(project-context): move Where-things-are to AGENTS.md, imperative lines Where-things-are pointers serve planning sessions as much as coding ones, so they belong in the always-loaded file. Shape rules now require every line to state an action (bare facts only as justification clauses) and stable contract headings across runs. * docs(project-context): session-kind guides as a third structural axis A maintainer-named frequent session kind (UX, manual testing, data work) may earn its own AGENTS-<kind>.md behind a pointer; module-level differences stay with scoped guides. * refactor(project-context): action-gated dev-guide pointer, two-file example The AGENTS-dev.md hop is the most common progressive-discovery trigger, so it is now gated on the first hands-on action rather than session self-classification, names its payoff, and names the exemption. The contract's worked example shows the two-file form with the pointer in situ. Scoped-guide discovery no longer assumes harness nearest-file loading: the root-guide pointer is the mechanism. * refactor(project-context): adopt shared memlog, drop unearned claims The run record is now a standard memlog kept with the shared memlog.py script — append-only typed entries, latest entry wins — replacing the bespoke ledger format; stale-disposition notes become structurally impossible. Two appeal-to-measurement assertions cut: the operative admission and exclusion rules carry that load. * docs(project-context): guard handwritten guides The skill never commits — its output stays as working-tree changes for the user. Headless runs never rewrite a guide the memlog doesn't record writing; they leave an AGENTS.md.proposed for an interactive merge. * docs(project-context): fold in prior-art research findings Five adoptions from the generator prior-art survey: prohibitions name their permitted alternative; an emphasis-marker budget; a git-log --diff-filter=DR drift check on refresh; TODO placeholders over guessed greenfield commands; commit and branch conventions mined from history. * docs(project-context): route candidates to enforcement before prose Compose now asks, per accepted candidate, whether a hook, lint rule, or CI check enforces it better than a guide line; the line is the fallback and a landed check deletes it. * docs(project-context): narrow refresh interview and contradiction flagging Refresh interviews shrink to one recall question — what changed since the last run. Cross-file contradictions are flagged only when they change behavior; rewording and overlap are not contradictions. * refactor(project-context): conversational skill, no script, AGENTS.md block Refine the skill into an implementation-layer capability: a conversation that produces one small verified block inside the repo's AGENTS.md. The human is in the loop for every write; there is no autonomous mode. - Drop src/scripts/context.py and its tests. Nothing it did is needed once the output is a single spliced block rather than a bundle of files. - Replace guide-contract.md and evidence.md with best-practices.md (admission, exclusion, retirement, retrieval, maintenance) and template.md (section list plus a worked example, no placeholders). - Collapse the two-file AGENTS.md/AGENTS-dev.md split into one block. A pointer the agent must choose to follow gets skipped; anything load-bearing goes in the always-loaded file. - Replace per-section admission rules with one test: anything derivable from source is read live, never stored. Commands stated in package.json, a Makefile, or CI config no longer earn a line; their caveats do. - Ask up front whether a run covers the root only or named sub-projects, gated on observable evidence (a workspace manifest, per-directory build manifests). - Husk bmad-document-project and bmad-generate-project-context onto setup intent, and say plainly that the deeper system-explanation altitude is a separate capability rather than shipping a thin substitute. - Align module-help.csv, bmad-correct-course, the analyst menu, and the docs set with the block as the output. --------- Co-authored-by: Alex Verkhovsky <alexey.verkhovsky@gmail.com> |
||
|
|
5247108ba3 |
fix(installer): plain-text directory prompt, retire WDS, position on AiDD (#2680)
* fix(installer): submit the path shown and retire WDS from the picker Directory prompt The installation-directory prompt was a clack AutocompletePrompt whose render() drew only the text line. The candidate list existed but was never shown, and Enter returns the focused option rather than the typed text. Focus was sticky: it only reset when the previously focused value left the list, so a subdirectory selected while narrowing survived deleting back to the parent. Typing /path/to/workspace could install to /path/to/workspace/some-child with no sign of it on screen. Rebuilt on TextPrompt so the input line is the value: - the candidate list is visible, windowed, with an active-row marker - arrow keys and Tab write the highlighted candidate onto the input line - the list is frozen against the last typed text while browsing, so arrows walk siblings instead of descending (this also unsticks Tab cycling) - index -1 is the typed text, so backing out of the list restores it - Tab completes to real directories only, skipping "Create/use:" entries - directory() takes optional input/output streams so it is testable Module registry - WDS is marked deprecated: hidden from the picker unless already installed, shown with a notice when it is, never removed and still resolvable from its source so existing installs keep updating - deprecation notices now reach the CLI paths (--modules, --yes) and quick-update, which never render the picker's option hints - picker order is now bmm, bmb, cis, tea, bmad-loop, gds - the core row is hidden; it was a locked always-on checkbox. core is still added to the result, and the picker no longer requires a selection so a core-only install stays possible * fix(installer): replace the whole line when browsing directories _clearUserInput() sends readline ctrl+u, which deletes only what is left of the cursor, and _setUserInput() inserts at the cursor. Browsing after an arrow-key edit therefore left the surviving tail appended to the selected candidate: typing a path, pressing left three times, then down twice submitted ".../workspaceace" instead of ".../workspace/alpha". validateDirectorySync accepts that path when its parent exists, so the install went somewhere the user never typed - the same silent-divergence class this prompt was rebuilt to prevent. replaceLine() now moves to end of line (ctrl+e) before clearing. This also fixes the pre-existing instance of the bug on Tab. Alongside it: - shift+tab steps back through completions instead of acting as tab - the "... N more" counter counts only entries below the window, not every off-window entry, which overstated it once scrolled - an empty line resolves the default through expandHome/path.resolve, and seeds the candidate list from the same place, so the list always describes what Enter would submit - selectAllModules JSDoc no longer claims core is excluded - test escape sequences are written as escapes rather than raw bytes, and the keystroke driver has wider timing margins for CI * refactor(installer): make the directory prompt a plain text entry The candidate list, key hints and completion cycling were noise for the common case: people run the installer from the directory they want to install into, or one under it. Enter on an empty line already accepts that, so the list mostly served to push the actual question off screen. Removed the list rendering, the hint line, arrow/Tab browsing and the helpers that fed them (listDirectoryOptions, directoryWindow and the directory-probing utilities). What remains is a clack TextPrompt with a placeholder showing the default. The original defect stays fixed by construction rather than by bookkeeping: TextPrompt's value is the text on the input line, so there is no hidden selection that Enter could submit instead. Net effect on prompts.js versus main is -66 lines. * docs(installer): shorten module descriptions in the picker The hint beside a highlighted module ran long enough to wrap, which made the list harder to scan than the module names alone. Each description is now a single short phrase: - bmm Agile AI driven development - bmb Skill, workflow, and agent builder - cis Brainstorming, ideation, and creative problem solving - tea Enterprise testing BMM add-on - loop Builds, verifies, and retros a whole epic unattended - gds Ideate, design, and build games in any framework TEA is the only module that depends on BMM, and its description now says so. The others no longer imply it. "Loop" means nothing to a new user, so that description leads with what the module does rather than its name, and gds no longer enumerates engines. * feat(installer): pre-fill the directory prompt with the current directory The default was shown as dim placeholder text, so choosing anything near it meant typing the whole path by hand. It is now the real starting value on the input line: press Enter to take it, append to install one level down, or backspace to move up. Clearing the line and pressing Enter still accepts the default, and the placeholder remains for that case. * docs: reposition on Agile Ai Driven Development The tagline was absent from the installer and the README, and the slot under the wordmark where a tagline belongs was carrying the company line instead. AiDD is the category BMad Method operates in; the agile part is what BMad adds to it. Installer: - the banner reads tagline, then positioning, then company credit, in descending weight - bmm and cis picker descriptions match, with cis short enough that its row no longer wraps and shifts the list as you arrow onto it README: - the opening states the phrase, defines AiDD on first use, and drops the rhetorical "heard BMad means heavyweight process?" framing while keeping what it was defending - greenfield lean corrected: the opening now states the range, "add BMad to an existing codebase" is a CTA above the fold rather than a link at line 57, and a bullet names working from verified context on inherited code. Everything above the fold previously scaled by change size and nothing by codebase maturity, so a brownfield reader had no answer. - the module table matches the installer descriptions, uses full module names instead of letter codes, and adds BMad Loop, which was missing * docs: carry the module descriptions into the translated READMEs Game Dev Studio was the last picker row wide enough to wrap an 80-column terminal, which shifts the list as you arrow onto it. The engine list stays in the README tables, where there is room for it. The Chinese and Vietnamese READMEs have their own structure rather than being a translation of the current English one, so this only touches the two parts that had gone stale against the installer: the opening positioning line and the module table. Both tables now match the English one - installer descriptions, full module names instead of letter codes, and BMad Loop, which none of the three had. The translated prose needs a native reviewer before release. |
||
|
|
57e70562e3 |
feat: bmad-project-context skill — verified kernel + bundle context system (#2674)
* Add bmad-project-context skill; husk document-project and generate-project-context - New bmad-project-context: one engine, three intents (ingest/query/audit) building a verified kernel + bundle context system; interactive default, auto/headless mode; works with a BMad install or standalone via bootstrap - context.py core runtime script (validate/index/map/sweep/resolve/compass/ sync/bootstrap/config) with 52 tests; config resolution delegates to the installed BMad resolver so script and session never disagree - bmad-document-project and bmad-generate-project-context reduced to 10-line deprecation shims forwarding to the new skill - Docs updated: project-context explanation/how-to rewritten, established projects guide + FAQ, agents references, workflow map; deprecation notes kept for old-name searches - module-help.csv single PC row; analyst menu DP -> PC - validate-file-refs: context.yaml is runtime-generated * refactor: remove map command from context.py — discovery is the model's job Real-repo testing showed map's descriptor pass grinding through large asset trees. Discovery is judgment work the model does better with its own tools; the script keeps only measurement, mutation, and resolution (validate/index/sweep/resolve/compass/sync/bootstrap/config). SKILL.md brownfield flow de-prescribed to outcome-driven wording; added a bounding-question rule for huge external sources. * feat: closing message when the harness may not load AGENTS.md 43+ harnesses make per-harness load verification impractical. Whenever AGENTS.md carries the kernel, the run now closes by telling the user: if your harness doesn't auto-load AGENTS.md, make the context file it does load pull this one in (e.g. a CLAUDE.md containing @AGENTS.md). Found in real-repo testing: the kernel sat unloaded under Claude Code until a CLAUDE.md pointer was hand-made. * docs: add The Theory of Project Context explanation Why the skill captures so little: the evidence against generated docs, the pruning test and what earns a place, the deliberate exclusions with their reasons, context-as-liability, and an honest comparison with the two replaced skills. * fix: address PR review findings - Force-add eval fixture files the repo gitignore silently dropped (pnpm-lock.yaml, _bmad/context.yaml, context/.memlog.md) - docs/reference/agents.md Analyst row: DP/Document Project -> PC/Project Context - context.py: cmd_index no longer crashes on an empty index.md (and allows overwriting one); inline # comments in frontmatter values are only stripped when preceded by whitespace (C#-style values survive); cache_lookup tolerates corrupt pointer files; pointer writes are atomic - triggers.json: positive trigger for the query intent |
||
|
|
770d425985 |
fix(installer): apply --set core overrides before config collection (#2671)
`--set core.<key>` was applied only as a post-install TOML patch, but core values are dependency-bearing: module artifact paths are built from output_folder during config collection, the output directory is created from those paths, and each module's config.yaml snapshots the core values at generate time. A patch that lands after all of that leaves the sources disagreeing. `--set core.output_folder=generated` produced output_folder: generated in core config, BMM paths under _bmad-output, and a _bmad-output/ directory on disk. `--set core.project_name=Foo` left BMM's copy on the default. The docs present --set core.<key> and the legacy shortcuts as equivalent and label --set the preferred form, so both were reachable by following the documented advice. Seed core config from setOverrides.core alongside the legacy shortcut flags, so every core key takes effect during collection rather than only the four that have a dedicated flag. Non-core overrides keep the existing post-install patch path. |
||
|
|
57ad793167 |
refactor(bmm): reorganize skills into agents / plan / ship; retire tech-writer agent (#2658)
* refactor(bmm): move agent skills into agents/ * refactor(bmm): collapse phase folders into planning/ and shipping/ Skills reorganize from numbered pipeline folders (1-analysis, 2-plan-workflows, 3-solutioning, 4-implementation) into two sets: planning/ and shipping/. Path and phase-label references updated across marketplace.json, module-help.csv, tests, and bmad-help; also trues up two marketplace paths that were stale on main (create-story/dev-story already lived in v6-shims). * refactor(bmm): shorten skill folders to plan/ and ship/ * refactor(bmm): retire tech-writer agent (Paige on hiatus) Paige's capabilities were generic LLM defaults with no domain substance; her one real menu item (DP) dispatches bmad-document-project, which stays directly invocable and remains on the Analyst menu. Added to removals.txt so installs clean up, and docs (all languages) carry a hiatus notice — she returns in the future far more capable. |
||
|
|
022bcbc66d |
Rename Quick Dev to Build (#2651)
* feat(bmm): rename quick dev to build * fix: address build rename review findings * fix: clarify deprecated build shims * fix: offer legacy customization migration |
||
|
|
029ba287bc |
docs: make Quick Dev the canonical implementation workflow (#2643)
Rewrite published documentation and maintained translations around variable planning depth with one Phase 4 implementation loop. Update diagrams and AI indexes, and reject obsolete workflow terminology in deployable output. |
||
|
|
c2530ea53f |
feat: add inspectable workflow snapshots (#2601)
Render complete dev-auto workflows into root-scoped immutable snapshots using shared declarative rendering and strict TOML configuration layers. Keep generated render state out of installer module discovery and custom file preservation, preserve quick-dev behavior, and provide deterministic Python version failures for standalone resolver use. |
||
|
|
c23f23400d |
feat: streamline core to an 8-skill set with merged review and editorial skills (#2603)
* feat: streamline core to a 5-skill kernel with standalone skill modules
Core installs 14 -> 5 catalog-visible skills; atoms exit to standalone
modules; installer gains real dependency resolution; zero npm deps.
- Merge bmad-editorial-review-prose/-structure into bmad-editorial-review
(structure models JIT-loaded, new customize.toml)
- Merge bmad-review-adversarial-general/-edge-case-hunter/-verification-gap
into bmad-review as selectable lenses; hidden husk-forwarders remain at
the old IDs (no catalog rows) so gds/loop/os-utils keep working
- Move bmad-brainstorming, bmad-party-mode, bmad-forge-idea out of core to
src/standalone-skills/ as single-skill modules; add bmad-analysis bundle
module (curated dependency list over the atoms)
- Move bmad-spec into bmm (2-plan-workflows)
- Modernize bmad-advanced-elicitation: uv run, customize.toml, methods
pick offloaded to scripts/pick_methods.py (with tests)
- Delete bmad-index-docs, bmad-shard-doc (removes the tree's only external
npm dependency), and the four deprecation shims (bmad-create-prd,
bmad-edit-prd, bmad-validate-prd, bmad-create-architecture); all added
to removals.txt
- Installer: activate the dependencies field (recursive union into
selectedModules, cycle-guarded, warn on unknown), config-driven picker
visibility; core stays force-installed
- bmm module.yaml declares deps on the three atoms
- Docs updated across all locales; new reference/standalone-skills.md;
shard-doc how-tos removed
* Restore original critical wording lost in the review/editorial merges
The merges into bmad-review and bmad-editorial-review were meant to keep
the source skills' critical wording behind progressive disclosure, not
paraphrase it away. Restore what was lost:
- lens-adversarial: clueless-weasel framing, extreme-skepticism wording,
the at-least-ten-issues quota, and zero-findings-is-suspicious (the
merge had inverted this to zero-is-valid)
- bmad-review SKILL: zero-findings stance is now per-lens
- lens-edge-case: mandatory exact-order step enforcement
- lens-verification-gap: exact 'No verification gaps found.' clean line
- editorial-review: full Human/LLM reader principles restored to new
references/reader-principles.md; structure-pass HIGH-VALUE DENSITY
role, front-load-value, anti-patterns, pacing check, and length_target
assessment; prose-pass role sentence, analyze-style-first step, and
merge-overlapping-fixes rule; output summary block and min-3-words HALT
* feat(installer): promote bmad-analysis bundle to src/bmad-analysis-skills
Move the bmad-analysis bundle module out of src/standalone-skills/ into its
own src/bmad-analysis-skills root, teach the installer to resolve it there
(getModulePath, official-modules listing, isBuiltInModule helper), and
update the marketplace manifest and standalone-skills docs to match.
* refactor(bmad-review): rename edge-case lens to edge-case-hunter
Rename the lens code and reference file (lens-edge-case.md ->
lens-edge-case-hunter.md), add explicit when = "always" to the shipped
lenses, and tighten the lens-selection wording in SKILL.md.
* feat(bmad-editorial-review): configurable style guide + analysis-driven rework
Apply the workflow-builder analysis recommendations:
- Make the baseline style guide configurable: style_guide in customize.toml
now IS the baseline (default "Microsoft Writing Style Guide") instead of
an empty override slot; SKILL.md no longer hardcodes the guide.
- Inline reader-principles.md into SKILL.md and delete the reference (it
loaded on every run and was half-duplicated inline).
- Complete the customization surface: activation_steps_prepend/append,
persistent_facts (project-context glob), on_complete, and a
review_output_path scalar split out of output_preferences; add a
file:-load fallback convention.
- Ground word metrics: new scripts/word_metrics.py (stdlib, PEP 723, tests)
emits total/per-section word counts so impact estimates and the reduction
summary use exact numbers.
- Cross-pass dedup: prose pass skips CUT-tagged passages and re-attaches
fixes in MERGE'd ones; output ranks by impact with a long-tail rollup.
- Polish: HALT threshold replaced with plain outcome, duplicate LLM-reader
bullets merged, all-caps lowered, literal Overview heading added.
* fix(installer): stop cache-refresh git commands from escaping to the parent repo
Two compounding bugs let a pre-commit test run shallow-fetch and hard-reset
the developer's own repository:
1. Git spawns in custom-module-manager and external-manager inherited the
hook environment. Git exports GIT_DIR (absolute, in worktree checkouts)
into pre-commit hooks; a child git then targets the hook's repo regardless
of cwd, and treats its cwd — the module cache dir — as the work tree. The
cache refresh's 'git fetch --depth 1' + 'git reset --hard origin/main'
therefore shallowed the shared .bare and moved the checked-out branch.
New git-env.js strips repo-targeting GIT_* vars from every git spawn in
both managers, including calls that previously inherited process.env
implicitly.
2. Test suite 51 (quickUpdate dependency expansion) ran the real
CustomModuleManager lookup, which scans ~/.bmad/cache/custom-modules and
network-refreshes every cached clone — real user state. The suite now
stubs findModuleSourceByCode.
Verified by rerunning the suite with GIT_DIR pointed at the repo and a PATH
shim blocking fetch/reset/clone: 432 passing, zero blocked calls.
* De-scope standalone-skills mechanism: atoms return to core, shims reinstated
Shrink the PR to its heart — the skill merges — and defer the module
mechanics to a follow-up where all skills become module-driven:
- bmad-brainstorming, bmad-party-mode, bmad-forge-idea move back to
src/core-skills/ as ordinary core skills with their catalog rows
restored; src/standalone-skills/ and the bmad-analysis bundle module
are removed
- Installer reverted to main: standalone discovery, hidden-module
filtering, dependency resolution, manifest changes (test suites 49-51
removed with the code); the cache-refresh git fix is retained
- The four bmm deprecation shims (create/edit/validate-prd,
create-architecture) are reinstated so enterprise installs that
invoke the old IDs or carry _bmad/custom overrides keep working;
descriptions trimmed to the short husk style; their removals.txt
entries dropped (removal rides the v7 cut as their frontmatter
promises)
- marketplace.json keeps the five plugin entries with atom paths
pointing at src/core-skills/
- Docs (en/cs/fr/vi/zh) reframe the three skills as core thinking
skills; standalone-skills.md reference page removed
* Fix all findings from the max-effort adversarial review
Correctness:
- Finish the edge-case -> edge-case-hunter lens rename at every caller:
the forwarder husk, the code-review/dev-auto/quick-dev review layers,
the renderer test assertion, and the stale example path in
bmad-review/SKILL.md
- marketplace.json: ship the five core kernel skills with
bmad-method-lifecycle so its skills' bmad-review/bmad-editorial-review/
bmad-help/bmad-advanced-elicitation invocations resolve in a
marketplace install
- pick_methods.py / word_metrics.py: force UTF-8 stdout (Windows locale
code pages crashed on the catalog's arrows and CJK headings)
- word_metrics.py: pair fences CommonMark-style so 4-backtick fences can
embed 3-backtick examples without corrupting sections; count CJK
characters as words
- pick_methods.py: validate --extra entries are JSON objects (was an
uncaught AttributeError); read catalogs with utf-8-sig (BOM'd CSVs
silently blanked every num)
- bmad-spec: activation now resolves {output_folder} (which the
Workspace uses) instead of the unused {planning_artifacts}; drop the
stale core-only-installs comment
- Editorial husks: pin the legacy output contracts (three-column table /
Document Summary report and exact empty-state lines) like the review
husks do
- PRD shims: advertise the real bmad-prd customize keys
(validation_checklist_template, prd_output_path, run_folder_pattern,
finalize_reviewers) instead of three that don't exist
- bmad-prd: add the forwarded-activation clause its shims rely on
(ported from bmad-architecture)
- Locale workflow-maps (fr/cs/vi/zh): add the bmad-spec Phase-2 row the
English map gained, which every locale's core-tools note points at
- git-env.js: also strip GIT_CONFIG_PARAMETERS and the
GIT_CONFIG_COUNT/KEY_n/VALUE_n family; pass gitEnv() to the three npm
install spawns whose transitive git calls inherited hook vars
Consistency:
- brain.py --extra overlay now replaces-by-name like pick_methods.py
(same customize.toml additional_* semantics across sibling skills),
with a regression test
* Fix prettier formatting in marketplace.json
* Apply valid CodeRabbit findings
- brain.py: catch malformed --extra overlays (bad JSON, non-array root,
non-object entries) into the clean error path instead of a raw
traceback, with a regression test; read catalogs and overlays with
utf-8-sig; normalize ALL CSV fields (required ones were unstripped and
could arrive as None from short rows)
- brain-selector: clamp the random-technique count to what the pool can
supply so the Total badge matches the actual draw (template +
regenerated assets/brain-selector.html)
- bmad-editorial-review: word_metrics command now uses the explicit
{skill-root}/ prefix
- resolve_party.py / resolve_personas.py: custom member overrides now
start from the installed entry, so omitted fields (icon, title,
description, module, team) survive; non-string member tokens land in
unresolved instead of raising TypeError; party's member loop gains the
isinstance guards its personas twin already had
- bmad-brainstorming: fix the SKILL.md claim that headless is the only
context for self-generated ideas (autonomous mode is interactive);
autonomous mode honors user-supplied techniques before self-selecting
- Docs: drop duplicate 'only' in the spec template; align zh-cn
forge-idea's bmad-review description with the English wording
* Create only the output folder at install time
bmm no longer pre-creates planning_artifacts, implementation_artifacts,
and project_knowledge — the last of which put an empty docs/ at every
project root. Skills create those lazily on first write. core now
declares {output_folder} in its directories block, which was previously
created only as a side effect of the artifact folders nesting under it.
|
||
|
|
717479bc3f |
fix(dev-auto): temporarily revert skill-entry renderer (#2598)
Back out the dev-auto render.py workflow entry change from #2587, including the follow-up renderer-only fix on top of it, so the skill returns to the pre-renderer SKILL.md flow while the longer fixes are worked separately. |
||
|
|
64157d394c |
feat(dev-auto): render templates via stdlib Python at skill entry (#2587)
Propagate bmad-quick-dev's render.py pattern (#2281) to bmad-dev-auto. SKILL.md becomes the two-line stdout-dispatch shim that runs render.py via uv and follows the instruction it prints; the old SKILL.md body moves to workflow.md, rendered to _bmad/render/bmad-dev-auto/ with all compile-time values baked in. - render.py is a copy of quick-dev's, differing only in skill-name references; a test guards against the two copies drifting apart. - Compile-time config refs ({communication_language}, {planning_artifacts}, {implementation_artifacts}, {deferred_work_file}, {document_output_language}) become {{.var}} substitutions resolved from the central four-layer TOML config. Runtime refs ({spec_file}, {diff_output}, ...) pass through. - [workflow] customization resolves at render time: on_complete inlines into the HALT On Complete section, implementation_handoff into step-03, and review_layers materialize as invocation blocks in step-04 — the runtime resolve_customization.py calls and the activation-time workflow-block resolution step are gone, along with the Load Config activation step (values are baked at point of use; the language rule moves into each step's RULES). - Step files now reference workflow.md instead of SKILL.md; step-02 resolves the spec template's date field; step-04 defines {date} for the triage-log header. - tools/validate-file-refs.js whitelists render/bmad-dev-auto/; test:renderer now also runs the new test/test-dev-auto-renderer.js. - docs: the dev-auto reference's Context Inputs now names the central _bmad/config.toml surface instead of _bmad/bmm/config.yaml. |
||
|
|
49069b8b52 |
feat(quick-dev): render templates via stdlib Python at skill entry (#2281)
* feat(quick-dev): render templates via stdlib Python at skill entry Move compile-time variable substitution out of the LLM and into a deterministic Python step. SKILL.md becomes a two-line stdout-dispatch shim that runs render.py and follows the instruction it prints. The renderer reads BMad configuration from the central four-layer TOML surface introduced in #2285 (_bmad/config.toml plus config.user.toml and the two _bmad/custom/ overrides), with a fallback to the legacy per-module _bmad/bmm/config.yaml for pre-#2285 installs. Compile-time refs ({{.var}}) get substituted at render time. LLM-runtime refs ({var}) pass through untouched. Renderer (render.py) - Python 3 stdlib only (tomllib, already bundled since 3.11). UTF-8 I/O. Every invocation rebuilds from scratch — no hash, no cache. - find_project_root walks up from cwd; HALT to stdout if no _bmad/ is found anywhere on the path. - load_central_config deep-merges the four TOML layers in priority order (base-team → base-user → custom-team → custom-user) so user overrides in _bmad/custom/config.user.toml win over installer- regenerated base values. flatten_central_config lifts scalar keys from [core] and [modules.bmm] into the renderer's flat namespace; module keys beat core on collision (matches the installer's own core-key-stripping behavior). - When _bmad/config.toml is absent, falls through to the legacy flat-YAML parser for _bmad/bmm/config.yaml — the renderer keeps working across the #2285 transition. - {{.var}} substitution; unresolved refs emit empty string (Go missingkey=zero semantics). - Smart defaults for planning_artifacts / implementation_artifacts / communication_language applied after config load. Derives sprint_status / deferred_work_file from implementation_artifacts. {{.main_config}} points at whichever surface was actually read. - Renders every .md in the skill dir except SKILL.md to {project-root}/_bmad/render/bmad-quick-dev/. - On success, stderr summary plus a single stdout line: "read and follow {workflow_md}". On failure, stdout HALT directive — per the Anthropic skills spec, script stdout is the defined agent- communication channel. Skill entry (SKILL.md) - Two-line shim: run python render.py, follow stdout. No template tokens in SKILL.md itself. Template conversions - workflow.md, step-01..05, step-oneshot, sync-sprint-status: convert every compile-time {var} reference to {{.var}}. Runtime refs preserved. - spec-template.md untouched (single-curly comment hint stays as documentation). Skill-prose cleanups bundled in - Remove dead step-file frontmatter: empty-string variable declarations (spec_file, story_key, diff_output, review_mode) in quick-dev step-01 and code-review step-01; empty --- --- blocks in step-03 and step-05; the specLoopIteration counter init moved from step-04 frontmatter into the step body where first-entry vs loopback semantics are explicit. - Unify the language rule across all six quick-dev step files plus workflow.md. Tooling - tools/validate-skills.js: add TPL-01 rule. Files whose name contains "template" must not contain compile-time {{.var}} substitutions. Template files seed durable, version-controlled artifacts that execute on other machines; baking a value at render time would freeze a machine-local path into every downstream artifact. - tools/validate-file-refs.js: add render/ to INSTALL_ONLY_PATHS so the validator recognizes the runtime-generated buffer. - tools/skill-validator.md: document TPL-01; deterministic rule count bumped from 14 to 15. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(quick-dev): drop render.py YAML fallback and smart defaults Single happy path: central _bmad/config.toml with four-layer merge, Python 3.11+ required (no ImportError guard), HALT if config missing. Deletes load_flat_yaml, the YAML fallback branch, the setdefault block for planning_artifacts/implementation_artifacts/communication_language, and the tomllib ImportError fallback. Part of plan-quick-dev-python-config-hardening.md (F0). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): normalize render.py paths to forward slashes On Windows, os.path.join returns backslash-separated paths that can misrender as escape sequences when later concatenated into POSIX shell strings or regexes. Normalize the project root to forward slashes after find_project_root, and use posixpath.join for every path that gets baked into rendered .md files or joined into config values. os.makedirs and os.listdir accept forward-slash paths on Windows, so their call sites stay as-is. Part of plan-quick-dev-python-config-hardening.md (F3). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): preserve source line endings in render.py Python text-mode open() with the platform default performs universal- newline translation: on Windows, LF source files get written as CRLF, producing spurious diffs when rendered output is compared against source. Pass newline="" on both the source read and the rendered write so line endings pass through verbatim. Part of plan-quick-dev-python-config-hardening.md (F4). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): delete stale .md renders before rebuilding render.py rebuilds from scratch per the docstring, but makedirs(exist_ok=True) only overwrites files that still exist in the source — stale outputs from renamed/deleted source files linger in _bmad/render/bmad-quick-dev/ forever. Remove every .md in the render dir before the render loop; keep the dir itself and any non-.md files. Part of plan-quick-dev-python-config-hardening.md (F5). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): scope render/ whitelist to bmad-quick-dev The previous INSTALL_ONLY_PATHS entry 'render/' was a blanket prefix that let every {project-root}/_bmad/render/... reference in any skill slip past validation. Narrow to 'render/bmad-quick-dev/' so only this skill's render buffer is whitelisted. Future skills adopting the stdout-dispatch renderer pattern add their own entries explicitly. Part of plan-quick-dev-python-config-hardening.md (F6). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(quick-dev): add renderer smoke test with TOML override New test/test-quick-dev-renderer.js spins up a temp project with base _bmad/config.toml and a _bmad/custom/config.user.toml override, runs render.py, and asserts the override wins in rendered workflow.md and that sprint_status is rooted at an absolute path in the temp project. Registered as test:renderer in package.json and chained into the npm test script. Part of plan-quick-dev-python-config-hardening.md (F7). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): HALT cleanly when base config.toml is unparseable Load the four config layers through a load_toml helper that marks the base _bmad/config.toml as required. A missing, unparseable, or unreadable base now prints a HALT directive to stdout and exits, instead of being silently skipped and then crashing downstream with a KeyError when a derived value (e.g. implementation_artifacts) is absent. Optional layers still warn on stderr and fall back to empty. Merge semantics are unchanged (dict-aware deep merge, override wins for lists and scalars). * fix(quick-dev): resolve render.py via {skill-root} in skill entry shim The bare `python render.py` shim assumes the agent's working directory is the skill directory, but agents run from the project root, so the script is not found. Reference it as `{skill-root}/render.py` — BMAD's standard token for a skill's installed directory, already used by every other skill's resolve_customization.py invocation — and add the one-line `{skill-root}` explainer so the model resolves it from an instruction rather than guessing. Interpreter stays `python`; the python vs python3 choice is a separate cross-platform concern. * refactor(quick-dev): resolve [workflow] customization in render.py render.py now merges the three customize layers (customize.toml -> custom/bmad-quick-dev.toml -> .user.toml) with the same structural rules as resolve_customization.py and inlines the resolved [workflow] values, so no {workflow.*} placeholder survives. workflow.md drops its Step 1 runtime resolver + manual-merge fallback; step-05 and step-oneshot drop their runtime workflow.on_complete calls. The shared resolve_customization.py and every other skill are untouched. Smoke test extended with a [workflow] override fixture covering inlining, array append, and no-leak assertions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): harden render.py invocation in the SKILL.md shim The shim called bare `python`, which can resolve to Python 2 or be absent; render.py needs 3.11+ for tomllib. Spell out python3 and the version requirement. Also make the exit code authoritative: on a non-zero exit (including an uncaught crash that writes only to stderr), do not proceed -- report what was printed and stop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(quick-dev): drop the render.py success stderr line The "rendered N files" progress line was pure diagnostic noise. The shim already tells the LLM to ignore stderr and follow the stdout instruction, so on success render.py now prints only the "read and follow ..." line. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(quick-dev): drop the activation gate sentence from the rendered workflow The gate ported from #2398 defended against runtime customization indirection: agents guessed resolver outputs instead of executing them, silently skipping append steps. render.py inlines the prepend/append entries into the rendered workflow.md, so there is nothing left to short-circuit, and each inlined list already carries its own execute- in-order imperative. In the default install both lists render as _None._ and the gate is pure noise. * feat(quick-dev): materialize review layers into invocation blocks Reconcile #2550 with render-time [workflow] resolution. Main made review layers configurable as [[workflow.review_layers]] arrays of tables and had the LLM resolve them during activation; this branch resolves the [workflow] block in render.py instead, so activation-time resolution no longer exists and the layer refs must be materialized at render time. Rather than inlining the layer tables as data plus interpretation rules, render.py now knows this skill's customization schema outright and renders review_layers/oneshot_review_layers as direct invocation blocks: disabled layers (empty instruction) drop out, each active layer becomes a #### section holding its instruction verbatim, zero active layers renders the HALT instruction, and runtime placeholders like {diff_output} pass through. The only judgment left to the LLM is the optional `when` condition, which renders as a run-time guard line. The step-04/step-oneshot review intros collapse to a single execute-in- parallel imperative. Smoke test covers default rendering, replace-by-id, disable-by-empty-instruction, when-guards, and the all-disabled HALT. * fix(quick-dev): invoke render.py via uv run per house standard The SKILL.md shim launched render.py with bare `python3`, which the rest of BMAD is migrating away from: the customize-bmad docs and the installer's uv-check standardize on `uv run` (uv provisions a suitable 3.11+ interpreter on demand). Bare `python3` is also fragile on Windows, where python.org installs expose `python`/`py` rather than `python3`. Make `uv run` the primary invocation and demote `python3` to the documented fallback, spelling out `python`/`py -3` for Windows and the 3.11+ tomllib requirement. render.py itself is unchanged; the renderer test drives it directly and is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(quick-dev): HALT cleanly on missing or malformed config render.py derived sprint_status/deferred_work_file from an unconditional vars_["implementation_artifacts"] subscript, so a config lacking that key raised a raw KeyError instead of the stdout HALT the rest of the script uses on bad input. flatten_central_config likewise called .get("bmm") on merged["modules"] without checking it was a table, so a non-table [modules] crashed with an AttributeError. Guard both: HALT with a clear stdout directive when implementation_artifacts is missing or blank, and coerce a non-dict modules to {} before indexing. Add renderer regression tests asserting each path exits without a Python traceback. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(quick-dev): resolve config at compile time, drop the runtime re-read The activation "Load Config" step told the LLM to open {{.main_config}} and re-resolve project_name, communication_language, sprint_status, etc. at run time -- but render.py already bakes those from the full four-layer config merge. main_config pointed at only the base _bmad/config.toml, so on installs with override layers (config.user.toml / custom/*) the runtime re-read saw stale values that could contradict the baked {{.var}} in the same rendered file. It also handed resolution back to the LLM: the drift this skill's renderer exists to remove. Delete the ceremony and wire each value where it is actually used: - Every value the step resolved is already inlined at its point of use (planning/implementation_artifacts, sprint_status, communication_language) or loaded via persistent_facts (project-context.md), so the central block was pure redundancy. - Fold document_output_language into the per-step language rule, adopting the house-canonical form ("Speak in X. Write any file output in Y.") already used by bmad-checkpoint-preview. - Move the {date} = current-datetime definition to step-02, where the spec template's {date} field is filled. - Drop the user greeting (user_name) and user_skill_level tailoring: quick-dev is not a conversational skill and neither was load-bearing. - Remove main_config from render.py; it had no remaining consumer. Renderer tests repointed at the files that now carry these values, plus coverage for document_output_language baking and main_config removal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(quick-dev): reference variables by bare name, not placeholder curlies Curlies mean "expand this to the value"; a bare backticked name means "this is the variable/field I'm talking about". Several step files wrapped a variable in curlies where they were only naming, assigning, passing, or testing it -- so the notation implied an expansion that never happens: - step-01: identify `epic_num`/`story_num`, set/leave `story_key` unset - step-02: test `preserved_intent`; and resolve the template's `date` field (was `{date}`, which read as "expand date here" rather than naming it) - step-03/step-05/step-oneshot: pass `target_status` to sync-sprint-status, set `title` - sync-sprint-status: the `target_status` parameter, `story_key` precondition, and both `target_status` conditionals Value tokens that are genuinely materialized in place -- `{spec_file}` paths, `development_status[{story_key}]`, "set ... to `{target_status}`" -- stay curly. Also reword step-02's frozen-block instruction from the ambiguous "substitute it for the `<frozen-after-approval>` block" to "replace the `<frozen-after-approval>` block in the spec you just filled out with `preserved_intent`" so it's clear the replacement happens in the artifact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(quick-dev): require uv, drop the python3 interpreter fallback The SKILL.md shim tried `uv run render.py` and, if uv was missing, retried with a bare `python3`/`py -3` interpreter. Nothing else in the codebase does that interpreter fallback: the uv-based skills (bmad-prd, bmad-ux, bmad-architecture, bmad-product-brief) fall back to reading customize.toml and using defaults -- graceful feature degradation, never a different runner -- and the legacy skills just call python3 outright. uv is the established house runner (memlog.py, resolve_customization.py, lint_spine.py all invoke it). That graceful-degrade path does not exist here: render.py is the entry dispatch that produces the workflow.md the LLM then follows, so there is nothing to fall back to. The only honest outcomes are "uv runs it" or "HALT". Make uv the floor and drop the fallback. Pin the interpreter the house way -- a PEP 723 `requires-python = ">=3.11"` block, matching memlog.py/lint_spine.py -- so `uv run` provisions a 3.11+ interpreter and the tomllib requirement is guaranteed rather than hoped for. This replaces the prose "needs 3.11+" hedge the shim used to carry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
5f3ebc91ed |
feat: add Antigravity CLI (AGY) as supported installer platform (#2551)
* feat: add Antigravity CLI (AGY) as supported installer platform Distinct from the Antigravity IDE entry: the CLI reads workspace skills from the shared .agents/skills standard and its own global dir. Closes #2440. * test: assert Antigravity CLI global_target_dir differs from the IDE |
||
|
|
c0fa3231a2 |
v6.10.0: bmad-loop replaces bmad-automator, changelog draft (#2545)
* docs: draft v6.10.0 changelog; rebrand bmad-auto to bmad-loop; simplify uv check message Drafts the v6.10.0 changelog entry, headlined by bmad-loop landing as an installable module and bmad-automator's deprecation in its favor. Renames the installer's bmad-auto module registry entry (code, name, url, module-definition path, post-install message) to bmad-loop ahead of the upstream repo rename. Also simplifies the uv-detected install message to a plain pass/fail line with a checkmark, since the prior "ready to run BMAD's Python-powered scripts via uv run" phrasing read as more actionable than it was. * feat(installer): support module-code aliases, migrate bauto to bmad-loop Adds a bauto -> bmad-loop registry alias so existing installs migrate forward on quick-update (and the interactive Modify flow) instead of being orphaned as "no source available" the way the prior baut -> automator rename was (CHANGELOG v6.7.1). ExternalModuleManager resolves aliases in getModuleByCode/resolveCanonicalCode; quickUpdate translates installed ids up front and removes the stale _bmad/<alias>/ directory after a successful migration. removals.txt gains bmad-auto-setup, the renamed skill id, so stale IDE-side skill dirs get pruned too. Also corrects bmad-modules.yaml's bmad-loop entry to match the real upstream repo content (src/bmad_loop/..., bmad-loop-setup skill) now that the bmad-auto -> bmad-loop rename has actually landed there, and moves bmad-loop to the top of the installer picker with a shorter, less wrap-prone description. |
||
|
|
4b6288d836 |
feat(installer): deprecate automator, add bmad-auto marketplace module (#2532)
* feat(installer): deprecate automator, add bmad-auto marketplace module Add a `deprecated` registry property (with `deprecation-message`): deprecated modules are hidden from the installer picker unless already installed, and the message is surfaced in the picker hint so existing users see the replacement. Mark bmad-automator deprecated, pointing to bmad-auto. Add bmad-auto as a new official module. Since its installable skills live outside a single module.yaml directory (it ships .claude-plugin/marketplace.json with module.yaml inside the -setup skill's assets/), add a `marketplace-plugin` flag that routes such registry modules through the PluginResolver — the same machinery custom-URL installs use — to copy the resolved skill dirs and module-help.csv. Manifest/version handling is unchanged (source: external). The flag is opt-in, so existing modules (e.g. WDS) are unaffected. * fix(installer): harden marketplace-plugin install (review #1/#5/#8) - Fail loud when a marketplace-plugin module's skills cannot be resolved from marketplace.json, instead of silently copying the -setup skill's assets/ dir (module.yaml + module-help.csv) with no skills — a broken partial install. - Extract _copyResolvedSkills() shared by install() and installFromResolution() so the official registry and custom-URL plugin paths cannot drift; this also picks up the synthesizedHelpCsv (strategy 5) handling in both paths. - Detect duplicate skill leaf names in _copyResolvedSkills and throw instead of letting two skills silently overwrite each other. * feat(installer): registry-driven post-install messages Add a `post-install-message` property to the module registry. After the install summary, any installed module that defines one shows an "action needed" notice; interactive installs require the user to acknowledge it (press Enter), while non-interactive (--yes) installs print it and continue so CI never blocks. Use it on bmad-auto to tell the user to run the bmad-auto-setup skill from their agent to finish setup (install the orchestrator + wire hooks/policy). * fix(installer): acknowledge post-install messages before the summary Show the "action needed" post-install messages (and gate on acknowledgment) before rendering the install summary, so "BMAD is ready to use!" remains the last thing the user sees. |
||
|
|
35b19db2e3 |
fix(installer): accept windows custom module paths (#2511)
* fix(installer): accept windows custom module paths * fix(installer): reject versioned windows local paths * style: format custom module manager --------- Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
c9813c6862 |
fix(validate-skills): exempt deprecated skills from SKILL-06 trigger (#2486)
* fix(validate-skills): exempt deprecated skills from SKILL-06 trigger SKILL-06 flagged deprecated compatibility shims for missing a "Use when" trigger phrase. Deprecated skills omit it on purpose so users are steered to their replacement, so exempt them from that specific check. - detect deprecation via description starting with "DEPRECATED" - keep the other SKILL-06 check (length) and all other rules applying - add test/test-validate-skills.js + fixtures, wired into npm test * test(validate-skills): document test helpers with JSDoc Added JSDoc to the test/assert/hasTriggerFinding helpers so the new test file documents its own helpers. No behaviour change — the suite still passes 3/3. |
||
|
|
02739932bc |
feat(installer): check for uv and standardize messaging on uv run (#2495)
Replace the standalone python3 environment check with a uv check, since uv is becoming the de facto standard for running BMad's Python scripts (`uv run <script>`) and uv provisions the interpreter itself. Installer: - Remove tools/installer/core/python-check.js and its wiring in ui.js - Add tools/installer/core/uv-check.js: warn-don't-block, no ack prompt (the migration is in progress, so a missing uv never blocks install). Missing uv warns and points the user at setup, preferring "ask your agent to set up uv" - Add a uv heads-up to the install intro (install-messages.yaml) and a uv tip line to the final "BMAD is ready" summary box - Swap test Suite 46 from python-check to uv-check coverage Docs and script comments (no functional skill invocations changed): - resolve_config.py / resolve_customization.py docstrings: drop the "No uv ... plain python3 is sufficient" claims; frame uv run as the standard, python3 as the transition fallback; examples use uv run - customize-bmad.md (en/fr/vi-vn): same reframing; example commands use uv run - Update uv run hints in brain.py / list_customizable test comments |
||
|
|
e600181ab8 |
feat(installer): add hermes-agent tool target (#2489)
Co-authored-by: bigblackcoder <llewis@sovrlabs.com> Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
5bcc235cdb | fix(installer): guard WSL installs from Windows Node (#2470) | ||
|
|
560a2e3a6f |
feat: installer detects Python version and warns when 3.11+ (tomllib) is missing (#2466)
* 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. |
||
|
|
fbb48ed711 |
fix: remove empty skill-group dirs left in _bmad after install (#2461)
* 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> |
||
|
|
b9431d6d99 |
Shared canonical memlog script (src/scripts/memlog.py) + bmad-spec as first consumer (#2462)
* 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. |
||
|
|
397b2a5c87 |
feat: add CodeWhale as supported installer platform (#2459)
CodeWhale uses .codewhale/skills/ (project) and ~/.codewhale/skills/ (global) for skill directories, matching the existing config-driven installer pattern. - platform-codes.yaml: codewhale entry after codex - test: Test 12b validates install target and setup |
||
|
|
717a84f2e8 |
docs(fr): sync French docs with latest English source + fix non-ASCII anchor validation (#2408)
* docs(fr): translation of install-custom-modules Reference commit |
||
|
|
db744d405f |
fix: support nested group paths in SSH Git URLs (#2379)
Co-authored-by: Brian <bmadcode@gmail.com> |
||
|
|
9c291b7ca9 |
fix: resolve default branch explicitly when updating shallow-cloned custom modules (#2332)
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> |
||
|
|
fea431fd2e |
fix(installer): read config.toml on re-run so user_name (and other user-scoped answers) are preserved as defaults (#2411)
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> |
||
|
|
065003fc95 |
Fix stale custom-source redeploys on quick-update (#2399)
* fix(installer): refresh custom-source cache on quick-update and persist channel marker * fix(installer): persist real next ref and atomically dedupe custom refresh * fix(installer): preserve custom-source cache when remote unreachable When git fetch fails against an existing custom-module cache, cloneRepo previously wiped the cache and attempted a fresh clone, which then also failed for the same reason (network down, repo deleted/moved, auth revoked) — leaving the user with no usable cache. With the new quick-update refresh path calling cloneRepo for every cached custom module, this turned transient remote outages into cache loss on every quick-update. - cloneRepo: on fetch failure with an existing cache, keep the previous clone and surface a warning via prompts.log.warn instead of removing the cache. The downstream metadata write uses the existing HEAD. - _refreshRepoCacheOnce: update the comment to reflect that the common "remote unreachable but cache exists" case is now handled inside cloneRepo; warn on the remaining unrecoverable failures so they aren't silent. Tests: 349 passed, 0 failed. --------- Co-authored-by: Brian Madison <bmadcode@gmail.com> |
||
|
|
2b76d03316 |
feat(web-bundles): release packager + manifest for bmadcode.com/web-bundles/ (#2424)
* feat(web-bundles): add release packager + bundle manifest
Adds the infrastructure for shipping web bundles as downloadable ZIPs
attached to a GitHub Release, consumed by the upcoming
bmadcode.com/web-bundles/ page.
- web-bundles/bundles.json — manifest with persona, tagline, description,
accent color, motif key, knowledge files, and feature flags
(web-browsing, deep-research, stitch integration) for each of the 6
bundles. Top-level releaseTag and downloadUrlPattern so the
consuming page can construct download URLs without hardcoding.
- tools/bundle-web-bundles.js — packager that zips each bundle dir into
dist/web-bundles/{slug}.zip and prints the gh release create command.
Zero dependencies; uses system zip.
- .gitignore — exclude dist/web-bundles/ build artifacts.
The web-bundles-v1.0.0 release on GitHub is currently in draft state
with the 6 zips attached; it'll be published in coordination with the
Ghost site page going live.
* fix(web-bundles): single-source release tag, sharper bundle copy
- Remove downloadUrlPattern from bundles.json — the consuming page
derives the URL from releaseTag, so version bumps now touch one
field instead of two.
- product-brief-coach: drop "one-page" (briefs are whatever length
the product earns).
- brainstorming-coach: real numbers — 60 techniques across 10
categories — with concrete examples (SCAMPER, Drunk History
Retelling, Nature's Solutions, Six Thinking Hats, etc.) so the
card actually communicates the surprising breadth.
* fix(web-bundles): harden release script per PR review
- Verify the zip CLI is on PATH up front with a clear install
hint, instead of crashing mid-zip with an opaque execSync error.
- Wrap JSON.parse in try/catch; validate the manifest shape (bundles
array non-empty, releaseTag present, slug present per entry) before
trying to package, so config errors fail with a targeted message.
- Catch zip failures per-bundle and surface the failing slug.
- Refuse to print the gh release command when zero bundles were
packaged (would otherwise mislead the user into creating an empty
release).
- Derive --title from manifest.releaseTag so the printed command can
never drift from the actual tag (was previously hardcoded
"Web Bundles v1" while the tag had moved to v1.0.0).
- Remove the stale `web-bundles-v1` example from the file header.
Addresses augmentcode bot review comments on PR #2424.
* docs(web-bundles): rewrite copy to actually sell what each bundle does
The JSON drives the bmadcode.com/web-bundles/ page; previous copy
was generic and undersold the actual capabilities. Rewrote each
tagline + description to lead with concrete, differentiating facts
pulled directly from each bundle's SKILL.md:
- Brainstorming Coach: 60 techniques across 10 categories with
specific names (SCAMPER, Drunk History Retelling, Nature's
Solutions, Shadow Work Mining, Superposition Collapse); calls
out the 4 routes (browse, recommend, random, progressive) and
the ~100-idea quantity-unlocks-quality target.
- Product Brief Coach: names the three intent modes (Create /
Update / Validate) and the two working paths (Fast / Coaching);
surfaces the [ASSUMPTION] tag system and the Addendum.
- PRFAQ Coach: details the 4 stages (Ignition / Press Release /
Customer FAQ / Internal FAQ + Verdict), the 9 press release
sections, the weasel-word list ("best-in-class", "seamless"),
and that it adapts for commercial, internal, OSS, community.
- PRD Coach: spells out the two entry points (Vision+Features
vs Journey-led), named-protagonist journeys, glossary
discipline, stable ID system (FR-1..N, SM-C1..N), and the
7-dimension validation rubric.
- UX Coach: leads with the two-spine contract (DESIGN.md +
EXPERIENCE.md), Don Norman framing, named-protagonist
journeys, surface closure as the test, and Stitch integration.
- Market & Industry Research: leads with Deep Research as the
engine, names Porter and Christensen as anchors, lists the 6
deliverable sections, and frames the deliverable as synthesis
not a research dump.
* fix(web-bundles): security hardening + strict bundle validation
Two issues raised by coderabbit on the latest commit:
1. Shell injection surface: execSync was building the zip command
with a template literal that interpolated bundle.slug from JSON.
Even with our controlled inputs, a slug with shell metacharacters
would break quoting. Switched to execFileSync with an argument
array (no shell) and added a strict ^[a-z0-9][a-z0-9-]*$ slug
regex enforced before any FS or zip call.
2. Missing bundle directories were [SKIP]-warned but the script
still printed the release command, allowing an incomplete release
to ship cleanly. Now treated as fatal: any missing or invalid slug
blocks the printed gh command and exits non-zero with the offending
slugs listed.
|
||
|
|
cede485217 |
feat(docs): Add sidebar order validator for doc frontmatter (#2409)
* feat(docs): add sidebar order validator
Adds tools/validate-sidebar-order.js to validate sidebar.order values
in YAML frontmatter across English and translated docs.
Checks for duplicate orders, gaps in sequence, and missing order fields.
For translations, also warns on order drift from English counterparts.
Wired into the quality script as docs:validate-sidebar.
* fix(validate-sidebar): tighten language detection and drift guard, add docstrings
* fix(validate-sidebar): replace subdirectory heuristic with locale pattern matching
detectLanguageDirs() previously classified any top-level docs/ directory
containing subdirectories as a translation language. This was too broad —
if an English section ever gained nested subfolders it would be silently
excluded from validation.
Replaced with a BCP 47 locale-code regex (/^[a-z]{2}(?:-[a-zA-Z]{2})?$/)
that matches known patterns (cs, fr, vi-vn, zh-cn) and won't falsely
classify content sections like explanation/ or reference/.
* fix(validate-sidebar): guard drift check against undefined order values
extractSidebarOrder() returns { hasSidebar: false } when no sidebar block
exists, leaving order as undefined rather than null. The drift check only
guarded against null, allowing undefined values to emit noisy warnings
like "Order drift: ... order undefined".
Changed the guard to typeof === 'number' which correctly excludes both
undefined and null without relying on a specific sentinel value.
* chore(validate-sidebar): add JSDoc docstrings to all functions
Adds @param and @returns annotations to extractSidebarOrder,
detectLanguageDirs, getEnglishSections, checkDirectory,
checkTranslationDrift, and relativePath.
* fix(validate-sidebar): add to pre-commit hook
* refactor(validate-sidebar): harden parsing and edge-case handling
Refactor to main() wrapper with pure return-based APIs, single directory
scan, and shared reporting. Harden frontmatter parsing (anchored delimiter,
direct-child-only order extraction, flow mapping support) and validation
(Infinity/zero guard, gap flood cap, multi-segment locales, graceful ENOENT).
* docs: fix sidebar.order duplicates and gaps across all locales
Resolves all validator errors flagged by the new
tools/validate-sidebar-order.js check.
English (docs/{explanation,how-to,reference}/):
- Renumbered to remove duplicates; established reading order
for new explanation pages added since orders were last set.
Translations (cs, fr, vi-vn, zh-cn):
- Mirrored English structural ordering where files exist, then
compacted to 1..N within each directory to eliminate gaps
caused by missing translation files.
Non-blocking drift warnings remain where translation directories
have fewer files than English; these are expected per the
validator's design.
---------
Co-authored-by: Brian Madison <bmadcode@gmail.com>
|
||
|
|
ee47e30cf6 |
refactor(bmad-ux): spine-based UX skill (DESIGN.md + EXPERIENCE.md) (#2413)
* refactor(bmad-ux): replace bmad-create-ux-design with lean spine-based bmad-ux
* refactor(bmad-ux): adopt DESIGN.md spec, split into two-file spine, align prd/brief
DESIGN.md (visual identity per the Google Labs spec) and EXPERIENCE.md
(behavior, flow, IA) replace the single design.md spine. EXPERIENCE.md
cross-references DESIGN.md tokens via the spec's {path.to.token} syntax.
Example suite restructure
- 3 DESIGN.md examples: editorial (Stitch source / Linen & Logic), calm
native mobile (Quill), shadcn-on-Tailwind web SaaS (Drift)
- 2 paired EXPERIENCE.md examples (Quill, Drift); Linen & Logic unpaired
to model the Stitch handoff scenario
- Replaces the prior 2-example combined spine set
Discovery additions (outcome-driven, one line each)
- Source scan: glob {planning_artifacts}/ for candidates, parent never reads
- Form-factor: resolve before IA closes; journeys often derive it
- Surface closure: every stated need has a surface, every surface a journey
- Named-protagonist journeys (Mary, not "the user")
- Design handoff working mode (extensible producer registry, default: Stitch)
PRD and brief alignment with same insights
- bmad-prd: dropped standalone Primary Persona section from template;
renamed "Personas + Journeys" entry to "Journey-led"; named-protagonist
rule on UJs; form-factor probe; validation checklist updated
- bmad-product-brief: form-factor surfaced in Discovery topics
Quality scan fixes
- Added ## Overview heading; renamed ## Activation to ## On Activation
- Replaced ../ paths in example assets with {planning_artifacts}/
- Sources section compressed (abstract delta-only rule)
- Working mode aligned to "Fast path" / "Coaching path" BMad-wide convention
New
- references/design-md-spec.md: working summary of the spec for the LLM
- customize.toml: design_md_examples, experience_md_examples,
design_handoffs registries
- .prettierignore: ignore .analysis/ quality-scan artifacts repo-wide
* refactor(bmad-ux): activation parity with prd/brief, opt-in reviewer gate, no headline grade
- Restructure On Activation as numbered six-step list mirroring bmad-prd
and bmad-product-brief, restoring the explicit key-resolution list that
earlier crammed-paragraph form had dropped (planning_artifacts and
friends were silently unresolved at Create).
- Make Reviewer Gate opt-in and lens-selectable. At Finalize, ask before
spending tokens on parallel reviewer subagents; at Validate intent,
skip that question but still confirm lens picks. Stops the auto-run
WCAG audit on hobby-stakes work.
- Drop the overall validation grade. Per-category verdicts and severity
counts already say what is true; a single headline grade conflated
design rigor with release readiness and led "POOR" pills landing on
reports whose own bodies described the work as strong. Removed from
references/validate.md (ladder rule + markdown twin), HTML template
(grade pill div + CSS vars + classes).
- Trim creative-tools.md: drop the Custom entries section. Runtime
prompt files should only carry what the LLM needs to act in this
moment; how-to-extend-via-TOML is setup-time human documentation
already covered by customize.toml comments.
* fix(bmad-ux): align validation report template with 8-category rubric
Template placeholders referenced 'Decision-readiness' and 'seven dimensions'
from the prior rubric. Replace with TEMPLATE_CATEGORY_NAME and inline the
eight canonical categories from references/validate.md so the synthesis pass
names them verbatim.
* fix(validate-skills): remove stale WF-01/WF-02 rules
WF-01/WF-02 were originally scoped to workflow.md files (now mostly gone)
but had been generalized to flag name/description in any non-SKILL.md
markdown. That over-captured legitimate spec files — e.g. DESIGN.md
examples in bmad-ux/assets/ that carry name/description per the Google
Labs DESIGN.md spec.
Step files are already covered by STEP-06. Rule count: 14 → 12.
* fix(bmad-ux): address PR review followups
- validation-report-template.html: severity badge class is badge-sev-*,
not sev-* (the comment misled the synthesis pass).
- Sweep dangling bmad-create-ux-design references: module-help.csv,
bmad-agent-ux-designer/customize.toml, bmad-prd/SKILL.md handoff list,
workflow-map.md (en + 4 translations), getting-started.md (en + 4
translations). Workflow-map output column updated to DESIGN.md +
EXPERIENCE.md.
- references/validate.md: Markdown capitalized as a proper noun.
|
||
|
|
a08522631b |
fix(installer): preserve stale installed modules during update (#2391)
* fix(installer): preserve stale installed modules on update * test: drop stale baut regression case * fix(installer): preserve source-backed modules and configs * fix(installer): retain preserved module config in quick update * fix(installer): preserve module config blocks for retained modules * fix(installer): preserve user-scope blocks for retained modules * fix(installer): retain stale modules during updates |
||
|
|
74cf467d57 |
v6.7.0: bundle module registry, retire marketplace, refresh display names (#2388)
* feat(installer): bundle module registry, retire marketplace, refresh display names Prepares v6.7.0 for release: - Moves bundled module list from tools/installer/modules/registry-fallback.yaml to bmad-modules.yaml at repo root; renames to reflect single-source-of-truth role. - Retires the remote marketplace registry fetch in ExternalModuleManager; the installer now reads the bundled YAML only. - Adds WDS (Whiteport Design Studio) entry alongside BMM, BMB, BMA, CIS, GDS, TEA. - Refreshes display names and descriptions on every bundled module; TEA repositioned after BMM in the picker. - Adds plugin_name override field on registry entries so modules whose marketplace.json declares a plugin under a different name than the installer code (e.g. WDS uses bmad-wds) match without falling back to the single-plugin heuristic. - Removes the community modules picker from the interactive installer; previously installed community modules are preserved on update and can still be installed via --custom-source. - Renames the custom-source confirm prompt for clarity. CHANGELOG.md updated with the full v6.7.0 entry. * feat(installer): fully retire community catalog plumbing Removes the last marketplace network connections from the installer. The v6.7.0 first pass retired the official-registry fetch but left CommunityModuleManager + RegistryClient in place, which still fetched community-index.yaml and categories.yaml on every install to support the channel-gate and update flows. This commit: - Deletes tools/installer/modules/community-manager.js and registry-client.js entirely. - Strips CommunityModuleManager calls from ui.js (channel gate + update channels), core/manifest.js (getModuleVersionInfo), core/installer.js (resolution + installed-modules listing), and modules/official-modules.js (findModuleSource fallback + pre-install plugin resolution + post-install manifest entry). - Simplifies installFromResolution: community branch removed; all non-external installs are now treated as custom-source. - Removes corresponding test suites (CommunityModuleManager unit tests and the entire RegistryClient suite). - Updates CHANGELOG with the migration note. After this commit, grep confirms zero references to the bmad-plugins- marketplace registry from the installer. The only remaining 'marketplace' references are about per-repo .claude-plugin/marketplace.json files, which the installer reads from cloned custom-source repos. |
||
|
|
0f852a38ac |
feat(prompts): add directory prompt with updated Clack runtime (#2387)
* chore(deps): update @clack/core and @clack/prompts to latest versions and adjust Node.js engine requirement * feat(prompts): add directory prompt with autocomplete and create-directory support * chore(docs): update Node.js version requirement to 20.12+ across multiple documentation files * fix(prompts): code review fixes |
||
|
|
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 |
||
|
|
a3e0545847 | feat(installer): register automator module | ||
|
|
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> |
||
|
|
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> |
||
|
|
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). |