Compare commits

...

21 Commits

Author SHA1 Message Date
Jacob du Toit 8bbd3736bc
Merge 9bcafdef51 into 88b9a1c842 2026-04-26 09:34:30 -05:00
Brian 88b9a1c842
fix(installer): remove pre-v6.2.0 wrapper skills on update (closes #2309) (#2315)
Adds 32 entries to removals.txt covering the module-prefixed wrapper
skill names used pre-v6.2.0 (bmad-bmm-* and bmad-agent-bmm-*). Users
upgrading from v6.0.x / v6.1.x had these installed in their IDE skill
directories, but the v6.2.0 architecture switch dropped the module
prefix and the cleanup never knew the old names. Stale wrappers stayed
behind alongside the new self-contained skills, causing duplicates and
broken-file errors when invoked (referenced files no longer exist).

The removals.txt entries get added to the cleanup removalSet on every
install/update, so the next install run for an upgrading user removes
the stale wrappers automatically.
2026-04-25 22:08:44 -05:00
github-actions[bot] 69cbeb4d07 chore(release): v6.5.0 [skip ci] 2026-04-26 02:25:31 +00:00
Brian 1d35acfd84
docs: add v6.5.0 changelog entry (#2314) 2026-04-25 21:24:43 -05:00
Brian 01cc32540b
feat(installer): expand to 42 platforms with shared target_dir coordination (#2313)
* refactor(installer): replace legacy_targets auto-cleanup with upgrade warnings

Removes the legacy_targets YAML field and its install-time auto-migration
of pre-v6.1.0 directories (.claude/commands, .opencode/agents, etc.). On
install, surface a warning instead: read manifest version and scan 24
known legacy paths, then print rm -rf commands the user can run themselves.
Also deletes orphan tools/platform-codes.yaml (never loaded by any code)
and fixes a stale URL in the cs translation.

* feat(installer): consolidate to .agents/skills and add global_target_dir for all platforms

Updates platform-codes.yaml against verified primary docs for all 24 supported
platforms. 14 platforms (auggie, codex, crush, cursor, gemini, github-copilot,
kilo, kimi-code, opencode, pi, roo, rovo-dev, windsurf) move their project
target_dir to the cross-tool .agents/skills/ standard. Junie moves from the
broken .agents/skills/ to its own .junie/skills/ per JetBrains docs.

Adds global_target_dir to every platform: 11 share ~/.agents/skills/, Crush
uses XDG ~/.config/agents/skills/, Codex global stays ~/.codex/skills/, the
rest are tool-specific. Ona and Trae omit global (no documented home path).

Note: installer logic does not yet dedupe writes for platforms sharing a
target_dir — users installing multiple .agents/skills/ tools together will
overwrite the same files (harmless on install, but uninstalling one clears
the dir for the others). Coordination logic is the next step.

* feat(installer): add 18 new platforms, dedup shared target_dir, ownership-aware cleanup

Adds 18 platforms from the verified Vercel list (adal, amp, bob, command-code,
cortex, droid, firebender, goose, kode, mistral-vibe, mux, neovate, openclaw,
openhands, pochi, replit, warp, zencoder). Marks codex and github-copilot as
preferred alongside claude-code and cursor.

Coordination for platforms sharing a target_dir:

- IdeManager.setupBatch dedups skill writes when multiple selected platforms
  point at the same target_dir (e.g. .agents/skills/). The first platform
  writes, peers skip the redundant wipe-and-rewrite. Result reports the same
  count and target dir for every member so the install summary is consistent.

- IdeManager.cleanupByList accepts remainingIdes; when removing one platform
  from a shared dir while another co-installed platform still owns it, the
  target_dir wipe is skipped. Platform-specific hooks (copilot markers, kilo
  modes, rovodev prompts) still run.

- _setupIdes uses setupBatch; _removeDeselectedIdes passes remainingIdes so
  partial reconfigure preserves shared skills.

Skill ownership now uses skill-manifest.csv canonicalIds, not the bmad- prefix.
This unblocks custom modules that ship skills with non-bmad names (e.g.
fred-cool-skill). Affected sites:

- _config-driven.detect: reads canonicalIds from the project's bmadDir
- _config-driven.findAncestorConflict: reads canonicalIds from the ancestor's
  own bmadDir, falling back to the prefix only when no manifest exists
- legacy-warnings.findStaleLegacyDirs: same canonicalId-based detection

Migration warnings: LEGACY_SKILL_PATHS adds 12 skill dirs that moved to the
.agents/skills/ standard (cursor, gemini, github-copilot, kimi, opencode, pi,
roo, rovodev, windsurf, plus their globals). Users with stale skills in those
locations get a one-line warning with the rm command per dir.

New shared helper tools/installer/ide/shared/installed-skills.js exposes
getInstalledCanonicalIds(bmadDir) and isBmadOwnedEntry(entry, canonicalIds).

Tests: 9 new assertions across two suites covering dedup, partial uninstall
preservation, and custom-module skill detection. All 286 tests pass.

* fix(installer): setupBatch must not claim a shared target_dir on failure

If the first platform's setup throws or returns success: false, the dedup map
previously still recorded the claim with skillCount: 0, causing every peer
sharing the target_dir to skip its install — leaving the dir empty/broken
behind a cascade of misleading "shares with X" rows.

Now the claim is only recorded when the install succeeded and wrote skills.
On failure, the next peer becomes the new first writer and recovers.

Adds Suite 40b regression test that monkey-patches cursor.setup to throw
and verifies gemini still populates the shared dir.

* fix(installer): address PR #2313 review findings

Three issues raised by augmentcode and coderabbit bot reviewers:

1. _removeDeselectedIdes silently swallowed cleanup failures after the
   refactor to cleanupByList. The old per-IDE try/catch logged a warning;
   the new path discarded the result array. Now logs a warning per failed
   ide so failures stay visible.

2. The legacy-dir cleanup hint printed `rm -rf "<path>"/bmad*` which both
   matched bmad-os-* utility skills the user should keep AND missed the
   custom-module skills (e.g. fred-cool-skill) that the new canonical-id
   detection now finds. Findings now carry the exact entry names from the
   scan, and the warning prints one precise rm line per entry.

3. warnPreNativeSkillsLegacy did unguarded fs reads at install start. A
   permission/IO error would have aborted the whole install. Wrapped the
   call site in try/catch so legacy-scan failures only emit a warning.
2026-04-25 21:14:00 -05:00
github-actions[bot] 1197122001 chore(release): v6.4.0 [skip ci] 2026-04-25 03:34:02 +00:00
Brian 314fe69d14
docs: add v6.4.0 changelog entry (#2310) 2026-04-24 22:31:01 -05:00
Yahya Bin Naveed 9ff9d6f8f3
feat: add Kimi Code CLI support (#2302)
Adds kimi-code to both platform-codes.yaml files so Kimi Code CLI
is available as an install target via the config-driven installer.
Skills are installed to .kimi/skills/, which is the project-level
skills directory per the official Kimi Code CLI documentation.

Closes #1630

Co-authored-by: Brian <bmadcode@gmail.com>
2026-04-24 18:22:09 -05:00
Pablo Ontiveros c29b72ecc0
fix(create-story): read UPDATE files before generating dev notes (#2274)
When a story modifies existing files, create-story must read those
files before generating dev notes. Without this, dev agents improvise
design decisions without knowing the current state of the code, leading
to regressions caught only at review time.

Adds a step at the end of Step 3 (Architecture analysis) that reads
every file marked UPDATE in the architecture directory structure and
documents its current state, what the story changes, and what must
be preserved.

Fixes #2273

Co-authored-by: Brian Madison <bmadcode@gmail.com>
2026-04-24 18:21:10 -05:00
Jérôme Revillard e7a213ed07
feat: uniform customize.toml support across all BMM workflows (#2308)
* feat: extend customize.toml to all 6 developer-execution workflows (#2303)

Add uniform customization support to dev-story, code-review,
sprint-planning, sprint-status, quick-dev, and checkpoint-preview,
matching the same 4 extension points (activation_steps_prepend,
activation_steps_append, persistent_facts, on_complete) already
available on 17 BMM workflows from PR #2287.

- Create customize.toml for each workflow
- Add 6-step activation block to SKILL.md (merge workflow.md
  content in, delete workflow.md per PR #2287 pattern)
- Wire on_complete at terminal steps (inline <action> for XML
  workflows, ## On Complete section for step-file workflows)
- Fix pre-existing step number reference in dev-story (Step 6 → 9)

* fix: correct goto step="6" → step="9" in dev-story

The XML goto at line 203 still pointed to step 6 ("Author
comprehensive tests") instead of step 9 ("Story completion and mark
for review"), which is the actual completion gate. This was the
same class of pre-existing bug fixed in the text (M-1) but
missed in the XML action.

---------

Co-authored-by: Brian <bmadcode@gmail.com>
2026-04-24 17:45:25 -05:00
Murat K Ozcan 0533976753
fix: installer live version for external modules (#2307)
* resolved merge conflict

* fix: addressed PR comments

* fix: use git tags for installer module versions
2026-04-24 13:13:56 -05:00
Jacob du Toit 9bcafdef51
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-04-03 11:04:11 +02:00
Jacob du Toit 92498ebb52
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-26 05:31:03 +02:00
Jacob du Toit fdfe23fc22
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-23 04:01:03 +02:00
Jacob du Toit f32d1d4e8d
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-22 06:03:59 +02:00
Alex Verkhovsky f9e7d65cf9
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-20 15:20:27 -06:00
Jacob du Toit bfdeef0453
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-20 11:00:45 +02:00
Jacob du Toit 3ac8736756
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-20 06:25:14 +02:00
Brian 417fc44a98
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-19 19:29:28 -05:00
Jacob du Toit 4e96a50515
Merge branch 'main' into feat/expand-advanced-elicitation-methods 2026-03-19 07:53:14 +02:00
de Villiers du Toit ad77c8e1c6 feat: expand advanced elicitation methods with 19 new techniques
Adds 19 new elicitation methods across 7 categories including a new
'framing' category. All existing 50 methods preserved. Entries sorted
alphabetically by category then method name.

New methods added:
- advanced: Chain-of-Thought Scaffolding, Few-Shot Exemplar Priming
- collaboration: Six Thinking Hats, Delphi Method
- core: Second-Order Thinking, Inversion Analysis, Problem Decomposition,
  Analogy Mapping, Steelmanning
- creative: Constraint Injection, Morphological Analysis
- framing (new): Abstraction Laddering, Reframe the Question,
  Stakeholder Lens Rotation
- learning: Deliberate Practice Loop
- research: Source Triangulation
- risk: Assumption Audit, Cascading Failure Simulation
- technical: Boundary & Edge Case Sweep

Closes #2061
2026-03-19 05:28:52 +02:00
39 changed files with 2877 additions and 1828 deletions

View File

@ -1,5 +1,74 @@
# Changelog
## v6.5.0 - 2026-04-26
### 🎁 Features
* Support for 18 new agent platforms: AdaL, Sourcegraph Amp, IBM Bob, Command Code, Snowflake Cortex Code, Factory Droid, Firebender, Block Goose, Kode, Mistral Vibe, Mux, Neovate, OpenClaw, OpenHands, Pochi, Replit Agent, Warp, Zencoder — bringing total supported platforms to 42 (#2313)
* All platforms that support the cross-tool `.agents/skills/` standard now use it (#2313)
## v6.4.0 - 2026-04-24
### ✨ Headline
**Full agent and workflow customization across the entire BMad Method.** Every agent and workflow in BMM, Core, CIS, GDS, and TEA can now be customized via TOML overrides in `_bmad/custom/`. Customize agents to apply tooling, version control, or behavior changes across whole groups of workflows. Drop in fine-grained per-workflow overrides where you need them. Built for power users who want BMad to fit their stack without forking.
**Stable and bleeding-edge release channels, standardized across all modules.** Pick `stable` or `next` per module, pin specific versions, and switch channels interactively or via CLI flags (`--channel`, `--all-stable`, `--all-next`, `--next=CODE`, `--pin CODE=TAG`). Same model across BMM, Core, and every external module.
### 💥 Breaking Changes
* Customization is now TOML-based; the briefly introduced YAML-based customization is no longer supported (#2284, #2283)
### 🎁 Features
**Customization framework**
* TOML-based agent and workflow customization with flat schema, structural merge rules (scalars, tables, code-keyed arrays, append arrays), and `persistent_facts` unification (#2284)
* Central `_bmad/config.toml` surface with four-file architecture (`config.toml`, `config.user.toml`, `custom/config.toml`, `custom/config.user.toml`) for agent roster and scope-partitioned install answers (#2285)
* `customize.toml` support extended to 17 bmm-skills workflows with flattened SKILL.md architecture and standardized `[workflow]` block (#2287)
* `customize.toml` extended to all six developer-execution workflows: bmad-dev-story, bmad-code-review, bmad-sprint-planning, bmad-sprint-status, bmad-quick-dev, bmad-checkpoint-preview (#2308)
* `bmad-customize` skill — guided authoring of TOML overrides in `_bmad/custom/` with stdlib-only resolver verification (#2289)
* Wire `on_complete` hook into all 23 workflow terminal steps with full customize.toml documentation (#2290)
**Release channels & installer**
* Channel-based version resolution for external modules with interactive channel management (`stable` / `next` / `pinned`) and CLI flags (`--channel`, `--all-stable`, `--all-next`, `--next=CODE`, `--pin CODE=TAG`) (#2305)
* GitHub API as primary fetch with raw CDN fallback in installer registry client to support corporate proxies (#2248)
**Other**
* Kimi Code CLI support for installing BMM skills in `.kimi/skills/` (#2302)
* `bmad-create-story` now reads every UPDATE-marked file before generating dev notes so brownfield stories preserve current behavior instead of improvising at implementation time (#2274)
* Sync `sprint-status.yaml` from quick-dev on epic-story implementation with idempotent writes tracking `in-progress` and `review` transitions (#2234)
* Enforce model parity for all code review subagents to match orchestrator session capability for improved rare-event detection (#2236)
* Set `team: software-development` on all six BMM agents for unified grouping in party-mode and retrospective skills (#2286)
### 🐛 Bug Fixes
* PRD workflow no longer silently de-scopes user requirements or invents MVP/Growth/Vision phasing; requires explicit confirmation before any scope reduction (#1927)
* Installer shows live npm version for external modules instead of stale cached metadata (#2307)
* Resolve external-module agents from cache during manifest write so agents land in `config.toml` (#2295)
* Fix installer version resolution for external modules with shared resolver preferring package.json > module.yaml > marketplace.json (#2298)
* Replace fs-extra with native `node:fs` to prevent file loss during multi-module installs from deferred retry-queue races (#2253)
* Add `move()` and overwrite support to fs-native wrapper for directory migrations during upgrades (#2253)
* Stop skill scanner from recursing into discovered skills to prevent spurious errors on nested template files (#2255)
* Source built-in modules locally in installer UI to preserve core and bmm in module list when registry is unreachable (#2251)
* Remove dead Batch-apply option from code-review patch menu and rename apply options for clarity (#2225)
### ♻️ Refactoring
* Remove 1,683 lines of dead code: three entirely dead files (agent-command-generator.js, bmad-artifacts.js, module-injections.js) and ~50 unused exports across installer modules (#2247)
* Remove dead template and agent-command pipeline from installer; SKILL.md directory copying is the sole installation path (#2244)
### 📚 Documentation
* Sync and update Vietnamese (vi-VN) docs with missing pages and refreshed translations (#2291, #2222)
* Sync French (fr-FR) translations with upstream, restore Amelia as dev agent, fix sidebar ordering (#2231)
* Add Czech (cs-CZ) `analysis-phase.md` translation; normalize typographic quotes (#2240, #2241, #2242)
* Add missing Chinese (zh-CN) translations for 3 documents (#2254)
* Update stale Analyst agent triggers and add PRFAQ link (#2238)
* Remove Bob from workflow map diagrams reflecting consolidation into Amelia in v6.3.0 (#2252)
## v6.3.0 - 2026-04-09
### 💥 Breaking Changes

View File

@ -60,7 +60,7 @@ Dostupná ID nástrojů pro příznak `--tools`:
**Preferované:** `claude-code`, `cursor`
Spusťte `npx bmad-method install` interaktivně jednou pro zobrazení aktuálního seznamu podporovaných nástrojů, nebo zkontrolujte [konfiguraci kódů platforem](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/tools/cli/installers/lib/ide/platform-codes.yaml).
Spusťte `npx bmad-method install` interaktivně jednou pro zobrazení aktuálního seznamu podporovaných nástrojů, nebo zkontrolujte [konfiguraci kódů platforem](https://github.com/bmad-code-org/BMAD-METHOD/blob/main/tools/installer/ide/platform-codes.yaml).
## Režimy instalace

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "bmad-method",
"version": "6.3.0",
"version": "6.5.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "bmad-method",
"version": "6.3.0",
"version": "6.5.0",
"license": "MIT",
"dependencies": {
"@clack/core": "^1.0.0",

View File

@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "bmad-method",
"version": "6.3.0",
"version": "6.5.0",
"description": "Breakthrough Method of Agile AI-driven Development",
"keywords": [
"agile",

View File

@ -15,3 +15,40 @@ bmad-quick-spec
bmad-quick-flow
bmad-quick-dev-new-preview
bmad-init
# Pre-v6.2.0 wrapper skills (module-prefixed naming, dropped in v6.2.0).
# Users upgrading from v6.0.x / v6.1.x had these installed and the cleanup
# never knew to remove them; they remained alongside the new self-contained
# skills causing duplicates and broken-file errors. See issue #2309.
bmad-agent-bmm-analyst
bmad-agent-bmm-architect
bmad-agent-bmm-dev
bmad-agent-bmm-pm
bmad-agent-bmm-qa
bmad-agent-bmm-quick-flow-solo-dev
bmad-agent-bmm-sm
bmad-agent-bmm-tech-writer
bmad-agent-bmm-ux-designer
bmad-bmm-check-implementation-readiness
bmad-bmm-code-review
bmad-bmm-correct-course
bmad-bmm-create-architecture
bmad-bmm-create-epics-and-stories
bmad-bmm-create-prd
bmad-bmm-create-product-brief
bmad-bmm-create-story
bmad-bmm-create-ux-design
bmad-bmm-dev-story
bmad-bmm-document-project
bmad-bmm-domain-research
bmad-bmm-edit-prd
bmad-bmm-generate-project-context
bmad-bmm-market-research
bmad-bmm-qa-generate-e2e-tests
bmad-bmm-quick-dev
bmad-bmm-quick-spec
bmad-bmm-retrospective
bmad-bmm-sprint-planning
bmad-bmm-sprint-status
bmad-bmm-technical-research
bmad-bmm-validate-prd

View File

@ -7,7 +7,55 @@ description: 'LLM-assisted human-in-the-loop review. Make sense of a change, foc
**Goal:** Guide a human through reviewing a change — from purpose and context into details.
You are assisting the user in reviewing a change.
**Your Role:** You are assisting the user in reviewing a change.
## Conventions
- Bare paths (e.g. `step-01-orientation.md`) resolve from the skill root.
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives).
- `{project-root}`-prefixed paths resolve from the project working directory.
- `{skill-name}` resolves to the skill directory's basename.
## On Activation
### Step 1: Resolve the Workflow Block
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
1. `{skill-root}/customize.toml` — defaults
2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides
3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides
Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append.
### Step 2: Execute Prepend Steps
Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding.
### Step 3: Load Persistent Facts
Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
### Step 4: Load Config
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `implementation_artifacts`
- `planning_artifacts`
- `communication_language`
- `document_output_language`
### Step 5: Greet the User
Greet the user, speaking in `{communication_language}`.
### Step 6: Execute Append Steps
Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete. Begin the workflow below.
## Global Step Rules (apply to every step)
@ -15,15 +63,6 @@ You are assisting the user in reviewing a change.
- **Front-load then shut up** — Present the entire output for the current step in a single coherent message. Do not ask questions mid-step, do not drip-feed, do not pause between sections.
- **Language** — Speak in `{communication_language}`. Write any file output in `{document_output_language}`.
## INITIALIZATION
Load and read full config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `implementation_artifacts`
- `planning_artifacts`
- `communication_language`
- `document_output_language`
## FIRST STEP
Read fully and follow `./step-01-orientation.md` to begin.

View File

@ -0,0 +1,41 @@
# DO NOT EDIT -- overwritten on every update.
#
# Workflow customization surface for bmad-checkpoint-preview. Mirrors the
# agent customization shape under the [workflow] namespace.
[workflow]
# --- Configurable below. Overrides merge per BMad structural rules: ---
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
# Steps to run before the standard activation (config load, greet).
# Overrides append. Use for pre-flight loads, compliance checks, etc.
activation_steps_prepend = []
# Steps to run after greet but before the workflow begins.
# Overrides append. Use for context-heavy setup that should happen
# once the user has been acknowledged.
activation_steps_append = []
# Persistent facts the workflow keeps in mind for the whole run
# (standards, compliance constraints, stylistic guardrails).
# Distinct from the runtime memory sidecar — these are static context
# loaded on activation. Overrides append.
#
# Each entry is either:
# - a literal sentence, e.g. "All stories must include testable acceptance criteria."
# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
# (glob patterns are supported; the file's contents are loaded and treated as facts).
persistent_facts = [
"file:{project-root}/**/project-context.md",
]
# Scalar: executed when the workflow reaches its final step,
# after the review decision (approve/rework/discuss) is made. Override wins.
# Leave empty for no custom post-completion behavior.
on_complete = ""

View File

@ -22,3 +22,9 @@ HALT — do not proceed until the user makes their choice.
- **Approve**: Acknowledge briefly. If the human wants to patch something before shipping, help apply the fix interactively. If reviewing a PR, offer to approve via `gh pr review --approve` — but confirm with the human before executing, since this is a visible action on a shared resource.
- **Rework**: Ask what went wrong — was it the approach, the spec, or the implementation? Help the human decide on next steps (revert commit, open an issue, revise the spec, etc.). Help draft specific, actionable feedback tied to `path:line` locations if the change is a PR from someone else.
- **Discuss**: Open conversation — answer questions, explore concerns, dig into any aspect. After discussion, return to the decision prompt above.
## On Complete
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.

View File

@ -3,4 +3,88 @@ name: bmad-code-review
description: 'Review code changes adversarially using parallel review layers (Blind Hunter, Edge Case Hunter, Acceptance Auditor) with structured triage into actionable categories. Use when the user says "run code review" or "review this code"'
---
Follow the instructions in ./workflow.md.
# Code Review Workflow
**Goal:** Review code changes adversarially using parallel review layers and structured triage.
**Your Role:** You are an elite code reviewer. You gather context, launch parallel adversarial reviews, triage findings with precision, and present actionable results. No noise, no filler.
## Conventions
- Bare paths (e.g. `checklist.md`) resolve from the skill root.
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives).
- `{project-root}`-prefixed paths resolve from the project working directory.
- `{skill-name}` resolves to the skill directory's basename.
## On Activation
### Step 1: Resolve the Workflow Block
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
1. `{skill-root}/customize.toml` — defaults
2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides
3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides
Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append.
### Step 2: Execute Prepend Steps
Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding.
### Step 3: Load Persistent Facts
Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
### Step 4: Load Config
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level`
- `date` as system-generated current datetime
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
- `project_context` = `**/project-context.md` (load if exists)
- CLAUDE.md / memory files (load if exist)
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
### Step 5: Greet the User
Greet `{user_name}`, speaking in `{communication_language}`.
### Step 6: Execute Append Steps
Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete. Begin the workflow below.
## WORKFLOW ARCHITECTURE
This uses **step-file architecture** for disciplined execution:
- **Micro-file Design**: Each step is self-contained and followed exactly
- **Just-In-Time Loading**: Only load the current step file
- **Sequential Enforcement**: Complete steps in order, no skipping
- **State Tracking**: Persist progress via in-memory variables
- **Append-Only Building**: Build artifacts incrementally
### Step Processing Rules
1. **READ COMPLETELY**: Read the entire step file before acting
2. **FOLLOW SEQUENCE**: Execute sections in order
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human
4. **LOAD NEXT**: When directed, read fully and follow the next step file
### Critical Rules (NO EXCEPTIONS)
- **NEVER** load multiple step files simultaneously
- **ALWAYS** read entire step file before execution
- **NEVER** skip steps or optimize the sequence
- **ALWAYS** follow the exact instructions in the step file
- **ALWAYS** halt at checkpoints and wait for human input
## FIRST STEP
Read fully and follow: `./steps/step-01-gather-context.md`

View File

@ -0,0 +1,41 @@
# DO NOT EDIT -- overwritten on every update.
#
# Workflow customization surface for bmad-code-review. Mirrors the
# agent customization shape under the [workflow] namespace.
[workflow]
# --- Configurable below. Overrides merge per BMad structural rules: ---
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
# Steps to run before the standard activation (config load, greet).
# Overrides append. Use for pre-flight loads, compliance checks, etc.
activation_steps_prepend = []
# Steps to run after greet but before the workflow begins.
# Overrides append. Use for context-heavy setup that should happen
# once the user has been acknowledged.
activation_steps_append = []
# Persistent facts the workflow keeps in mind for the whole run
# (standards, compliance constraints, stylistic guardrails).
# Distinct from the runtime memory sidecar — these are static context
# loaded on activation. Overrides append.
#
# Each entry is either:
# - a literal sentence, e.g. "All stories must include testable acceptance criteria."
# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
# (glob patterns are supported; the file's contents are loaded and treated as facts).
persistent_facts = [
"file:{project-root}/**/project-context.md",
]
# Scalar: executed when the workflow reaches its final step,
# after review findings are presented and sprint status is synced. Override wins.
# Leave empty for no custom post-completion behavior.
on_complete = ""

View File

@ -124,3 +124,9 @@ Present the user with follow-up options:
> 3. **Done** — end the workflow
**HALT** — I am waiting for your choice. Do not proceed until the user selects an option.
## On Complete
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.

View File

@ -1,55 +0,0 @@
---
main_config: '{project-root}/_bmad/bmm/config.yaml'
---
# Code Review Workflow
**Goal:** Review code changes adversarially using parallel review layers and structured triage.
**Your Role:** You are an elite code reviewer. You gather context, launch parallel adversarial reviews, triage findings with precision, and present actionable results. No noise, no filler.
## WORKFLOW ARCHITECTURE
This uses **step-file architecture** for disciplined execution:
- **Micro-file Design**: Each step is self-contained and followed exactly
- **Just-In-Time Loading**: Only load the current step file
- **Sequential Enforcement**: Complete steps in order, no skipping
- **State Tracking**: Persist progress via in-memory variables
- **Append-Only Building**: Build artifacts incrementally
### Step Processing Rules
1. **READ COMPLETELY**: Read the entire step file before acting
2. **FOLLOW SEQUENCE**: Execute sections in order
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human
4. **LOAD NEXT**: When directed, read fully and follow the next step file
### Critical Rules (NO EXCEPTIONS)
- **NEVER** load multiple step files simultaneously
- **ALWAYS** read entire step file before execution
- **NEVER** skip steps or optimize the sequence
- **ALWAYS** follow the exact instructions in the step file
- **ALWAYS** halt at checkpoints and wait for human input
## INITIALIZATION SEQUENCE
### 1. Configuration Loading
Load and read full config from `{main_config}` and resolve:
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level`
- `date` as system-generated current datetime
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
- `project_context` = `**/project-context.md` (load if exists)
- CLAUDE.md / memory files (load if exist)
YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`.
### 2. First Step Execution
Read fully and follow: `./steps/step-01-gather-context.md` to begin the workflow.

View File

@ -302,6 +302,18 @@ Activation is complete. Begin the workflow below.
processes - **Integration Patterns:** External service integrations, data flows <action>Extract any story-specific requirements that the
developer MUST follow</action>
<action>Identify any architectural decisions that override previous patterns</action>
<!-- Read existing code being modified — non-negotiable -->
<critical>📂 READ FILES BEING MODIFIED — skipping this is the primary cause of implementation failures and review cycles</critical>
<action>From the architecture directory structure, identify every file marked UPDATE (not NEW) that this story will touch</action>
<action>Read each relevant UPDATE file completely. For each one, document in dev notes:
- Current state: what it does today (state machine, API calls, data shapes, existing behaviors)
- What this story changes: the specific sections or behaviors being modified
- What must be preserved: existing interactions and behaviors the story must not break
</action>
<critical>A story implementation must leave the system working end-to-end — not just satisfy its stated ACs.
If a behavior is required for the feature to work correctly in the existing system, it is a requirement
whether or not it is explicitly written in the story. The dev agent owns this.</critical>
</step>
<step n="4" goal="Web research for latest technical specifics">

View File

@ -3,4 +3,483 @@ name: bmad-dev-story
description: 'Execute story implementation following a context filled story spec file. Use when the user says "dev this story [story file]" or "implement the next story in the sprint plan"'
---
Follow the instructions in ./workflow.md.
# Dev Story Workflow
**Goal:** Execute story implementation following a context filled story spec file.
**Your Role:** Developer implementing the story.
- Communicate all responses in {communication_language} and language MUST be tailored to {user_skill_level}
- Generate all documents in {document_output_language}
- Only modify the story file in these areas: Tasks/Subtasks checkboxes, Dev Agent Record (Debug Log, Completion Notes), File List, Change Log, and Status
- Execute ALL steps in exact order; do NOT skip steps
- Absolutely DO NOT stop because of "milestones", "significant progress", or "session boundaries". Continue in a single execution until the story is COMPLETE (all ACs satisfied and all tasks/subtasks checked) UNLESS a HALT condition is triggered or the USER gives other instruction.
- Do NOT schedule a "next session" or request review pauses unless a HALT condition applies. Only Step 9 decides completion.
- User skill level ({user_skill_level}) affects conversation style ONLY, not code updates.
## Conventions
- Bare paths (e.g. `steps/step-01-init.md`) resolve from the skill root.
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives).
- `{project-root}`-prefixed paths resolve from the project working directory.
- `{skill-name}` resolves to the skill directory's basename.
## On Activation
### Step 1: Resolve the Workflow Block
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
1. `{skill-root}/customize.toml` — defaults
2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides
3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides
Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append.
### Step 2: Execute Prepend Steps
Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding.
### Step 3: Load Persistent Facts
Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
### Step 4: Load Config
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `user_name`
- `communication_language`, `document_output_language`
- `user_skill_level`
- `implementation_artifacts`
- `date` as system-generated current datetime
### Step 5: Greet the User
Greet `{user_name}`, speaking in `{communication_language}`.
### Step 6: Execute Append Steps
Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete. Begin the workflow below.
## Paths
- `story_file` = `` (explicit story path; auto-discovered if empty)
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
## Execution
<workflow>
<critical>Communicate all responses in {communication_language} and language MUST be tailored to {user_skill_level}</critical>
<critical>Generate all documents in {document_output_language}</critical>
<critical>Only modify the story file in these areas: Tasks/Subtasks checkboxes, Dev Agent Record (Debug Log, Completion Notes), File List,
Change Log, and Status</critical>
<critical>Execute ALL steps in exact order; do NOT skip steps</critical>
<critical>Absolutely DO NOT stop because of "milestones", "significant progress", or "session boundaries". Continue in a single execution
until the story is COMPLETE (all ACs satisfied and all tasks/subtasks checked) UNLESS a HALT condition is triggered or the USER gives
other instruction.</critical>
<critical>Do NOT schedule a "next session" or request review pauses unless a HALT condition applies. Only Step 9 decides completion.</critical>
<critical>User skill level ({user_skill_level}) affects conversation style ONLY, not code updates.</critical>
<step n="1" goal="Find next ready story and load it" tag="sprint-status">
<check if="{{story_path}} is provided">
<action>Use {{story_path}} directly</action>
<action>Read COMPLETE story file</action>
<action>Extract story_key from filename or metadata</action>
<goto anchor="task_check" />
</check>
<!-- Sprint-based story discovery -->
<check if="{{sprint_status}} file exists">
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{sprint_status}}</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely to understand story order</action>
<action>Find the FIRST story (by reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "ready-for-dev"
</action>
<check if="no ready-for-dev or in-progress story found">
<output>📋 No ready-for-dev stories found in sprint-status.yaml
**Current Sprint Status:** {{sprint_status_summary}}
**What would you like to do?**
1. Run `create-story` to create next story from epics with comprehensive context
2. Run `*validate-create-story` to improve existing stories before development (recommended quality check)
3. Specify a particular story file to develop (provide full path)
4. Check {{sprint_status}} file to see current sprint status
💡 **Tip:** Stories in `ready-for-dev` may not have been validated. Consider running `validate-create-story` first for a quality
check.
</output>
<ask>Choose option [1], [2], [3], or [4], or specify story file path:</ask>
<check if="user chooses '1'">
<action>HALT - Run create-story to create next story</action>
</check>
<check if="user chooses '2'">
<action>HALT - Run validate-create-story to improve existing stories</action>
</check>
<check if="user chooses '3'">
<ask>Provide the story file path to develop:</ask>
<action>Store user-provided story path as {{story_path}}</action>
<goto anchor="task_check" />
</check>
<check if="user chooses '4'">
<output>Loading {{sprint_status}} for detailed status review...</output>
<action>Display detailed sprint status analysis</action>
<action>HALT - User can review sprint status and provide story path</action>
</check>
<check if="user provides story file path">
<action>Store user-provided story path as {{story_path}}</action>
<goto anchor="task_check" />
</check>
</check>
</check>
<!-- Non-sprint story discovery -->
<check if="{{sprint_status}} file does NOT exist">
<action>Search {implementation_artifacts} for stories directly</action>
<action>Find stories with "ready-for-dev" status in files</action>
<action>Look for story files matching pattern: *-*-*.md</action>
<action>Read each candidate story file to check Status section</action>
<check if="no ready-for-dev stories found in story files">
<output>📋 No ready-for-dev stories found
**Available Options:**
1. Run `create-story` to create next story from epics with comprehensive context
2. Run `*validate-create-story` to improve existing stories
3. Specify which story to develop
</output>
<ask>What would you like to do? Choose option [1], [2], or [3]:</ask>
<check if="user chooses '1'">
<action>HALT - Run create-story to create next story</action>
</check>
<check if="user chooses '2'">
<action>HALT - Run validate-create-story to improve existing stories</action>
</check>
<check if="user chooses '3'">
<ask>It's unclear what story you want developed. Please provide the full path to the story file:</ask>
<action>Store user-provided story path as {{story_path}}</action>
<action>Continue with provided story file</action>
</check>
</check>
<check if="ready-for-dev story found in files">
<action>Use discovered story file and extract story_key</action>
</check>
</check>
<action>Store the found story_key (e.g., "1-2-user-authentication") for later status updates</action>
<action>Find matching story file in {implementation_artifacts} using story_key pattern: {{story_key}}.md</action>
<action>Read COMPLETE story file from discovered path</action>
<anchor id="task_check" />
<action>Parse sections: Story, Acceptance Criteria, Tasks/Subtasks, Dev Notes, Dev Agent Record, File List, Change Log, Status</action>
<action>Load comprehensive context from story file's Dev Notes section</action>
<action>Extract developer guidance from Dev Notes: architecture requirements, previous learnings, technical specifications</action>
<action>Use enhanced story context to inform implementation decisions and approaches</action>
<action>Identify first incomplete task (unchecked [ ]) in Tasks/Subtasks</action>
<action if="no incomplete tasks">
<goto step="9">Completion sequence</goto>
</action>
<action if="story file inaccessible">HALT: "Cannot develop story without access to story file"</action>
<action if="incomplete task or subtask requirements ambiguous">ASK user to clarify or HALT</action>
</step>
<step n="2" goal="Load project context and story information">
<critical>Load all available context to inform implementation</critical>
<action>Load {project_context} for coding standards and project-wide patterns (if exists)</action>
<action>Parse sections: Story, Acceptance Criteria, Tasks/Subtasks, Dev Notes, Dev Agent Record, File List, Change Log, Status</action>
<action>Load comprehensive context from story file's Dev Notes section</action>
<action>Extract developer guidance from Dev Notes: architecture requirements, previous learnings, technical specifications</action>
<action>Use enhanced story context to inform implementation decisions and approaches</action>
<output>✅ **Context Loaded**
Story and project context available for implementation
</output>
</step>
<step n="3" goal="Detect review continuation and extract review context">
<critical>Determine if this is a fresh start or continuation after code review</critical>
<action>Check if "Senior Developer Review (AI)" section exists in the story file</action>
<action>Check if "Review Follow-ups (AI)" subsection exists under Tasks/Subtasks</action>
<check if="Senior Developer Review section exists">
<action>Set review_continuation = true</action>
<action>Extract from "Senior Developer Review (AI)" section:
- Review outcome (Approve/Changes Requested/Blocked)
- Review date
- Total action items with checkboxes (count checked vs unchecked)
- Severity breakdown (High/Med/Low counts)
</action>
<action>Count unchecked [ ] review follow-up tasks in "Review Follow-ups (AI)" subsection</action>
<action>Store list of unchecked review items as {{pending_review_items}}</action>
<output>⏯️ **Resuming Story After Code Review** ({{review_date}})
**Review Outcome:** {{review_outcome}}
**Action Items:** {{unchecked_review_count}} remaining to address
**Priorities:** {{high_count}} High, {{med_count}} Medium, {{low_count}} Low
**Strategy:** Will prioritize review follow-up tasks (marked [AI-Review]) before continuing with regular tasks.
</output>
</check>
<check if="Senior Developer Review section does NOT exist">
<action>Set review_continuation = false</action>
<action>Set {{pending_review_items}} = empty</action>
<output>🚀 **Starting Fresh Implementation**
Story: {{story_key}}
Story Status: {{current_status}}
First incomplete task: {{first_task_description}}
</output>
</check>
</step>
<step n="4" goal="Mark story in-progress" tag="sprint-status">
<check if="{{sprint_status}} file exists">
<action>Load the FULL file: {{sprint_status}}</action>
<action>Read all development_status entries to find {{story_key}}</action>
<action>Get current status value for development_status[{{story_key}}]</action>
<check if="current status == 'ready-for-dev' OR review_continuation == true">
<action>Update the story in the sprint status report to = "in-progress"</action>
<action>Update last_updated field to current date</action>
<output>🚀 Starting work on story {{story_key}}
Status updated: ready-for-dev → in-progress
</output>
</check>
<check if="current status == 'in-progress'">
<output>⏯️ Resuming work on story {{story_key}}
Story is already marked in-progress
</output>
</check>
<check if="current status is neither ready-for-dev nor in-progress">
<output>⚠️ Unexpected story status: {{current_status}}
Expected ready-for-dev or in-progress. Continuing anyway...
</output>
</check>
<action>Store {{current_sprint_status}} for later use</action>
</check>
<check if="{{sprint_status}} file does NOT exist">
<output>ℹ️ No sprint status file exists - story progress will be tracked in story file only</output>
<action>Set {{current_sprint_status}} = "no-sprint-tracking"</action>
</check>
</step>
<step n="5" goal="Implement task following red-green-refactor cycle">
<critical>FOLLOW THE STORY FILE TASKS/SUBTASKS SEQUENCE EXACTLY AS WRITTEN - NO DEVIATION</critical>
<action>Review the current task/subtask from the story file - this is your authoritative implementation guide</action>
<action>Plan implementation following red-green-refactor cycle</action>
<!-- RED PHASE -->
<action>Write FAILING tests first for the task/subtask functionality</action>
<action>Confirm tests fail before implementation - this validates test correctness</action>
<!-- GREEN PHASE -->
<action>Implement MINIMAL code to make tests pass</action>
<action>Run tests to confirm they now pass</action>
<action>Handle error conditions and edge cases as specified in task/subtask</action>
<!-- REFACTOR PHASE -->
<action>Improve code structure while keeping tests green</action>
<action>Ensure code follows architecture patterns and coding standards from Dev Notes</action>
<action>Document technical approach and decisions in Dev Agent Record → Implementation Plan</action>
<action if="new dependencies required beyond story specifications">HALT: "Additional dependencies need user approval"</action>
<action if="3 consecutive implementation failures occur">HALT and request guidance</action>
<action if="required configuration is missing">HALT: "Cannot proceed without necessary configuration files"</action>
<critical>NEVER implement anything not mapped to a specific task/subtask in the story file</critical>
<critical>NEVER proceed to next task until current task/subtask is complete AND tests pass</critical>
<critical>Execute continuously without pausing until all tasks/subtasks are complete or explicit HALT condition</critical>
<critical>Do NOT propose to pause for review until Step 9 completion gates are satisfied</critical>
</step>
<step n="6" goal="Author comprehensive tests">
<action>Create unit tests for business logic and core functionality introduced/changed by the task</action>
<action>Add integration tests for component interactions specified in story requirements</action>
<action>Include end-to-end tests for critical user flows when story requirements demand them</action>
<action>Cover edge cases and error handling scenarios identified in story Dev Notes</action>
</step>
<step n="7" goal="Run validations and tests">
<action>Determine how to run tests for this repo (infer test framework from project structure)</action>
<action>Run all existing tests to ensure no regressions</action>
<action>Run the new tests to verify implementation correctness</action>
<action>Run linting and code quality checks if configured in project</action>
<action>Validate implementation meets ALL story acceptance criteria; enforce quantitative thresholds explicitly</action>
<action if="regression tests fail">STOP and fix before continuing - identify breaking changes immediately</action>
<action if="new tests fail">STOP and fix before continuing - ensure implementation correctness</action>
</step>
<step n="8" goal="Validate and mark task complete ONLY when fully done">
<critical>NEVER mark a task complete unless ALL conditions are met - NO LYING OR CHEATING</critical>
<!-- VALIDATION GATES -->
<action>Verify ALL tests for this task/subtask ACTUALLY EXIST and PASS 100%</action>
<action>Confirm implementation matches EXACTLY what the task/subtask specifies - no extra features</action>
<action>Validate that ALL acceptance criteria related to this task are satisfied</action>
<action>Run full test suite to ensure NO regressions introduced</action>
<!-- REVIEW FOLLOW-UP HANDLING -->
<check if="task is review follow-up (has [AI-Review] prefix)">
<action>Extract review item details (severity, description, related AC/file)</action>
<action>Add to resolution tracking list: {{resolved_review_items}}</action>
<!-- Mark task in Review Follow-ups section -->
<action>Mark task checkbox [x] in "Tasks/Subtasks → Review Follow-ups (AI)" section</action>
<!-- CRITICAL: Also mark corresponding action item in review section -->
<action>Find matching action item in "Senior Developer Review (AI) → Action Items" section by matching description</action>
<action>Mark that action item checkbox [x] as resolved</action>
<action>Add to Dev Agent Record → Completion Notes: "✅ Resolved review finding [{{severity}}]: {{description}}"</action>
</check>
<!-- ONLY MARK COMPLETE IF ALL VALIDATION PASS -->
<check if="ALL validation gates pass AND tests ACTUALLY exist and pass">
<action>ONLY THEN mark the task (and subtasks) checkbox with [x]</action>
<action>Update File List section with ALL new, modified, or deleted files (paths relative to repo root)</action>
<action>Add completion notes to Dev Agent Record summarizing what was ACTUALLY implemented and tested</action>
</check>
<check if="ANY validation fails">
<action>DO NOT mark task complete - fix issues first</action>
<action>HALT if unable to fix validation failures</action>
</check>
<check if="review_continuation == true and {{resolved_review_items}} is not empty">
<action>Count total resolved review items in this session</action>
<action>Add Change Log entry: "Addressed code review findings - {{resolved_count}} items resolved (Date: {{date}})"</action>
</check>
<action>Save the story file</action>
<action>Determine if more incomplete tasks remain</action>
<action if="more tasks remain">
<goto step="5">Next task</goto>
</action>
<action if="no tasks remain">
<goto step="9">Completion</goto>
</action>
</step>
<step n="9" goal="Story completion and mark for review" tag="sprint-status">
<action>Verify ALL tasks and subtasks are marked [x] (re-scan the story document now)</action>
<action>Run the full regression suite (do not skip)</action>
<action>Confirm File List includes every changed file</action>
<action>Execute enhanced definition-of-done validation</action>
<action>Update the story Status to: "review"</action>
<!-- Enhanced Definition of Done Validation -->
<action>Validate definition-of-done checklist with essential requirements:
- All tasks/subtasks marked complete with [x]
- Implementation satisfies every Acceptance Criterion
- Unit tests for core functionality added/updated
- Integration tests for component interactions added when required
- End-to-end tests for critical flows added when story demands them
- All tests pass (no regressions, new tests successful)
- Code quality checks pass (linting, static analysis if configured)
- File List includes every new/modified/deleted file (relative paths)
- Dev Agent Record contains implementation notes
- Change Log includes summary of changes
- Only permitted story sections were modified
</action>
<!-- Mark story ready for review - sprint status conditional -->
<check if="{sprint_status} file exists AND {{current_sprint_status}} != 'no-sprint-tracking'">
<action>Load the FULL file: {sprint_status}</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "in-progress" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "review"</action>
<action>Update last_updated field to current date</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<output>✅ Story status updated to "review" in sprint-status.yaml</output>
</check>
<check if="{sprint_status} file does NOT exist OR {{current_sprint_status}} == 'no-sprint-tracking'">
<output>ℹ️ Story status updated to "review" in story file (no sprint tracking configured)</output>
</check>
<check if="story key not found in sprint status">
<output>⚠️ Story file updated, but sprint-status update failed: {{story_key}} not found
Story status is set to "review" in file, but sprint-status.yaml may be out of sync.
</output>
</check>
<!-- Final validation gates -->
<action if="any task is incomplete">HALT - Complete remaining tasks before marking ready for review</action>
<action if="regression failures exist">HALT - Fix regression issues before completing</action>
<action if="File List is incomplete">HALT - Update File List with all changed files</action>
<action if="definition-of-done validation fails">HALT - Address DoD failures before completing</action>
</step>
<step n="10" goal="Completion communication and user support">
<action>Execute the enhanced definition-of-done checklist using the validation framework</action>
<action>Prepare a concise summary in Dev Agent Record → Completion Notes</action>
<action>Communicate to {user_name} that story implementation is complete and ready for review</action>
<action>Summarize key accomplishments: story ID, story key, title, key changes made, tests added, files modified</action>
<action>Provide the story file path and current status (now "review")</action>
<action>Based on {user_skill_level}, ask if user needs any explanations about:
- What was implemented and how it works
- Why certain technical decisions were made
- How to test or verify the changes
- Any patterns, libraries, or approaches used
- Anything else they'd like clarified
</action>
<check if="user asks for explanations">
<action>Provide clear, contextual explanations tailored to {user_skill_level}</action>
<action>Use examples and references to specific code when helpful</action>
</check>
<action>Once explanations are complete (or user indicates no questions), suggest logical next steps</action>
<action>Recommended next steps (flexible based on project setup):
- Review the implemented story and test the changes
- Verify all acceptance criteria are met
- Ensure deployment readiness if applicable
- Run `code-review` workflow for peer review
- Optional: If Test Architect module installed, run `/bmad:tea:automate` to expand guardrail tests
</action>
<output>💡 **Tip:** For best results, run `code-review` using a **different** LLM than the one that implemented this story.</output>
<check if="{sprint_status} file exists">
<action>Suggest checking {sprint_status} to see project progress</action>
</check>
<action>Remain flexible - allow user to choose their own path or ask for other assistance</action>
<action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
</step>
</workflow>

View File

@ -0,0 +1,41 @@
# DO NOT EDIT -- overwritten on every update.
#
# Workflow customization surface for bmad-dev-story. Mirrors the
# agent customization shape under the [workflow] namespace.
[workflow]
# --- Configurable below. Overrides merge per BMad structural rules: ---
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
# Steps to run before the standard activation (config load, greet).
# Overrides append. Use for pre-flight loads, compliance checks, etc.
activation_steps_prepend = []
# Steps to run after greet but before the workflow begins.
# Overrides append. Use for context-heavy setup that should happen
# once the user has been acknowledged.
activation_steps_append = []
# Persistent facts the workflow keeps in mind for the whole run
# (standards, compliance constraints, stylistic guardrails).
# Distinct from the runtime memory sidecar — these are static context
# loaded on activation. Overrides append.
#
# Each entry is either:
# - a literal sentence, e.g. "All stories must include testable acceptance criteria."
# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
# (glob patterns are supported; the file's contents are loaded and treated as facts).
persistent_facts = [
"file:{project-root}/**/project-context.md",
]
# Scalar: executed when the workflow reaches its final step,
# after the story implementation is complete and status is updated. Override wins.
# Leave empty for no custom post-completion behavior.
on_complete = ""

View File

@ -1,450 +0,0 @@
# Dev Story Workflow
**Goal:** Execute story implementation following a context filled story spec file.
**Your Role:** Developer implementing the story.
- Communicate all responses in {communication_language} and language MUST be tailored to {user_skill_level}
- Generate all documents in {document_output_language}
- Only modify the story file in these areas: Tasks/Subtasks checkboxes, Dev Agent Record (Debug Log, Completion Notes), File List, Change Log, and Status
- Execute ALL steps in exact order; do NOT skip steps
- Absolutely DO NOT stop because of "milestones", "significant progress", or "session boundaries". Continue in a single execution until the story is COMPLETE (all ACs satisfied and all tasks/subtasks checked) UNLESS a HALT condition is triggered or the USER gives other instruction.
- Do NOT schedule a "next session" or request review pauses unless a HALT condition applies. Only Step 6 decides completion.
- User skill level ({user_skill_level}) affects conversation style ONLY, not code updates.
---
## INITIALIZATION
### Configuration Loading
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `user_name`
- `communication_language`, `document_output_language`
- `user_skill_level`
- `implementation_artifacts`
- `date` as system-generated current datetime
### Paths
- `story_file` = `` (explicit story path; auto-discovered if empty)
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
### Context
- `project_context` = `**/project-context.md` (load if exists)
---
## EXECUTION
<workflow>
<critical>Communicate all responses in {communication_language} and language MUST be tailored to {user_skill_level}</critical>
<critical>Generate all documents in {document_output_language}</critical>
<critical>Only modify the story file in these areas: Tasks/Subtasks checkboxes, Dev Agent Record (Debug Log, Completion Notes), File List,
Change Log, and Status</critical>
<critical>Execute ALL steps in exact order; do NOT skip steps</critical>
<critical>Absolutely DO NOT stop because of "milestones", "significant progress", or "session boundaries". Continue in a single execution
until the story is COMPLETE (all ACs satisfied and all tasks/subtasks checked) UNLESS a HALT condition is triggered or the USER gives
other instruction.</critical>
<critical>Do NOT schedule a "next session" or request review pauses unless a HALT condition applies. Only Step 6 decides completion.</critical>
<critical>User skill level ({user_skill_level}) affects conversation style ONLY, not code updates.</critical>
<step n="1" goal="Find next ready story and load it" tag="sprint-status">
<check if="{{story_path}} is provided">
<action>Use {{story_path}} directly</action>
<action>Read COMPLETE story file</action>
<action>Extract story_key from filename or metadata</action>
<goto anchor="task_check" />
</check>
<!-- Sprint-based story discovery -->
<check if="{{sprint_status}} file exists">
<critical>MUST read COMPLETE sprint-status.yaml file from start to end to preserve order</critical>
<action>Load the FULL file: {{sprint_status}}</action>
<action>Read ALL lines from beginning to end - do not skip any content</action>
<action>Parse the development_status section completely to understand story order</action>
<action>Find the FIRST story (by reading in order from top to bottom) where:
- Key matches pattern: number-number-name (e.g., "1-2-user-auth")
- NOT an epic key (epic-X) or retrospective (epic-X-retrospective)
- Status value equals "ready-for-dev"
</action>
<check if="no ready-for-dev or in-progress story found">
<output>📋 No ready-for-dev stories found in sprint-status.yaml
**Current Sprint Status:** {{sprint_status_summary}}
**What would you like to do?**
1. Run `create-story` to create next story from epics with comprehensive context
2. Run `*validate-create-story` to improve existing stories before development (recommended quality check)
3. Specify a particular story file to develop (provide full path)
4. Check {{sprint_status}} file to see current sprint status
💡 **Tip:** Stories in `ready-for-dev` may not have been validated. Consider running `validate-create-story` first for a quality
check.
</output>
<ask>Choose option [1], [2], [3], or [4], or specify story file path:</ask>
<check if="user chooses '1'">
<action>HALT - Run create-story to create next story</action>
</check>
<check if="user chooses '2'">
<action>HALT - Run validate-create-story to improve existing stories</action>
</check>
<check if="user chooses '3'">
<ask>Provide the story file path to develop:</ask>
<action>Store user-provided story path as {{story_path}}</action>
<goto anchor="task_check" />
</check>
<check if="user chooses '4'">
<output>Loading {{sprint_status}} for detailed status review...</output>
<action>Display detailed sprint status analysis</action>
<action>HALT - User can review sprint status and provide story path</action>
</check>
<check if="user provides story file path">
<action>Store user-provided story path as {{story_path}}</action>
<goto anchor="task_check" />
</check>
</check>
</check>
<!-- Non-sprint story discovery -->
<check if="{{sprint_status}} file does NOT exist">
<action>Search {implementation_artifacts} for stories directly</action>
<action>Find stories with "ready-for-dev" status in files</action>
<action>Look for story files matching pattern: *-*-*.md</action>
<action>Read each candidate story file to check Status section</action>
<check if="no ready-for-dev stories found in story files">
<output>📋 No ready-for-dev stories found
**Available Options:**
1. Run `create-story` to create next story from epics with comprehensive context
2. Run `*validate-create-story` to improve existing stories
3. Specify which story to develop
</output>
<ask>What would you like to do? Choose option [1], [2], or [3]:</ask>
<check if="user chooses '1'">
<action>HALT - Run create-story to create next story</action>
</check>
<check if="user chooses '2'">
<action>HALT - Run validate-create-story to improve existing stories</action>
</check>
<check if="user chooses '3'">
<ask>It's unclear what story you want developed. Please provide the full path to the story file:</ask>
<action>Store user-provided story path as {{story_path}}</action>
<action>Continue with provided story file</action>
</check>
</check>
<check if="ready-for-dev story found in files">
<action>Use discovered story file and extract story_key</action>
</check>
</check>
<action>Store the found story_key (e.g., "1-2-user-authentication") for later status updates</action>
<action>Find matching story file in {implementation_artifacts} using story_key pattern: {{story_key}}.md</action>
<action>Read COMPLETE story file from discovered path</action>
<anchor id="task_check" />
<action>Parse sections: Story, Acceptance Criteria, Tasks/Subtasks, Dev Notes, Dev Agent Record, File List, Change Log, Status</action>
<action>Load comprehensive context from story file's Dev Notes section</action>
<action>Extract developer guidance from Dev Notes: architecture requirements, previous learnings, technical specifications</action>
<action>Use enhanced story context to inform implementation decisions and approaches</action>
<action>Identify first incomplete task (unchecked [ ]) in Tasks/Subtasks</action>
<action if="no incomplete tasks">
<goto step="6">Completion sequence</goto>
</action>
<action if="story file inaccessible">HALT: "Cannot develop story without access to story file"</action>
<action if="incomplete task or subtask requirements ambiguous">ASK user to clarify or HALT</action>
</step>
<step n="2" goal="Load project context and story information">
<critical>Load all available context to inform implementation</critical>
<action>Load {project_context} for coding standards and project-wide patterns (if exists)</action>
<action>Parse sections: Story, Acceptance Criteria, Tasks/Subtasks, Dev Notes, Dev Agent Record, File List, Change Log, Status</action>
<action>Load comprehensive context from story file's Dev Notes section</action>
<action>Extract developer guidance from Dev Notes: architecture requirements, previous learnings, technical specifications</action>
<action>Use enhanced story context to inform implementation decisions and approaches</action>
<output>✅ **Context Loaded**
Story and project context available for implementation
</output>
</step>
<step n="3" goal="Detect review continuation and extract review context">
<critical>Determine if this is a fresh start or continuation after code review</critical>
<action>Check if "Senior Developer Review (AI)" section exists in the story file</action>
<action>Check if "Review Follow-ups (AI)" subsection exists under Tasks/Subtasks</action>
<check if="Senior Developer Review section exists">
<action>Set review_continuation = true</action>
<action>Extract from "Senior Developer Review (AI)" section:
- Review outcome (Approve/Changes Requested/Blocked)
- Review date
- Total action items with checkboxes (count checked vs unchecked)
- Severity breakdown (High/Med/Low counts)
</action>
<action>Count unchecked [ ] review follow-up tasks in "Review Follow-ups (AI)" subsection</action>
<action>Store list of unchecked review items as {{pending_review_items}}</action>
<output>⏯️ **Resuming Story After Code Review** ({{review_date}})
**Review Outcome:** {{review_outcome}}
**Action Items:** {{unchecked_review_count}} remaining to address
**Priorities:** {{high_count}} High, {{med_count}} Medium, {{low_count}} Low
**Strategy:** Will prioritize review follow-up tasks (marked [AI-Review]) before continuing with regular tasks.
</output>
</check>
<check if="Senior Developer Review section does NOT exist">
<action>Set review_continuation = false</action>
<action>Set {{pending_review_items}} = empty</action>
<output>🚀 **Starting Fresh Implementation**
Story: {{story_key}}
Story Status: {{current_status}}
First incomplete task: {{first_task_description}}
</output>
</check>
</step>
<step n="4" goal="Mark story in-progress" tag="sprint-status">
<check if="{{sprint_status}} file exists">
<action>Load the FULL file: {{sprint_status}}</action>
<action>Read all development_status entries to find {{story_key}}</action>
<action>Get current status value for development_status[{{story_key}}]</action>
<check if="current status == 'ready-for-dev' OR review_continuation == true">
<action>Update the story in the sprint status report to = "in-progress"</action>
<action>Update last_updated field to current date</action>
<output>🚀 Starting work on story {{story_key}}
Status updated: ready-for-dev → in-progress
</output>
</check>
<check if="current status == 'in-progress'">
<output>⏯️ Resuming work on story {{story_key}}
Story is already marked in-progress
</output>
</check>
<check if="current status is neither ready-for-dev nor in-progress">
<output>⚠️ Unexpected story status: {{current_status}}
Expected ready-for-dev or in-progress. Continuing anyway...
</output>
</check>
<action>Store {{current_sprint_status}} for later use</action>
</check>
<check if="{{sprint_status}} file does NOT exist">
<output>ℹ️ No sprint status file exists - story progress will be tracked in story file only</output>
<action>Set {{current_sprint_status}} = "no-sprint-tracking"</action>
</check>
</step>
<step n="5" goal="Implement task following red-green-refactor cycle">
<critical>FOLLOW THE STORY FILE TASKS/SUBTASKS SEQUENCE EXACTLY AS WRITTEN - NO DEVIATION</critical>
<action>Review the current task/subtask from the story file - this is your authoritative implementation guide</action>
<action>Plan implementation following red-green-refactor cycle</action>
<!-- RED PHASE -->
<action>Write FAILING tests first for the task/subtask functionality</action>
<action>Confirm tests fail before implementation - this validates test correctness</action>
<!-- GREEN PHASE -->
<action>Implement MINIMAL code to make tests pass</action>
<action>Run tests to confirm they now pass</action>
<action>Handle error conditions and edge cases as specified in task/subtask</action>
<!-- REFACTOR PHASE -->
<action>Improve code structure while keeping tests green</action>
<action>Ensure code follows architecture patterns and coding standards from Dev Notes</action>
<action>Document technical approach and decisions in Dev Agent Record → Implementation Plan</action>
<action if="new dependencies required beyond story specifications">HALT: "Additional dependencies need user approval"</action>
<action if="3 consecutive implementation failures occur">HALT and request guidance</action>
<action if="required configuration is missing">HALT: "Cannot proceed without necessary configuration files"</action>
<critical>NEVER implement anything not mapped to a specific task/subtask in the story file</critical>
<critical>NEVER proceed to next task until current task/subtask is complete AND tests pass</critical>
<critical>Execute continuously without pausing until all tasks/subtasks are complete or explicit HALT condition</critical>
<critical>Do NOT propose to pause for review until Step 9 completion gates are satisfied</critical>
</step>
<step n="6" goal="Author comprehensive tests">
<action>Create unit tests for business logic and core functionality introduced/changed by the task</action>
<action>Add integration tests for component interactions specified in story requirements</action>
<action>Include end-to-end tests for critical user flows when story requirements demand them</action>
<action>Cover edge cases and error handling scenarios identified in story Dev Notes</action>
</step>
<step n="7" goal="Run validations and tests">
<action>Determine how to run tests for this repo (infer test framework from project structure)</action>
<action>Run all existing tests to ensure no regressions</action>
<action>Run the new tests to verify implementation correctness</action>
<action>Run linting and code quality checks if configured in project</action>
<action>Validate implementation meets ALL story acceptance criteria; enforce quantitative thresholds explicitly</action>
<action if="regression tests fail">STOP and fix before continuing - identify breaking changes immediately</action>
<action if="new tests fail">STOP and fix before continuing - ensure implementation correctness</action>
</step>
<step n="8" goal="Validate and mark task complete ONLY when fully done">
<critical>NEVER mark a task complete unless ALL conditions are met - NO LYING OR CHEATING</critical>
<!-- VALIDATION GATES -->
<action>Verify ALL tests for this task/subtask ACTUALLY EXIST and PASS 100%</action>
<action>Confirm implementation matches EXACTLY what the task/subtask specifies - no extra features</action>
<action>Validate that ALL acceptance criteria related to this task are satisfied</action>
<action>Run full test suite to ensure NO regressions introduced</action>
<!-- REVIEW FOLLOW-UP HANDLING -->
<check if="task is review follow-up (has [AI-Review] prefix)">
<action>Extract review item details (severity, description, related AC/file)</action>
<action>Add to resolution tracking list: {{resolved_review_items}}</action>
<!-- Mark task in Review Follow-ups section -->
<action>Mark task checkbox [x] in "Tasks/Subtasks → Review Follow-ups (AI)" section</action>
<!-- CRITICAL: Also mark corresponding action item in review section -->
<action>Find matching action item in "Senior Developer Review (AI) → Action Items" section by matching description</action>
<action>Mark that action item checkbox [x] as resolved</action>
<action>Add to Dev Agent Record → Completion Notes: "✅ Resolved review finding [{{severity}}]: {{description}}"</action>
</check>
<!-- ONLY MARK COMPLETE IF ALL VALIDATION PASS -->
<check if="ALL validation gates pass AND tests ACTUALLY exist and pass">
<action>ONLY THEN mark the task (and subtasks) checkbox with [x]</action>
<action>Update File List section with ALL new, modified, or deleted files (paths relative to repo root)</action>
<action>Add completion notes to Dev Agent Record summarizing what was ACTUALLY implemented and tested</action>
</check>
<check if="ANY validation fails">
<action>DO NOT mark task complete - fix issues first</action>
<action>HALT if unable to fix validation failures</action>
</check>
<check if="review_continuation == true and {{resolved_review_items}} is not empty">
<action>Count total resolved review items in this session</action>
<action>Add Change Log entry: "Addressed code review findings - {{resolved_count}} items resolved (Date: {{date}})"</action>
</check>
<action>Save the story file</action>
<action>Determine if more incomplete tasks remain</action>
<action if="more tasks remain">
<goto step="5">Next task</goto>
</action>
<action if="no tasks remain">
<goto step="9">Completion</goto>
</action>
</step>
<step n="9" goal="Story completion and mark for review" tag="sprint-status">
<action>Verify ALL tasks and subtasks are marked [x] (re-scan the story document now)</action>
<action>Run the full regression suite (do not skip)</action>
<action>Confirm File List includes every changed file</action>
<action>Execute enhanced definition-of-done validation</action>
<action>Update the story Status to: "review"</action>
<!-- Enhanced Definition of Done Validation -->
<action>Validate definition-of-done checklist with essential requirements:
- All tasks/subtasks marked complete with [x]
- Implementation satisfies every Acceptance Criterion
- Unit tests for core functionality added/updated
- Integration tests for component interactions added when required
- End-to-end tests for critical flows added when story demands them
- All tests pass (no regressions, new tests successful)
- Code quality checks pass (linting, static analysis if configured)
- File List includes every new/modified/deleted file (relative paths)
- Dev Agent Record contains implementation notes
- Change Log includes summary of changes
- Only permitted story sections were modified
</action>
<!-- Mark story ready for review - sprint status conditional -->
<check if="{sprint_status} file exists AND {{current_sprint_status}} != 'no-sprint-tracking'">
<action>Load the FULL file: {sprint_status}</action>
<action>Find development_status key matching {{story_key}}</action>
<action>Verify current status is "in-progress" (expected previous state)</action>
<action>Update development_status[{{story_key}}] = "review"</action>
<action>Update last_updated field to current date</action>
<action>Save file, preserving ALL comments and structure including STATUS DEFINITIONS</action>
<output>✅ Story status updated to "review" in sprint-status.yaml</output>
</check>
<check if="{sprint_status} file does NOT exist OR {{current_sprint_status}} == 'no-sprint-tracking'">
<output>ℹ️ Story status updated to "review" in story file (no sprint tracking configured)</output>
</check>
<check if="story key not found in sprint status">
<output>⚠️ Story file updated, but sprint-status update failed: {{story_key}} not found
Story status is set to "review" in file, but sprint-status.yaml may be out of sync.
</output>
</check>
<!-- Final validation gates -->
<action if="any task is incomplete">HALT - Complete remaining tasks before marking ready for review</action>
<action if="regression failures exist">HALT - Fix regression issues before completing</action>
<action if="File List is incomplete">HALT - Update File List with all changed files</action>
<action if="definition-of-done validation fails">HALT - Address DoD failures before completing</action>
</step>
<step n="10" goal="Completion communication and user support">
<action>Execute the enhanced definition-of-done checklist using the validation framework</action>
<action>Prepare a concise summary in Dev Agent Record → Completion Notes</action>
<action>Communicate to {user_name} that story implementation is complete and ready for review</action>
<action>Summarize key accomplishments: story ID, story key, title, key changes made, tests added, files modified</action>
<action>Provide the story file path and current status (now "review")</action>
<action>Based on {user_skill_level}, ask if user needs any explanations about:
- What was implemented and how it works
- Why certain technical decisions were made
- How to test or verify the changes
- Any patterns, libraries, or approaches used
- Anything else they'd like clarified
</action>
<check if="user asks for explanations">
<action>Provide clear, contextual explanations tailored to {user_skill_level}</action>
<action>Use examples and references to specific code when helpful</action>
</check>
<action>Once explanations are complete (or user indicates no questions), suggest logical next steps</action>
<action>Recommended next steps (flexible based on project setup):
- Review the implemented story and test the changes
- Verify all acceptance criteria are met
- Ensure deployment readiness if applicable
- Run `code-review` workflow for peer review
- Optional: If Test Architect module installed, run `/bmad:tea:automate` to expand guardrail tests
</action>
<output>💡 **Tip:** For best results, run `code-review` using a **different** LLM than the one that implemented this story.</output>
<check if="{sprint_status} file exists">
<action>Suggest checking {sprint_status} to see project progress</action>
</check>
<action>Remain flexible - allow user to choose their own path or ask for other assistance</action>
</step>
</workflow>

View File

@ -3,4 +3,109 @@ name: bmad-quick-dev
description: 'Implements any user intent, requirement, story, bug fix or change request by producing clean working code artifacts that follow the project''s existing architecture, patterns and conventions. Use when the user wants to build, fix, tweak, refactor, add or modify any code, component or feature.'
---
Follow the instructions in ./workflow.md.
# Quick Dev New Preview Workflow
**Goal:** Turn user intent into a hardened, reviewable artifact.
**CRITICAL:** If a step says "read fully and follow step-XX", you read and follow step-XX. No exceptions.
## READY FOR DEVELOPMENT STANDARD
A specification is "Ready for Development" when:
- **Actionable**: Every task has a file path and specific action.
- **Logical**: Tasks ordered by dependency.
- **Testable**: All ACs use Given/When/Then.
- **Complete**: No placeholders or TBDs.
## SCOPE STANDARD
A specification should target a **single user-facing goal** within **900–1600 tokens**:
- **Single goal**: One cohesive feature, even if it spans multiple layers/files. Multi-goal means >=2 **top-level independent shippable deliverables** — each could be reviewed, tested, and merged as a separate PR without breaking the others. Never count surface verbs, "and" conjunctions, or noun phrases. Never split cross-layer implementation details inside one user goal.
- Split: "add dark mode toggle AND refactor auth to JWT AND build admin dashboard"
- Don't split: "add validation and display errors" / "support drag-and-drop AND paste AND retry"
- **900–1600 tokens**: Optimal range for LLM consumption. Below 900 risks ambiguity; above 1600 risks context-rot in implementation agents.
- **Neither limit is a gate.** Both are proposals with user override.
## Conventions
- Bare paths (e.g. `step-01-clarify-and-route.md`) resolve from the skill root.
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives).
- `{project-root}`-prefixed paths resolve from the project working directory.
- `{skill-name}` resolves to the skill directory's basename.
## On Activation
### Step 1: Resolve the Workflow Block
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
1. `{skill-root}/customize.toml` — defaults
2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides
3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides
Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append.
### Step 2: Execute Prepend Steps
Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding.
### Step 3: Load Persistent Facts
Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. Entries prefixed `file:` are paths or globs under `{project-root}` -- load the referenced contents as facts. All other entries are facts verbatim.
### Step 4: Load Config
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level`
- `date` as system-generated current datetime
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
- `project_context` = `**/project-context.md` (load if exists)
- CLAUDE.md / memory files (load if exist)
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- Language MUST be tailored to `{user_skill_level}`
- Generate all documents in `{document_output_language}`
### Step 5: Greet the User
Greet `{user_name}`, speaking in `{communication_language}`.
### Step 6: Execute Append Steps
Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete. Begin the workflow below.
## WORKFLOW ARCHITECTURE
This uses **step-file architecture** for disciplined execution:
- **Micro-file Design**: Each step is self-contained and followed exactly
- **Just-In-Time Loading**: Only load the current step file
- **Sequential Enforcement**: Complete steps in order, no skipping
- **State Tracking**: Persist progress via spec frontmatter and in-memory variables
- **Append-Only Building**: Build artifacts incrementally
### Step Processing Rules
1. **READ COMPLETELY**: Read the entire step file before acting
2. **FOLLOW SEQUENCE**: Execute sections in order
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human
4. **LOAD NEXT**: When directed, read fully and follow the next step file
### Critical Rules (NO EXCEPTIONS)
- **NEVER** load multiple step files simultaneously
- **ALWAYS** read entire step file before execution
- **NEVER** skip steps or optimize the sequence
- **ALWAYS** follow the exact instructions in the step file
- **ALWAYS** halt at checkpoints and wait for human input
## FIRST STEP
Read fully and follow: `./step-01-clarify-and-route.md` to begin the workflow.

View File

@ -0,0 +1,41 @@
# DO NOT EDIT -- overwritten on every update.
#
# Workflow customization surface for bmad-quick-dev. Mirrors the
# agent customization shape under the [workflow] namespace.
[workflow]
# --- Configurable below. Overrides merge per BMad structural rules: ---
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
# Steps to run before the standard activation (config load, greet).
# Overrides append. Use for pre-flight loads, compliance checks, etc.
activation_steps_prepend = []
# Steps to run after greet but before the workflow begins.
# Overrides append. Use for context-heavy setup that should happen
# once the user has been acknowledged.
activation_steps_append = []
# Persistent facts the workflow keeps in mind for the whole run
# (standards, compliance constraints, stylistic guardrails).
# Distinct from the runtime memory sidecar — these are static context
# loaded on activation. Overrides append.
#
# Each entry is either:
# - a literal sentence, e.g. "All stories must include testable acceptance criteria."
# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
# (glob patterns are supported; the file's contents are loaded and treated as facts).
persistent_facts = [
"file:{project-root}/**/project-context.md",
]
# Scalar: executed when the workflow reaches its final step,
# after implementation is complete and explanations are provided. Override wins.
# Leave empty for no custom post-completion behavior.
on_complete = ""

View File

@ -70,3 +70,9 @@ Display summary of your work to the user, including the commit hash if one was c
- Offer to push and/or create a pull request.
Workflow complete.
## On Complete
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.

View File

@ -63,3 +63,9 @@ If version control is available and the tree is dirty, create a local commit wit
HALT and wait for human input.
Workflow complete.
## On Complete
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
If the resolved `workflow.on_complete` is non-empty, follow it as the final terminal instruction before exiting.

View File

@ -1,76 +0,0 @@
---
main_config: '{project-root}/_bmad/bmm/config.yaml'
---
# Quick Dev New Preview Workflow
**Goal:** Turn user intent into a hardened, reviewable artifact.
**CRITICAL:** If a step says "read fully and follow step-XX", you read and follow step-XX. No exceptions.
## READY FOR DEVELOPMENT STANDARD
A specification is "Ready for Development" when:
- **Actionable**: Every task has a file path and specific action.
- **Logical**: Tasks ordered by dependency.
- **Testable**: All ACs use Given/When/Then.
- **Complete**: No placeholders or TBDs.
## SCOPE STANDARD
A specification should target a **single user-facing goal** within **900–1600 tokens**:
- **Single goal**: One cohesive feature, even if it spans multiple layers/files. Multi-goal means >=2 **top-level independent shippable deliverables** — each could be reviewed, tested, and merged as a separate PR without breaking the others. Never count surface verbs, "and" conjunctions, or noun phrases. Never split cross-layer implementation details inside one user goal.
- Split: "add dark mode toggle AND refactor auth to JWT AND build admin dashboard"
- Don't split: "add validation and display errors" / "support drag-and-drop AND paste AND retry"
- **900–1600 tokens**: Optimal range for LLM consumption. Below 900 risks ambiguity; above 1600 risks context-rot in implementation agents.
- **Neither limit is a gate.** Both are proposals with user override.
## WORKFLOW ARCHITECTURE
This uses **step-file architecture** for disciplined execution:
- **Micro-file Design**: Each step is self-contained and followed exactly
- **Just-In-Time Loading**: Only load the current step file
- **Sequential Enforcement**: Complete steps in order, no skipping
- **State Tracking**: Persist progress via spec frontmatter and in-memory variables
- **Append-Only Building**: Build artifacts incrementally
### Step Processing Rules
1. **READ COMPLETELY**: Read the entire step file before acting
2. **FOLLOW SEQUENCE**: Execute sections in order
3. **WAIT FOR INPUT**: Halt at checkpoints and wait for human
4. **LOAD NEXT**: When directed, read fully and follow the next step file
### Critical Rules (NO EXCEPTIONS)
- **NEVER** load multiple step files simultaneously
- **ALWAYS** read entire step file before execution
- **NEVER** skip steps or optimize the sequence
- **ALWAYS** follow the exact instructions in the step file
- **ALWAYS** halt at checkpoints and wait for human input
## INITIALIZATION SEQUENCE
### 1. Configuration Loading
Load and read full config from `{main_config}` and resolve:
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
- `communication_language`, `document_output_language`, `user_skill_level`
- `date` as system-generated current datetime
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
- `project_context` = `**/project-context.md` (load if exists)
- CLAUDE.md / memory files (load if exist)
YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`.
### 2. First Step Execution
Read fully and follow: `./step-01-clarify-and-route.md` to begin the workflow.

View File

@ -3,4 +3,297 @@ name: bmad-sprint-planning
description: 'Generate sprint status tracking from epics. Use when the user says "run sprint planning" or "generate sprint plan"'
---
Follow the instructions in ./workflow.md.
# Sprint Planning Workflow
**Goal:** Generate sprint status tracking from epics, detecting current story statuses and building a complete sprint-status.yaml file.
**Your Role:** You are a Developer generating and maintaining sprint tracking. Parse epic files, detect story statuses, and produce a structured sprint-status.yaml.
## Conventions
- Bare paths (e.g. `checklist.md`) resolve from the skill root.
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives).
- `{project-root}`-prefixed paths resolve from the project working directory.
- `{skill-name}` resolves to the skill directory's basename.
## On Activation
### Step 1: Resolve the Workflow Block
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
1. `{skill-root}/customize.toml` — defaults
2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides
3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides
Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append.
### Step 2: Execute Prepend Steps
Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding.
### Step 3: Load Persistent Facts
Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
### Step 4: Load Config
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `user_name`
- `communication_language`, `document_output_language`
- `implementation_artifacts`
- `planning_artifacts`
- `date` as system-generated current datetime
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- Generate all documents in `{document_output_language}`
### Step 5: Greet the User
Greet `{user_name}`, speaking in `{communication_language}`.
### Step 6: Execute Append Steps
Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete. Begin the workflow below.
## Paths
- `tracking_system` = `file-system`
- `project_key` = `NOKEY`
- `story_location` = `{implementation_artifacts}`
- `story_location_absolute` = `{implementation_artifacts}`
- `epics_location` = `{planning_artifacts}`
- `epics_pattern` = `*epic*.md`
- `status_file` = `{implementation_artifacts}/sprint-status.yaml`
## Input Files
| Input | Path | Load Strategy |
|-------|------|---------------|
| Epics | `{planning_artifacts}/*epic*.md` (whole) or `{planning_artifacts}/*epic*/*.md` (sharded) | FULL_LOAD |
## Execution
### Document Discovery - Full Epic Loading
**Strategy**: Sprint planning needs ALL epics and stories to build complete status tracking.
**Epic Discovery Process:**
1. **Search for whole document first** - Look for `epics.md`, `bmm-epics.md`, or any `*epic*.md` file
2. **Check for sharded version** - If whole document not found, look for `epics/index.md`
3. **If sharded version found**:
- Read `index.md` to understand the document structure
- Read ALL epic section files listed in the index (e.g., `epic-1.md`, `epic-2.md`, etc.)
- Process all epics and their stories from the combined content
- This ensures complete sprint status coverage
4. **Priority**: If both whole and sharded versions exist, use the whole document
**Fuzzy matching**: Be flexible with document names - users may use variations like `epics.md`, `bmm-epics.md`, `user-stories.md`, etc.
<workflow>
<step n="1" goal="Parse epic files and extract all work items">
<action>Load {project_context} for project-wide patterns and conventions (if exists)</action>
<action>Communicate in {communication_language} with {user_name}</action>
<action>Look for all files matching `{epics_pattern}` in {epics_location}</action>
<action>Could be a single `epics.md` file or multiple `epic-1.md`, `epic-2.md` files</action>
<action>For each epic file found, extract:</action>
- Epic numbers from headers like `## Epic 1:` or `## Epic 2:`
- Story IDs and titles from patterns like `### Story 1.1: User Authentication`
- Convert story format from `Epic.Story: Title` to kebab-case key: `epic-story-title`
**Story ID Conversion Rules:**
- Original: `### Story 1.1: User Authentication`
- Replace period with dash: `1-1`
- Convert title to kebab-case: `user-authentication`
- Final key: `1-1-user-authentication`
<action>Build complete inventory of all epics and stories from all epic files</action>
</step>
<step n="2" goal="Build sprint status structure">
<action>For each epic found, create entries in this order:</action>
1. **Epic entry** - Key: `epic-{num}`, Default status: `backlog`
2. **Story entries** - Key: `{epic}-{story}-{title}`, Default status: `backlog`
3. **Retrospective entry** - Key: `epic-{num}-retrospective`, Default status: `optional`
**Example structure:**
```yaml
development_status:
epic-1: backlog
1-1-user-authentication: backlog
1-2-account-management: backlog
epic-1-retrospective: optional
```
</step>
<step n="3" goal="Apply intelligent status detection">
<action>For each story, detect current status by checking files:</action>
**Story file detection:**
- Check: `{story_location_absolute}/{story-key}.md` (e.g., `stories/1-1-user-authentication.md`)
- If exists → upgrade status to at least `ready-for-dev`
**Preservation rule:**
- If existing `{status_file}` exists and has more advanced status, preserve it
- Never downgrade status (e.g., don't change `done` to `ready-for-dev`)
**Status Flow Reference:**
- Epic: `backlog` → `in-progress` → `done`
- Story: `backlog` → `ready-for-dev` → `in-progress` → `review` → `done`
- Retrospective: `optional` ↔ `done`
</step>
<step n="4" goal="Generate sprint status file">
<action>Create or update {status_file} with:</action>
**File Structure:**
```yaml
# generated: {date}
# last_updated: {date}
# project: {project_name}
# project_key: {project_key}
# tracking_system: {tracking_system}
# story_location: {story_location}
# STATUS DEFINITIONS:
# ==================
# Epic Status:
# - backlog: Epic not yet started
# - in-progress: Epic actively being worked on
# - done: All stories in epic completed
#
# Epic Status Transitions:
# - backlog → in-progress: Automatically when first story is created (via create-story)
# - in-progress → done: Manually when all stories reach 'done' status
#
# Story Status:
# - backlog: Story only exists in epic file
# - ready-for-dev: Story file created in stories folder
# - in-progress: Developer actively working on implementation
# - review: Ready for code review (via Dev's code-review workflow)
# - done: Story completed
#
# Retrospective Status:
# - optional: Can be completed but not required
# - done: Retrospective has been completed
#
# WORKFLOW NOTES:
# ===============
# - Epic transitions to 'in-progress' automatically when first story is created
# - Stories can be worked in parallel if team capacity allows
# - Developer typically creates next story after previous one is 'done' to incorporate learnings
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
generated: { date }
last_updated: { date }
project: { project_name }
project_key: { project_key }
tracking_system: { tracking_system }
story_location: { story_location }
development_status:
# All epics, stories, and retrospectives in order
```
<action>Write the complete sprint status YAML to {status_file}</action>
<action>CRITICAL: Metadata appears TWICE - once as comments (#) for documentation, once as YAML key:value fields for parsing</action>
<action>Ensure all items are ordered: epic, its stories, its retrospective, next epic...</action>
</step>
<step n="5" goal="Validate and report">
<action>Perform validation checks:</action>
- [ ] Every epic in epic files appears in {status_file}
- [ ] Every story in epic files appears in {status_file}
- [ ] Every epic has a corresponding retrospective entry
- [ ] No items in {status_file} that don't exist in epic files
- [ ] All status values are legal (match state machine definitions)
- [ ] File is valid YAML syntax
<action>Count totals:</action>
- Total epics: {{epic_count}}
- Total stories: {{story_count}}
- Epics in-progress: {{in_progress_count}}
- Stories done: {{done_count}}
<action>Display completion summary to {user_name} in {communication_language}:</action>
**Sprint Status Generated Successfully**
- **File Location:** {status_file}
- **Total Epics:** {{epic_count}}
- **Total Stories:** {{story_count}}
- **Epics In Progress:** {{in_progress_count}}
- **Stories Completed:** {{done_count}}
**Next Steps:**
1. Review the generated {status_file}
2. Use this file to track development progress
3. Agents will update statuses as they work
4. Re-run this workflow to refresh auto-detected statuses
<action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
</step>
</workflow>
## Additional Documentation
### Status State Machine
**Epic Status Flow:**
```
backlog → in-progress → done
```
- **backlog**: Epic not yet started
- **in-progress**: Epic actively being worked on (stories being created/implemented)
- **done**: All stories in epic completed
**Story Status Flow:**
```
backlog → ready-for-dev → in-progress → review → done
```
- **backlog**: Story only exists in epic file
- **ready-for-dev**: Story file created (e.g., `stories/1-3-plant-naming.md`)
- **in-progress**: Developer actively working
- **review**: Ready for code review (via Dev's code-review workflow)
- **done**: Completed
**Retrospective Status:**
```
optional ↔ done
```
- **optional**: Ready to be conducted but not required
- **done**: Finished
### Guidelines
1. **Epic Activation**: Mark epic as `in-progress` when starting work on its first story
2. **Sequential Default**: Stories are typically worked in order, but parallel work is supported
3. **Parallel Work Supported**: Multiple stories can be `in-progress` if team capacity allows
4. **Review Before Done**: Stories should pass through `review` before `done`
5. **Learning Transfer**: Developer typically creates next story after previous one is `done` to incorporate learnings

View File

@ -0,0 +1,41 @@
# DO NOT EDIT -- overwritten on every update.
#
# Workflow customization surface for bmad-sprint-planning. Mirrors the
# agent customization shape under the [workflow] namespace.
[workflow]
# --- Configurable below. Overrides merge per BMad structural rules: ---
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
# Steps to run before the standard activation (config load, greet).
# Overrides append. Use for pre-flight loads, compliance checks, etc.
activation_steps_prepend = []
# Steps to run after greet but before the workflow begins.
# Overrides append. Use for context-heavy setup that should happen
# once the user has been acknowledged.
activation_steps_append = []
# Persistent facts the workflow keeps in mind for the whole run
# (standards, compliance constraints, stylistic guardrails).
# Distinct from the runtime memory sidecar — these are static context
# loaded on activation. Overrides append.
#
# Each entry is either:
# - a literal sentence, e.g. "All stories must include testable acceptance criteria."
# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
# (glob patterns are supported; the file's contents are loaded and treated as facts).
persistent_facts = [
"file:{project-root}/**/project-context.md",
]
# Scalar: executed when the workflow reaches its final step,
# after sprint-status.yaml is generated and validated. Override wins.
# Leave empty for no custom post-completion behavior.
on_complete = ""

View File

@ -1,263 +0,0 @@
# Sprint Planning Workflow
**Goal:** Generate sprint status tracking from epics, detecting current story statuses and building a complete sprint-status.yaml file.
**Your Role:** You are a Developer generating and maintaining sprint tracking. Parse epic files, detect story statuses, and produce a structured sprint-status.yaml.
---
## INITIALIZATION
### Configuration Loading
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `user_name`
- `communication_language`, `document_output_language`
- `implementation_artifacts`
- `planning_artifacts`
- `date` as system-generated current datetime
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
### Paths
- `tracking_system` = `file-system`
- `project_key` = `NOKEY`
- `story_location` = `{implementation_artifacts}`
- `story_location_absolute` = `{implementation_artifacts}`
- `epics_location` = `{planning_artifacts}`
- `epics_pattern` = `*epic*.md`
- `status_file` = `{implementation_artifacts}/sprint-status.yaml`
### Input Files
| Input | Path | Load Strategy |
|-------|------|---------------|
| Epics | `{planning_artifacts}/*epic*.md` (whole) or `{planning_artifacts}/*epic*/*.md` (sharded) | FULL_LOAD |
### Context
- `project_context` = `**/project-context.md` (load if exists)
---
## EXECUTION
### Document Discovery - Full Epic Loading
**Strategy**: Sprint planning needs ALL epics and stories to build complete status tracking.
**Epic Discovery Process:**
1. **Search for whole document first** - Look for `epics.md`, `bmm-epics.md`, or any `*epic*.md` file
2. **Check for sharded version** - If whole document not found, look for `epics/index.md`
3. **If sharded version found**:
- Read `index.md` to understand the document structure
- Read ALL epic section files listed in the index (e.g., `epic-1.md`, `epic-2.md`, etc.)
- Process all epics and their stories from the combined content
- This ensures complete sprint status coverage
4. **Priority**: If both whole and sharded versions exist, use the whole document
**Fuzzy matching**: Be flexible with document names - users may use variations like `epics.md`, `bmm-epics.md`, `user-stories.md`, etc.
<workflow>
<step n="1" goal="Parse epic files and extract all work items">
<action>Load {project_context} for project-wide patterns and conventions (if exists)</action>
<action>Communicate in {communication_language} with {user_name}</action>
<action>Look for all files matching `{epics_pattern}` in {epics_location}</action>
<action>Could be a single `epics.md` file or multiple `epic-1.md`, `epic-2.md` files</action>
<action>For each epic file found, extract:</action>
- Epic numbers from headers like `## Epic 1:` or `## Epic 2:`
- Story IDs and titles from patterns like `### Story 1.1: User Authentication`
- Convert story format from `Epic.Story: Title` to kebab-case key: `epic-story-title`
**Story ID Conversion Rules:**
- Original: `### Story 1.1: User Authentication`
- Replace period with dash: `1-1`
- Convert title to kebab-case: `user-authentication`
- Final key: `1-1-user-authentication`
<action>Build complete inventory of all epics and stories from all epic files</action>
</step>
<step n="2" goal="Build sprint status structure">
<action>For each epic found, create entries in this order:</action>
1. **Epic entry** - Key: `epic-{num}`, Default status: `backlog`
2. **Story entries** - Key: `{epic}-{story}-{title}`, Default status: `backlog`
3. **Retrospective entry** - Key: `epic-{num}-retrospective`, Default status: `optional`
**Example structure:**
```yaml
development_status:
epic-1: backlog
1-1-user-authentication: backlog
1-2-account-management: backlog
epic-1-retrospective: optional
```
</step>
<step n="3" goal="Apply intelligent status detection">
<action>For each story, detect current status by checking files:</action>
**Story file detection:**
- Check: `{story_location_absolute}/{story-key}.md` (e.g., `stories/1-1-user-authentication.md`)
- If exists → upgrade status to at least `ready-for-dev`
**Preservation rule:**
- If existing `{status_file}` exists and has more advanced status, preserve it
- Never downgrade status (e.g., don't change `done` to `ready-for-dev`)
**Status Flow Reference:**
- Epic: `backlog` → `in-progress` → `done`
- Story: `backlog` → `ready-for-dev` → `in-progress` → `review` → `done`
- Retrospective: `optional` ↔ `done`
</step>
<step n="4" goal="Generate sprint status file">
<action>Create or update {status_file} with:</action>
**File Structure:**
```yaml
# generated: {date}
# last_updated: {date}
# project: {project_name}
# project_key: {project_key}
# tracking_system: {tracking_system}
# story_location: {story_location}
# STATUS DEFINITIONS:
# ==================
# Epic Status:
# - backlog: Epic not yet started
# - in-progress: Epic actively being worked on
# - done: All stories in epic completed
#
# Epic Status Transitions:
# - backlog → in-progress: Automatically when first story is created (via create-story)
# - in-progress → done: Manually when all stories reach 'done' status
#
# Story Status:
# - backlog: Story only exists in epic file
# - ready-for-dev: Story file created in stories folder
# - in-progress: Developer actively working on implementation
# - review: Ready for code review (via Dev's code-review workflow)
# - done: Story completed
#
# Retrospective Status:
# - optional: Can be completed but not required
# - done: Retrospective has been completed
#
# WORKFLOW NOTES:
# ===============
# - Epic transitions to 'in-progress' automatically when first story is created
# - Stories can be worked in parallel if team capacity allows
# - Developer typically creates next story after previous one is 'done' to incorporate learnings
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
generated: { date }
last_updated: { date }
project: { project_name }
project_key: { project_key }
tracking_system: { tracking_system }
story_location: { story_location }
development_status:
# All epics, stories, and retrospectives in order
```
<action>Write the complete sprint status YAML to {status_file}</action>
<action>CRITICAL: Metadata appears TWICE - once as comments (#) for documentation, once as YAML key:value fields for parsing</action>
<action>Ensure all items are ordered: epic, its stories, its retrospective, next epic...</action>
</step>
<step n="5" goal="Validate and report">
<action>Perform validation checks:</action>
- [ ] Every epic in epic files appears in {status_file}
- [ ] Every story in epic files appears in {status_file}
- [ ] Every epic has a corresponding retrospective entry
- [ ] No items in {status_file} that don't exist in epic files
- [ ] All status values are legal (match state machine definitions)
- [ ] File is valid YAML syntax
<action>Count totals:</action>
- Total epics: {{epic_count}}
- Total stories: {{story_count}}
- Epics in-progress: {{in_progress_count}}
- Stories done: {{done_count}}
<action>Display completion summary to {user_name} in {communication_language}:</action>
**Sprint Status Generated Successfully**
- **File Location:** {status_file}
- **Total Epics:** {{epic_count}}
- **Total Stories:** {{story_count}}
- **Epics In Progress:** {{in_progress_count}}
- **Stories Completed:** {{done_count}}
**Next Steps:**
1. Review the generated {status_file}
2. Use this file to track development progress
3. Agents will update statuses as they work
4. Re-run this workflow to refresh auto-detected statuses
</step>
</workflow>
## Additional Documentation
### Status State Machine
**Epic Status Flow:**
```
backlog → in-progress → done
```
- **backlog**: Epic not yet started
- **in-progress**: Epic actively being worked on (stories being created/implemented)
- **done**: All stories in epic completed
**Story Status Flow:**
```
backlog → ready-for-dev → in-progress → review → done
```
- **backlog**: Story only exists in epic file
- **ready-for-dev**: Story file created (e.g., `stories/1-3-plant-naming.md`)
- **in-progress**: Developer actively working
- **review**: Ready for code review (via Dev's code-review workflow)
- **done**: Completed
**Retrospective Status:**
```
optional ↔ done
```
- **optional**: Ready to be conducted but not required
- **done**: Finished
### Guidelines
1. **Epic Activation**: Mark epic as `in-progress` when starting work on its first story
2. **Sequential Default**: Stories are typically worked in order, but parallel work is supported
3. **Parallel Work Supported**: Multiple stories can be `in-progress` if team capacity allows
4. **Review Before Done**: Stories should pass through `review` before `done`
5. **Learning Transfer**: Developer typically creates next story after previous one is `done` to incorporate learnings

View File

@ -3,4 +3,295 @@ name: bmad-sprint-status
description: 'Summarize sprint status and surface risks. Use when the user says "check sprint status" or "show sprint status"'
---
Follow the instructions in ./workflow.md.
# Sprint Status Workflow
**Goal:** Summarize sprint status, surface risks, and recommend the next workflow action.
**Your Role:** You are a Developer providing clear, actionable sprint visibility. No time estimates — focus on status, risks, and next steps.
## Conventions
- Bare paths (e.g. `checklist.md`) resolve from the skill root.
- `{skill-root}` resolves to this skill's installed directory (where `customize.toml` lives).
- `{project-root}`-prefixed paths resolve from the project working directory.
- `{skill-name}` resolves to the skill directory's basename.
## On Activation
### Step 1: Resolve the Workflow Block
Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow`
**If the script fails**, resolve the `workflow` block yourself by reading these three files in base → team → user order and applying the same structural merge rules as the resolver:
1. `{skill-root}/customize.toml` — defaults
2. `{project-root}/_bmad/custom/{skill-name}.toml` — team overrides
3. `{project-root}/_bmad/custom/{skill-name}.user.toml` — personal overrides
Any missing file is skipped. Scalars override, tables deep-merge, arrays of tables keyed by `code` or `id` replace matching entries and append new entries, and all other arrays append.
### Step 2: Execute Prepend Steps
Execute each entry in `{workflow.activation_steps_prepend}` in order before proceeding.
### Step 3: Load Persistent Facts
Treat every entry in `{workflow.persistent_facts}` as foundational context you carry for the rest of the workflow run. Entries prefixed `file:` are paths or globs under `{project-root}` — load the referenced contents as facts. All other entries are facts verbatim.
### Step 4: Load Config
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `user_name`
- `communication_language`, `document_output_language`
- `implementation_artifacts`
- `date` as system-generated current datetime
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
### Step 5: Greet the User
Greet `{user_name}`, speaking in `{communication_language}`.
### Step 6: Execute Append Steps
Execute each entry in `{workflow.activation_steps_append}` in order.
Activation is complete. Begin the workflow below.
## Paths
- `sprint_status_file` = `{implementation_artifacts}/sprint-status.yaml`
## Input Files
| Input | Path | Load Strategy |
|-------|------|---------------|
| Sprint status | `{sprint_status_file}` | FULL_LOAD |
## Execution
<workflow>
<step n="0" goal="Determine execution mode">
<action>Set mode = {{mode}} if provided by caller; otherwise mode = "interactive"</action>
<check if="mode == data">
<action>Jump to Step 20</action>
</check>
<check if="mode == validate">
<action>Jump to Step 30</action>
</check>
<check if="mode == interactive">
<action>Continue to Step 1</action>
</check>
</step>
<step n="1" goal="Locate sprint status file">
<action>Load {project_context} for project-wide patterns and conventions (if exists)</action>
<action>Try {sprint_status_file}</action>
<check if="file not found">
<output>sprint-status.yaml not found.
Run `/bmad:bmm:workflows:sprint-planning` to generate it, then rerun sprint-status.</output>
<action>Exit workflow</action>
</check>
<action>Continue to Step 2</action>
</step>
<step n="2" goal="Read and parse sprint-status.yaml">
<action>Read the FULL file: {sprint_status_file}</action>
<action>Parse fields: generated, last_updated, project, project_key, tracking_system, story_location</action>
<action>Parse development_status map. Classify keys:</action>
- Epics: keys starting with "epic-" (and not ending with "-retrospective")
- Retrospectives: keys ending with "-retrospective"
- Stories: everything else (e.g., 1-2-login-form)
<action>Map legacy story status "drafted" → "ready-for-dev"</action>
<action>Count story statuses: backlog, ready-for-dev, in-progress, review, done</action>
<action>Map legacy epic status "contexted" → "in-progress"</action>
<action>Count epic statuses: backlog, in-progress, done</action>
<action>Count retrospective statuses: optional, done</action>
<action>Validate all statuses against known values:</action>
- Valid story statuses: backlog, ready-for-dev, in-progress, review, done, drafted (legacy)
- Valid epic statuses: backlog, in-progress, done, contexted (legacy)
- Valid retrospective statuses: optional, done
<check if="any status is unrecognized">
<output>
**Unknown status detected:**
{{#each invalid_entries}}
- `{{key}}`: "{{status}}" (not recognized)
{{/each}}
**Valid statuses:**
- Stories: backlog, ready-for-dev, in-progress, review, done
- Epics: backlog, in-progress, done
- Retrospectives: optional, done
</output>
<ask>How should these be corrected?
{{#each invalid_entries}}
{{@index}}. {{key}}: "{{status}}" → [select valid status]
{{/each}}
Enter corrections (e.g., "1=in-progress, 2=backlog") or "skip" to continue without fixing:</ask>
<check if="user provided corrections">
<action>Update sprint-status.yaml with corrected values</action>
<action>Re-parse the file with corrected statuses</action>
</check>
</check>
<action>Detect risks:</action>
- IF any story has status "review": suggest `/bmad:bmm:workflows:code-review`
- IF any story has status "in-progress" AND no stories have status "ready-for-dev": recommend staying focused on active story
- IF all epics have status "backlog" AND no stories have status "ready-for-dev": prompt `/bmad:bmm:workflows:create-story`
- IF `last_updated` timestamp is more than 7 days old (or `last_updated` is missing, fall back to `generated`): warn "sprint-status.yaml may be stale"
- IF any story key doesn't match an epic pattern (e.g., story "5-1-..." but no "epic-5"): warn "orphaned story detected"
- IF any epic has status in-progress but has no associated stories: warn "in-progress epic has no stories"
</step>
<step n="3" goal="Select next action recommendation">
<action>Pick the next recommended workflow using priority:</action>
<note>When selecting "first" story: sort by epic number, then story number (e.g., 1-1 before 1-2 before 2-1)</note>
1. If any story status == in-progress → recommend `dev-story` for the first in-progress story
2. Else if any story status == review → recommend `code-review` for the first review story
3. Else if any story status == ready-for-dev → recommend `dev-story`
4. Else if any story status == backlog → recommend `create-story`
5. Else if any retrospective status == optional → recommend `retrospective`
6. Else → All implementation items done; congratulate the user - you both did amazing work together!
<action>Store selected recommendation as: next_story_id, next_workflow_id, next_agent (DEV)</action>
</step>
<step n="4" goal="Display summary">
<output>
## Sprint Status
- Project: {{project}} ({{project_key}})
- Tracking: {{tracking_system}}
- Status file: {sprint_status_file}
**Stories:** backlog {{count_backlog}}, ready-for-dev {{count_ready}}, in-progress {{count_in_progress}}, review {{count_review}}, done {{count_done}}
**Epics:** backlog {{epic_backlog}}, in-progress {{epic_in_progress}}, done {{epic_done}}
**Next Recommendation:** /bmad:bmm:workflows:{{next_workflow_id}} ({{next_story_id}})
{{#if risks}}
**Risks:**
{{#each risks}}
- {{this}}
{{/each}}
{{/if}}
</output>
</step>
<step n="5" goal="Offer actions">
<ask>Pick an option:
1) Run recommended workflow now
2) Show all stories grouped by status
3) Show raw sprint-status.yaml
4) Exit
Choice:</ask>
<check if="choice == 1">
<output>Run `/bmad:bmm:workflows:{{next_workflow_id}}`.
If the command targets a story, set `story_key={{next_story_id}}` when prompted.</output>
</check>
<check if="choice == 2">
<output>
### Stories by Status
- In Progress: {{stories_in_progress}}
- Review: {{stories_in_review}}
- Ready for Dev: {{stories_ready_for_dev}}
- Backlog: {{stories_backlog}}
- Done: {{stories_done}}
</output>
</check>
<check if="choice == 3">
<action>Display the full contents of {sprint_status_file}</action>
</check>
<check if="choice == 4">
<action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
<action>Exit workflow</action>
</check>
</step>
<!-- ========================= -->
<!-- Data mode for other flows -->
<!-- ========================= -->
<step n="20" goal="Data mode output">
<action>Load and parse {sprint_status_file} same as Step 2</action>
<action>Compute recommendation same as Step 3</action>
<template-output>next_workflow_id = {{next_workflow_id}}</template-output>
<template-output>next_story_id = {{next_story_id}}</template-output>
<template-output>count_backlog = {{count_backlog}}</template-output>
<template-output>count_ready = {{count_ready}}</template-output>
<template-output>count_in_progress = {{count_in_progress}}</template-output>
<template-output>count_review = {{count_review}}</template-output>
<template-output>count_done = {{count_done}}</template-output>
<template-output>epic_backlog = {{epic_backlog}}</template-output>
<template-output>epic_in_progress = {{epic_in_progress}}</template-output>
<template-output>epic_done = {{epic_done}}</template-output>
<template-output>risks = {{risks}}</template-output>
<action>Return to caller</action>
</step>
<!-- ========================= -->
<!-- Validate mode -->
<!-- ========================= -->
<step n="30" goal="Validate sprint-status file">
<action>Check that {sprint_status_file} exists</action>
<check if="missing">
<template-output>is_valid = false</template-output>
<template-output>error = "sprint-status.yaml missing"</template-output>
<template-output>suggestion = "Run sprint-planning to create it"</template-output>
<action>Return</action>
</check>
<action>Read and parse {sprint_status_file}</action>
<action>Validate required metadata fields exist: generated, project, project_key, tracking_system, story_location (last_updated is optional for backward compatibility)</action>
<check if="any required field missing">
<template-output>is_valid = false</template-output>
<template-output>error = "Missing required field(s): {{missing_fields}}"</template-output>
<template-output>suggestion = "Re-run sprint-planning or add missing fields manually"</template-output>
<action>Return</action>
</check>
<action>Verify development_status section exists with at least one entry</action>
<check if="development_status missing or empty">
<template-output>is_valid = false</template-output>
<template-output>error = "development_status missing or empty"</template-output>
<template-output>suggestion = "Re-run sprint-planning or repair the file manually"</template-output>
<action>Return</action>
</check>
<action>Validate all status values against known valid statuses:</action>
- Stories: backlog, ready-for-dev, in-progress, review, done (legacy: drafted)
- Epics: backlog, in-progress, done (legacy: contexted)
- Retrospectives: optional, done
<check if="any invalid status found">
<template-output>is_valid = false</template-output>
<template-output>error = "Invalid status values: {{invalid_entries}}"</template-output>
<template-output>suggestion = "Fix invalid statuses in sprint-status.yaml"</template-output>
<action>Return</action>
</check>
<template-output>is_valid = true</template-output>
<template-output>message = "sprint-status.yaml valid: metadata complete, all statuses recognized"</template-output>
<action>Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete` — if the resolved value is non-empty, follow it as the final terminal instruction before exiting.</action>
</step>
</workflow>

View File

@ -0,0 +1,41 @@
# DO NOT EDIT -- overwritten on every update.
#
# Workflow customization surface for bmad-sprint-status. Mirrors the
# agent customization shape under the [workflow] namespace.
[workflow]
# --- Configurable below. Overrides merge per BMad structural rules: ---
# scalars: override wins • arrays (persistent_facts, activation_steps_*): append
# arrays-of-tables with `code`/`id`: replace matching items, append new ones.
# Steps to run before the standard activation (config load, greet).
# Overrides append. Use for pre-flight loads, compliance checks, etc.
activation_steps_prepend = []
# Steps to run after greet but before the workflow begins.
# Overrides append. Use for context-heavy setup that should happen
# once the user has been acknowledged.
activation_steps_append = []
# Persistent facts the workflow keeps in mind for the whole run
# (standards, compliance constraints, stylistic guardrails).
# Distinct from the runtime memory sidecar — these are static context
# loaded on activation. Overrides append.
#
# Each entry is either:
# - a literal sentence, e.g. "All stories must include testable acceptance criteria."
# - a file reference prefixed with `file:`, e.g. "file:{project-root}/docs/standards.md"
# (glob patterns are supported; the file's contents are loaded and treated as facts).
persistent_facts = [
"file:{project-root}/**/project-context.md",
]
# Scalar: executed when the workflow reaches its final step,
# after sprint status is summarized and risks are surfaced. Override wins.
# Leave empty for no custom post-completion behavior.
on_complete = ""

View File

@ -1,261 +0,0 @@
# Sprint Status Workflow
**Goal:** Summarize sprint status, surface risks, and recommend the next workflow action.
**Your Role:** You are a Developer providing clear, actionable sprint visibility. No time estimates — focus on status, risks, and next steps.
---
## INITIALIZATION
### Configuration Loading
Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
- `project_name`, `user_name`
- `communication_language`, `document_output_language`
- `implementation_artifacts`
- `date` as system-generated current datetime
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
### Paths
- `sprint_status_file` = `{implementation_artifacts}/sprint-status.yaml`
### Input Files
| Input | Path | Load Strategy |
|-------|------|---------------|
| Sprint status | `{sprint_status_file}` | FULL_LOAD |
### Context
- `project_context` = `**/project-context.md` (load if exists)
---
## EXECUTION
<workflow>
<step n="0" goal="Determine execution mode">
<action>Set mode = {{mode}} if provided by caller; otherwise mode = "interactive"</action>
<check if="mode == data">
<action>Jump to Step 20</action>
</check>
<check if="mode == validate">
<action>Jump to Step 30</action>
</check>
<check if="mode == interactive">
<action>Continue to Step 1</action>
</check>
</step>
<step n="1" goal="Locate sprint status file">
<action>Load {project_context} for project-wide patterns and conventions (if exists)</action>
<action>Try {sprint_status_file}</action>
<check if="file not found">
<output>❌ sprint-status.yaml not found.
Run `/bmad:bmm:workflows:sprint-planning` to generate it, then rerun sprint-status.</output>
<action>Exit workflow</action>
</check>
<action>Continue to Step 2</action>
</step>
<step n="2" goal="Read and parse sprint-status.yaml">
<action>Read the FULL file: {sprint_status_file}</action>
<action>Parse fields: generated, last_updated, project, project_key, tracking_system, story_location</action>
<action>Parse development_status map. Classify keys:</action>
- Epics: keys starting with "epic-" (and not ending with "-retrospective")
- Retrospectives: keys ending with "-retrospective"
- Stories: everything else (e.g., 1-2-login-form)
<action>Map legacy story status "drafted" → "ready-for-dev"</action>
<action>Count story statuses: backlog, ready-for-dev, in-progress, review, done</action>
<action>Map legacy epic status "contexted" → "in-progress"</action>
<action>Count epic statuses: backlog, in-progress, done</action>
<action>Count retrospective statuses: optional, done</action>
<action>Validate all statuses against known values:</action>
- Valid story statuses: backlog, ready-for-dev, in-progress, review, done, drafted (legacy)
- Valid epic statuses: backlog, in-progress, done, contexted (legacy)
- Valid retrospective statuses: optional, done
<check if="any status is unrecognized">
<output>
⚠️ **Unknown status detected:**
{{#each invalid_entries}}
- `{{key}}`: "{{status}}" (not recognized)
{{/each}}
**Valid statuses:**
- Stories: backlog, ready-for-dev, in-progress, review, done
- Epics: backlog, in-progress, done
- Retrospectives: optional, done
</output>
<ask>How should these be corrected?
{{#each invalid_entries}}
{{@index}}. {{key}}: "{{status}}" → [select valid status]
{{/each}}
Enter corrections (e.g., "1=in-progress, 2=backlog") or "skip" to continue without fixing:</ask>
<check if="user provided corrections">
<action>Update sprint-status.yaml with corrected values</action>
<action>Re-parse the file with corrected statuses</action>
</check>
</check>
<action>Detect risks:</action>
- IF any story has status "review": suggest `/bmad:bmm:workflows:code-review`
- IF any story has status "in-progress" AND no stories have status "ready-for-dev": recommend staying focused on active story
- IF all epics have status "backlog" AND no stories have status "ready-for-dev": prompt `/bmad:bmm:workflows:create-story`
- IF `last_updated` timestamp is more than 7 days old (or `last_updated` is missing, fall back to `generated`): warn "sprint-status.yaml may be stale"
- IF any story key doesn't match an epic pattern (e.g., story "5-1-..." but no "epic-5"): warn "orphaned story detected"
- IF any epic has status in-progress but has no associated stories: warn "in-progress epic has no stories"
</step>
<step n="3" goal="Select next action recommendation">
<action>Pick the next recommended workflow using priority:</action>
<note>When selecting "first" story: sort by epic number, then story number (e.g., 1-1 before 1-2 before 2-1)</note>
1. If any story status == in-progress → recommend `dev-story` for the first in-progress story
2. Else if any story status == review → recommend `code-review` for the first review story
3. Else if any story status == ready-for-dev → recommend `dev-story`
4. Else if any story status == backlog → recommend `create-story`
5. Else if any retrospective status == optional → recommend `retrospective`
6. Else → All implementation items done; congratulate the user - you both did amazing work together!
<action>Store selected recommendation as: next_story_id, next_workflow_id, next_agent (DEV)</action>
</step>
<step n="4" goal="Display summary">
<output>
## 📊 Sprint Status
- Project: {{project}} ({{project_key}})
- Tracking: {{tracking_system}}
- Status file: {sprint_status_file}
**Stories:** backlog {{count_backlog}}, ready-for-dev {{count_ready}}, in-progress {{count_in_progress}}, review {{count_review}}, done {{count_done}}
**Epics:** backlog {{epic_backlog}}, in-progress {{epic_in_progress}}, done {{epic_done}}
**Next Recommendation:** /bmad:bmm:workflows:{{next_workflow_id}} ({{next_story_id}})
{{#if risks}}
**Risks:**
{{#each risks}}
- {{this}}
{{/each}}
{{/if}}
</output>
</step>
<step n="5" goal="Offer actions">
<ask>Pick an option:
1) Run recommended workflow now
2) Show all stories grouped by status
3) Show raw sprint-status.yaml
4) Exit
Choice:</ask>
<check if="choice == 1">
<output>Run `/bmad:bmm:workflows:{{next_workflow_id}}`.
If the command targets a story, set `story_key={{next_story_id}}` when prompted.</output>
</check>
<check if="choice == 2">
<output>
### Stories by Status
- In Progress: {{stories_in_progress}}
- Review: {{stories_in_review}}
- Ready for Dev: {{stories_ready_for_dev}}
- Backlog: {{stories_backlog}}
- Done: {{stories_done}}
</output>
</check>
<check if="choice == 3">
<action>Display the full contents of {sprint_status_file}</action>
</check>
<check if="choice == 4">
<action>Exit workflow</action>
</check>
</step>
<!-- ========================= -->
<!-- Data mode for other flows -->
<!-- ========================= -->
<step n="20" goal="Data mode output">
<action>Load and parse {sprint_status_file} same as Step 2</action>
<action>Compute recommendation same as Step 3</action>
<template-output>next_workflow_id = {{next_workflow_id}}</template-output>
<template-output>next_story_id = {{next_story_id}}</template-output>
<template-output>count_backlog = {{count_backlog}}</template-output>
<template-output>count_ready = {{count_ready}}</template-output>
<template-output>count_in_progress = {{count_in_progress}}</template-output>
<template-output>count_review = {{count_review}}</template-output>
<template-output>count_done = {{count_done}}</template-output>
<template-output>epic_backlog = {{epic_backlog}}</template-output>
<template-output>epic_in_progress = {{epic_in_progress}}</template-output>
<template-output>epic_done = {{epic_done}}</template-output>
<template-output>risks = {{risks}}</template-output>
<action>Return to caller</action>
</step>
<!-- ========================= -->
<!-- Validate mode -->
<!-- ========================= -->
<step n="30" goal="Validate sprint-status file">
<action>Check that {sprint_status_file} exists</action>
<check if="missing">
<template-output>is_valid = false</template-output>
<template-output>error = "sprint-status.yaml missing"</template-output>
<template-output>suggestion = "Run sprint-planning to create it"</template-output>
<action>Return</action>
</check>
<action>Read and parse {sprint_status_file}</action>
<action>Validate required metadata fields exist: generated, project, project_key, tracking_system, story_location (last_updated is optional for backward compatibility)</action>
<check if="any required field missing">
<template-output>is_valid = false</template-output>
<template-output>error = "Missing required field(s): {{missing_fields}}"</template-output>
<template-output>suggestion = "Re-run sprint-planning or add missing fields manually"</template-output>
<action>Return</action>
</check>
<action>Verify development_status section exists with at least one entry</action>
<check if="development_status missing or empty">
<template-output>is_valid = false</template-output>
<template-output>error = "development_status missing or empty"</template-output>
<template-output>suggestion = "Re-run sprint-planning or repair the file manually"</template-output>
<action>Return</action>
</check>
<action>Validate all status values against known valid statuses:</action>
- Stories: backlog, ready-for-dev, in-progress, review, done (legacy: drafted)
- Epics: backlog, in-progress, done (legacy: contexted)
- Retrospectives: optional, done
<check if="any invalid status found">
<template-output>is_valid = false</template-output>
<template-output>error = "Invalid status values: {{invalid_entries}}"</template-output>
<template-output>suggestion = "Fix invalid statuses in sprint-status.yaml"</template-output>
<action>Return</action>
</check>
<template-output>is_valid = true</template-output>
<template-output>message = "sprint-status.yaml valid: metadata complete, all statuses recognized"</template-output>
</step>
</workflow>

View File

@ -1,51 +1,70 @@
num,category,method_name,description,output_pattern
1,collaboration,Stakeholder Round Table,Convene multiple personas to contribute diverse perspectives - essential for requirements gathering and finding balanced solutions across competing interests,perspectives → synthesis → alignment
2,collaboration,Expert Panel Review,Assemble domain experts for deep specialized analysis - ideal when technical depth and peer review quality are needed,expert views → consensus → recommendations
3,collaboration,Debate Club Showdown,Two personas argue opposing positions while a moderator scores points - great for exploring controversial decisions and finding middle ground,thesis → antithesis → synthesis
4,collaboration,User Persona Focus Group,Gather your product's user personas to react to proposals and share frustrations - essential for validating features and discovering unmet needs,reactions → concerns → priorities
5,collaboration,Time Traveler Council,Past-you and future-you advise present-you on decisions - powerful for gaining perspective on long-term consequences vs short-term pressures,past wisdom → present choice → future impact
6,collaboration,Cross-Functional War Room,Product manager + engineer + designer tackle a problem together - reveals trade-offs between feasibility desirability and viability,constraints → trade-offs → balanced solution
7,collaboration,Mentor and Apprentice,Senior expert teaches junior while junior asks naive questions - surfaces hidden assumptions through teaching,explanation → questions → deeper understanding
8,collaboration,Good Cop Bad Cop,Supportive persona and critical persona alternate - finds both strengths to build on and weaknesses to address,encouragement → criticism → balanced view
9,collaboration,Improv Yes-And,Multiple personas build on each other's ideas without blocking - generates unexpected creative directions through collaborative building,idea → build → build → surprising result
10,collaboration,Customer Support Theater,Angry customer and support rep roleplay to find pain points - reveals real user frustrations and service gaps,complaint → investigation → resolution → prevention
11,advanced,Tree of Thoughts,Explore multiple reasoning paths simultaneously then evaluate and select the best - perfect for complex problems with multiple valid approaches,paths → evaluation → selection
12,advanced,Graph of Thoughts,Model reasoning as an interconnected network of ideas to reveal hidden relationships - ideal for systems thinking and discovering emergent patterns,nodes → connections → patterns
13,advanced,Thread of Thought,Maintain coherent reasoning across long contexts by weaving a continuous narrative thread - essential for RAG systems and maintaining consistency,context → thread → synthesis
14,advanced,Self-Consistency Validation,Generate multiple independent approaches then compare for consistency - crucial for high-stakes decisions where verification matters,approaches → comparison → consensus
15,advanced,Meta-Prompting Analysis,Step back to analyze the approach structure and methodology itself - valuable for optimizing prompts and improving problem-solving,current → analysis → optimization
16,advanced,Reasoning via Planning,Build a reasoning tree guided by world models and goal states - excellent for strategic planning and sequential decision-making,model → planning → strategy
17,competitive,Red Team vs Blue Team,Adversarial attack-defend analysis to find vulnerabilities - critical for security testing and building robust solutions,defense → attack → hardening
18,competitive,Shark Tank Pitch,Entrepreneur pitches to skeptical investors who poke holes - stress-tests business viability and forces clarity on value proposition,pitch → challenges → refinement
19,competitive,Code Review Gauntlet,Senior devs with different philosophies review the same code - surfaces style debates and finds consensus on best practices,reviews → debates → standards
20,technical,Architecture Decision Records,Multiple architect personas propose and debate architectural choices with explicit trade-offs - ensures decisions are well-reasoned and documented,options → trade-offs → decision → rationale
21,technical,Rubber Duck Debugging Evolved,Explain your code to progressively more technical ducks until you find the bug - forces clarity at multiple abstraction levels,simple → detailed → technical → aha
22,technical,Algorithm Olympics,Multiple approaches compete on the same problem with benchmarks - finds optimal solution through direct comparison,implementations → benchmarks → winner
23,technical,Security Audit Personas,Hacker + defender + auditor examine system from different threat models - comprehensive security review from multiple angles,vulnerabilities → defenses → compliance
24,technical,Performance Profiler Panel,Database expert + frontend specialist + DevOps engineer diagnose slowness - finds bottlenecks across the full stack,symptoms → analysis → optimizations
25,creative,SCAMPER Method,Apply seven creativity lenses (Substitute/Combine/Adapt/Modify/Put/Eliminate/Reverse) - systematic ideation for product innovation,S→C→A→M→P→E→R
26,creative,Reverse Engineering,Work backwards from desired outcome to find implementation path - powerful for goal achievement and understanding endpoints,end state → steps backward → path forward
27,creative,What If Scenarios,Explore alternative realities to understand possibilities and implications - valuable for contingency planning and exploration,scenarios → implications → insights
28,creative,Random Input Stimulus,Inject unrelated concepts to spark unexpected connections - breaks creative blocks through forced lateral thinking,random word → associations → novel ideas
29,creative,Exquisite Corpse Brainstorm,Each persona adds to the idea seeing only the previous contribution - generates surprising combinations through constrained collaboration,contribution → handoff → contribution → surprise
30,creative,Genre Mashup,Combine two unrelated domains to find fresh approaches - innovation through unexpected cross-pollination,domain A + domain B → hybrid insights
31,research,Literature Review Personas,Optimist researcher + skeptic researcher + synthesizer review sources - balanced assessment of evidence quality,sources → critiques → synthesis
32,research,Thesis Defense Simulation,Student defends hypothesis against committee with different concerns - stress-tests research methodology and conclusions,thesis → challenges → defense → refinements
33,research,Comparative Analysis Matrix,Multiple analysts evaluate options against weighted criteria - structured decision-making with explicit scoring,options → criteria → scores → recommendation
34,risk,Pre-mortem Analysis,Imagine future failure then work backwards to prevent it - powerful technique for risk mitigation before major launches,failure scenario → causes → prevention
35,risk,Failure Mode Analysis,Systematically explore how each component could fail - critical for reliability engineering and safety-critical systems,components → failures → prevention
36,risk,Challenge from Critical Perspective,Play devil's advocate to stress-test ideas and find weaknesses - essential for overcoming groupthink,assumptions → challenges → strengthening
37,risk,Identify Potential Risks,Brainstorm what could go wrong across all categories - fundamental for project planning and deployment preparation,categories → risks → mitigations
38,risk,Chaos Monkey Scenarios,Deliberately break things to test resilience and recovery - ensures systems handle failures gracefully,break → observe → harden
39,core,First Principles Analysis,Strip away assumptions to rebuild from fundamental truths - breakthrough technique for innovation and solving impossible problems,assumptions → truths → new approach
40,core,5 Whys Deep Dive,Repeatedly ask why to drill down to root causes - simple but powerful for understanding failures,why chain → root cause → solution
41,core,Socratic Questioning,Use targeted questions to reveal hidden assumptions and guide discovery - excellent for teaching and self-discovery,questions → revelations → understanding
42,core,Critique and Refine,Systematic review to identify strengths and weaknesses then improve - standard quality check for drafts,strengths/weaknesses → improvements → refined
43,core,Explain Reasoning,Walk through step-by-step thinking to show how conclusions were reached - crucial for transparency,steps → logic → conclusion
44,core,Expand or Contract for Audience,Dynamically adjust detail level and technical depth for target audience - matches content to reader capabilities,audience → adjustments → refined content
45,learning,Feynman Technique,Explain complex concepts simply as if teaching a child - the ultimate test of true understanding,complex → simple → gaps → mastery
46,learning,Active Recall Testing,Test understanding without references to verify true knowledge - essential for identifying gaps,test → gaps → reinforcement
47,philosophical,Occam's Razor Application,Find the simplest sufficient explanation by eliminating unnecessary complexity - essential for debugging,options → simplification → selection
48,philosophical,Trolley Problem Variations,Explore ethical trade-offs through moral dilemmas - valuable for understanding values and difficult decisions,dilemma → analysis → decision
49,retrospective,Hindsight Reflection,Imagine looking back from the future to gain perspective - powerful for project reviews,future view → insights → application
50,retrospective,Lessons Learned Extraction,Systematically identify key takeaways and actionable improvements - essential for continuous improvement,experience → lessons → actions
1,advanced,Tree of Thoughts,Explore multiple reasoning paths simultaneously then evaluate and select the best - perfect for complex problems with multiple valid approaches,paths → evaluation → selection
2,advanced,Graph of Thoughts,Model reasoning as an interconnected network of ideas to reveal hidden relationships - ideal for systems thinking and discovering emergent patterns,nodes → connections → patterns
3,advanced,Thread of Thought,Maintain coherent reasoning across long contexts by weaving a continuous narrative thread - essential for RAG systems and maintaining consistency,context → thread → synthesis
4,advanced,Self-Consistency Validation,Generate multiple independent approaches then compare for consistency - crucial for high-stakes decisions where verification matters,approaches → comparison → consensus
5,advanced,Meta-Prompting Analysis,Step back to analyze the approach structure and methodology itself - valuable for optimizing prompts and improving problem-solving,current → analysis → optimization
6,advanced,Reasoning via Planning,Build a reasoning tree guided by world models and goal states - excellent for strategic planning and sequential decision-making,model → planning → strategy
7,advanced,Chain-of-Thought Scaffolding,Force explicit intermediate reasoning steps before any conclusion — prevents intuitive leaps that skip flawed logic,premise → step → step → conclusion
8,advanced,Few-Shot Exemplar Priming,Provide 2-3 worked examples of the desired reasoning pattern before the real task — aligns output format and depth through demonstration,examples → pattern recognition → application
9,collaboration,Stakeholder Round Table,Convene multiple personas to contribute diverse perspectives - essential for requirements gathering and finding balanced solutions across competing interests,perspectives → synthesis → alignment
10,collaboration,Expert Panel Review,Assemble domain experts for deep specialized analysis - ideal when technical depth and peer review quality are needed,expert views → consensus → recommendations
11,collaboration,Debate Club Showdown,Two personas argue opposing positions while a moderator scores points - great for exploring controversial decisions and finding middle ground,thesis → antithesis → synthesis
12,collaboration,User Persona Focus Group,Gather your product's user personas to react to proposals and share frustrations - essential for validating features and discovering unmet needs,reactions → concerns → priorities
13,collaboration,Time Traveler Council,Past-you and future-you advise present-you on decisions - powerful for gaining perspective on long-term consequences vs short-term pressures,past wisdom → present choice → future impact
14,collaboration,Cross-Functional War Room,Product manager + engineer + designer tackle a problem together - reveals trade-offs between feasibility desirability and viability,constraints → trade-offs → balanced solution
15,collaboration,Mentor and Apprentice,Senior expert teaches junior while junior asks naive questions - surfaces hidden assumptions through teaching,explanation → questions → deeper understanding
16,collaboration,Good Cop Bad Cop,Supportive persona and critical persona alternate - finds both strengths to build on and weaknesses to address,encouragement → criticism → balanced view
17,collaboration,Improv Yes-And,Multiple personas build on each other's ideas without blocking - generates unexpected creative directions through collaborative building,idea → build → build → surprising result
18,collaboration,Customer Support Theater,Angry customer and support rep roleplay to find pain points - reveals real user frustrations and service gaps,complaint → investigation → resolution → prevention
19,collaboration,Six Thinking Hats,Rotate through six modes (facts - feelings - caution - optimism - creativity - process) to ensure a group covers every angle without crosstalk,white → red → black → yellow → green → blue
20,collaboration,Delphi Method,Experts give independent estimates - see anonymized results - then revise — converges on calibrated group judgment while avoiding anchoring bias,independent estimates → reveal → revise → converge
21,competitive,Red Team vs Blue Team,Adversarial attack-defend analysis to find vulnerabilities - critical for security testing and building robust solutions,defense → attack → hardening
22,competitive,Shark Tank Pitch,Entrepreneur pitches to skeptical investors who poke holes - stress-tests business viability and forces clarity on value proposition,pitch → challenges → refinement
23,competitive,Code Review Gauntlet,Senior devs with different philosophies review the same code - surfaces style debates and finds consensus on best practices,reviews → debates → standards
24,core,First Principles Analysis,Strip away assumptions to rebuild from fundamental truths - breakthrough technique for innovation and solving impossible problems,assumptions → truths → new approach
25,core,5 Whys Deep Dive,Repeatedly ask why to drill down to root causes - simple but powerful for understanding failures,why chain → root cause → solution
26,core,Socratic Questioning,Use targeted questions to reveal hidden assumptions and guide discovery - excellent for teaching and self-discovery,questions → revelations → understanding
27,core,Critique and Refine,Systematic review to identify strengths and weaknesses then improve - standard quality check for drafts,strengths/weaknesses → improvements → refined
28,core,Explain Reasoning,Walk through step-by-step thinking to show how conclusions were reached - crucial for transparency,steps → logic → conclusion
29,core,Expand or Contract for Audience,Dynamically adjust detail level and technical depth for target audience - matches content to reader capabilities,audience → adjustments → refined content
30,core,Second-Order Thinking,Think beyond immediate consequences to anticipate cascading effects and long-term implications - essential for strategic decisions where first-order solutions create hidden downstream problems,action → consequences → second-order effects → informed choice
31,core,Inversion Analysis,Flip the problem by asking what would guarantee failure instead of how to succeed - reveals hidden obstacles and blind spots by approaching challenges from the opposite direction,goal → invert → failure paths → avoidance → solution
32,core,Problem Decomposition,Break a complex problem into independent sub-problems - solve each - then reassemble — essential when a task is too large or tangled to tackle whole,whole → parts → solutions → reassembly
33,core,Analogy Mapping,Find a well-understood parallel domain and transfer its structure to the current problem — unlocks insight by borrowing proven mental models,source domain → mapping → target insight
34,core,Steelmanning,Construct the strongest possible version of an opposing argument before responding — builds credibility and catches blind spots that strawmanning misses,opposing view → strongest form → honest rebuttal
35,creative,SCAMPER Method,Apply seven creativity lenses (Substitute/Combine/Adapt/Modify/Put/Eliminate/Reverse) - systematic ideation for product innovation,S→C→A→M→P→E→R
36,creative,Reverse Engineering,Work backwards from desired outcome to find implementation path - powerful for goal achievement and understanding endpoints,end state → steps backward → path forward
37,creative,What If Scenarios,Explore alternative realities to understand possibilities and implications - valuable for contingency planning and exploration,scenarios → implications → insights
38,creative,Random Input Stimulus,Inject unrelated concepts to spark unexpected connections - breaks creative blocks through forced lateral thinking,random word → associations → novel ideas
39,creative,Exquisite Corpse Brainstorm,Each persona adds to the idea seeing only the previous contribution - generates surprising combinations through constrained collaboration,contribution → handoff → contribution → surprise
40,creative,Genre Mashup,Combine two unrelated domains to find fresh approaches - innovation through unexpected cross-pollination,domain A + domain B → hybrid insights
41,creative,Constraint Injection,Deliberately add an artificial limitation (budget - time - technology) to force novel solutions — creativity thrives under pressure,add constraint → forced creativity → remove constraint → evaluate
42,creative,Morphological Analysis,List independent parameters of a problem - enumerate options for each - then systematically combine — ensures you don't miss non-obvious configurations,parameters → options grid → combinations → evaluation
43,framing,Abstraction Laddering,"Move up (""why?"") for strategic clarity or down (""how?"") for tactical detail — ensures you're solving at the right altitude",concrete ↔ abstract → right level
44,framing,Reframe the Question,Challenge whether the stated problem is the real problem — often the question itself is wrong and a better framing unlocks an easy answer,stated problem → reframe → true problem → solution
45,framing,Stakeholder Lens Rotation,Serially adopt each stakeholder's world-view to see the same situation differently — reveals whose needs are being overlooked,perspective A → B → C → gaps found
46,learning,Feynman Technique,Explain complex concepts simply as if teaching a child - the ultimate test of true understanding,complex → simple → gaps → mastery
47,learning,Active Recall Testing,Test understanding without references to verify true knowledge - essential for identifying gaps,test → gaps → reinforcement
48,learning,Deliberate Practice Loop,Identify a specific sub-skill - drill it with immediate feedback - adjust - repeat — targeted improvement beats general repetition,isolate → drill → feedback → adjust → repeat
49,philosophical,Occam's Razor Application,Find the simplest sufficient explanation by eliminating unnecessary complexity - essential for debugging,options → simplification → selection
50,philosophical,Trolley Problem Variations,Explore ethical trade-offs through moral dilemmas - valuable for understanding values and difficult decisions,dilemma → analysis → decision
51,research,Literature Review Personas,Optimist researcher + skeptic researcher + synthesizer review sources - balanced assessment of evidence quality,sources → critiques → synthesis
52,research,Thesis Defense Simulation,Student defends hypothesis against committee with different concerns - stress-tests research methodology and conclusions,thesis → challenges → defense → refinements
53,research,Comparative Analysis Matrix,Multiple analysts evaluate options against weighted criteria - structured decision-making with explicit scoring,options → criteria → scores → recommendation
54,research,Source Triangulation,Require at least three independent source types (quantitative - qualitative - expert) before accepting a claim — guards against single-source bias,claim → source A → source B → source C → confidence rating
55,retrospective,Hindsight Reflection,Imagine looking back from the future to gain perspective - powerful for project reviews,future view → insights → application
56,retrospective,Lessons Learned Extraction,Systematically identify key takeaways and actionable improvements - essential for continuous improvement,experience → lessons → actions
57,risk,Pre-mortem Analysis,Imagine future failure then work backwards to prevent it - powerful technique for risk mitigation before major launches,failure scenario → causes → prevention
58,risk,Failure Mode Analysis,Systematically explore how each component could fail - critical for reliability engineering and safety-critical systems,components → failures → prevention
59,risk,Challenge from Critical Perspective,Play devil's advocate to stress-test ideas and find weaknesses - essential for overcoming groupthink,assumptions → challenges → strengthening
60,risk,Identify Potential Risks,Brainstorm what could go wrong across all categories - fundamental for project planning and deployment preparation,categories → risks → mitigations
61,risk,Chaos Monkey Scenarios,Deliberately break things to test resilience and recovery - ensures systems handle failures gracefully,break → observe → harden
62,risk,Assumption Audit,Explicitly list every assumption underlying a plan - rate each by confidence and impact - then stress-test the weakest — prevents building on shaky foundations,list → rate → stress-test → shore up
63,risk,Cascading Failure Simulation,Trace how one component's failure propagates through dependencies — reveals hidden coupling and single points of failure,trigger failure → trace propagation → find amplifiers → decouple
64,technical,Architecture Decision Records,Multiple architect personas propose and debate architectural choices with explicit trade-offs - ensures decisions are well-reasoned and documented,options → trade-offs → decision → rationale
65,technical,Rubber Duck Debugging Evolved,Explain your code to progressively more technical ducks until you find the bug - forces clarity at multiple abstraction levels,simple → detailed → technical → aha
66,technical,Algorithm Olympics,Multiple approaches compete on the same problem with benchmarks - finds optimal solution through direct comparison,implementations → benchmarks → winner
67,technical,Security Audit Personas,Hacker + defender + auditor examine system from different threat models - comprehensive security review from multiple angles,vulnerabilities → defenses → compliance
68,technical,Performance Profiler Panel,Database expert + frontend specialist + DevOps engineer diagnose slowness - finds bottlenecks across the full stack,symptoms → analysis → optimizations
69,technical,Boundary & Edge Case Sweep,Systematically test extremes - zeros - nulls - maximums - and type mismatches — catches the failures that happy-path thinking always misses,inputs → boundaries → edge cases → failures found

1 num category method_name description output_pattern
2 1 collaboration advanced Stakeholder Round Table Tree of Thoughts Convene multiple personas to contribute diverse perspectives - essential for requirements gathering and finding balanced solutions across competing interests Explore multiple reasoning paths simultaneously then evaluate and select the best - perfect for complex problems with multiple valid approaches perspectives → synthesis → alignment paths → evaluation → selection
3 2 collaboration advanced Expert Panel Review Graph of Thoughts Assemble domain experts for deep specialized analysis - ideal when technical depth and peer review quality are needed Model reasoning as an interconnected network of ideas to reveal hidden relationships - ideal for systems thinking and discovering emergent patterns expert views → consensus → recommendations nodes → connections → patterns
4 3 collaboration advanced Debate Club Showdown Thread of Thought Two personas argue opposing positions while a moderator scores points - great for exploring controversial decisions and finding middle ground Maintain coherent reasoning across long contexts by weaving a continuous narrative thread - essential for RAG systems and maintaining consistency thesis → antithesis → synthesis context → thread → synthesis
5 4 collaboration advanced User Persona Focus Group Self-Consistency Validation Gather your product's user personas to react to proposals and share frustrations - essential for validating features and discovering unmet needs Generate multiple independent approaches then compare for consistency - crucial for high-stakes decisions where verification matters reactions → concerns → priorities approaches → comparison → consensus
6 5 collaboration advanced Time Traveler Council Meta-Prompting Analysis Past-you and future-you advise present-you on decisions - powerful for gaining perspective on long-term consequences vs short-term pressures Step back to analyze the approach structure and methodology itself - valuable for optimizing prompts and improving problem-solving past wisdom → present choice → future impact current → analysis → optimization
7 6 collaboration advanced Cross-Functional War Room Reasoning via Planning Product manager + engineer + designer tackle a problem together - reveals trade-offs between feasibility desirability and viability Build a reasoning tree guided by world models and goal states - excellent for strategic planning and sequential decision-making constraints → trade-offs → balanced solution model → planning → strategy
8 7 collaboration advanced Mentor and Apprentice Chain-of-Thought Scaffolding Senior expert teaches junior while junior asks naive questions - surfaces hidden assumptions through teaching Force explicit intermediate reasoning steps before any conclusion — prevents intuitive leaps that skip flawed logic explanation → questions → deeper understanding premise → step → step → conclusion
9 8 collaboration advanced Good Cop Bad Cop Few-Shot Exemplar Priming Supportive persona and critical persona alternate - finds both strengths to build on and weaknesses to address Provide 2-3 worked examples of the desired reasoning pattern before the real task — aligns output format and depth through demonstration encouragement → criticism → balanced view examples → pattern recognition → application
10 9 collaboration Improv Yes-And Stakeholder Round Table Multiple personas build on each other's ideas without blocking - generates unexpected creative directions through collaborative building Convene multiple personas to contribute diverse perspectives - essential for requirements gathering and finding balanced solutions across competing interests idea → build → build → surprising result perspectives → synthesis → alignment
11 10 collaboration Customer Support Theater Expert Panel Review Angry customer and support rep roleplay to find pain points - reveals real user frustrations and service gaps Assemble domain experts for deep specialized analysis - ideal when technical depth and peer review quality are needed complaint → investigation → resolution → prevention expert views → consensus → recommendations
12 11 advanced collaboration Tree of Thoughts Debate Club Showdown Explore multiple reasoning paths simultaneously then evaluate and select the best - perfect for complex problems with multiple valid approaches Two personas argue opposing positions while a moderator scores points - great for exploring controversial decisions and finding middle ground paths → evaluation → selection thesis → antithesis → synthesis
13 12 advanced collaboration Graph of Thoughts User Persona Focus Group Model reasoning as an interconnected network of ideas to reveal hidden relationships - ideal for systems thinking and discovering emergent patterns Gather your product's user personas to react to proposals and share frustrations - essential for validating features and discovering unmet needs nodes → connections → patterns reactions → concerns → priorities
14 13 advanced collaboration Thread of Thought Time Traveler Council Maintain coherent reasoning across long contexts by weaving a continuous narrative thread - essential for RAG systems and maintaining consistency Past-you and future-you advise present-you on decisions - powerful for gaining perspective on long-term consequences vs short-term pressures context → thread → synthesis past wisdom → present choice → future impact
15 14 advanced collaboration Self-Consistency Validation Cross-Functional War Room Generate multiple independent approaches then compare for consistency - crucial for high-stakes decisions where verification matters Product manager + engineer + designer tackle a problem together - reveals trade-offs between feasibility desirability and viability approaches → comparison → consensus constraints → trade-offs → balanced solution
16 15 advanced collaboration Meta-Prompting Analysis Mentor and Apprentice Step back to analyze the approach structure and methodology itself - valuable for optimizing prompts and improving problem-solving Senior expert teaches junior while junior asks naive questions - surfaces hidden assumptions through teaching current → analysis → optimization explanation → questions → deeper understanding
17 16 advanced collaboration Reasoning via Planning Good Cop Bad Cop Build a reasoning tree guided by world models and goal states - excellent for strategic planning and sequential decision-making Supportive persona and critical persona alternate - finds both strengths to build on and weaknesses to address model → planning → strategy encouragement → criticism → balanced view
18 17 competitive collaboration Red Team vs Blue Team Improv Yes-And Adversarial attack-defend analysis to find vulnerabilities - critical for security testing and building robust solutions Multiple personas build on each other's ideas without blocking - generates unexpected creative directions through collaborative building defense → attack → hardening idea → build → build → surprising result
19 18 competitive collaboration Shark Tank Pitch Customer Support Theater Entrepreneur pitches to skeptical investors who poke holes - stress-tests business viability and forces clarity on value proposition Angry customer and support rep roleplay to find pain points - reveals real user frustrations and service gaps pitch → challenges → refinement complaint → investigation → resolution → prevention
20 19 competitive collaboration Code Review Gauntlet Six Thinking Hats Senior devs with different philosophies review the same code - surfaces style debates and finds consensus on best practices Rotate through six modes (facts - feelings - caution - optimism - creativity - process) to ensure a group covers every angle without crosstalk reviews → debates → standards white → red → black → yellow → green → blue
21 20 technical collaboration Architecture Decision Records Delphi Method Multiple architect personas propose and debate architectural choices with explicit trade-offs - ensures decisions are well-reasoned and documented Experts give independent estimates - see anonymized results - then revise — converges on calibrated group judgment while avoiding anchoring bias options → trade-offs → decision → rationale independent estimates → reveal → revise → converge
22 21 technical competitive Rubber Duck Debugging Evolved Red Team vs Blue Team Explain your code to progressively more technical ducks until you find the bug - forces clarity at multiple abstraction levels Adversarial attack-defend analysis to find vulnerabilities - critical for security testing and building robust solutions simple → detailed → technical → aha defense → attack → hardening
23 22 technical competitive Algorithm Olympics Shark Tank Pitch Multiple approaches compete on the same problem with benchmarks - finds optimal solution through direct comparison Entrepreneur pitches to skeptical investors who poke holes - stress-tests business viability and forces clarity on value proposition implementations → benchmarks → winner pitch → challenges → refinement
24 23 technical competitive Security Audit Personas Code Review Gauntlet Hacker + defender + auditor examine system from different threat models - comprehensive security review from multiple angles Senior devs with different philosophies review the same code - surfaces style debates and finds consensus on best practices vulnerabilities → defenses → compliance reviews → debates → standards
25 24 technical core Performance Profiler Panel First Principles Analysis Database expert + frontend specialist + DevOps engineer diagnose slowness - finds bottlenecks across the full stack Strip away assumptions to rebuild from fundamental truths - breakthrough technique for innovation and solving impossible problems symptoms → analysis → optimizations assumptions → truths → new approach
26 25 creative core SCAMPER Method 5 Whys Deep Dive Apply seven creativity lenses (Substitute/Combine/Adapt/Modify/Put/Eliminate/Reverse) - systematic ideation for product innovation Repeatedly ask why to drill down to root causes - simple but powerful for understanding failures S→C→A→M→P→E→R why chain → root cause → solution
27 26 creative core Reverse Engineering Socratic Questioning Work backwards from desired outcome to find implementation path - powerful for goal achievement and understanding endpoints Use targeted questions to reveal hidden assumptions and guide discovery - excellent for teaching and self-discovery end state → steps backward → path forward questions → revelations → understanding
28 27 creative core What If Scenarios Critique and Refine Explore alternative realities to understand possibilities and implications - valuable for contingency planning and exploration Systematic review to identify strengths and weaknesses then improve - standard quality check for drafts scenarios → implications → insights strengths/weaknesses → improvements → refined
29 28 creative core Random Input Stimulus Explain Reasoning Inject unrelated concepts to spark unexpected connections - breaks creative blocks through forced lateral thinking Walk through step-by-step thinking to show how conclusions were reached - crucial for transparency random word → associations → novel ideas steps → logic → conclusion
30 29 creative core Exquisite Corpse Brainstorm Expand or Contract for Audience Each persona adds to the idea seeing only the previous contribution - generates surprising combinations through constrained collaboration Dynamically adjust detail level and technical depth for target audience - matches content to reader capabilities contribution → handoff → contribution → surprise audience → adjustments → refined content
31 30 creative core Genre Mashup Second-Order Thinking Combine two unrelated domains to find fresh approaches - innovation through unexpected cross-pollination Think beyond immediate consequences to anticipate cascading effects and long-term implications - essential for strategic decisions where first-order solutions create hidden downstream problems domain A + domain B → hybrid insights action → consequences → second-order effects → informed choice
32 31 research core Literature Review Personas Inversion Analysis Optimist researcher + skeptic researcher + synthesizer review sources - balanced assessment of evidence quality Flip the problem by asking what would guarantee failure instead of how to succeed - reveals hidden obstacles and blind spots by approaching challenges from the opposite direction sources → critiques → synthesis goal → invert → failure paths → avoidance → solution
33 32 research core Thesis Defense Simulation Problem Decomposition Student defends hypothesis against committee with different concerns - stress-tests research methodology and conclusions Break a complex problem into independent sub-problems - solve each - then reassemble — essential when a task is too large or tangled to tackle whole thesis → challenges → defense → refinements whole → parts → solutions → reassembly
34 33 research core Comparative Analysis Matrix Analogy Mapping Multiple analysts evaluate options against weighted criteria - structured decision-making with explicit scoring Find a well-understood parallel domain and transfer its structure to the current problem — unlocks insight by borrowing proven mental models options → criteria → scores → recommendation source domain → mapping → target insight
35 34 risk core Pre-mortem Analysis Steelmanning Imagine future failure then work backwards to prevent it - powerful technique for risk mitigation before major launches Construct the strongest possible version of an opposing argument before responding — builds credibility and catches blind spots that strawmanning misses failure scenario → causes → prevention opposing view → strongest form → honest rebuttal
36 35 risk creative Failure Mode Analysis SCAMPER Method Systematically explore how each component could fail - critical for reliability engineering and safety-critical systems Apply seven creativity lenses (Substitute/Combine/Adapt/Modify/Put/Eliminate/Reverse) - systematic ideation for product innovation components → failures → prevention S→C→A→M→P→E→R
37 36 risk creative Challenge from Critical Perspective Reverse Engineering Play devil's advocate to stress-test ideas and find weaknesses - essential for overcoming groupthink Work backwards from desired outcome to find implementation path - powerful for goal achievement and understanding endpoints assumptions → challenges → strengthening end state → steps backward → path forward
38 37 risk creative Identify Potential Risks What If Scenarios Brainstorm what could go wrong across all categories - fundamental for project planning and deployment preparation Explore alternative realities to understand possibilities and implications - valuable for contingency planning and exploration categories → risks → mitigations scenarios → implications → insights
39 38 risk creative Chaos Monkey Scenarios Random Input Stimulus Deliberately break things to test resilience and recovery - ensures systems handle failures gracefully Inject unrelated concepts to spark unexpected connections - breaks creative blocks through forced lateral thinking break → observe → harden random word → associations → novel ideas
40 39 core creative First Principles Analysis Exquisite Corpse Brainstorm Strip away assumptions to rebuild from fundamental truths - breakthrough technique for innovation and solving impossible problems Each persona adds to the idea seeing only the previous contribution - generates surprising combinations through constrained collaboration assumptions → truths → new approach contribution → handoff → contribution → surprise
41 40 core creative 5 Whys Deep Dive Genre Mashup Repeatedly ask why to drill down to root causes - simple but powerful for understanding failures Combine two unrelated domains to find fresh approaches - innovation through unexpected cross-pollination why chain → root cause → solution domain A + domain B → hybrid insights
42 41 core creative Socratic Questioning Constraint Injection Use targeted questions to reveal hidden assumptions and guide discovery - excellent for teaching and self-discovery Deliberately add an artificial limitation (budget - time - technology) to force novel solutions — creativity thrives under pressure questions → revelations → understanding add constraint → forced creativity → remove constraint → evaluate
43 42 core creative Critique and Refine Morphological Analysis Systematic review to identify strengths and weaknesses then improve - standard quality check for drafts List independent parameters of a problem - enumerate options for each - then systematically combine — ensures you don't miss non-obvious configurations strengths/weaknesses → improvements → refined parameters → options grid → combinations → evaluation
44 43 core framing Explain Reasoning Abstraction Laddering Walk through step-by-step thinking to show how conclusions were reached - crucial for transparency Move up ("why?") for strategic clarity or down ("how?") for tactical detail — ensures you're solving at the right altitude steps → logic → conclusion concrete ↔ abstract → right level
45 44 core framing Expand or Contract for Audience Reframe the Question Dynamically adjust detail level and technical depth for target audience - matches content to reader capabilities Challenge whether the stated problem is the real problem — often the question itself is wrong and a better framing unlocks an easy answer audience → adjustments → refined content stated problem → reframe → true problem → solution
46 45 learning framing Feynman Technique Stakeholder Lens Rotation Explain complex concepts simply as if teaching a child - the ultimate test of true understanding Serially adopt each stakeholder's world-view to see the same situation differently — reveals whose needs are being overlooked complex → simple → gaps → mastery perspective A → B → C → gaps found
47 46 learning Active Recall Testing Feynman Technique Test understanding without references to verify true knowledge - essential for identifying gaps Explain complex concepts simply as if teaching a child - the ultimate test of true understanding test → gaps → reinforcement complex → simple → gaps → mastery
48 47 philosophical learning Occam's Razor Application Active Recall Testing Find the simplest sufficient explanation by eliminating unnecessary complexity - essential for debugging Test understanding without references to verify true knowledge - essential for identifying gaps options → simplification → selection test → gaps → reinforcement
49 48 philosophical learning Trolley Problem Variations Deliberate Practice Loop Explore ethical trade-offs through moral dilemmas - valuable for understanding values and difficult decisions Identify a specific sub-skill - drill it with immediate feedback - adjust - repeat — targeted improvement beats general repetition dilemma → analysis → decision isolate → drill → feedback → adjust → repeat
50 49 retrospective philosophical Hindsight Reflection Occam's Razor Application Imagine looking back from the future to gain perspective - powerful for project reviews Find the simplest sufficient explanation by eliminating unnecessary complexity - essential for debugging future view → insights → application options → simplification → selection
51 50 retrospective philosophical Lessons Learned Extraction Trolley Problem Variations Systematically identify key takeaways and actionable improvements - essential for continuous improvement Explore ethical trade-offs through moral dilemmas - valuable for understanding values and difficult decisions experience → lessons → actions dilemma → analysis → decision
52 51 research Literature Review Personas Optimist researcher + skeptic researcher + synthesizer review sources - balanced assessment of evidence quality sources → critiques → synthesis
53 52 research Thesis Defense Simulation Student defends hypothesis against committee with different concerns - stress-tests research methodology and conclusions thesis → challenges → defense → refinements
54 53 research Comparative Analysis Matrix Multiple analysts evaluate options against weighted criteria - structured decision-making with explicit scoring options → criteria → scores → recommendation
55 54 research Source Triangulation Require at least three independent source types (quantitative - qualitative - expert) before accepting a claim — guards against single-source bias claim → source A → source B → source C → confidence rating
56 55 retrospective Hindsight Reflection Imagine looking back from the future to gain perspective - powerful for project reviews future view → insights → application
57 56 retrospective Lessons Learned Extraction Systematically identify key takeaways and actionable improvements - essential for continuous improvement experience → lessons → actions
58 57 risk Pre-mortem Analysis Imagine future failure then work backwards to prevent it - powerful technique for risk mitigation before major launches failure scenario → causes → prevention
59 58 risk Failure Mode Analysis Systematically explore how each component could fail - critical for reliability engineering and safety-critical systems components → failures → prevention
60 59 risk Challenge from Critical Perspective Play devil's advocate to stress-test ideas and find weaknesses - essential for overcoming groupthink assumptions → challenges → strengthening
61 60 risk Identify Potential Risks Brainstorm what could go wrong across all categories - fundamental for project planning and deployment preparation categories → risks → mitigations
62 61 risk Chaos Monkey Scenarios Deliberately break things to test resilience and recovery - ensures systems handle failures gracefully break → observe → harden
63 62 risk Assumption Audit Explicitly list every assumption underlying a plan - rate each by confidence and impact - then stress-test the weakest — prevents building on shaky foundations list → rate → stress-test → shore up
64 63 risk Cascading Failure Simulation Trace how one component's failure propagates through dependencies — reveals hidden coupling and single points of failure trigger failure → trace propagation → find amplifiers → decouple
65 64 technical Architecture Decision Records Multiple architect personas propose and debate architectural choices with explicit trade-offs - ensures decisions are well-reasoned and documented options → trade-offs → decision → rationale
66 65 technical Rubber Duck Debugging Evolved Explain your code to progressively more technical ducks until you find the bug - forces clarity at multiple abstraction levels simple → detailed → technical → aha
67 66 technical Algorithm Olympics Multiple approaches compete on the same problem with benchmarks - finds optimal solution through direct comparison implementations → benchmarks → winner
68 67 technical Security Audit Personas Hacker + defender + auditor examine system from different threat models - comprehensive security review from multiple angles vulnerabilities → defenses → compliance
69 68 technical Performance Profiler Panel Database expert + frontend specialist + DevOps engineer diagnose slowness - finds bottlenecks across the full stack symptoms → analysis → optimizations
70 69 technical Boundary & Edge Case Sweep Systematically test extremes - zeros - nulls - maximums - and type mismatches — catches the failures that happy-path thinking always misses inputs → boundaries → edge cases → failures found

File diff suppressed because it is too large Load Diff

View File

@ -222,7 +222,6 @@ Support assumption: full Agent Skills support. Gemini CLI docs confirm workspace
- [x] Confirm Gemini CLI native skills path is `.gemini/skills/{skill-name}/SKILL.md` (per [geminicli.com/docs/cli/skills](https://geminicli.com/docs/cli/skills/))
- [x] Implement native skills output — target_dir `.gemini/skills`, skill_format true, template_type default (replaces TOML templates)
- [x] Add legacy cleanup for `.gemini/commands` (via `legacy_targets`)
- [x] Test fresh install — skills written to `.gemini/skills/bmad-master/SKILL.md` with correct frontmatter
- [x] Test reinstall/upgrade from legacy TOML command output — legacy dir removed, skills installed
- [x] Confirm no ancestor conflict protection is needed — Gemini CLI uses workspace > user > extension precedence, no ancestor directory inheritance
@ -236,7 +235,6 @@ Support assumption: full Agent Skills support. iFlow docs confirm workspace skil
- [x] Confirm iFlow native skills path is `.iflow/skills/{skill-name}/SKILL.md`
- [x] Implement native skills output — target_dir `.iflow/skills`, skill_format true, template_type default
- [x] Add legacy cleanup for `.iflow/commands` (via `legacy_targets`)
- [x] Test fresh install — skills written to `.iflow/skills/bmad-master/SKILL.md`
- [x] Test legacy cleanup — legacy commands dir removed
- [x] Implement/extend automated tests — 6 assertions in test suite 24
@ -249,7 +247,6 @@ Support assumption: full Agent Skills support. Qwen Code supports workspace skil
- [x] Confirm QwenCoder native skills path is `.qwen/skills/{skill-name}/SKILL.md`
- [x] Implement native skills output — target_dir `.qwen/skills`, skill_format true, template_type default
- [x] Add legacy cleanup for `.qwen/commands` (via `legacy_targets`)
- [x] Test fresh install — skills written to `.qwen/skills/bmad-master/SKILL.md`
- [x] Test legacy cleanup — legacy commands dir removed
- [x] Implement/extend automated tests — 6 assertions in test suite 25
@ -262,7 +259,6 @@ Support assumption: full Agent Skills support. Rovo Dev now supports workspace s
- [x] Confirm Rovo Dev native skills path is `.rovodev/skills/{skill-name}/SKILL.md` (per Atlassian blog)
- [x] Replace 257-line custom `rovodev.js` with config-driven entry in `platform-codes.yaml`
- [x] Add legacy cleanup for `.rovodev/workflows` (via `legacy_targets`) and BMAD entries in `prompts.yml` (via `cleanupRovoDevPrompts()` in `_config-driven.js`)
- [x] Test fresh install — skills written to `.rovodev/skills/bmad-master/SKILL.md`
- [x] Test legacy cleanup — legacy workflows dir removed, `prompts.yml` BMAD entries stripped while preserving user entries
- [x] Implement/extend automated tests — 8 assertions in test suite 26

View File

@ -14,6 +14,7 @@ const { ExternalModuleManager } = require('../modules/external-manager');
const { resolveModuleVersion } = require('../modules/version-resolver');
const { ExistingInstall } = require('./existing-install');
const { warnPreNativeSkillsLegacy } = require('./legacy-warnings');
class Installer {
constructor() {
@ -41,6 +42,16 @@ class Installer {
const officialModules = await OfficialModules.build(config, paths);
const existingInstall = await ExistingInstall.detect(paths.bmadDir);
try {
await warnPreNativeSkillsLegacy({
projectRoot: paths.projectRoot,
existingVersion: existingInstall.installed ? existingInstall.version : null,
});
} catch (error) {
// Legacy-dir scan is informational; never let it abort install.
await prompts.log.warn(`Warning: Could not check for legacy BMAD entries: ${error.message}`);
}
if (existingInstall.installed) {
await this._removeDeselectedModules(existingInstall, config, paths);
updateState = await this._prepareUpdateState(paths, config, existingInstall, officialModules);
@ -183,15 +194,16 @@ class Installer {
if (toRemove.length === 0) return;
await this.ideManager.ensureInitialized();
for (const ide of toRemove) {
try {
const handler = this.ideManager.handlers.get(ide);
if (handler) {
await handler.cleanup(paths.projectRoot);
}
} catch (error) {
await prompts.log.warn(`Warning: Failed to remove ${ide}: ${error.message}`);
// Pass the newly-selected list as remainingIdes so cleanupByList skips
// target_dir wipes for IDEs whose directory is still owned by a peer
// (e.g. removing 'cursor' while 'gemini' remains — both share .agents/skills).
const results = await this.ideManager.cleanupByList(paths.projectRoot, toRemove, {
remainingIdes: [...newlySelected],
});
for (const result of results || []) {
if (result && result.success === false) {
await prompts.log.warn(`Warning: Failed to remove ${result.ide}: ${result.error || 'unknown error'}`);
}
}
}
@ -342,13 +354,14 @@ class Installer {
return;
}
for (const ide of validIdes) {
const setupResult = await this.ideManager.setup(ide, paths.projectRoot, paths.bmadDir, {
selectedModules: allModules || [],
verbose: config.verbose,
previousSkillIds,
});
const setupResults = await this.ideManager.setupBatch(validIdes, paths.projectRoot, paths.bmadDir, {
selectedModules: allModules || [],
verbose: config.verbose,
previousSkillIds,
});
for (const setupResult of setupResults) {
const ide = setupResult.ide;
if (setupResult.success) {
addResult(ide, 'ok', setupResult.detail || '');
} else {

View File

@ -0,0 +1,151 @@
const os = require('node:os');
const path = require('node:path');
const semver = require('semver');
const fs = require('../fs-native');
const prompts = require('../prompts');
const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
const { getInstalledCanonicalIds, isBmadOwnedEntry } = require('../ide/shared/installed-skills');
const MIN_NATIVE_SKILLS_VERSION = '6.1.0';
// Pre-v6.1.0 paths: BMAD used to install commands/workflows/etc in tool-specific dirs.
// In v6.1.0 BMAD switched to native SKILL.md format.
const LEGACY_COMMAND_PATHS = [
'.agent/workflows',
'.augment/commands',
'.claude/commands',
'.clinerules/workflows',
'.codex/prompts',
'~/.codex/prompts',
'.codebuddy/commands',
'.crush/commands',
'.cursor/commands',
'.gemini/commands',
'.github/agents',
'.github/prompts',
'.iflow/commands',
'.kilocode/workflows',
'.kiro/steering',
'.opencode/agents',
'.opencode/commands',
'.opencode/agent',
'.opencode/command',
'.qwen/commands',
'.roo/commands',
'.rovodev/workflows',
'.trae/rules',
'.windsurf/workflows',
];
// Skill paths that moved to the cross-tool .agents/skills/ standard.
// Users upgrading from a prior install may have stale BMAD skills here that
// the AI tool will load alongside the new ones, causing duplicates.
const LEGACY_SKILL_PATHS = [
'.augment/skills',
'~/.augment/skills',
'.codex/skills',
'.crush/skills',
'.cursor/skills',
'~/.cursor/skills',
'.gemini/skills',
'~/.gemini/skills',
'.github/skills',
'~/.github/skills',
'.kilocode/skills',
'.kimi/skills',
'~/.kimi/skills',
'.opencode/skills',
'~/.opencode/skills',
'.pi/skills',
'~/.pi/skills',
'.roo/skills',
'~/.roo/skills',
'.rovodev/skills',
'~/.rovodev/skills',
'.windsurf/skills',
'~/.windsurf/skills',
'~/.codeium/windsurf/skills',
];
const LEGACY_PATHS = [...LEGACY_COMMAND_PATHS, ...LEGACY_SKILL_PATHS];
function expandPath(p) {
if (p === '~') return os.homedir();
if (p.startsWith('~/')) return path.join(os.homedir(), p.slice(2));
return p;
}
function resolveLegacyPath(projectRoot, p) {
if (path.isAbsolute(p) || p.startsWith('~')) return expandPath(p);
return path.join(projectRoot, p);
}
async function findStaleLegacyDirs(projectRoot) {
const bmadDir = path.join(projectRoot, BMAD_FOLDER_NAME);
const canonicalIds = await getInstalledCanonicalIds(bmadDir);
const findings = [];
for (const legacyPath of LEGACY_PATHS) {
const resolved = resolveLegacyPath(projectRoot, legacyPath);
if (!(await fs.pathExists(resolved))) continue;
try {
const entries = await fs.readdir(resolved);
const bmadEntries = entries.filter((e) => isBmadOwnedEntry(e, canonicalIds));
if (bmadEntries.length > 0) {
findings.push({ path: resolved, displayPath: legacyPath, count: bmadEntries.length, entries: bmadEntries });
}
} catch {
// Unreadable dir — skip
}
}
return findings;
}
function isPreNativeSkillsVersion(version) {
if (!version) return false;
const coerced = semver.valid(version) || semver.valid(semver.coerce(version));
if (!coerced) return false;
return semver.lt(coerced, MIN_NATIVE_SKILLS_VERSION);
}
async function warnPreNativeSkillsLegacy({ projectRoot, existingVersion } = {}) {
const versionTriggered = isPreNativeSkillsVersion(existingVersion);
const staleDirs = await findStaleLegacyDirs(projectRoot);
if (!versionTriggered && staleDirs.length === 0) return;
if (versionTriggered) {
await prompts.log.warn(
`Detected previous BMAD install v${existingVersion} (pre-${MIN_NATIVE_SKILLS_VERSION}). ` +
`BMAD switched to native skills format in v${MIN_NATIVE_SKILLS_VERSION}; old command/workflow directories from your prior install may still be present.`,
);
}
if (staleDirs.length > 0) {
await prompts.log.warn(
`Found stale BMAD entries in ${staleDirs.length} legacy location(s) that the new installer no longer manages. ` +
`Your AI tool may load these alongside the new skills, causing duplicates. Remove them manually:`,
);
for (const finding of staleDirs) {
// Print each entry by exact name. A `bmad*` glob would (a) miss
// custom-module skills the canonicalId scan now picks up, and
// (b) match bmad-os-* utility skills the user should keep.
const entries = finding.entries || [];
for (const entry of entries) {
await prompts.log.message(` rm -rf "${path.join(finding.path, entry)}"`);
}
}
} else if (versionTriggered) {
await prompts.log.message(
' No stale legacy directories detected, but if your AI tool shows duplicate BMAD commands after install, check for old `bmad-*` entries in tool-specific dirs (e.g. .claude/commands, .cursor/commands).',
);
}
}
module.exports = {
warnPreNativeSkillsLegacy,
findStaleLegacyDirs,
isPreNativeSkillsVersion,
LEGACY_PATHS,
MIN_NATIVE_SKILLS_VERSION,
};

View File

@ -1,9 +1,20 @@
const path = require('node:path');
const https = require('node:https');
const { execFile } = require('node:child_process');
const { promisify } = require('node:util');
const fs = require('../fs-native');
const crypto = require('node:crypto');
const { resolveModuleVersion } = require('../modules/version-resolver');
const prompts = require('../prompts');
const execFileAsync = promisify(execFile);
const NPM_LOOKUP_TIMEOUT_MS = 10_000;
const NPM_PACKAGE_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
function isValidNpmPackageName(packageName) {
return typeof packageName === 'string' && NPM_PACKAGE_NAME_PATTERN.test(packageName);
}
class Manifest {
/**
* Create a new manifest
@ -362,35 +373,40 @@ class Manifest {
* @returns {string|null} Latest version or null
*/
async fetchNpmVersion(packageName) {
try {
const https = require('node:https');
const { execSync } = require('node:child_process');
if (!isValidNpmPackageName(packageName)) {
return null;
}
try {
// Try using npm view first (more reliable)
try {
const result = execSync(`npm view ${packageName} version`, {
const { stdout } = await execFileAsync('npm', ['view', packageName, 'version'], {
encoding: 'utf8',
stdio: 'pipe',
timeout: 10_000,
timeout: NPM_LOOKUP_TIMEOUT_MS,
});
return result.trim();
return stdout.trim();
} catch {
// Fallback to npm registry API
return new Promise((resolve, reject) => {
https
.get(`https://registry.npmjs.org/${packageName}`, (res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('end', () => {
try {
const pkg = JSON.parse(data);
resolve(pkg['dist-tags']?.latest || pkg.version || null);
} catch {
resolve(null);
}
});
})
.on('error', () => resolve(null));
return new Promise((resolve) => {
const request = https.get(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, (res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('end', () => {
try {
const pkg = JSON.parse(data);
resolve(pkg['dist-tags']?.latest || pkg.version || null);
} catch {
resolve(null);
}
});
});
request.setTimeout(NPM_LOOKUP_TIMEOUT_MS, () => {
request.destroy();
resolve(null);
});
request.on('error', () => resolve(null));
});
}
} catch {

View File

@ -1,10 +1,10 @@
const os = require('node:os');
const path = require('node:path');
const fs = require('../fs-native');
const yaml = require('yaml');
const prompts = require('../prompts');
const csv = require('csv-parse/sync');
const { BMAD_FOLDER_NAME } = require('./shared/path-utils');
const { getInstalledCanonicalIds, isBmadOwnedEntry } = require('./shared/installed-skills');
/**
* Config-driven IDE setup handler
@ -16,7 +16,7 @@ const { BMAD_FOLDER_NAME } = require('./shared/path-utils');
* Features:
* - Config-driven from platform-codes.yaml
* - Verbatim skill installation from skill-manifest.csv
* - Legacy directory cleanup and IDE-specific marker removal
* - IDE-specific marker removal (copilot-instructions, kilo modes, rovodev prompts)
*/
class ConfigDrivenIdeSetup {
constructor(platformCode, platformConfig) {
@ -44,16 +44,20 @@ class ConfigDrivenIdeSetup {
async detect(projectDir) {
if (!this.configDir) return false;
const dir = path.join(projectDir || process.cwd(), this.configDir);
if (await fs.pathExists(dir)) {
try {
const entries = await fs.readdir(dir);
return entries.some((e) => typeof e === 'string' && e.startsWith('bmad'));
} catch {
return false;
}
const root = projectDir || process.cwd();
const dir = path.join(root, this.configDir);
if (!(await fs.pathExists(dir))) return false;
let entries;
try {
entries = await fs.readdir(dir);
} catch {
return false;
}
return false;
const bmadDir = await this._findBmadDir(root);
const canonicalIds = await getInstalledCanonicalIds(bmadDir);
return entries.some((e) => isBmadOwnedEntry(e, canonicalIds));
}
/**
@ -92,6 +96,12 @@ class ConfigDrivenIdeSetup {
return { success: false, reason: 'no-config' };
}
// When a peer platform in the same install batch owns this target_dir,
// skip the skill write — the peer has already populated it.
if (options.skipTarget) {
return { success: true, results: { skills: 0, sharedTargetHandledByPeer: true } };
}
if (this.installerConfig.target_dir) {
return this.installToTarget(projectDir, bmadDir, this.installerConfig, options);
}
@ -222,27 +232,6 @@ class ConfigDrivenIdeSetup {
removalSet = new Set();
}
// Migrate legacy target directories (e.g. .opencode/agent → .opencode/agents)
// Legacy dirs are abandoned entirely, so use prefix matching (null removalSet)
if (this.installerConfig?.legacy_targets) {
const legacyDirsExist = await Promise.all(
this.installerConfig.legacy_targets.map((d) =>
this.isGlobalPath(d) ? fs.pathExists(d.replace(/^~/, os.homedir())) : fs.pathExists(path.join(projectDir, d)),
),
);
if (legacyDirsExist.some(Boolean)) {
if (!options.silent) await prompts.log.message(' Migrating legacy directories...');
for (const legacyDir of this.installerConfig.legacy_targets) {
if (this.isGlobalPath(legacyDir)) {
await this.warnGlobalLegacy(legacyDir, options);
} else {
await this.cleanupTarget(projectDir, legacyDir, options, null);
await this.removeEmptyParents(projectDir, legacyDir);
}
}
}
}
// Strip BMAD markers from copilot-instructions.md if present
if (this.name === 'github-copilot') {
await this.cleanupCopilotInstructions(projectDir, options);
@ -258,47 +247,17 @@ class ConfigDrivenIdeSetup {
await this.cleanupRovoDevPrompts(projectDir, options);
}
// Skip target_dir cleanup when a peer platform owns this directory
// (set during dedup'd install or when uninstalling one of several
// platforms that share the same target_dir).
if (options.skipTarget) return;
// Clean current target directory
if (this.installerConfig?.target_dir) {
await this.cleanupTarget(projectDir, this.installerConfig.target_dir, options, removalSet);
}
}
/**
* Check if a path is global (starts with ~ or is absolute)
* @param {string} p - Path to check
* @returns {boolean}
*/
isGlobalPath(p) {
return p.startsWith('~') || path.isAbsolute(p);
}
/**
* Warn about stale BMAD files in a global legacy directory (never auto-deletes)
* @param {string} legacyDir - Legacy directory path (may start with ~)
* @param {Object} options - Options (silent, etc.)
*/
async warnGlobalLegacy(legacyDir, options = {}) {
try {
const expanded = legacyDir.startsWith('~/')
? path.join(os.homedir(), legacyDir.slice(2))
: legacyDir === '~'
? os.homedir()
: legacyDir;
if (!(await fs.pathExists(expanded))) return;
const entries = await fs.readdir(expanded);
const bmadFiles = entries.filter((e) => typeof e === 'string' && e.startsWith('bmad'));
if (bmadFiles.length > 0 && !options.silent) {
await prompts.log.warn(`Found ${bmadFiles.length} stale BMAD file(s) in ${expanded}. Remove manually: rm ${expanded}/bmad-*`);
}
} catch {
// Errors reading global paths are silently ignored
}
}
/**
* Find the _bmad directory in a project
* @param {string} projectDir - Project directory
@ -426,8 +385,8 @@ class ConfigDrivenIdeSetup {
// Always preserve bmad-os-* utility skills regardless of cleanup mode
if (entry.startsWith('bmad-os-')) continue;
// Surgical removal from set, or legacy prefix matching when set is null
const shouldRemove = removalSet ? removalSet.has(entry) : entry.startsWith('bmad');
// Surgical removal from set, or fallback to manifest+prefix detection when null
const shouldRemove = removalSet ? removalSet.has(entry) : isBmadOwnedEntry(entry, null);
if (shouldRemove) {
try {
@ -590,10 +549,9 @@ class ConfigDrivenIdeSetup {
try {
if (await fs.pathExists(candidatePath)) {
const entries = await fs.readdir(candidatePath);
const hasBmad = entries.some(
(e) => typeof e === 'string' && e.toLowerCase().startsWith('bmad') && !e.toLowerCase().startsWith('bmad-os-'),
);
if (hasBmad) {
const ancestorBmadDir = await this._findBmadDir(current);
const canonicalIds = await getInstalledCanonicalIds(ancestorBmadDir);
if (entries.some((e) => isBmadOwnedEntry(e, canonicalIds))) {
return candidatePath;
}
}
@ -605,43 +563,6 @@ class ConfigDrivenIdeSetup {
return null;
}
/**
* Walk up ancestor directories from relativeDir toward projectDir, removing each if empty
* Stops at projectDir boundary — never removes projectDir itself
* @param {string} projectDir - Project root (boundary)
* @param {string} relativeDir - Relative directory to start from
*/
async removeEmptyParents(projectDir, relativeDir) {
const resolvedProject = path.resolve(projectDir);
let current = relativeDir;
let last = null;
while (current && current !== '.' && current !== last) {
last = current;
const fullPath = path.resolve(projectDir, current);
// Boundary guard: never traverse outside projectDir
if (!fullPath.startsWith(resolvedProject + path.sep) && fullPath !== resolvedProject) break;
try {
if (!(await fs.pathExists(fullPath))) {
// Dir already gone — advance current; last is reset at top of next iteration
current = path.dirname(current);
continue;
}
const remaining = await fs.readdir(fullPath);
if (remaining.length > 0) break;
await fs.rmdir(fullPath);
} catch (error) {
// ENOTEMPTY: TOCTOU race (file added between readdir and rmdir) — skip level, continue upward
// ENOENT: dir removed by another process between pathExists and rmdir — skip level, continue upward
if (error.code === 'ENOTEMPTY' || error.code === 'ENOENT') {
current = path.dirname(current);
continue;
}
break; // fatal error (e.g. EACCES) — stop upward walk
}
current = path.dirname(current);
}
}
}
module.exports = { ConfigDrivenIdeSetup };

View File

@ -160,8 +160,18 @@ class IdeManager {
let detail = '';
if (handlerResult && handlerResult.results) {
const r = handlerResult.results;
const count = r.skillDirectories || r.skills || 0;
if (count > 0) detail = `${count} skills`;
let count = r.skillDirectories || r.skills || 0;
// Dedup'd platform: report the count its peer wrote so the user sees
// a consistent picture across all platforms sharing the dir.
if (count === 0 && r.sharedTargetHandledByPeer && options.sharedSkillCount) {
count = options.sharedSkillCount;
}
const targetDir = handler.installerConfig?.target_dir || null;
if (count > 0 && targetDir) {
detail = `${count} skills → ${targetDir}`;
} else if (count > 0) {
detail = `${count} skills`;
}
}
// Propagate handler's success status (default true for backward compat)
const success = handlerResult?.success !== false;
@ -172,6 +182,57 @@ class IdeManager {
}
}
/**
* Run setup for multiple IDEs as a single batch.
* Dedupes work when several selected platforms share the same target_dir:
* the first platform owns the directory write, peers skip it.
* @param {Array<string>} ideList - IDE names to set up
* @param {string} projectDir
* @param {string} bmadDir
* @param {Object} [options] - Forwarded to each handler.setup
* @returns {Promise<Array>} Per-IDE results
*/
async setupBatch(ideList, projectDir, bmadDir, options = {}) {
await this.ensureInitialized();
const results = [];
// target_dir → { firstIde, skillCount } from the platform that actually wrote it
const claimedTargets = new Map();
for (const ideName of ideList) {
const handler = this.handlers.get(ideName.toLowerCase());
if (!handler) {
results.push(await this.setup(ideName, projectDir, bmadDir, options));
continue;
}
const target = handler.installerConfig?.target_dir || null;
const claim = target ? claimedTargets.get(target) : null;
const skipTarget = !!claim;
const result = await this.setup(ideName, projectDir, bmadDir, {
...options,
skipTarget,
sharedWith: claim?.firstIde || null,
sharedTarget: target,
sharedSkillCount: claim?.skillCount || 0,
});
if (target && !claim) {
const writtenCount = result.handlerResult?.results?.skillDirectories || result.handlerResult?.results?.skills || 0;
// Only claim the target when the install actually succeeded and wrote skills.
// If the first platform fails (ancestor conflict, exception, etc.), leave the
// dir unclaimed so the next peer becomes the new first writer instead of
// silently skipping into a broken/empty target_dir.
if (result.success && writtenCount > 0) {
claimedTargets.set(target, { firstIde: ideName, skillCount: writtenCount });
}
}
results.push(result);
}
return results;
}
/**
* Cleanup IDE configurations
* @param {string} projectDir - Project directory
@ -198,6 +259,8 @@ class IdeManager {
* @param {string} projectDir - Project directory
* @param {Array<string>} ideList - List of IDE names to clean up
* @param {Object} [options] - Cleanup options passed through to handlers
* options.remainingIdes - IDE names still installed after this cleanup; used
* to skip target_dir wipe when a co-installed platform shares the dir.
* @returns {Array} Results array
*/
async cleanupByList(projectDir, ideList, options = {}) {
@ -211,13 +274,27 @@ class IdeManager {
// Build lowercase lookup for case-insensitive matching
const lowercaseHandlers = new Map([...this.handlers.entries()].map(([k, v]) => [k.toLowerCase(), v]));
// Resolve target_dirs for IDEs that will remain installed after this cleanup
const remainingTargets = new Set();
if (Array.isArray(options.remainingIdes)) {
for (const remaining of options.remainingIdes) {
const h = lowercaseHandlers.get(String(remaining).toLowerCase());
const t = h?.installerConfig?.target_dir;
if (t) remainingTargets.add(t);
}
}
for (const ideName of ideList) {
const handler = lowercaseHandlers.get(ideName.toLowerCase());
if (!handler) continue;
const target = handler.installerConfig?.target_dir || null;
const skipTarget = target && remainingTargets.has(target);
const cleanupOptions = skipTarget ? { ...options, skipTarget: true } : options;
try {
await handler.cleanup(projectDir, options);
results.push({ ide: ideName, success: true });
await handler.cleanup(projectDir, cleanupOptions);
results.push({ ide: ideName, success: true, skippedTarget: !!skipTarget });
} catch (error) {
results.push({ ide: ideName, success: false, error: error.message });
}

View File

@ -5,122 +5,203 @@
# preferred: Whether shown as a recommended option on install
# suspended: (optional) Message explaining why install is blocked
# installer:
# target_dir: Directory where skill directories are installed
# legacy_targets: (optional) Old target dirs to clean up on reinstall
# target_dir: Directory where skill directories are installed (project/workspace)
# global_target_dir: (optional) User-home directory for global install
# ancestor_conflict_check: (optional) Refuse install when ancestor dir has BMAD files
#
# Multiple platforms may share the same target_dir or global_target_dir — many tools
# read from the shared `.agents/skills/` and `~/.agents/skills/` cross-tool standard.
# Paths verified against each tool's primary docs as of 2026-04-25.
platforms:
adal:
name: "AdaL"
preferred: false
installer:
target_dir: .adal/skills
global_target_dir: ~/.adal/skills
amp:
name: "Sourcegraph Amp"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.config/agents/skills
antigravity:
name: "Google Antigravity"
preferred: false
installer:
legacy_targets:
- .agent/workflows
target_dir: .agent/skills
global_target_dir: ~/.gemini/antigravity/skills
auggie:
name: "Auggie"
preferred: false
installer:
legacy_targets:
- .augment/commands
target_dir: .augment/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
bob:
name: "IBM Bob"
preferred: false
installer:
target_dir: .bob/skills
global_target_dir: ~/.bob/skills
claude-code:
name: "Claude Code"
preferred: true
installer:
legacy_targets:
- .claude/commands
target_dir: .claude/skills
global_target_dir: ~/.claude/skills
cline:
name: "Cline"
preferred: false
installer:
legacy_targets:
- .clinerules/workflows
target_dir: .cline/skills
global_target_dir: ~/.cline/skills
codex:
name: "Codex"
preferred: false
preferred: true
installer:
legacy_targets:
- .codex/prompts
- ~/.codex/prompts
target_dir: .agents/skills
global_target_dir: ~/.codex/skills
codebuddy:
name: "CodeBuddy"
preferred: false
installer:
legacy_targets:
- .codebuddy/commands
target_dir: .codebuddy/skills
global_target_dir: ~/.codebuddy/skills
command-code:
name: "Command Code"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
cortex:
name: "Snowflake Cortex Code"
preferred: false
installer:
target_dir: .cortex/skills
global_target_dir: ~/.snowflake/cortex/skills
crush:
name: "Crush"
preferred: false
installer:
legacy_targets:
- .crush/commands
target_dir: .crush/skills
target_dir: .agents/skills
global_target_dir: ~/.config/agents/skills
cursor:
name: "Cursor"
preferred: true
installer:
legacy_targets:
- .cursor/commands
target_dir: .cursor/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
droid:
name: "Factory Droid"
preferred: false
installer:
target_dir: .factory/skills
global_target_dir: ~/.factory/skills
firebender:
name: "Firebender"
preferred: false
installer:
target_dir: .firebender/skills
global_target_dir: ~/.agents/skills
gemini:
name: "Gemini CLI"
preferred: false
installer:
legacy_targets:
- .gemini/commands
target_dir: .gemini/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
github-copilot:
name: "GitHub Copilot"
preferred: true
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
goose:
name: "Block Goose"
preferred: false
installer:
legacy_targets:
- .github/agents
- .github/prompts
target_dir: .github/skills
target_dir: .agents/skills
global_target_dir: ~/.config/agents/skills
iflow:
name: "iFlow"
preferred: false
installer:
legacy_targets:
- .iflow/commands
target_dir: .iflow/skills
global_target_dir: ~/.iflow/skills
junie:
name: "Junie"
preferred: false
installer:
target_dir: .agents/skills
target_dir: .junie/skills
global_target_dir: ~/.junie/skills
kilo:
name: "KiloCoder"
preferred: false
installer:
legacy_targets:
- .kilocode/workflows
target_dir: .kilocode/skills
target_dir: .agents/skills
global_target_dir: ~/.kilocode/skills
kimi-code:
name: "Kimi Code"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
kiro:
name: "Kiro"
preferred: false
installer:
legacy_targets:
- .kiro/steering
target_dir: .kiro/skills
global_target_dir: ~/.kiro/skills
kode:
name: "Kode"
preferred: false
installer:
target_dir: .kode/skills
global_target_dir: ~/.kode/skills
mistral-vibe:
name: "Mistral Vibe"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.vibe/skills
mux:
name: "Mux"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
neovate:
name: "Neovate"
preferred: false
installer:
target_dir: .neovate/skills
global_target_dir: ~/.neovate/skills
ona:
name: "Ona"
@ -128,65 +209,98 @@ platforms:
installer:
target_dir: .ona/skills
openclaw:
name: "OpenClaw"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
opencode:
name: "OpenCode"
preferred: false
installer:
legacy_targets:
- .opencode/agents
- .opencode/commands
- .opencode/agent
- .opencode/command
target_dir: .opencode/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
openhands:
name: "OpenHands"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
pi:
name: "Pi"
preferred: false
installer:
target_dir: .pi/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
pochi:
name: "Pochi"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
qoder:
name: "Qoder"
preferred: false
installer:
target_dir: .qoder/skills
global_target_dir: ~/.qoder/skills
qwen:
name: "QwenCoder"
preferred: false
installer:
legacy_targets:
- .qwen/commands
target_dir: .qwen/skills
global_target_dir: ~/.qwen/skills
replit:
name: "Replit Agent"
preferred: false
installer:
target_dir: .agents/skills
roo:
name: "Roo Code"
preferred: false
installer:
legacy_targets:
- .roo/commands
target_dir: .roo/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
rovo-dev:
name: "Rovo Dev"
preferred: false
installer:
legacy_targets:
- .rovodev/workflows
target_dir: .rovodev/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
trae:
name: "Trae"
preferred: false
installer:
legacy_targets:
- .trae/rules
target_dir: .trae/skills
warp:
name: "Warp"
preferred: false
installer:
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
windsurf:
name: "Windsurf"
preferred: false
installer:
legacy_targets:
- .windsurf/workflows
target_dir: .windsurf/skills
target_dir: .agents/skills
global_target_dir: ~/.agents/skills
zencoder:
name: "Zencoder"
preferred: false
installer:
target_dir: .zencoder/skills
global_target_dir: ~/.zencoder/skills

View File

@ -0,0 +1,50 @@
const path = require('node:path');
const fs = require('../../fs-native');
const csv = require('csv-parse/sync');
/**
* Read the global skill-manifest.csv and return the set of canonicalIds.
* These define which directory entries in a target_dir are BMAD-owned, regardless
* of whether they happen to start with "bmad-" (custom modules can ship skills
* with any prefix, e.g. "fred-cool-skill").
*
* @param {string} bmadDir - Path to the _bmad install directory
* @returns {Promise<Set<string>>} Set of canonicalIds, or empty set if manifest missing
*/
async function getInstalledCanonicalIds(bmadDir) {
const ids = new Set();
if (!bmadDir) return ids;
const csvPath = path.join(bmadDir, '_config', 'skill-manifest.csv');
if (!(await fs.pathExists(csvPath))) return ids;
try {
const content = await fs.readFile(csvPath, 'utf8');
const records = csv.parse(content, { columns: true, skip_empty_lines: true });
for (const record of records) {
if (record.canonicalId) ids.add(record.canonicalId);
}
} catch {
// Unreadable/invalid manifest — treat as no info
}
return ids;
}
/**
* Test whether a directory entry is BMAD-owned.
* Prefers the manifest's canonicalIds; falls back to the legacy "bmad" prefix
* when no manifest is available (early install, ancestor lookup with no bmad dir).
*
* @param {string} entry - Directory entry name
* @param {Set<string>|null} canonicalIds - From getInstalledCanonicalIds, or null
* @returns {boolean}
*/
function isBmadOwnedEntry(entry, canonicalIds) {
if (!entry || typeof entry !== 'string') return false;
if (entry.toLowerCase().startsWith('bmad-os-')) return false;
if (canonicalIds && canonicalIds.size > 0) return canonicalIds.has(entry);
return entry.toLowerCase().startsWith('bmad');
}
module.exports = { getInstalledCanonicalIds, isBmadOwnedEntry };

View File

@ -1,20 +1,107 @@
const path = require('node:path');
const os = require('node:os');
const semver = require('semver');
const fs = require('./fs-native');
const { CLIUtils } = require('./cli-utils');
const { ExternalModuleManager } = require('./modules/external-manager');
const { resolveModuleVersion } = require('./modules/version-resolver');
const { parseChannelOptions, buildPlan, orphanPinWarnings, bundledTargetWarnings } = require('./modules/channel-plan');
const { Manifest } = require('./core/manifest');
const {
parseChannelOptions,
buildPlan,
decideChannelForModule,
orphanPinWarnings,
bundledTargetWarnings,
} = require('./modules/channel-plan');
const channelResolver = require('./modules/channel-resolver');
const prompts = require('./prompts');
const manifest = new Manifest();
/**
* Read a module version from the freshest local metadata available.
* @param {string} moduleCode - Module code (e.g., 'core', 'bmm', 'cis')
* @returns {string} Version string or empty string
* Format a resolved version for display in installer labels.
* Semver-like values are normalized to a single leading "v".
* @param {string|null|undefined} version
* @returns {string}
*/
async function getModuleVersion(moduleCode) {
function formatDisplayVersion(version) {
const trimmed = typeof version === 'string' ? version.trim() : '';
if (!trimmed) return '';
const normalized = semver.valid(semver.coerce(trimmed));
if (normalized) {
return `v${normalized}`;
}
return trimmed;
}
/**
* Build the display label for a module, showing an upgrade arrow when an
* installed semver differs from the latest resolvable semver.
* @param {string} name
* @param {string} latestVersion
* @param {string} installedVersion
* @returns {string}
*/
function buildModuleLabel(name, latestVersion, installedVersion = '') {
const latestDisplay = formatDisplayVersion(latestVersion);
if (!latestDisplay) return name;
const installedDisplay = formatDisplayVersion(installedVersion);
const latestSemver = semver.valid(semver.coerce(latestVersion || ''));
const installedSemver = semver.valid(semver.coerce(installedVersion || ''));
if (installedDisplay && latestSemver && installedSemver && semver.neq(installedSemver, latestSemver)) {
return `${name} (${installedDisplay} → ${latestDisplay})`;
}
return `${name} (${latestDisplay})`;
}
/**
* Resolve the version to show for a module picker entry. External modules use
* the same channel/tag resolver as installs; bundled modules fall back to local
* source metadata.
* @param {string} moduleCode - Module code (e.g., 'core', 'bmm', 'cis')
* @param {Object} options
* @param {string|null} [options.repoUrl] - Module repository URL for tag resolution
* @param {string|null} [options.registryDefault] - Registry default channel
* @param {Object|null} [options.channelOptions] - Parsed installer channel options
* @returns {Promise<{version: string, lookupAttempted: boolean, lookupSucceeded: boolean}>}
*/
async function getModuleVersion(moduleCode, { repoUrl = null, registryDefault = null, channelOptions = null } = {}) {
if (repoUrl) {
const plan = decideChannelForModule({
code: moduleCode,
channelOptions,
registryDefault,
});
try {
const resolved = await channelResolver.resolveChannel({
channel: plan.channel,
pin: plan.pin,
repoUrl,
});
if (resolved?.version) {
return {
version: resolved.version,
lookupAttempted: plan.channel === 'stable',
lookupSucceeded: true,
};
}
} catch {
// Fall back to local metadata when tag resolution is unavailable.
}
}
const versionInfo = await resolveModuleVersion(moduleCode);
return versionInfo.version || '';
return {
version: versionInfo.version || '',
lookupAttempted: !!repoUrl,
lookupSucceeded: false,
};
}
/**
@ -122,7 +209,7 @@ class UI {
// Return early with modify configuration
if (actionType === 'update') {
// Get existing installation info
const { installedModuleIds } = await this.getExistingInstallation(confirmedDirectory);
const { installedModuleIds, installedModuleVersions } = await this.getExistingInstallation(confirmedDirectory);
await prompts.log.message(`Found existing modules: ${[...installedModuleIds].join(', ')}`);
@ -144,7 +231,7 @@ class UI {
`Non-interactive mode (--yes): using default modules (installed + defaults): ${selectedModules.join(', ')}`,
);
} else {
selectedModules = await this.selectAllModules(installedModuleIds);
selectedModules = await this.selectAllModules(installedModuleIds, installedModuleVersions, channelOptions);
}
// Resolve custom sources from --custom-source flag
@ -208,7 +295,7 @@ class UI {
}
// This section is only for new installations (update returns early above)
const { installedModuleIds } = await this.getExistingInstallation(confirmedDirectory);
const { installedModuleIds, installedModuleVersions } = await this.getExistingInstallation(confirmedDirectory);
// Unified module selection - all modules in one grouped multiselect
let selectedModules;
@ -227,7 +314,7 @@ class UI {
selectedModules = await this.getDefaultModules(installedModuleIds);
await prompts.log.info(`Using default modules (--yes flag): ${selectedModules.join(', ')}`);
} else {
selectedModules = await this.selectAllModules(installedModuleIds);
selectedModules = await this.selectAllModules(installedModuleIds, installedModuleVersions, channelOptions);
}
// Resolve custom sources from --custom-source flag
@ -526,7 +613,7 @@ class UI {
/**
* Get existing installation info and installed modules
* @param {string} directory - Installation directory
* @returns {Object} Object with existingInstall, installedModuleIds, and bmadDir
* @returns {Object} Object with existingInstall, installedModuleIds, installedModuleVersions, and bmadDir
*/
async getExistingInstallation(directory) {
const { ExistingInstall } = require('./core/existing-install');
@ -535,8 +622,26 @@ class UI {
const { bmadDir } = await installer.findBmadDir(directory);
const existingInstall = await ExistingInstall.detect(bmadDir);
const installedModuleIds = new Set(existingInstall.moduleIds);
const installedModuleVersions = new Map();
const manifestModules = await manifest.getAllModuleVersions(bmadDir);
return { existingInstall, installedModuleIds, bmadDir };
for (const module of manifestModules) {
if (module?.name && module.version) {
installedModuleVersions.set(module.name, module.version);
}
}
for (const module of existingInstall.modules) {
if (module?.id && module.version && module.version !== 'unknown' && !installedModuleVersions.has(module.id)) {
installedModuleVersions.set(module.id, module.version);
}
}
if (existingInstall.hasCore && existingInstall.version && !installedModuleVersions.has('core')) {
installedModuleVersions.set('core', existingInstall.version);
}
return { existingInstall, installedModuleIds, installedModuleVersions, bmadDir };
}
/**
@ -617,11 +722,13 @@ class UI {
/**
* Select all modules across three tiers: official, community, and custom URL.
* @param {Set} installedModuleIds - Currently installed module IDs
* @param {Map<string, string>} installedModuleVersions - Installed module versions from the local manifest
* @param {Object|null} channelOptions - Parsed installer channel options
* @returns {Array} Selected module codes (excluding core)
*/
async selectAllModules(installedModuleIds = new Set()) {
async selectAllModules(installedModuleIds = new Set(), installedModuleVersions = new Map(), channelOptions = null) {
// Phase 1: Official modules
const officialSelected = await this._selectOfficialModules(installedModuleIds);
const officialSelected = await this._selectOfficialModules(installedModuleIds, installedModuleVersions, channelOptions);
// Determine which installed modules are NOT official (community or custom).
// These must be preserved even if the user declines to browse community/custom.
@ -657,9 +764,11 @@ class UI {
* Select official modules using autocompleteMultiselect.
* Extracted from the original selectAllModules - unchanged behavior.
* @param {Set} installedModuleIds - Currently installed module IDs
* @param {Map<string, string>} installedModuleVersions - Installed module versions from the local manifest
* @param {Object|null} channelOptions - Parsed installer channel options
* @returns {Array} Selected official module codes
*/
async _selectOfficialModules(installedModuleIds = new Set()) {
async _selectOfficialModules(installedModuleIds = new Set(), installedModuleVersions = new Map(), channelOptions = null) {
// Built-in modules (core, bmm) come from local source, not the registry
const { OfficialModules } = require('./modules/official-modules');
const builtInModules = (await new OfficialModules().listAvailable()).modules || [];
@ -672,15 +781,18 @@ class UI {
const initialValues = [];
const lockedValues = ['core'];
const buildModuleEntry = async (code, name, description, isDefault) => {
const buildModuleEntry = async (code, name, description, isDefault, repoUrl = null, registryDefault = null) => {
const isInstalled = installedModuleIds.has(code);
const version = await getModuleVersion(code);
const label = version ? `${name} (v${version})` : name;
const installedVersion = installedModuleVersions.get(code) || '';
const versionState = await getModuleVersion(code, { repoUrl, registryDefault, channelOptions });
const label = buildModuleLabel(name, versionState.version, installedVersion);
return {
label,
value: code,
hint: description,
selected: isInstalled || isDefault,
lookupAttempted: versionState.lookupAttempted,
lookupSucceeded: versionState.lookupSucceeded,
};
};
@ -697,12 +809,38 @@ class UI {
}
// Add external registry modules (skip built-in duplicates)
for (const mod of registryModules) {
if (mod.builtIn || builtInCodes.has(mod.code)) continue;
const entry = await buildModuleEntry(mod.code, mod.name, mod.description, mod.defaultSelected);
const externalRegistryModules = registryModules.filter((mod) => !mod.builtIn && !builtInCodes.has(mod.code));
let externalRegistryEntries = [];
if (externalRegistryModules.length > 0) {
const spinner = await prompts.spinner();
spinner.start('Checking latest module versions...');
externalRegistryEntries = await Promise.all(
externalRegistryModules.map(async (mod) => ({
code: mod.code,
entry: await buildModuleEntry(
mod.code,
mod.name,
mod.description,
mod.defaultSelected,
mod.url || null,
mod.defaultChannel || null,
),
})),
);
spinner.stop('Checked latest module versions.');
const attemptedLookups = externalRegistryEntries.filter(({ entry }) => entry.lookupAttempted).length;
const successfulLookups = externalRegistryEntries.filter(({ entry }) => entry.lookupSucceeded).length;
if (attemptedLookups > 0 && successfulLookups === 0) {
await prompts.log.warn('Could not check latest module versions; showing cached/local versions.');
}
}
for (const { code, entry } of externalRegistryEntries) {
allOptions.push({ label: entry.label, value: entry.value, hint: entry.hint });
if (entry.selected) {
initialValues.push(mod.code);
initialValues.push(code);
}
}

View File

@ -1,169 +0,0 @@
# BMAD Platform Codes Configuration
# Central configuration for all platform/IDE codes used in the BMAD system
#
# This file defines the standardized platform codes that are used throughout
# the installation system to identify different platforms (IDEs, tools, etc.)
#
# Format:
# code: Platform identifier used internally
# name: Display name shown to users
# preferred: Whether this platform is shown as a recommended option on install
# category: Type of platform (ide, tool, service, etc.)
platforms:
# Recommended Platforms
claude-code:
name: "Claude Code"
preferred: true
category: cli
description: "Anthropic's official CLI for Claude"
cursor:
name: "Cursor"
preferred: true
category: ide
description: "AI-first code editor"
# Other IDEs and Tools
cline:
name: "Cline"
preferred: false
category: ide
description: "AI coding assistant"
opencode:
name: "OpenCode"
preferred: false
category: ide
description: "OpenCode terminal coding assistant"
codebuddy:
name: "CodeBuddy"
preferred: false
category: ide
description: "Tencent Cloud Code Assistant - AI-powered coding companion"
auggie:
name: "Auggie"
preferred: false
category: cli
description: "AI development tool"
roo:
name: "Roo Code"
preferred: false
category: ide
description: "Enhanced Cline fork"
rovo-dev:
name: "Rovo Dev"
preferred: false
category: ide
description: "Atlassian's Rovo development environment"
kiro:
name: "Kiro"
preferred: false
category: ide
description: "Amazon's AI-powered IDE"
github-copilot:
name: "GitHub Copilot"
preferred: false
category: ide
description: "GitHub's AI pair programmer"
codex:
name: "Codex"
preferred: false
category: cli
description: "OpenAI Codex integration"
qwen:
name: "QwenCoder"
preferred: false
category: ide
description: "Qwen AI coding assistant"
gemini:
name: "Gemini CLI"
preferred: false
category: cli
description: "Google's CLI for Gemini"
iflow:
name: "iFlow"
preferred: false
category: ide
description: "AI workflow automation"
kilo:
name: "KiloCoder"
preferred: false
category: ide
description: "AI coding platform"
crush:
name: "Crush"
preferred: false
category: ide
description: "AI development assistant"
antigravity:
name: "Google Antigravity"
preferred: false
category: ide
description: "Google's AI development environment"
trae:
name: "Trae"
preferred: false
category: ide
description: "AI coding tool"
windsurf:
name: "Windsurf"
preferred: false
category: ide
description: "AI-powered IDE with cascade flows"
junie:
name: "Junie"
preferred: false
category: cli
description: "AI coding agent by JetBrains"
ona:
name: "Ona"
preferred: false
category: ide
description: "Ona AI development environment"
# Platform categories
categories:
ide:
name: "Integrated Development Environment"
description: "Full-featured code editors with AI assistance"
cli:
name: "Command Line Interface"
description: "Terminal-based tools"
tool:
name: "Development Tool"
description: "Standalone development utilities"
service:
name: "Cloud Service"
description: "Cloud-based development platforms"
extension:
name: "Editor Extension"
description: "Plugins for existing editors"
# Naming conventions and rules
conventions:
code_format: "lowercase-kebab-case"
name_format: "Title Case"
max_code_length: 20
allowed_characters: "a-z0-9-"