Compare commits

...

5 Commits

Author SHA1 Message Date
Hayden Carson 75441e0cba
Merge 7416866694 into 35a7f101dd 2026-03-03 19:48:24 +08:00
Alex Verkhovsky 35a7f101dd
feat(quick-flow): add quick-dev2 unified workflow (#1807)
* feat(quick-flow): add quick-dev2 unified workflow

Add the quick-dev2 workflow that unifies clarify, plan, implement,
review, and present into a single flow. Register it in the agent
menu, module-help catalog, and test fixtures.

* fix(quick-flow): rename QD2 trigger to QQ for schema compliance

COMPOUND_TRIGGER_PATTERN only allows uppercase letters in shortcuts.
Rename to QQ so quick-dev2 passes agent schema validation.

* fix(quick-flow): address PR review findings for quick-dev2

- step-04-review: fix copy-paste fallback text to say "perform all
  three reviews inline sequentially" instead of "implement directly"
- workflow.md: add missing planning_artifacts to initialization list,
  matching quick-spec and quick-dev siblings
- quick-flow-solo-dev.agent.yaml: change QD and QQ menu entries from
  workflow: to exec: for .md files, matching the exec-for-md convention

* fix(quick-flow): use human-in-the-loop fallback for review without subagents

Sequential inline reviews in the same context suffer from anchoring
bias and context blowout. Instead, generate separate review prompt
files and ask the human to run each in a separate session.

* refactor(quick-flow): rename quick-dev2 to quick-dev-new-preview

Rename directory, update all references in agent menu, module-help,
and workflow internals.
2026-03-02 19:36:14 -06:00
Hayden Carson 7416866694 fix: address PR review comments on copilot installer
- Dynamically compute step number for options instruction instead of
  hardcoding 4 (fixes skipped step 3 for .md and .xml patterns)
- Add validation guard for empty/undefined artifact.name in
  createAgentContent
- Trim leading/trailing dashes from slugs, guard against empty and
  colliding slugs in duplicate command handling
- Use artifact.module for config.yaml path in agent activator prompts
  instead of hardcoding bmm (core agents now reference core/config.yaml)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 14:18:16 +08:00
Hayden Carson 2a9d984a2c fix: use raw agent names and resolve duplicate command filenames
Use raw agent names (e.g., 'dev', 'pm') for the name field in .agent.md
frontmatter and all agent references in prompt frontmatter, instead of
persona display names. This provides clean @mention and /command names.

Resolve Create Story / Validate Story filename collision where both
entries shared command 'bmad-bmm-create-story'. When multiple entries
share a command, derive unique filenames from the entry name slug.
Also pass workflow options (Create Mode, Validate Mode) to the prompt
body so each prompt invokes the correct workflow mode.

Fixes #1794

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 12:53:01 +08:00
Hayden Carson 78ab55c7e3 feat: remove tools, add name and agent assignments to GitHub Copilot installer
Remove tools declaration from agent and prompt frontmatter since users
manage their own tooling. Add name field to agents for cleaner @mention
names and to prompts for cleaner /command display. Set agent field in
prompts to the actual agent displayName for context continuity instead
of resetting to default. Omit agent from prompts with no assigned agent.

Remove now-unused getToolsForFile() and collectExistingToolPermissions()
methods and related tool-permission preservation code from setup().

Fixes #1794

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 16:37:43 +08:00
10 changed files with 468 additions and 79 deletions

View File

@ -24,9 +24,13 @@ agent:
description: "[QS] Quick Spec: Architect a quick but complete technical spec with implementation-ready stories/specs" description: "[QS] Quick Spec: Architect a quick but complete technical spec with implementation-ready stories/specs"
- trigger: QD or fuzzy match on quick-dev - trigger: QD or fuzzy match on quick-dev
workflow: "{project-root}/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md" exec: "{project-root}/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md"
description: "[QD] Quick-flow Develop: Implement a story tech spec end-to-end (Core of Quick Flow)" description: "[QD] Quick-flow Develop: Implement a story tech spec end-to-end (Core of Quick Flow)"
- trigger: QQ or fuzzy match on quick-dev-new-preview
exec: "{project-root}/_bmad/bmm/workflows/bmad-quick-flow/quick-dev-new-preview/workflow.md"
description: "[QQ] Quick Dev New (Preview): Unified quick flow — clarify intent, plan, implement, review, present (experimental)"
- trigger: CR or fuzzy match on code-review - trigger: CR or fuzzy match on code-review
workflow: "{project-root}/_bmad/bmm/workflows/4-implementation/code-review/workflow.yaml" workflow: "{project-root}/_bmad/bmm/workflows/4-implementation/code-review/workflow.yaml"
description: "[CR] Code Review: Initiate a comprehensive code review across multiple quality facets. For best results, use a fresh context and a different quality LLM if available" description: "[CR] Code Review: Initiate a comprehensive code review across multiple quality facets. For best results, use a fresh context and a different quality LLM if available"

View File

@ -3,6 +3,7 @@ bmm,anytime,Document Project,DP,,_bmad/bmm/workflows/document-project/workflow.y
bmm,anytime,Generate Project Context,GPC,,_bmad/bmm/workflows/generate-project-context/workflow.md,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow.",output_folder,"project context", bmm,anytime,Generate Project Context,GPC,,_bmad/bmm/workflows/generate-project-context/workflow.md,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow.",output_folder,"project context",
bmm,anytime,Quick Spec,QS,,_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md,bmad-bmm-quick-spec,false,quick-flow-solo-dev,Create Mode,"Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps brownfield additions to well established patterns utilities without extensive planning",planning_artifacts,"tech spec", bmm,anytime,Quick Spec,QS,,_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md,bmad-bmm-quick-spec,false,quick-flow-solo-dev,Create Mode,"Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps brownfield additions to well established patterns utilities without extensive planning",planning_artifacts,"tech spec",
bmm,anytime,Quick Dev,QD,,_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan",,, bmm,anytime,Quick Dev,QD,,_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan",,,
bmm,anytime,Quick Dev New Preview,QQ,,_bmad/bmm/workflows/bmad-quick-flow/quick-dev-new-preview/workflow.md,bmad-bmm-quick-dev-new-preview,false,quick-flow-solo-dev,Create Mode,"Unified quick flow (experimental): clarify intent plan implement review and present in a single workflow",implementation_artifacts,"tech spec implementation",
bmm,anytime,Correct Course,CC,,_bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal", bmm,anytime,Correct Course,CC,,_bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal",
bmm,anytime,Write Document,WD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review.",project-knowledge,"document", bmm,anytime,Write Document,WD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review.",project-knowledge,"document",
bmm,anytime,Update Standards,US,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions.",_bmad/_memory/tech-writer-sidecar,"standards", bmm,anytime,Update Standards,US,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions.",_bmad/_memory/tech-writer-sidecar,"standards",

1 module phase name code sequence workflow-file command required agent options description output-location outputs
3 bmm anytime Generate Project Context GPC _bmad/bmm/workflows/generate-project-context/workflow.md bmad-bmm-generate-project-context false analyst Create Mode Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow. output_folder project context
4 bmm anytime Quick Spec QS _bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md bmad-bmm-quick-spec false quick-flow-solo-dev Create Mode Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method. Quick one-off tasks small changes simple apps brownfield additions to well established patterns utilities without extensive planning planning_artifacts tech spec
5 bmm anytime Quick Dev QD _bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md bmad-bmm-quick-dev false quick-flow-solo-dev Create Mode Quick one-off tasks small changes simple apps utilities without extensive planning - Do not suggest for potentially very complex things unless requested or if the user complains that they do not want to follow the extensive planning of the bmad method, unless the user is already working through the implementation phase and just requests a 1 off things not already in the plan
6 bmm anytime Quick Dev New Preview QQ _bmad/bmm/workflows/bmad-quick-flow/quick-dev-new-preview/workflow.md bmad-bmm-quick-dev-new-preview false quick-flow-solo-dev Create Mode Unified quick flow (experimental): clarify intent plan implement review and present in a single workflow implementation_artifacts tech spec implementation
7 bmm anytime Correct Course CC _bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml bmad-bmm-correct-course false sm Create Mode Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories planning_artifacts change proposal
8 bmm anytime Write Document WD _bmad/bmm/agents/tech-writer/tech-writer.agent.yaml false tech-writer Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review. project-knowledge document
9 bmm anytime Update Standards US _bmad/bmm/agents/tech-writer/tech-writer.agent.yaml false tech-writer Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions. _bmad/_memory/tech-writer-sidecar standards

View File

@ -0,0 +1,51 @@
---
name: 'step-01-clarify-and-route'
description: 'Capture intent, route to execution path'
wipFile: '{implementation_artifacts}/tech-spec-wip.md'
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
spec_file: '' # set at runtime before leaving this step
---
# Step 1: Clarify and Route
## RULES
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- The prompt that triggered this workflow IS the intent — not a hint.
- Do NOT assume you start from zero.
## ARTIFACT SCAN
- `{wipFile}` exists? → Offer resume or archive.
- Active specs (`ready-for-dev`, `in-progress`, `in-review`) in `{implementation_artifacts}`? → List them and HALT. Ask user which to resume (or `[N]` for new).
- If `ready-for-dev` or `in-progress` selected: Set `spec_file`, set `execution_mode = "plan-code-review"`, skip to step 3.
- If `in-review` selected: Set `spec_file`, set `execution_mode = "plan-code-review"`, skip to step 4.
- Unformatted spec or intent file lacking `status` frontmatter in `{implementation_artifacts}`? → Suggest to the user to treat its contents as the starting intent for this workflow. DO NOT attempt to infer a state and resume it.
## INSTRUCTIONS
1. Load context.
- List files in `{planning_artifacts}` and `{implementation_artifacts}`.
- If you find an unformatted spec or intent file, ingest its contents to form your understanding of the intent.
2. Clarify intent. Do not fantasize, do not leave open questions. If you must ask questions, ask them as a numbered list. When the human replies, verify that every single numbered question was answered. If any were ignored, HALT and re-ask only the missing questions before proceeding. Keep looping until intent is clear enough to implement.
3. Version control sanity check. Is the working tree clean? Does the current branch make sense for this intent — considering its name and recent history? If the tree is dirty or the branch is an obvious mismatch, HALT and ask the human before proceeding. If version control is unavailable, skip this check.
4. Multi-goal check (see SCOPE STANDARD). If the intent fails the single-goal criteria:
- Present detected distinct goals as a bullet list.
- HALT and ask human: `[S] Split — pick first goal, defer the rest` | `[K] Keep as-is`
- On **S**: Append deferred goals to `{deferred_work_file}`. Narrow scope to the first-mentioned goal. Continue routing.
- On **K**: Proceed as-is.
5. Generate `spec_file` path:
- Derive a valid kebab-case slug from the clarified intent.
- If `{implementation_artifacts}/tech-spec-{slug}.md` already exists, append `-2`, `-3`, etc.
- Set `spec_file` = `{implementation_artifacts}/tech-spec-{slug}.md`.
6. Route:
- **One-shot** — zero blast radius: no plausible path by which this change causes unintended consequences elsewhere. Clear intent, no architectural decisions. `execution_mode = "one-shot"`. → Step 3.
- **Plan-code-review** — everything else. `execution_mode = "plan-code-review"`. → Step 2.
- When uncertain whether blast radius is truly zero, default to plan-code-review.
## NEXT
- One-shot / ready-for-dev: Read fully and follow `{installed_path}/steps/step-03-implement.md`
- Plan-code-review: Read fully and follow `{installed_path}/steps/step-02-plan.md`

View File

@ -0,0 +1,39 @@
---
name: 'step-02-plan'
description: 'Investigate, generate spec, present for approval'
templateFile: '{installed_path}/tech-spec-template.md'
wipFile: '{implementation_artifacts}/tech-spec-wip.md'
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
---
# Step 2: Plan
## RULES
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- No intermediate approvals.
## INSTRUCTIONS
1. Investigate codebase. _Isolate deep exploration in sub-agents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._
2. Read `{templateFile}` fully. Fill it out based on the intent and investigation, and write the result to `{wipFile}`.
3. Self-review against READY FOR DEVELOPMENT standard.
4. If intent gaps exist, do not fantasize, do not leave open questions, HALT and ask the human.
5. Token count check (see SCOPE STANDARD). If spec exceeds 1600 tokens:
- Show user the token count.
- HALT and ask human: `[S] Split — carve off secondary goals` | `[K] Keep as-is`
- On **S**: Propose the split — name each secondary goal. Append deferred goals to `{deferred_work_file}`. Rewrite the current spec to cover only the main goal — do not surgically carve sections out; regenerate the spec for the narrowed scope. Continue to checkpoint.
- On **K**: Continue to checkpoint with full spec.
### CHECKPOINT 1
Present summary. If token count exceeded 1600 and user chose [K], include the token count and explain why it may be a problem. HALT and ask human: `[A] Approve` | `[E] Edit`
- **A**: Rename `{wipFile}` to `{spec_file}`, set status `ready-for-dev`. Everything inside `<frozen-after-approval>` is now locked — only the human can change it. → Step 3.
- **E**: Apply changes, then return to CHECKPOINT 1.
## NEXT
Read fully and follow `{installed_path}/steps/step-03-implement.md`

View File

@ -0,0 +1,35 @@
---
name: 'step-03-implement'
description: 'Execute implementation directly or via sub-agent. Local only.'
---
# Step 3: Implement
## RULES
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- No push. No remote ops.
- Sequential execution only.
- Content inside `<frozen-after-approval>` in `{spec_file}` is read-only. Do not modify.
## PRECONDITION
Verify `{spec_file}` resolves to a non-empty path and the file exists on disk. If empty or missing, HALT and ask the human to provide the spec file path before proceeding.
## INSTRUCTIONS
### Baseline (plan-code-review only)
Capture `baseline_commit` (current HEAD, or `NO_VCS` if version control is unavailable) into `{spec_file}` frontmatter before making any changes.
### Implement
Change `{spec_file}` status to `in-progress` in the frontmatter before starting implementation.
`execution_mode = "one-shot"` or no sub-agents/tasks available: implement the intent.
Otherwise (`execution_mode = "plan-code-review"`): hand `{spec_file}` to a sub-agent/task and let it implement.
## NEXT
Read fully and follow `{installed_path}/steps/step-04-review.md`

View File

@ -0,0 +1,57 @@
---
name: 'step-04-review'
description: 'Adversarial review, classify findings, optional spec loop'
adversarial_review_task: '{project-root}/_bmad/core/tasks/review-adversarial-general.xml'
edge_case_hunter_task: '{project-root}/_bmad/core/tasks/review-edge-case-hunter.xml'
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
specLoopIteration: 1
---
# Step 4: Review
## RULES
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- Review subagents get NO conversation context.
## INSTRUCTIONS
Change `{spec_file}` status to `in-review` in the frontmatter before continuing.
### Construct Diff (plan-code-review only)
Read `{baseline_commit}` from `{spec_file}` frontmatter. If `{baseline_commit}` is missing or `NO_VCS`, use best effort to determine what changed. Otherwise, construct `{diff_output}` covering all changes — tracked and untracked — since `{baseline_commit}`.
Do NOT `git add` anything — this is read-only inspection.
### Review
**One-shot:** Skip diff construction. Still invoke `{adversarial_review_task}` in a subagent with the changed files — inline review invites anchoring bias.
**Plan-code-review:** Launch three subagents without conversation context. If no sub-agents are available, generate three review prompt files in `{implementation_artifacts}` — one per reviewer role below — and HALT. Ask the human to run each in a separate session (ideally a different LLM) and paste back the findings.
- **Blind hunter** — receives `{diff_output}` only. No spec, no context docs, no project access. Invoke via `{adversarial_review_task}`.
- **Edge case hunter** — receives `{diff_output}` and read access to the project. Invoke via `{edge_case_hunter_task}`.
- **Acceptance auditor** — receives `{diff_output}`, `{spec_file}`, and read access to the project. Must also read the docs listed in `{spec_file}` frontmatter `context`. Checks for violations of acceptance criteria, rules, and principles from the spec and context docs.
### Classify
1. Deduplicate all review findings.
2. Classify each finding. The first three categories are **this story's problem** — caused or exposed by the current change. The last two are **not this story's problem**.
- **intent_gap** — caused by the change; cannot be resolved from the spec because the captured intent is incomplete. Do not infer intent unless there is exactly one possible reading.
- **bad_spec** — caused by the change, including direct deviations from spec. The spec should have been clear enough to prevent it. When in doubt between bad_spec and patch, prefer bad_spec — a spec-level fix is more likely to produce coherent code.
- **patch** — caused by the change; trivially fixable without human input. Just part of the diff.
- **defer** — pre-existing issue not caused by this story, surfaced incidentally by the review. Collect for later focused attention.
- **reject** — noise. Drop silently. When unsure between defer and reject, prefer reject — only defer findings you are confident are real.
3. Process findings in cascading order. If intent_gap or bad_spec findings exist, they trigger a loopback — lower findings are moot since code will be re-derived. If neither exists, process patch and defer normally. Increment `{specLoopIteration}` on each loopback. If it exceeds 5, HALT and escalate to the human. On any loopback, re-evaluate routing — if scope has grown beyond one-shot, escalate `execution_mode` to plan-code-review.
- **intent_gap** — Root cause is inside `<frozen-after-approval>`. Revert code changes. Loop back to the human to resolve, then re-run steps 24.
- **bad_spec** — Root cause is outside `<frozen-after-approval>`. Before reverting code: extract KEEP instructions for positive preservation (what worked well and must survive re-derivation). Revert code changes. Read the `## Spec Change Log` in `{spec_file}` and strictly respect all logged constraints when amending the non-frozen sections that contain the root cause. Append a new change-log entry recording: the triggering finding, what was amended, the known-bad state avoided, and the KEEP instructions. Read fully and follow `{installed_path}/steps/step-03-implement.md` to re-derive the code, then this step will run again.
- **patch** — Auto-fix. These are the only findings that survive loopbacks.
- **defer** — Append to `{deferred_work_file}`.
- **reject** — Drop silently.
4. Commit.
## NEXT
Read fully and follow `{installed_path}/steps/step-05-present.md`

View File

@ -0,0 +1,19 @@
---
name: 'step-05-present'
description: 'Present findings, get approval, create PR'
---
# Step 5: Present
## RULES
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
- NEVER auto-push.
## INSTRUCTIONS
1. If version control is available and the tree is dirty, create a local commit with a conventional message derived from the spec title.
2. Change `{spec_file}` status to `done` in the frontmatter.
3. Display summary of your work to the user, including the commit hash if one was created. Advise on how to review the changes. Offer to push and/or create a pull request.
Workflow complete.

View File

@ -0,0 +1,90 @@
---
title: '{title}'
type: 'feature' # feature | bugfix | refactor | chore
created: '{date}'
status: 'draft' # draft | ready-for-dev | in-progress | in-review | done
context: [] # optional: max 3 project-wide standards/docs. NO source code files.
---
<!-- Target: 9001300 tokens. Above 1600 = high risk of context rot.
Never over-specify "how" — use boundaries + examples instead.
Cohesive cross-layer stories (DB+BE+UI) stay in ONE file.
IMPORTANT: Remove all HTML comments when filling this template. -->
# {title}
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
## Intent
<!-- What is broken or missing, and why it matters. Then the high-level approach — the "what", not the "how". -->
**Problem:** ONE_TO_TWO_SENTENCES
**Approach:** ONE_TO_TWO_SENTENCES
## Boundaries & Constraints
<!-- Three tiers: Always = invariant rules. Ask First = human-gated decisions. Never = out of scope + forbidden approaches. -->
**Always:** INVARIANT_RULES
**Ask First:** DECISIONS_REQUIRING_HUMAN_APPROVAL
<!-- Agent: if any of these trigger during execution, HALT and ask the user before proceeding. -->
**Never:** NON_GOALS_AND_FORBIDDEN_APPROACHES
## I/O & Edge-Case Matrix
<!-- If no meaningful I/O scenarios exist, DELETE THIS ENTIRE SECTION. Do not write "N/A" or "None". -->
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|----------|--------------|---------------------------|----------------|
| HAPPY_PATH | INPUT | OUTCOME | N/A |
| ERROR_CASE | INPUT | OUTCOME | ERROR_HANDLING |
</frozen-after-approval>
## Code Map
<!-- Agent-populated during planning. Annotated paths prevent blind codebase searching. -->
- `FILE` -- ROLE_OR_RELEVANCE
- `FILE` -- ROLE_OR_RELEVANCE
## Tasks & Acceptance
<!-- Tasks: backtick-quoted file path -- action -- rationale. Prefer one task per file; group tightly-coupled changes when splitting would be artificial. -->
<!-- If an I/O Matrix is present, include a task to unit-test its edge cases. -->
<!-- AC covers system-level behaviors not captured by the I/O Matrix. Do not duplicate I/O scenarios here. -->
**Execution:**
- [ ] `FILE` -- ACTION -- RATIONALE
**Acceptance Criteria:**
- Given PRECONDITION, when ACTION, then EXPECTED_RESULT
## Spec Change Log
<!-- Append-only. Populated by step-04 during review loops. Do not modify or delete existing entries.
Each entry records: what finding triggered the change, what was amended, what known-bad state
the amendment avoids, and any KEEP instructions (what worked well and must survive re-derivation).
Empty until the first bad_spec loopback. -->
## Design Notes
<!-- If the approach is straightforward, DELETE THIS ENTIRE SECTION. Do not write "N/A" or "None". -->
<!-- Design rationale and golden examples only when non-obvious. Keep examples to 510 lines. -->
DESIGN_RATIONALE_AND_EXAMPLES
## Verification
<!-- If no build, test, or lint commands apply, DELETE THIS ENTIRE SECTION. Do not write "N/A" or "None". -->
<!-- How the agent confirms its own work. Prefer CLI commands. When no CLI check applies, state what to inspect manually. -->
**Commands:**
- `COMMAND` -- expected: SUCCESS_CRITERIA
**Manual checks (if no CLI):**
- WHAT_TO_INSPECT_AND_EXPECTED_STATE

View File

@ -0,0 +1,90 @@
---
name: quick-dev-new-preview
description: 'Unified quick flow - clarify intent, plan, implement, review, present.'
main_config: '{project-root}/_bmad/bmm/config.yaml'
# Related workflows
advanced_elicitation: '{project-root}/_bmad/core/workflows/advanced-elicitation/workflow.xml'
party_mode_exec: '{project-root}/_bmad/core/workflows/party-mode/workflow.md'
# Review building block
adversarial_review_task: '{project-root}/_bmad/core/tasks/review-adversarial-general.xml'
---
# Quick Dev New Preview Workflow
**Goal:** Take a user request from intent through implementation, adversarial review, and PR creation in a single unified flow.
**Your Role:** You are an elite developer. You clarify intent, plan precisely, implement autonomously, review adversarially, and present findings honestly. Minimum ceremony, maximum signal.
## 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 **9001600 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"
- **9001600 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
- `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. Paths
- `installed_path` = `{project-root}/_bmad/bmm/workflows/bmad-quick-flow/quick-dev-new-preview`
- `templateFile` = `{installed_path}/tech-spec-template.md`
- `wipFile` = `{implementation_artifacts}/tech-spec-wip.md`
### 3. First Step Execution
Read fully and follow: `{installed_path}/steps/step-01-clarify-and-route.md` to begin the workflow.

View File

@ -40,9 +40,6 @@ class GitHubCopilotSetup extends BaseIdeSetup {
await this.ensureDir(agentsDir); await this.ensureDir(agentsDir);
await this.ensureDir(promptsDir); await this.ensureDir(promptsDir);
// Preserve any customised tool permissions from existing files before cleanup
this.existingToolPermissions = await this.collectExistingToolPermissions(projectDir);
// Clean up any existing BMAD files before reinstalling // Clean up any existing BMAD files before reinstalling
await this.cleanup(projectDir); await this.cleanup(projectDir);
@ -58,11 +55,9 @@ class GitHubCopilotSetup extends BaseIdeSetup {
for (const artifact of agentArtifacts) { for (const artifact of agentArtifacts) {
const agentMeta = agentManifest.get(artifact.name); const agentMeta = agentManifest.get(artifact.name);
// Compute fileName first so we can look up any existing tool permissions
const dashName = toDashPath(artifact.relativePath); const dashName = toDashPath(artifact.relativePath);
const fileName = dashName.replace(/\.md$/, '.agent.md'); const fileName = dashName.replace(/\.md$/, '.agent.md');
const toolsStr = this.getToolsForFile(fileName); const agentContent = this.createAgentContent(artifact, agentMeta);
const agentContent = this.createAgentContent(artifact, agentMeta, toolsStr);
const targetPath = path.join(agentsDir, fileName); const targetPath = path.join(agentsDir, fileName);
await this.writeFile(targetPath, agentContent); await this.writeFile(targetPath, agentContent);
agentCount++; agentCount++;
@ -147,9 +142,14 @@ class GitHubCopilotSetup extends BaseIdeSetup {
* @param {Object|undefined} manifestEntry - Agent manifest entry with metadata * @param {Object|undefined} manifestEntry - Agent manifest entry with metadata
* @returns {string} Agent file content * @returns {string} Agent file content
*/ */
createAgentContent(artifact, manifestEntry, toolsStr) { createAgentContent(artifact, manifestEntry) {
if (!artifact?.name) {
throw new Error('Agent artifact must have a name');
}
// Build enriched description from manifest metadata // Build enriched description from manifest metadata
let description; let description;
// Use the raw agent name (e.g., "dev", "pm") for clean @mention selection
const name = artifact.name;
if (manifestEntry) { if (manifestEntry) {
const persona = manifestEntry.displayName || artifact.name; const persona = manifestEntry.displayName || artifact.name;
const title = manifestEntry.title || this.formatTitle(artifact.name); const title = manifestEntry.title || this.formatTitle(artifact.name);
@ -159,13 +159,15 @@ class GitHubCopilotSetup extends BaseIdeSetup {
description = `Activates the ${this.formatTitle(artifact.name)} agent persona.`; description = `Activates the ${this.formatTitle(artifact.name)} agent persona.`;
} }
const safeName = this.escapeYamlSingleQuote(name);
// Build the agent file path for the activation block // Build the agent file path for the activation block
const agentPath = artifact.agentPath || artifact.relativePath; const agentPath = artifact.agentPath || artifact.relativePath;
const agentFilePath = `{project-root}/${this.bmadFolderName}/${agentPath}`; const agentFilePath = `{project-root}/${this.bmadFolderName}/${agentPath}`;
return `--- return `---
name: '${safeName}'
description: '${description.replaceAll("'", "''")}' description: '${description.replaceAll("'", "''")}'
tools: ${toolsStr}
--- ---
You must fully embody this agent's persona and follow all activation instructions exactly as specified. You must fully embody this agent's persona and follow all activation instructions exactly as specified.
@ -197,15 +199,39 @@ You must fully embody this agent's persona and follow all activation instruction
const helpEntries = await this.loadBmadHelp(bmadDir); const helpEntries = await this.loadBmadHelp(bmadDir);
if (helpEntries) { if (helpEntries) {
// Detect duplicate commands to derive unique filenames when multiple entries share one
const commandCounts = new Map();
for (const entry of helpEntries) {
if (!entry.command || !entry['workflow-file']) continue;
commandCounts.set(entry.command, (commandCounts.get(entry.command) || 0) + 1);
}
const seenSlugs = new Set();
for (const entry of helpEntries) { for (const entry of helpEntries) {
const command = entry.command; const command = entry.command;
if (!command) continue; // Skip entries without a command (tech-writer commands have no command column) if (!command) continue; // Skip entries without a command (tech-writer commands have no command column)
const workflowFile = entry['workflow-file']; const workflowFile = entry['workflow-file'];
if (!workflowFile) continue; // Skip entries with no workflow file path if (!workflowFile) continue; // Skip entries with no workflow file path
const promptFileName = `${command}.prompt.md`;
const toolsStr = this.getToolsForFile(promptFileName); // When multiple entries share the same command, derive a unique filename from the entry name
const promptContent = this.createWorkflowPromptContent(entry, workflowFile, toolsStr); let promptFileName;
if (commandCounts.get(command) > 1) {
let slug = entry.name.toLowerCase().replaceAll(/[^a-z0-9]+/g, '-').replaceAll(/^-+|-+$/g, '');
if (!slug) {
slug = `unnamed-${promptCount}`;
}
// Guard against slug collisions
while (seenSlugs.has(slug)) {
slug = `${slug}-${promptCount}`;
}
seenSlugs.add(slug);
promptFileName = `bmad-bmm-${slug}.prompt.md`;
} else {
promptFileName = `${command}.prompt.md`;
}
const promptContent = this.createWorkflowPromptContent(entry, workflowFile);
const promptPath = path.join(promptsDir, promptFileName); const promptPath = path.join(promptsDir, promptFileName);
await this.writeFile(promptPath, promptContent); await this.writeFile(promptPath, promptContent);
promptCount++; promptCount++;
@ -228,8 +254,7 @@ You must fully embody this agent's persona and follow all activation instruction
for (const artifact of agentArtifacts) { for (const artifact of agentArtifacts) {
const agentMeta = agentManifest.get(artifact.name); const agentMeta = agentManifest.get(artifact.name);
const fileName = `bmad-${artifact.name}.prompt.md`; const fileName = `bmad-${artifact.name}.prompt.md`;
const toolsStr = this.getToolsForFile(fileName); const promptContent = this.createAgentActivatorPromptContent(artifact, agentMeta);
const promptContent = this.createAgentActivatorPromptContent(artifact, agentMeta, toolsStr);
const promptPath = path.join(promptsDir, fileName); const promptPath = path.join(promptsDir, fileName);
await this.writeFile(promptPath, promptContent); await this.writeFile(promptPath, promptContent);
promptCount++; promptCount++;
@ -245,8 +270,9 @@ You must fully embody this agent's persona and follow all activation instruction
* @param {string} workflowFile - Workflow file path * @param {string} workflowFile - Workflow file path
* @returns {string} Prompt file content * @returns {string} Prompt file content
*/ */
createWorkflowPromptContent(entry, workflowFile, toolsStr) { createWorkflowPromptContent(entry, workflowFile) {
const description = this.escapeYamlSingleQuote(this.createPromptDescription(entry.name)); const description = this.escapeYamlSingleQuote(this.createPromptDescription(entry.name));
const promptName = this.escapeYamlSingleQuote(entry.name || description);
// bmm/config.yaml is safe to hardcode here: these prompts are only generated when // bmm/config.yaml is safe to hardcode here: these prompts are only generated when
// bmad-help.csv exists (bmm module data), so bmm is guaranteed to be installed. // bmad-help.csv exists (bmm module data), so bmm is guaranteed to be installed.
const configLine = `1. Load {project-root}/${this.bmadFolderName}/bmm/config.yaml and store ALL fields as session variables`; const configLine = `1. Load {project-root}/${this.bmadFolderName}/bmm/config.yaml and store ALL fields as session variables`;
@ -267,13 +293,36 @@ You must fully embody this agent's persona and follow all activation instruction
2. Load and follow the workflow at {project-root}/${workflowFile}`; 2. Load and follow the workflow at {project-root}/${workflowFile}`;
} }
// Build the agent line: use raw agent name to match agent .agent.md name field
const agentName = (entry['agent-name'] || '').trim();
let agentLine = '';
if (agentName) {
agentLine = `\nagent: '${this.escapeYamlSingleQuote(agentName)}'`;
}
// Include options (e.g., "Create Mode", "Validate Mode") when present
const options = (entry.options || '').trim();
let optionsInstruction = '';
if (options) {
// Determine the next step number based on the last numbered step in the body
let nextStepNumber = 4;
const stepMatches = body.match(/(?:^|\n)(\d+)\.\s/g);
if (stepMatches && stepMatches.length > 0) {
const lastMatch = stepMatches.at(-1);
const numberMatch = lastMatch.match(/(\d+)\.\s/);
if (numberMatch) {
nextStepNumber = parseInt(numberMatch[1], 10) + 1;
}
}
optionsInstruction = `\n${nextStepNumber}. Use option: ${options}`;
}
return `--- return `---
description: '${description}' name: '${promptName}'
agent: 'agent' description: '${description}'${agentLine}
tools: ${toolsStr}
--- ---
${body} ${body}${optionsInstruction}
`; `;
} }
@ -341,13 +390,15 @@ ${body}
const cmd = techWriterCommands[entry.name]; const cmd = techWriterCommands[entry.name];
if (!cmd) return null; if (!cmd) return null;
const safeName = this.escapeYamlSingleQuote(entry.name);
const safeDescription = this.escapeYamlSingleQuote(cmd.description); const safeDescription = this.escapeYamlSingleQuote(cmd.description);
const toolsStr = this.getToolsForFile(`${cmd.file}.prompt.md`);
// Use raw agent name to match agent .agent.md name field
const agentLine = `\nagent: '${this.escapeYamlSingleQuote(entry['agent-name'])}'`;
const content = `--- const content = `---
description: '${safeDescription}' name: '${safeName}'
agent: 'agent' description: '${safeDescription}'${agentLine}
tools: ${toolsStr}
--- ---
1. Load {project-root}/${this.bmadFolderName}/bmm/config.yaml and store ALL fields as session variables 1. Load {project-root}/${this.bmadFolderName}/bmm/config.yaml and store ALL fields as session variables
@ -364,7 +415,7 @@ tools: ${toolsStr}
* @param {Object|undefined} manifestEntry - Agent manifest entry * @param {Object|undefined} manifestEntry - Agent manifest entry
* @returns {string} Prompt file content * @returns {string} Prompt file content
*/ */
createAgentActivatorPromptContent(artifact, manifestEntry, toolsStr) { createAgentActivatorPromptContent(artifact, manifestEntry) {
let description; let description;
if (manifestEntry) { if (manifestEntry) {
description = manifestEntry.title || this.formatTitle(artifact.name); description = manifestEntry.title || this.formatTitle(artifact.name);
@ -372,19 +423,21 @@ tools: ${toolsStr}
description = this.formatTitle(artifact.name); description = this.formatTitle(artifact.name);
} }
// Use the raw agent name (e.g., "dev") to match agent .agent.md name field
const name = artifact.name;
const safeName = this.escapeYamlSingleQuote(name);
const safeDescription = this.escapeYamlSingleQuote(description); const safeDescription = this.escapeYamlSingleQuote(description);
const agentPath = artifact.agentPath || artifact.relativePath; const agentPath = artifact.agentPath || artifact.relativePath;
const agentFilePath = `{project-root}/${this.bmadFolderName}/${agentPath}`; const agentFilePath = `{project-root}/${this.bmadFolderName}/${agentPath}`;
// bmm/config.yaml is safe to hardcode: agent activators are only generated from const moduleName = artifact.module || 'bmm';
// bmm agent artifacts, so bmm is guaranteed to be installed.
return `--- return `---
name: '${safeName}'
description: '${safeDescription}' description: '${safeDescription}'
agent: 'agent' agent: '${safeName}'
tools: ${toolsStr}
--- ---
1. Load {project-root}/${this.bmadFolderName}/bmm/config.yaml and store ALL fields as session variables 1. Load {project-root}/${this.bmadFolderName}/${moduleName}/config.yaml and store ALL fields as session variables
2. Load the full agent file from ${agentFilePath} 2. Load the full agent file from ${agentFilePath}
3. Follow ALL activation instructions in the agent file 3. Follow ALL activation instructions in the agent file
4. Display the welcome/greeting as instructed 4. Display the welcome/greeting as instructed
@ -534,56 +587,6 @@ Type \`/bmad-\` in Copilot Chat to see all available BMAD workflows and agent ac
return (value || '').replaceAll("'", "''"); return (value || '').replaceAll("'", "''");
} }
/**
* Scan existing agent and prompt files for customised tool permissions before cleanup.
* Returns a Map<filename, toolsArray> so permissions can be preserved across reinstalls.
* @param {string} projectDir - Project directory
* @returns {Map} Existing tool permissions keyed by filename
*/
async collectExistingToolPermissions(projectDir) {
const permissions = new Map();
const dirs = [
[path.join(projectDir, this.githubDir, this.agentsDir), /^bmad.*\.agent\.md$/],
[path.join(projectDir, this.githubDir, this.promptsDir), /^bmad-.*\.prompt\.md$/],
];
for (const [dir, pattern] of dirs) {
if (!(await fs.pathExists(dir))) continue;
const files = await fs.readdir(dir);
for (const file of files) {
if (!pattern.test(file)) continue;
try {
const content = await fs.readFile(path.join(dir, file), 'utf8');
const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
if (!fmMatch) continue;
const frontmatter = yaml.parse(fmMatch[1]);
if (frontmatter && Array.isArray(frontmatter.tools)) {
permissions.set(file, frontmatter.tools);
}
} catch {
// Skip unreadable files
}
}
}
return permissions;
}
/**
* Get the tools array string for a file, preserving any existing customisation.
* Falls back to the default tools if no prior customisation exists.
* @param {string} fileName - Target filename (e.g. 'bmad-agent-bmm-pm.agent.md')
* @returns {string} YAML inline array string
*/
getToolsForFile(fileName) {
const defaultTools = ['read', 'edit', 'search', 'execute'];
const tools = (this.existingToolPermissions && this.existingToolPermissions.get(fileName)) || defaultTools;
return '[' + tools.map((t) => `'${t}'`).join(', ') + ']';
}
/** /**
* Format name as title * Format name as title
*/ */