diff --git a/src/bmm-skills/1-analysis/bmad-agent-analyst/customize.yaml b/src/bmm-skills/1-analysis/bmad-agent-analyst/customize.yaml index 67fa56b06..a3284a9e8 100644 --- a/src/bmm-skills/1-analysis/bmad-agent-analyst/customize.yaml +++ b/src/bmm-skills/1-analysis/bmad-agent-analyst/customize.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT -- overwritten on every update. + agent: metadata: name: Mary @@ -42,7 +44,7 @@ agent: skill: bmad-technical-research - code: CB description: "Create or update product briefs through guided or autonomous discovery" - skill: bmad-product-brief-preview + skill: bmad-product-brief - code: WB description: "Working Backwards PRFAQ challenge — forge and stress-test product concepts" skill: bmad-prfaq diff --git a/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.yaml b/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.yaml index 272dfb5dd..48d5bb516 100644 --- a/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.yaml +++ b/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT -- overwritten on every update. + agent: metadata: name: Paige diff --git a/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md b/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md index 5b09a6503..3ecce2375 100644 --- a/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md +++ b/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md @@ -5,13 +5,6 @@ description: Create or update product briefs through guided or autonomous discov # Create Product Brief -## Conventions - -- Bare paths (e.g. `prompts/finalize.md`) resolve from the skill root. -- `{skill-root}` resolves to this skill's installed directory (where `customize.yaml` lives). -- `{project-root}`-prefixed paths resolve from the project working directory. -- `{skill-name}` resolves to the skill directory's basename. - ## Overview This skill helps you create compelling product briefs through collaborative discovery, intelligent artifact analysis, and web research. Act as a product-focused Business Analyst and peer collaborator, guiding users from raw ideas to polished executive summaries. Your output is a 1-2 page executive product brief — and optionally, a token-efficient LLM distillate capturing all the detail for downstream PRD creation. @@ -20,6 +13,13 @@ The user is the domain expert. You bring structured thinking, facilitation, mark **Design rationale:** We always understand intent before scanning artifacts — without knowing what the brief is about, scanning documents is noise, not signal. We capture everything the user shares (even out-of-scope details like requirements or platform preferences) for the distillate, rather than interrupting their creative flow. +## Conventions + +- Bare paths (e.g. `prompts/finalize.md`) resolve from the skill root. +- `{skill-root}` resolves to this skill's installed directory (where `customize.yaml` lives). +- `{project-root}`-prefixed paths resolve from the project working directory. +- `{skill-name}` resolves to the skill directory's basename. + ## Activation Mode Detection Check activation context immediately: @@ -39,23 +39,25 @@ Check activation context immediately: 1. **Resolve customization** - Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key inject --key additional_resources` + Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key activation_steps_prepend --key activation_steps_append` **If the script fails**, resolve yourself from `customize.yaml`, with `{project-root}/_bmad/custom/{skill-name}.yaml` overriding, and `{skill-name}.user.yaml` overriding both (any missing file is skipped). - - **Inject before** — If `inject.before` resolved to a non-empty value, prepend it to your active instructions and follow it. - - **Available resources** — Note the `additional_resources` list. Do not read these files now; they are available for subsequent prompts to reference when needed. + - Execute each item in `activation_steps_prepend` in order before proceeding. + - Retain `activation_steps_append` — you will execute it after step 3. -2. Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:: +2. Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: - Use `{user_name}` for greeting - Use `{communication_language}` for all communications - Use `{document_output_language}` for output documents - Use `{planning_artifacts}` for output location and artifact scanning - Use `{project_knowledge}` for additional context scanning -3. **Greet user** as `{user_name}`, speaking in `{communication_language}`. +3. **Greet user if you have not already** by `{user_name}`, speaking in `{communication_language}`. -4. **Stage 1: Understand Intent** (handled here in SKILL.md) +4. Execute each retained `activation_steps_append` item in order. + +5. **Stage 1: Understand Intent** (handled here in SKILL.md) ### Stage 1: Understand Intent @@ -97,10 +99,3 @@ Check activation context immediately: | 4 | Draft & Review | Draft brief, fan out review subagents | `prompts/draft-and-review.md` | | 5 | Finalize | Polish, output, offer distillate | `prompts/finalize.md` | -## Post-Workflow Customization - -After Stage 5 (Finalize) completes and before declaring the workflow done, resolve `inject.after`: - -Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key inject.after` - -If resolved `inject.after` is non-empty, append it to your active instructions and follow it. diff --git a/src/bmm-skills/1-analysis/bmad-product-brief/customize.yaml b/src/bmm-skills/1-analysis/bmad-product-brief/customize.yaml index 5cc2d6825..0f8d80033 100644 --- a/src/bmm-skills/1-analysis/bmad-product-brief/customize.yaml +++ b/src/bmm-skills/1-analysis/bmad-product-brief/customize.yaml @@ -1,20 +1,6 @@ -# Customization surface for bmad-product-brief. # DO NOT EDIT -- overwritten on every update. -# -# To customize, create one of the following and include only the fields -# you want to change (unmentioned fields inherit from this file): -# {project-root}/_bmad/custom/bmad-product-brief.yaml (team, committed) -# {project-root}/_bmad/custom/bmad-product-brief.user.yaml (personal, gitignored) -# Additional resource files loaded into workflow context on activation. -# Paths may use {project-root}. Agent notes the list on activation -# but does not preload the files; subsequent prompts reference them as needed. -# Arrays replace atomically -- include the full list you want. -additional_resources: [] - -# Injected prompts woven into the workflow's context. -# before: loaded before the workflow begins -# after: loaded after the workflow completes (pre-finalize) -inject: - before: "" - after: "" +# Standard customizations for all workflow skills +activation_steps_prepend: [] +activation_steps_append: [] +skill_end: "" diff --git a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/contextual-discovery.md b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/contextual-discovery.md index 68e12bfe1..6950a1da5 100644 --- a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/contextual-discovery.md +++ b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/contextual-discovery.md @@ -12,9 +12,9 @@ Now that you know what the brief is about, fan out subagents in parallel to gath **Launch in parallel:** -1. **Artifact Analyzer** (`../agents/artifact-analyzer.md`) — Scans `{planning_artifacts}` and `{project_knowledge}` for relevant documents. Also scans any specific paths the user provided. Returns structured synthesis of what it found. +1. **Artifact Analyzer** (`agents/artifact-analyzer.md`) — Scans `{planning_artifacts}` and `{project_knowledge}` for relevant documents. Also scans any specific paths the user provided. Returns structured synthesis of what it found. -2. **Web Researcher** (`../agents/web-researcher.md`) — Searches for competitive landscape, market context, trends, and relevant industry data. Returns structured findings scoped to the product domain. +2. **Web Researcher** (`agents/web-researcher.md`) — Searches for competitive landscape, market context, trends, and relevant industry data. Returns structured findings scoped to the product domain. ### Graceful Degradation @@ -38,20 +38,20 @@ Once subagent results return (or inline scanning completes): - Highlight anything surprising or worth discussing - Share the gaps you've identified - Ask: "Anything else you'd like to add, or shall we move on to filling in the details?" -- Route to `guided-elicitation.md` +- Route to `prompts/guided-elicitation.md` **Yolo mode:** - Absorb all findings silently -- Skip directly to `draft-and-review.md` — you have enough to draft +- Skip directly to `prompts/draft-and-review.md` — you have enough to draft - The user will refine later **Headless mode:** - Absorb all findings -- Skip directly to `draft-and-review.md` +- Skip directly to `prompts/draft-and-review.md` - No interaction ## Stage Complete This stage is complete when subagent results (or inline scanning fallback) have returned and findings are merged with user context. Route per mode: -- **Guided** → `guided-elicitation.md` -- **Yolo / Headless** → `draft-and-review.md` +- **Guided** → `prompts/guided-elicitation.md` +- **Yolo / Headless** → `prompts/draft-and-review.md` diff --git a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/draft-and-review.md b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/draft-and-review.md index e6dd8cf1b..b2d225a01 100644 --- a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/draft-and-review.md +++ b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/draft-and-review.md @@ -8,7 +8,7 @@ ## Step 1: Draft the Executive Brief -Use `../resources/brief-template.md` as a guide — adapt structure to fit the product's story. +Use `resources/brief-template.md` as a guide — adapt structure to fit the product's story. **Writing principles:** - **Executive audience** — persuasive, clear, concise. 1-2 pages. @@ -36,9 +36,9 @@ Before showing the draft to the user, run it through multiple review lenses in p **Launch in parallel:** -1. **Skeptic Reviewer** (`../agents/skeptic-reviewer.md`) — "What's missing? What assumptions are untested? What could go wrong? Where is the brief vague or hand-wavy?" +1. **Skeptic Reviewer** (`agents/skeptic-reviewer.md`) — "What's missing? What assumptions are untested? What could go wrong? Where is the brief vague or hand-wavy?" -2. **Opportunity Reviewer** (`../agents/opportunity-reviewer.md`) — "What adjacent value propositions are being missed? What market angles or partnerships could strengthen this? What's underemphasized?" +2. **Opportunity Reviewer** (`agents/opportunity-reviewer.md`) — "What adjacent value propositions are being missed? What market angles or partnerships could strengthen this? What's underemphasized?" 3. **Contextual Reviewer** — You (the main agent) pick the most useful third lens based on THIS specific product. Choose the lens that addresses the SINGLE BIGGEST RISK that the skeptic and opportunity reviewers won't naturally catch. Examples: - For healthtech: "Regulatory and compliance risk reviewer" @@ -65,7 +65,7 @@ After all reviews complete: ## Step 4: Present to User -**Headless mode:** Skip to `finalize.md` — no user interaction. Save the improved draft directly. +**Headless mode:** Skip to `prompts/finalize.md` — no user interaction. Save the improved draft directly. **Yolo and Guided modes:** @@ -83,4 +83,4 @@ Present reviewer findings with brief rationale, then offer: "Want me to dig into ## Stage Complete -This stage is complete when: (a) the draft has been reviewed by all three lenses and improvements integrated, AND either (autonomous) save and route directly, or (guided/yolo) the user is satisfied. Route to `finalize.md`. +This stage is complete when: (a) the draft has been reviewed by all three lenses and improvements integrated, AND either (autonomous) save and route directly, or (guided/yolo) the user is satisfied. Route to `prompts/finalize.md`. diff --git a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/finalize.md b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/finalize.md index b51c8afd3..9645482e2 100644 --- a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/finalize.md +++ b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/finalize.md @@ -72,4 +72,6 @@ purpose: "Token-efficient context for downstream PRD creation" ## Stage Complete -This is the terminal stage. After delivering the completion message and file paths, the workflow is done. If the user requests further revisions, loop back to `draft-and-review.md`. Otherwise, exit. +Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key skill_end` + +If resolved `skill_end` is non-empty follow it as the final terminal stage. After delivering the completion message and file paths, the workflow is done. If the user requests further revisions, loop back to `prompts/draft-and-review.md`. Otherwise, exit. diff --git a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/guided-elicitation.md b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/guided-elicitation.md index a5d0e3a1b..ec2e7705d 100644 --- a/src/bmm-skills/1-analysis/bmad-product-brief/prompts/guided-elicitation.md +++ b/src/bmm-skills/1-analysis/bmad-product-brief/prompts/guided-elicitation.md @@ -5,7 +5,7 @@ **Goal:** Fill the gaps in what you know. By now you have the user's brain dump, artifact analysis, and web research. This stage is about smart, targeted questioning — not rote section-by-section interrogation. -**Skip this stage entirely in Yolo and Autonomous modes** — go directly to `draft-and-review.md`. +**Skip this stage entirely in Yolo and Autonomous modes** — go directly to `prompts/draft-and-review.md`. ## Approach @@ -67,4 +67,4 @@ If the user is providing complete, confident answers and you have solid coverage ## Stage Complete -This stage is complete when sufficient substance exists to draft a compelling brief and the user confirms readiness. Route to `draft-and-review.md`. +This stage is complete when sufficient substance exists to draft a compelling brief and the user confirms readiness. Route to `prompts/draft-and-review.md`. diff --git a/src/bmm-skills/2-plan-workflows/bmad-agent-pm/customize.yaml b/src/bmm-skills/2-plan-workflows/bmad-agent-pm/customize.yaml index 269bde665..1a11ff538 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-agent-pm/customize.yaml +++ b/src/bmm-skills/2-plan-workflows/bmad-agent-pm/customize.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT -- overwritten on every update. + agent: metadata: name: John diff --git a/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/customize.yaml b/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/customize.yaml index b34e5e8dc..466495a3a 100644 --- a/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/customize.yaml +++ b/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/customize.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT -- overwritten on every update. + agent: metadata: name: Sally diff --git a/src/bmm-skills/3-solutioning/bmad-agent-architect/customize.yaml b/src/bmm-skills/3-solutioning/bmad-agent-architect/customize.yaml index 9991be800..b70756846 100644 --- a/src/bmm-skills/3-solutioning/bmad-agent-architect/customize.yaml +++ b/src/bmm-skills/3-solutioning/bmad-agent-architect/customize.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT -- overwritten on every update. + agent: metadata: name: Winston diff --git a/src/bmm-skills/4-implementation/bmad-agent-dev/customize.yaml b/src/bmm-skills/4-implementation/bmad-agent-dev/customize.yaml index 25841bf54..4c8497da8 100644 --- a/src/bmm-skills/4-implementation/bmad-agent-dev/customize.yaml +++ b/src/bmm-skills/4-implementation/bmad-agent-dev/customize.yaml @@ -1,3 +1,5 @@ +# DO NOT EDIT -- overwritten on every update. + agent: metadata: name: Amelia diff --git a/src/scripts/resolve_customization.py b/src/scripts/resolve_customization.py index 3dad882ce..78c4f7a5e 100644 --- a/src/scripts/resolve_customization.py +++ b/src/scripts/resolve_customization.py @@ -216,7 +216,11 @@ def main(): defaults = load_yaml(defaults_path, required=True) - project_root = find_project_root(Path.cwd()) or find_project_root(skill_dir) + # Prefer the project that contains this skill. Only fall back to cwd if + # the skill isn't inside a recognizable project tree (unusual but possible + # for standalone skills invoked directly). Using cwd first is unsafe when + # an ancestor of cwd happens to have a stray _bmad/ from another project. + project_root = find_project_root(skill_dir) or find_project_root(Path.cwd()) team = {} user = {} diff --git a/tools/installer/core/installer.js b/tools/installer/core/installer.js index 8d3d00654..2b6eb7840 100644 --- a/tools/installer/core/installer.js +++ b/tools/installer/core/installer.js @@ -718,8 +718,11 @@ class Installer { const customFiles = []; const modifiedFiles = []; - // Memory is always in _bmad/_memory - const bmadMemoryPath = '_memory'; + // Memory subtrees (v6.1: _bmad/_memory, current: _bmad/memory) hold + // per-user runtime data generated by agents with sidecars. These files + // aren't installer-managed and must never be reported as "custom" or + // "modified" — they're user state, not user overrides. + const bmadMemoryPaths = ['_memory', 'memory']; // Check if the manifest has hashes - if not, we can't detect modifications let manifestHasHashes = false; @@ -785,7 +788,7 @@ class Installer { continue; } - if (relativePath.startsWith(bmadMemoryPath + '/') && path.dirname(relativePath).includes('-sidecar')) { + if (bmadMemoryPaths.some((mp) => relativePath === mp || relativePath.startsWith(mp + '/'))) { continue; } @@ -836,7 +839,7 @@ class Installer { // Get all installed module directories const entries = await fs.readdir(bmadDir, { withFileTypes: true }); - const nonModuleDirs = new Set(['_config', '_memory', 'docs', 'scripts', 'custom']); + const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']); const installedModules = entries.filter((entry) => entry.isDirectory() && !nonModuleDirs.has(entry.name)).map((entry) => entry.name); // Generate config.yaml for each installed module @@ -963,7 +966,7 @@ class Installer { // Get all installed module directories const entries = await fs.readdir(bmadDir, { withFileTypes: true }); - const nonModuleDirs = new Set(['_config', '_memory', 'docs', 'scripts', 'custom']); + const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']); const installedModules = entries.filter((entry) => entry.isDirectory() && !nonModuleDirs.has(entry.name)).map((entry) => entry.name); // Add core module to scan (it's installed at root level as _config, but we check src/core-skills) diff --git a/tools/installer/modules/official-modules.js b/tools/installer/modules/official-modules.js index 421797a06..49b555541 100644 --- a/tools/installer/modules/official-modules.js +++ b/tools/installer/modules/official-modules.js @@ -820,7 +820,7 @@ class OfficialModules { let foundAny = false; const entries = await fs.readdir(bmadDir, { withFileTypes: true }); - const nonModuleDirs = new Set(['_config', '_memory', 'docs', 'scripts', 'custom']); + const nonModuleDirs = new Set(['_config', '_memory', 'memory', 'docs', 'scripts', 'custom']); for (const entry of entries) { if (entry.isDirectory()) { if (nonModuleDirs.has(entry.name)) {