Compare commits
4 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
4b1cb84b97 | |
|
|
c9813c6862 | |
|
|
b483e66c3b | |
|
|
20f7fa37e2 |
|
|
@ -99,7 +99,8 @@ Workflow skills run a structured, multi-step process without loading an agent pe
|
|||
| `bmad-create-epics-and-stories` | Create epics and stories |
|
||||
| `bmad-dev-story` | Implement a story |
|
||||
| `bmad-code-review` | Run a code review |
|
||||
| `bmad-quick-dev` | Unified quick flow — clarify intent, plan, implement, review, present |
|
||||
| `bmad-quick-dev` | Implement a story or any other small intent — clarify, plan, implement, review, present |
|
||||
| `bmad-dev-auto` | One unattended development-loop iteration — small intent in, code out, no human interaction |
|
||||
|
||||
See [Workflow Map](./workflow-map.md) for the complete workflow reference organized by phase.
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ Skip phases 1-3 for small, well-understood work.
|
|||
| Workflow | Purpose | Produces |
|
||||
|------------------|---------------------------------------------------------------------------|--------------------|
|
||||
| `bmad-quick-dev` | Unified quick flow — clarify intent, plan, implement, review, and present | `spec-*.md` + code |
|
||||
| `bmad-dev-auto` | One unattended development-loop iteration — small intent in, code out | `spec-*.md` + code |
|
||||
|
||||
## Context Management
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,11 @@
|
|||
"prepare": "command -v husky >/dev/null 2>&1 && husky || exit 0",
|
||||
"quality": "npm run format:check && npm run lint && npm run lint:md && npm run docs:build && npm run test:install && npm run test:urls && npm run validate:refs && npm run validate:skills && npm run docs:validate-sidebar",
|
||||
"rebundle": "node tools/installer/bundlers/bundle-web.js rebundle",
|
||||
"test": "npm run test:refs && npm run test:install && npm run test:urls && npm run test:channels && npm run lint && npm run lint:md && npm run format:check",
|
||||
"test": "npm run test:refs && npm run test:install && npm run test:urls && npm run test:channels && npm run test:skills && npm run lint && npm run lint:md && npm run format:check",
|
||||
"test:channels": "node test/test-installer-channels.js",
|
||||
"test:install": "node test/test-installation-components.js",
|
||||
"test:refs": "node test/test-file-refs-csv.js",
|
||||
"test:skills": "node test/test-validate-skills.js",
|
||||
"test:urls": "node test/test-parse-source-urls.js",
|
||||
"validate:refs": "node tools/validate-file-refs.js --strict",
|
||||
"validate:skills": "node tools/validate-skills.js --strict"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
---
|
||||
name: bmad-dev-auto
|
||||
description: 'One iteration of an unattended development loop. Use when invoked by name.'
|
||||
---
|
||||
|
||||
# Dev Auto Workflow
|
||||
|
||||
**Goal:** Turn intent into a hardened, reviewable artifact, without human interaction.
|
||||
|
||||
**CRITICAL:** If a step says "read fully and follow step-XX", you read and follow step-XX. No exceptions.
|
||||
|
||||
## HALT
|
||||
|
||||
To HALT with a final status and optional blocking condition:
|
||||
|
||||
1. If `{spec_file}` is known and exists, update `status` in frontmatter and append missing result details under `## Auto Run Result`.
|
||||
2. If `{spec_file}` is unknown or missing, create `{implementation_artifacts}/bmad-dev-auto-result-<slug-or-timestamp>.md` with:
|
||||
```markdown
|
||||
---
|
||||
status: <final status>
|
||||
---
|
||||
|
||||
# BMad Dev Auto Result
|
||||
|
||||
Status: <final status>
|
||||
Blocking condition: <blocking condition, if any>
|
||||
```
|
||||
3. Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key workflow.on_complete`
|
||||
4. If the resolved `workflow.on_complete` is non-empty, follow it as the final instruction before exiting.
|
||||
5. Stop the workflow.
|
||||
|
||||
## Subagents
|
||||
|
||||
Using subagents when instructed is mandatory. If you cannot, HALT with status `blocked` and blocking condition `no subagents`.
|
||||
|
||||
## 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.
|
||||
- **Sufficient**: No known requirement, acceptance, dependency, or implementation gaps remain unresolved.
|
||||
- **Coherent**: No unresolved ambiguities or internal contradictions.
|
||||
|
||||
## 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
|
||||
- `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: Execute Append Steps
|
||||
|
||||
Execute each entry in `{workflow.activation_steps_append}` in order.
|
||||
|
||||
Activation is complete after all activation steps have run.
|
||||
|
||||
## Workflow Execution
|
||||
|
||||
Follow the step files in order. Read one step fully, execute it, then load the next step only when directed. Do not skip, reorder, or pre-load steps.
|
||||
|
||||
## First workflow step
|
||||
|
||||
Read fully and follow: `./step-01-clarify-and-route.md` to begin the workflow.
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# Compile Epic Context
|
||||
|
||||
**Task**
|
||||
Given an epic number, the epics file, the planning artifacts directory, and a desired output path, compile a clean, focused, developer-ready context file (`epic-<N>-context.md`).
|
||||
|
||||
**Steps**
|
||||
|
||||
1. Read the epics file and extract the target epic's title, goal, and list of stories.
|
||||
2. Scan the planning artifacts directory for the standard files (PRD, architecture, UX/design, product brief).
|
||||
3. Pull only the information relevant to this epic.
|
||||
4. Write the compiled context to the exact output path using the format below.
|
||||
|
||||
## Exact Output Format
|
||||
|
||||
Use these headings:
|
||||
|
||||
```markdown
|
||||
# Epic {N} Context: {Epic Title}
|
||||
|
||||
<!-- Generated from planning artifacts. Regenerate with compile-epic-context if planning docs change. -->
|
||||
|
||||
## Goal
|
||||
|
||||
{One clear paragraph: what this epic achieves and why it matters.}
|
||||
|
||||
## Stories
|
||||
|
||||
- Story X.Y: Brief title only
|
||||
- ...
|
||||
|
||||
## Requirements & Constraints
|
||||
|
||||
{Relevant functional/non-functional requirements and success criteria for this epic (describe by purpose, not source).}
|
||||
|
||||
## Technical Decisions
|
||||
|
||||
{Key architecture decisions, constraints, patterns, data models, and conventions relevant to this epic.}
|
||||
|
||||
## UX & Interaction Patterns
|
||||
|
||||
{Relevant UX flows, interaction patterns, and design constraints (omit section entirely if nothing relevant).}
|
||||
|
||||
## Cross-Story Dependencies
|
||||
|
||||
{Dependencies between stories in this epic or with other epics/systems (omit if none).}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- **Scope aggressively.** Include only what a developer working on any story in this epic actually needs. When in doubt, leave it out — the developer can always read the full planning doc.
|
||||
- **Describe by purpose, not by source.** Write "API responses must include pagination metadata" not "Per PRD section 3.2.1, pagination is required." Planning doc internals will change; the constraint won't.
|
||||
- **No full copies.** Never quote source documents, section numbers, or paste large blocks verbatim. Always distill.
|
||||
- **No story-level details.** The story list is for orientation only. Individual story specs handle the details.
|
||||
- **Nothing derivable from the codebase.** Don't document what a developer can learn by reading the code.
|
||||
- **Be concise and actionable.** Target 800–1500 tokens total. This file loads into bmad-dev-auto's context alongside other material.
|
||||
- **Never hallucinate content.** If source material doesn't say something, don't invent it.
|
||||
- **Omit empty sections entirely**, except Goal and Stories, which are always required.
|
||||
|
||||
## Error handling
|
||||
|
||||
- **If the epics file is missing or the target epic is not found:** write nothing and report the problem to the calling agent. Goal and Stories cannot be populated without a usable epics file.
|
||||
- **If planning artifacts are missing or empty:** still produce the file with Goal and Stories populated from the epics file. Under Requirements & Constraints, write: "Planning artifacts were unavailable; only epics-file context was used." Never hallucinate content to fill missing sections.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# DO NOT EDIT -- overwritten on every update.
|
||||
#
|
||||
# Default customization values for bmad-dev-auto.
|
||||
# Override in _bmad/custom/bmad-dev-auto.toml or
|
||||
# _bmad/custom/bmad-dev-auto.user.toml.
|
||||
#
|
||||
# Merge rules:
|
||||
# - Strings replace the default.
|
||||
# - Lists append to the default list.
|
||||
# - Tables merge key by key.
|
||||
|
||||
[workflow]
|
||||
|
||||
# Extra instructions to run before config is loaded.
|
||||
|
||||
activation_steps_prepend = []
|
||||
|
||||
# Extra instructions to run after config is loaded and before step 01.
|
||||
|
||||
activation_steps_append = []
|
||||
|
||||
# Facts kept in context for the whole run.
|
||||
# Entries are literal text or file references prefixed with "file:".
|
||||
# File entries may use globs and are loaded during activation.
|
||||
|
||||
persistent_facts = [
|
||||
"file:{project-root}/**/project-context.md",
|
||||
]
|
||||
|
||||
# Instruction run by HALT after writing the terminal result.
|
||||
# Empty means no extra terminal behavior.
|
||||
|
||||
on_complete = ""
|
||||
|
|
@ -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 | blocked
|
||||
review_loop_iteration: 0 # incremented by step-04 before each review loopback
|
||||
context: [] # optional: `{project-root}/`-prefixed paths to project-wide standards/docs the implementation agent should load. Keep short — only what isn't already distilled into the spec body.
|
||||
warnings: [] # optional: machine-readable warnings for orchestration, e.g. oversized, multiple-goals
|
||||
---
|
||||
|
||||
<!-- Aim for 900–1600 tokens. If larger, add `oversized` to frontmatter `warnings` and continue.
|
||||
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. -->
|
||||
|
||||
<intent-contract>
|
||||
|
||||
## 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. Block If = decisions that cannot be made unattended. Never = out of scope + forbidden approaches. -->
|
||||
|
||||
**Always:** INVARIANT_RULES
|
||||
|
||||
**Block If:** DECISIONS_REQUIRING_HUMAN_INPUT
|
||||
<!-- Agent: if any of these trigger during execution, HALT with status blocked and the blocking condition. -->
|
||||
|
||||
**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 | No error expected |
|
||||
| ERROR_CASE | INPUT | OUTCOME | ERROR_HANDLING |
|
||||
|
||||
</intent-contract>
|
||||
|
||||
## 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 5–10 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
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||
spec_file: '' # set at runtime for both routes 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}`
|
||||
- Treat the invocation intent as workflow input, not as a substitute for step-02 investigation and spec generation.
|
||||
- **EARLY EXIT** means: stop this step immediately, then read and follow the target file. Return here only if a later step explicitly says to loop back.
|
||||
|
||||
## Intent check (do this first)
|
||||
|
||||
Use the invocation prompt as the intent.
|
||||
|
||||
If the invocation prompt explicitly points to an existing spec file with recognized `status` frontmatter, set `spec_file`, then **EARLY EXIT** to the appropriate step:
|
||||
- `draft` → `./step-02-plan.md`
|
||||
- `ready-for-dev` or `in-progress` → `./step-03-implement.md`
|
||||
- `in-review` → `./step-04-review.md`
|
||||
- `blocked` → HALT with status `blocked` and blocking condition `blocked spec supplied`.
|
||||
- `done` → ingest as context and proceed to INSTRUCTIONS — do not resume.
|
||||
|
||||
Otherwise, treat the invocation prompt as starting intent. This may be a story ID, ticket ID, file path, short description, or longer free-form intent. Do not infer workflow state from non-spec files.
|
||||
If the invocation prompt does not contain enough intent to identify what to implement, HALT with status `blocked` and blocking condition `unclear intent`.
|
||||
|
||||
## INSTRUCTIONS
|
||||
|
||||
1. Load context.
|
||||
- List files in `{planning_artifacts}` and `{implementation_artifacts}`.
|
||||
- If the invocation prompt points to an unformatted spec or intent file, ingest that file. Do not scan for unrelated intent files.
|
||||
- **Determine context strategy.** Using the intent and the artifact listing, infer whether the current work is a story from an epic. Do not rely on filename patterns or regex — reason about the intent, the listing, and any epics file content together.
|
||||
|
||||
**A) Epic story path** — if the intent is clearly an epic story:
|
||||
|
||||
1. Identify the epic number `{epic_num}` and (if present) the story number `{story_num}`. If you can't identify an epic number, use path B.
|
||||
|
||||
2. **Check for a valid cached epic context.** Look for `{implementation_artifacts}/epic-<N>-context.md` (where `<N>` is the epic number). A file is **valid** when it exists, is non-empty, starts with `# Epic <N> Context:` (with the correct epic number), and no file in `{planning_artifacts}` is newer.
|
||||
- **If valid:** load it as the primary planning context. Do not load raw planning docs (PRD, architecture, UX, etc.).
|
||||
- **If missing, empty, or invalid:** compile it in the next bullet.
|
||||
|
||||
3. **Compile epic context if needed.** If no valid cached epic context was loaded, produce `{implementation_artifacts}/epic-<N>-context.md` by spawning a subagent with `./compile-epic-context.md` as its prompt. Pass it the epic number, the epics file path, the `{planning_artifacts}` directory, and the output path `{implementation_artifacts}/epic-<N>-context.md`.
|
||||
|
||||
4. **Verify if compiled.** If epic context was compiled, verify the output file exists, is non-empty, and starts with `# Epic <N> Context:`. If valid, load it. If verification fails, HALT with status `blocked` and blocking condition `context compilation verification failed`.
|
||||
|
||||
5. **Previous story continuity.** Regardless of which context source succeeded above, scan `{implementation_artifacts}` for specs from the same epic with `status: done` and a lower story number. Load the most recent one (highest story number below current). Extract its **Code Map**, **Design Notes**, **Spec Change Log**, and **task list** as continuity context for step-02 planning. If no `done` spec is found but an `in-review` spec exists for the same epic with a lower story number, HALT with status `blocked` and blocking condition `missing previous-story continuity decision`.
|
||||
|
||||
**B) Freeform path** — if the intent is not an epic story:
|
||||
- Planning artifacts are the output of BMAD phases 1-3. Typical files include:
|
||||
- **PRD** (`*prd*`) — product requirements and success criteria
|
||||
- **Architecture** (`*architecture*`) — technical design decisions and constraints
|
||||
- **UX/Design** (`*ux*`) — user experience and interaction design
|
||||
- **Epics** (`*epic*`) — feature breakdown into implementable stories
|
||||
- **Product Brief** (`*brief*`) — project vision and scope
|
||||
- Scan the listing for files matching these patterns. If any look relevant to the current intent, load them selectively — you don't need all of them, but you need the right constraints and requirements rather than guessing from code alone.
|
||||
2. Resolve intent from the invocation prompt and loaded artifacts. Do not fantasize or leave open questions. If the intent cannot be resolved, HALT with status `blocked` and the unresolved questions as blocking condition.
|
||||
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 with status `blocked` and that condition as blocking condition. If version control is unavailable, skip this check.
|
||||
4. Multi-goal warning. If the intent appears to contain multiple independently shippable goals, carry `multiple-goals` forward so step-02 can add it to `{spec_file}` frontmatter `warnings`. Do not split or block.
|
||||
5. Route:
|
||||
|
||||
Derive a valid kebab-case slug from the clarified intent. If the intent references a tracking identifier (story number, issue number, ticket ID), lead the slug with it (e.g. `3-2-digest-delivery`, `gh-47-fix-auth`). If `{implementation_artifacts}/spec-{slug}.md` already exists: if its status is `draft`, treat it as the same work and resume it (set `spec_file` to that path, **EARLY EXIT** → `./step-02-plan.md`); otherwise append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/spec-{slug}.md`.
|
||||
|
||||
## NEXT
|
||||
|
||||
Read fully and follow `./step-02-plan.md`
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
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 human interaction: do not ask questions or wait for approval in this step.
|
||||
|
||||
## INSTRUCTIONS
|
||||
|
||||
1. Draft resume check. If `{spec_file}` exists with `status: draft`, read it and capture the verbatim `<intent-contract>...</intent-contract>` block as `preserved_intent_contract`. Otherwise `preserved_intent_contract` is empty.
|
||||
2. Investigate codebase. _Use subagents for deep exploration. To prevent context snowballing, instruct subagents to give you distilled summaries only._
|
||||
3. Read `./spec-template.md` fully. Fill it out based on the intent and investigation. If `{preserved_intent_contract}` is non-empty, substitute it for the `<intent-contract>` block in your filled spec before writing. Write the result to `{spec_file}`.
|
||||
4. Self-review against READY FOR DEVELOPMENT standard.
|
||||
5. If intent gaps exist, do not fantasize and do not leave open questions. HALT with status `blocked`, blocking condition `intent gaps`, and include the unanswered questions and evidence gathered.
|
||||
6. Warning check. If step-01 carried `multiple-goals`, add it to `{spec_file}` frontmatter `warnings`. If `{spec_file}` exceeds 1600 tokens, add `oversized` to frontmatter `warnings`. Continue either way.
|
||||
|
||||
### READY-FOR-DEVELOPMENT GATE
|
||||
|
||||
Re-read `./SKILL.md`, then re-read `{spec_file}` from disk and verify the spec meets the READY FOR DEVELOPMENT standard.
|
||||
|
||||
- **If the file is missing:** HALT with status `blocked` and blocking condition `planned spec file disappeared before implementation`.
|
||||
- **If the spec meets the standard:** set `{spec_file}` frontmatter status to `ready-for-dev`, then continue to step 3.
|
||||
- **If the spec does not meet the standard:** repair it once, then re-read it from disk and verify again. If it still does not meet the standard, HALT with status `blocked`, blocking condition `spec failed ready-for-development standard`, and include the failing criteria and evidence gathered.
|
||||
|
||||
|
||||
## NEXT
|
||||
|
||||
Read fully and follow `./step-03-implement.md`
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
---
|
||||
|
||||
# Step 3: Implement
|
||||
|
||||
## RULES
|
||||
|
||||
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
|
||||
- No human interaction: do not ask questions or wait for approval in this step.
|
||||
- Content inside `<intent-contract>` 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 with status `blocked` and blocking condition `missing spec_file before implementation`.
|
||||
|
||||
## INSTRUCTIONS
|
||||
|
||||
### Baseline
|
||||
|
||||
Capture `baseline_revision` (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.
|
||||
|
||||
If `{spec_file}` has a non-empty `context:` list in its frontmatter, load those files before implementation begins. When handing to a subagent, include them in the subagent prompt so it has access to the referenced context.
|
||||
|
||||
Hand `{spec_file}` to an implementation subagent.
|
||||
|
||||
**Path formatting rule:** Any markdown links written into `{spec_file}` must use paths relative to `{spec_file}`'s directory so they are clickable in VS Code. Any file paths displayed in terminal/conversation output must use CWD-relative format with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/` in either case.
|
||||
|
||||
### Tasks & Acceptance Verification
|
||||
|
||||
After the implementation subagent returns, verify every task in the `## Tasks & Acceptance` section of `{spec_file}` is complete and every acceptance criterion is satisfied. Mark each finished task `[x]`. If any task is not done or any acceptance criterion is not satisfied, finish the missing work before proceeding. If the missing work cannot be completed, HALT with status `blocked`, blocking condition `implementation verification failed`, and include the unfinished task or failing acceptance criterion and reason.
|
||||
|
||||
## NEXT
|
||||
|
||||
Read fully and follow `./step-04-review.md`
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
---
|
||||
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||
---
|
||||
|
||||
# Step 4: Review
|
||||
|
||||
## RULES
|
||||
|
||||
- YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `{communication_language}`
|
||||
- No human interaction: do not ask questions or wait for approval in this step.
|
||||
- Review subagents get no prior session context.
|
||||
- All review subagents must run at the same model capability as the current session.
|
||||
|
||||
## INSTRUCTIONS
|
||||
|
||||
Change `{spec_file}` status to `in-review` in the frontmatter before continuing.
|
||||
|
||||
### Construct Diff
|
||||
|
||||
Read `{baseline_revision}` from `{spec_file}` frontmatter. If `{baseline_revision}` is missing or `NO_VCS`, use best effort to determine what changed. Otherwise, construct `{diff_output}` covering all changes — tracked and untracked — since `{baseline_revision}`.
|
||||
|
||||
Do NOT `git add` anything — this is read-only inspection.
|
||||
|
||||
### Review
|
||||
|
||||
Launch two subagents without prior session context.
|
||||
|
||||
- **Blind hunter** — receives inline `{diff_output}` only. No spec, no context docs, no project access. Invoke via the `bmad-review-adversarial-general` skill.
|
||||
- **Edge case hunter** — receives `{diff_output}` and read access to the project. Invoke via the `bmad-review-edge-case-hunter` skill.
|
||||
|
||||
### 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 exists, lower findings are moot; follow the intent_gap branch below. If bad_spec exists, lower findings are moot since code will be re-derived. If neither exists, process patch and defer normally. Before each bad_spec loopback, read `{spec_file}` frontmatter `review_loop_iteration` (missing means `0`), increment it by 1, and write it back. If it exceeds 5, HALT with status `blocked` and blocking condition `review repair loop exceeded 5 iterations`.
|
||||
- **intent_gap** — Root cause is inside `<intent-contract>`. Revert code changes. HALT with status `blocked`, blocking condition `intent gap in intent contract`, and include the intent-gap findings.
|
||||
- **bad_spec** — Root cause is outside `<intent-contract>`. Do not modify content inside `<intent-contract>`. 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 sections outside `<intent-contract>` 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 `./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 one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates.
|
||||
```markdown
|
||||
- source_spec: `{spec_file}`
|
||||
summary: <one sentence>
|
||||
evidence: <why this is real>
|
||||
```
|
||||
- **reject** — Drop silently.
|
||||
|
||||
## Finalize
|
||||
|
||||
Prepare `Auto Run Result` details:
|
||||
- Summary of implemented change
|
||||
- Files changed with one-line descriptions
|
||||
- Review findings breakdown: patches applied, items deferred, items rejected
|
||||
- Verification performed, including command outcomes or manual inspection notes
|
||||
- Any residual risks
|
||||
|
||||
HALT with status `done`.
|
||||
|
|
@ -20,6 +20,8 @@ A specification is "Ready for Development" when:
|
|||
- **Logical**: Tasks ordered by dependency.
|
||||
- **Testable**: All ACs use Given/When/Then.
|
||||
- **Complete**: No placeholders or TBDs.
|
||||
- **Sufficient**: No known requirement, acceptance, dependency, or implementation gaps remain unresolved.
|
||||
- **Coherent**: No unresolved ambiguities or internal contradictions.
|
||||
|
||||
## SCOPE STANDARD
|
||||
|
||||
|
|
|
|||
|
|
@ -1,41 +1,33 @@
|
|||
# DO NOT EDIT -- overwritten on every update.
|
||||
#
|
||||
# Workflow customization surface for bmad-quick-dev. Mirrors the
|
||||
# agent customization shape under the [workflow] namespace.
|
||||
# Default customization values for bmad-quick-dev.
|
||||
# Override in _bmad/custom/bmad-quick-dev.toml or
|
||||
# _bmad/custom/bmad-quick-dev.user.toml.
|
||||
#
|
||||
# Merge rules:
|
||||
# - Strings replace the default.
|
||||
# - Lists append to the default list.
|
||||
# - Tables merge key by key.
|
||||
|
||||
[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.
|
||||
# Extra instructions to run before config is loaded and before the user is greeted.
|
||||
|
||||
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.
|
||||
# Extra instructions to run after the greeting and before step 01.
|
||||
|
||||
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).
|
||||
# Facts kept in context for the whole run.
|
||||
# Entries are literal text or file references prefixed with "file:".
|
||||
# File entries may use globs and are loaded during activation.
|
||||
|
||||
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.
|
||||
# Instruction run after Quick Dev completes.
|
||||
# Empty means no extra completion behavior.
|
||||
|
||||
on_complete = ""
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ title: '{title}'
|
|||
type: 'feature' # feature | bugfix | refactor | chore
|
||||
created: '{date}'
|
||||
status: 'draft' # draft | ready-for-dev | in-progress | in-review | done
|
||||
review_loop_iteration: 0 # incremented by step-04 before each review loopback
|
||||
context: [] # optional: `{project-root}/`-prefixed paths to project-wide standards/docs the implementation agent should load. Keep short — only what isn't already distilled into the spec body.
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -59,8 +59,8 @@ If the spec is an epic story and `{sprint_status}` exists: find the `development
|
|||
- **If missing, empty, or invalid:** continue to step 3.
|
||||
|
||||
3. **Compile epic context.** Produce `{implementation_artifacts}/epic-<N>-context.md` by following `./compile-epic-context.md`, in order of preference:
|
||||
- **Preferred — sub-agent:** spawn a sub-agent with `./compile-epic-context.md` as its prompt. Pass it the epic number, the epics file path, the `{planning_artifacts}` directory, and the output path `{implementation_artifacts}/epic-<N>-context.md`.
|
||||
- **Fallback — inline** (for runtimes without sub-agent support, e.g. Copilot, Codex, local Ollama, older Claude): if your runtime cannot spawn sub-agents, or the spawn fails/times out, read `./compile-epic-context.md` yourself and follow its instructions to produce the same output file.
|
||||
- **Preferred — subagent:** spawn a subagent with `./compile-epic-context.md` as its prompt. Pass it the epic number, the epics file path, the `{planning_artifacts}` directory, and the output path `{implementation_artifacts}/epic-<N>-context.md`.
|
||||
- **Fallback — inline** (for runtimes without subagent support, e.g. Copilot, Codex, local Ollama, older Claude): if your runtime cannot spawn subagents, or the spawn fails/times out, read `./compile-epic-context.md` yourself and follow its instructions to produce the same output file.
|
||||
|
||||
4. **Verify.** After compilation, verify the output file exists, is non-empty, and starts with `# Epic <N> Context:`. If valid, load it. If verification fails, HALT and report the failure.
|
||||
|
||||
|
|
@ -82,7 +82,12 @@ If the spec is an epic story and `{sprint_status}` exists: find the `development
|
|||
- Present detected distinct goals as a bullet list.
|
||||
- Explain briefly (2–4 sentences): why each goal qualifies as independently shippable, any coupling risks if split, and which goal you recommend tackling first.
|
||||
- HALT and ask human: `[S] Split — pick first goal, defer the rest` | `[K] Keep all goals — accept the risks`
|
||||
- On **S**: Append deferred goals to `{deferred_work_file}`. Narrow scope to the first-mentioned goal. Continue routing.
|
||||
- On **S**: For each deferred goal, append one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates. Narrow scope to the first-mentioned goal. Continue routing.
|
||||
```markdown
|
||||
- source_spec: none
|
||||
summary: <one sentence naming the deferred goal>
|
||||
evidence: <why this was split from the current intent>
|
||||
```
|
||||
- On **K**: Proceed as-is.
|
||||
5. Route — choose exactly one:
|
||||
|
||||
|
|
|
|||
|
|
@ -12,14 +12,19 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
|||
## INSTRUCTIONS
|
||||
|
||||
1. Draft resume check. If `{spec_file}` exists with `status: draft`, read it and capture the verbatim `<frozen-after-approval>...</frozen-after-approval>` block as `preserved_intent`. Otherwise `preserved_intent` is empty.
|
||||
2. Investigate codebase. _Isolate deep exploration in sub-agents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._
|
||||
2. Investigate codebase. _Isolate deep exploration in subagents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._
|
||||
3. Read `./spec-template.md` fully. Fill it out based on the intent and investigation. If `{preserved_intent}` is non-empty, substitute it for the `<frozen-after-approval>` block in your filled spec before writing. Write the result to `{spec_file}`.
|
||||
4. Self-review against READY FOR DEVELOPMENT standard.
|
||||
5. If intent gaps exist, do not fantasize, do not leave open questions, HALT and ask the human.
|
||||
6. 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 full spec — accept the risks`
|
||||
- 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 **S**: Propose the split — name each secondary goal. For each deferred goal, append one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates. 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.
|
||||
```markdown
|
||||
- source_spec: `{spec_file}`
|
||||
summary: <one sentence naming the deferred goal>
|
||||
evidence: <why this was split from the current spec>
|
||||
```
|
||||
- On **K**: Continue to checkpoint with full spec.
|
||||
|
||||
### CHECKPOINT 1
|
||||
|
|
|
|||
|
|
@ -26,15 +26,15 @@ Change `{spec_file}` status to `in-progress` in the frontmatter before starting
|
|||
|
||||
Follow `./sync-sprint-status.md` with `{target_status}` = `in-progress`.
|
||||
|
||||
If `{spec_file}` has a non-empty `context:` list in its frontmatter, load those files before implementation begins. When handing to a sub-agent, include them in the sub-agent prompt so it has access to the referenced context.
|
||||
If `{spec_file}` has a non-empty `context:` list in its frontmatter, load those files before implementation begins. When handing to a subagent, include them in the subagent prompt so it has access to the referenced context.
|
||||
|
||||
Hand `{spec_file}` to a sub-agent/task and let it implement. If no sub-agents are available, implement directly.
|
||||
Hand `{spec_file}` to a subagent/task and let it implement. If no subagents are available, implement directly.
|
||||
|
||||
**Path formatting rule:** Any markdown links written into `{spec_file}` must use paths relative to `{spec_file}`'s directory so they are clickable in VS Code. Any file paths displayed in terminal/conversation output must use CWD-relative format with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/` in either case.
|
||||
|
||||
### Self-Check
|
||||
### Tasks & Acceptance Verification
|
||||
|
||||
Before leaving this step, verify every task in the `## Tasks & Acceptance` section of `{spec_file}` is complete. Mark each finished task `[x]`. If any task is not done, finish it before proceeding.
|
||||
Before leaving this step, verify every task in the `## Tasks & Acceptance` section of `{spec_file}` is complete and every acceptance criterion is satisfied. Mark each finished task `[x]`. If any task is not done or any acceptance criterion is not satisfied, finish the missing work before proceeding.
|
||||
|
||||
## NEXT
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||
specLoopIteration: 1
|
||||
---
|
||||
|
||||
# Step 4: Review
|
||||
|
|
@ -23,11 +22,10 @@ Do NOT `git add` anything — this is read-only inspection.
|
|||
|
||||
### 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.
|
||||
Launch two subagents without conversation context. If no subagents are available, generate two 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 inline `{diff_output}` only. No spec, no context docs, no project access. Invoke via the `bmad-review-adversarial-general` skill.
|
||||
- **Edge case hunter** — receives `{diff_output}` and read access to the project. Invoke via the `bmad-review-edge-case-hunter` skill.
|
||||
- **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
|
||||
|
||||
|
|
@ -38,11 +36,16 @@ Launch three subagents without conversation context. If no sub-agents are availa
|
|||
- **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.
|
||||
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. Before each loopback, read `{spec_file}` frontmatter `review_loop_iteration` (missing means `0`), increment it by 1, and write it back. If it exceeds 5, HALT and escalate to the human.
|
||||
- **intent_gap** — Root cause is inside `<frozen-after-approval>`. Revert code changes. Loop back to the human to resolve. Once resolved, read fully and follow `./step-02-plan.md` to re-run steps 2–4.
|
||||
- **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 `./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}`.
|
||||
- **defer** — Append one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates.
|
||||
```markdown
|
||||
- source_spec: `{spec_file}`
|
||||
summary: <one sentence>
|
||||
evidence: <why this is real>
|
||||
```
|
||||
- **reject** — Drop silently.
|
||||
|
||||
## NEXT
|
||||
|
|
|
|||
|
|
@ -19,14 +19,19 @@ Implement the clarified intent directly.
|
|||
|
||||
### Review
|
||||
|
||||
Invoke the `bmad-review-adversarial-general` skill in a subagent with the changed files. The subagent gets NO conversation context — to avoid anchoring bias. Launch at the same model capability as the current session. If no sub-agents are available, write the changed files to a review prompt file in `{implementation_artifacts}` and HALT. Ask the human to run the review in a separate session and paste back the findings.
|
||||
Invoke the `bmad-review-adversarial-general` skill in a subagent with the changed files. The subagent gets NO conversation context — to avoid anchoring bias. Launch at the same model capability as the current session. If no subagents are available, write the changed files to a review prompt file in `{implementation_artifacts}` and HALT. Ask the human to run the review in a separate session and paste back the findings.
|
||||
|
||||
### Classify
|
||||
|
||||
Deduplicate all review findings. Three categories only:
|
||||
|
||||
- **patch** — trivially fixable. Auto-fix immediately.
|
||||
- **defer** — pre-existing issue not caused by this change. Append to `{deferred_work_file}`.
|
||||
- **defer** — pre-existing issue not caused by this change. Append one new entry to `{deferred_work_file}` using this format. Do not modify existing entries or look for duplicates.
|
||||
```markdown
|
||||
- source_spec: `{spec_file}`
|
||||
summary: <one sentence>
|
||||
evidence: <why this is real>
|
||||
```
|
||||
- **reject** — noise. Drop silently.
|
||||
|
||||
If a finding is caused by this change but too significant for a trivial patch, HALT and present it to the human for decision before proceeding.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: deprecated-shim
|
||||
description: 'DEPRECATED — consolidated into bmad-foo; this skill will be removed in v7 in favor of `bmad-foo`.'
|
||||
---
|
||||
|
||||
# DEPRECATED — forwards to bmad-foo
|
||||
|
||||
This skill was consolidated into `bmad-foo` and is retained as a thin compatibility
|
||||
shim so existing invocations keep working. New work should invoke `bmad-foo` directly.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
name: missing-trigger
|
||||
description: 'Generates a thing and writes it to disk for the user.'
|
||||
---
|
||||
|
||||
# Missing Trigger
|
||||
|
||||
An active (non-deprecated) skill whose description omits a "Use when" trigger phrase.
|
||||
This fixture guards against regressions: SKILL-06 must still flag it.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: with-trigger
|
||||
description: 'Generates a thing and writes it to disk. Use when the user asks to scaffold a thing.'
|
||||
---
|
||||
|
||||
# With Trigger
|
||||
|
||||
An active skill whose description includes a "Use when" trigger phrase.
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Skill Validation Test Runner
|
||||
*
|
||||
* Tests validateSkill() from validate-skills.js against fixtures, focused on
|
||||
* SKILL-06 (description quality) and its deprecated-skill exemption.
|
||||
*
|
||||
* Usage: node test/test-validate-skills.js
|
||||
* Exit codes: 0 = all tests pass, 1 = test failures
|
||||
*/
|
||||
|
||||
const path = require('node:path');
|
||||
const { validateSkill } = require('../tools/validate-skills.js');
|
||||
|
||||
// ANSI color codes
|
||||
const colors = {
|
||||
reset: '\u001B[0m',
|
||||
green: '\u001B[32m',
|
||||
red: '\u001B[31m',
|
||||
cyan: '\u001B[36m',
|
||||
dim: '\u001B[2m',
|
||||
};
|
||||
|
||||
const FIXTURES = path.join(__dirname, 'fixtures/validate-skills');
|
||||
|
||||
let totalTests = 0;
|
||||
let passedTests = 0;
|
||||
const failures = [];
|
||||
|
||||
/**
|
||||
* Run a single named test case, recording the result and printing a status line.
|
||||
* @param {string} name - Human-readable test description.
|
||||
* @param {Function} fn - Test body; throw to signal failure.
|
||||
*/
|
||||
function test(name, fn) {
|
||||
totalTests++;
|
||||
try {
|
||||
fn();
|
||||
passedTests++;
|
||||
console.log(` ${colors.green}✓${colors.reset} ${name}`);
|
||||
} catch (error) {
|
||||
console.log(` ${colors.red}✗${colors.reset} ${name} ${colors.red}${error.message}${colors.reset}`);
|
||||
failures.push({ name, message: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an Error with `message` when `condition` is falsy.
|
||||
* @param {boolean} condition - Expression that must hold.
|
||||
* @param {string} message - Failure message.
|
||||
*/
|
||||
function assert(condition, message) {
|
||||
if (!condition) throw new Error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether validateSkill emitted the SKILL-06 "Use when/Use if" trigger finding
|
||||
* for the given fixture skill directory.
|
||||
* @param {string} skillName - Fixture subdirectory name under FIXTURES.
|
||||
* @returns {boolean} True if the trigger-phrase finding was reported.
|
||||
*/
|
||||
function hasTriggerFinding(skillName) {
|
||||
const findings = validateSkill(path.join(FIXTURES, skillName));
|
||||
return findings.some((f) => f.rule === 'SKILL-06' && /trigger phrase/i.test(f.detail));
|
||||
}
|
||||
|
||||
console.log(`\n${colors.cyan}Skill Validation — SKILL-06 trigger phrase${colors.reset}\n`);
|
||||
|
||||
test('deprecated skill is exempt from the trigger-phrase requirement', () => {
|
||||
assert(hasTriggerFinding('deprecated-shim') === false, 'Expected no SKILL-06 trigger finding for a DEPRECATED skill');
|
||||
});
|
||||
|
||||
test('active skill missing a trigger phrase is still flagged', () => {
|
||||
assert(
|
||||
hasTriggerFinding('missing-trigger') === true,
|
||||
'Expected a SKILL-06 trigger finding for a non-deprecated skill without "Use when"',
|
||||
);
|
||||
});
|
||||
|
||||
test('active skill with a "Use when" trigger is not flagged', () => {
|
||||
assert(hasTriggerFinding('with-trigger') === false, 'Expected no SKILL-06 trigger finding when description contains "Use when"');
|
||||
});
|
||||
|
||||
// --- Summary ---
|
||||
console.log(`\n${colors.cyan}${'═'.repeat(55)}${colors.reset}`);
|
||||
console.log(`${colors.cyan}Test Results:${colors.reset}`);
|
||||
console.log(` Total: ${totalTests}`);
|
||||
console.log(` Passed: ${colors.green}${passedTests}${colors.reset}`);
|
||||
console.log(` Failed: ${passedTests === totalTests ? colors.green : colors.red}${totalTests - passedTests}${colors.reset}`);
|
||||
console.log(`${colors.cyan}${'═'.repeat(55)}${colors.reset}\n`);
|
||||
|
||||
if (failures.length > 0) {
|
||||
console.log(`${colors.red}FAILED TESTS:${colors.reset}\n`);
|
||||
for (const failure of failures) {
|
||||
console.log(`${colors.red}✗${colors.reset} ${failure.name}`);
|
||||
console.log(` ${failure.message}\n`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`${colors.green}All tests passed!${colors.reset}\n`);
|
||||
process.exit(0);
|
||||
|
|
@ -312,6 +312,11 @@ function validateSkill(skillDir) {
|
|||
const name = skillFm && skillFm.name;
|
||||
const description = skillFm && skillFm.description;
|
||||
|
||||
// Deprecated skills are thin compatibility shims that forward to a replacement.
|
||||
// They intentionally omit a "Use when" trigger so users are steered to the new
|
||||
// skill instead, so exempt them from the SKILL-06 trigger-phrase requirement.
|
||||
const isDeprecated = typeof description === 'string' && /^\s*deprecated\b/i.test(description);
|
||||
|
||||
// --- SKILL-04: name format ---
|
||||
if (name && !NAME_REGEX.test(name)) {
|
||||
findings.push({
|
||||
|
|
@ -349,7 +354,7 @@ function validateSkill(skillDir) {
|
|||
});
|
||||
}
|
||||
|
||||
if (!/use\s+when\b/i.test(description) && !/use\s+if\b/i.test(description)) {
|
||||
if (!isDeprecated && !/use\s+when\b/i.test(description) && !/use\s+if\b/i.test(description)) {
|
||||
findings.push({
|
||||
rule: 'SKILL-06',
|
||||
title: 'description Quality',
|
||||
|
|
|
|||
Loading…
Reference in New Issue