bmad-method 6.10.1-next.8 → 6.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +30 -57
- package/README.md +49 -82
- package/README_CN.md +10 -10
- package/README_VN.md +11 -11
- package/bmad-modules.yaml +43 -39
- package/package.json +7 -3
- package/removals.txt +17 -0
- package/src/bmm-skills/{1-analysis → agents}/bmad-agent-analyst/SKILL.md +1 -1
- package/src/bmm-skills/{1-analysis → agents}/bmad-agent-analyst/customize.toml +22 -7
- package/src/bmm-skills/{3-solutioning → agents}/bmad-agent-architect/SKILL.md +1 -1
- package/src/bmm-skills/{3-solutioning → agents}/bmad-agent-architect/customize.toml +2 -2
- package/src/bmm-skills/{4-implementation → agents}/bmad-agent-dev/SKILL.md +1 -1
- package/src/bmm-skills/{4-implementation → agents}/bmad-agent-dev/customize.toml +7 -14
- package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-pm/SKILL.md +1 -1
- package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-pm/customize.toml +2 -2
- package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-ux-designer/SKILL.md +1 -1
- package/src/bmm-skills/module-help.csv +14 -26
- package/src/bmm-skills/module.yaml +5 -15
- package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/SKILL.md +3 -3
- package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/customize.toml +4 -2
- package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/SKILL.md +1 -1
- package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-04-final-validation.md +1 -1
- package/src/bmm-skills/plan/bmad-generate-project-context/SKILL.md +10 -0
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/SKILL.md +3 -1
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/prd-template.md +1 -1
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/customize.toml +5 -3
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/references/validate.md +3 -3
- package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/SKILL.md +1 -1
- package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/bmad-manifest.json +1 -1
- package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/verdict.md +1 -1
- package/src/bmm-skills/{1-analysis → plan}/bmad-product-brief/SKILL.md +1 -1
- package/src/bmm-skills/{1-analysis → plan}/bmad-product-brief/customize.toml +5 -3
- package/src/bmm-skills/plan/bmad-project-context/SKILL.md +110 -0
- package/src/bmm-skills/plan/bmad-project-context/customize.toml +24 -0
- package/src/bmm-skills/plan/bmad-project-context/references/best-practices.md +65 -0
- package/src/bmm-skills/plan/bmad-project-context/references/template.md +55 -0
- package/src/{core-skills → bmm-skills/plan}/bmad-spec/SKILL.md +18 -3
- package/src/{core-skills → bmm-skills/plan}/bmad-spec/assets/spec-template.md +1 -1
- package/src/bmm-skills/plan/bmad-spec/assets/stories-schema.md +44 -0
- package/src/{core-skills → bmm-skills/plan}/bmad-spec/customize.toml +3 -4
- package/src/bmm-skills/plan/bmad-sprint-planning/SKILL.md +62 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/fix-sprint-status.md +30 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/generate-tracking.md +25 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/readiness-gate.md +20 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/status-view.md +14 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/references/validate.md +10 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/sprint_plan.py +697 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/test_sprint_plan.py +524 -0
- package/src/bmm-skills/{4-implementation → plan}/bmad-sprint-planning/sprint-status-template.yaml +9 -7
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/SKILL.md +1 -1
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/color-themes.md +1 -1
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/customize.toml +4 -2
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/creative-tools.md +1 -1
- package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/validate.md +1 -1
- package/src/bmm-skills/ship/bmad-build/SKILL.md +13 -0
- package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/compile-epic-context.md +1 -1
- package/src/bmm-skills/ship/bmad-build/customize.toml +164 -0
- package/src/bmm-skills/ship/bmad-build/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-build/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-build/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-01-clarify-and-route.md +20 -19
- package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-02-plan.md +5 -9
- package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-03-implement.md +10 -6
- package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-04-review.md +9 -15
- package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-05-present.md +10 -13
- package/src/bmm-skills/ship/bmad-build/step-oneshot.md +77 -0
- package/src/bmm-skills/ship/bmad-build/sync-sprint-status.md +19 -0
- package/src/bmm-skills/ship/bmad-build/workflow.md +84 -0
- package/src/bmm-skills/ship/bmad-build-auto/SKILL.md +13 -0
- package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/compile-epic-context.md +1 -1
- package/src/bmm-skills/ship/bmad-build-auto/customize.toml +121 -0
- package/src/{core-skills/bmad-review-edge-case-hunter/SKILL.md → bmm-skills/ship/bmad-build-auto/review-prompts/edge-case-hunter.md} +21 -6
- package/src/{core-skills/bmad-review-verification-gap/SKILL.md → bmm-skills/ship/bmad-build-auto/review-prompts/verification-gap.md} +15 -8
- package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/spec-template.md +2 -1
- package/src/bmm-skills/ship/bmad-build-auto/step-01-clarify-and-route.md +83 -0
- package/src/bmm-skills/ship/bmad-build-auto/step-02-plan.md +27 -0
- package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/step-03-implement.md +6 -4
- package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/step-04-review.md +26 -25
- package/src/bmm-skills/ship/bmad-build-auto/workflow.md +104 -0
- package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/SKILL.md +1 -1
- package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-05-wrapup.md +1 -1
- package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/SKILL.md +1 -1
- package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/customize.toml +37 -17
- package/src/bmm-skills/ship/bmad-code-review/references/deletion-check.md +14 -0
- package/src/bmm-skills/ship/bmad-code-review/review-prompts/edge-case-hunter.md +88 -0
- package/src/bmm-skills/ship/bmad-code-review/review-prompts/verification-gap.md +113 -0
- package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-01-gather-context.md +7 -4
- package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-02-review.md +1 -1
- package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-04-present.md +1 -1
- package/src/bmm-skills/{4-implementation → ship}/bmad-correct-course/SKILL.md +7 -8
- package/src/bmm-skills/{4-implementation → ship}/bmad-qa-generate-e2e-tests/SKILL.md +2 -2
- package/src/bmm-skills/ship/bmad-retrospective/SKILL.md +94 -0
- package/src/bmm-skills/{4-implementation → ship}/bmad-retrospective/customize.toml +2 -2
- package/src/bmm-skills/ship/bmad-retrospective/references/acceptance-verdict.md +55 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/aggregate-views.md +17 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/evidence-gathering.md +30 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/retro-document.md +84 -0
- package/src/bmm-skills/ship/bmad-retrospective/references/team-discussion.md +22 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/git_evidence.py +304 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/sprint_status.py +746 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/fixtures/sprint-status-template.yaml +71 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_git_evidence.py +750 -0
- package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_sprint_status.py +1579 -0
- package/src/bmm-skills/v6-shims/README.md +28 -0
- package/src/bmm-skills/{3-solutioning → v6-shims}/bmad-create-architecture/SKILL.md +2 -2
- package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-create-prd/SKILL.md +4 -4
- package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/SKILL.md +5 -3
- package/src/bmm-skills/v6-shims/bmad-dev-auto/SKILL.md +19 -0
- package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/SKILL.md +5 -3
- package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/customize.toml +3 -0
- package/src/bmm-skills/v6-shims/bmad-document-project/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-domain-research/SKILL.md +14 -0
- package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-edit-prd/SKILL.md +4 -4
- package/src/bmm-skills/v6-shims/bmad-market-research/SKILL.md +14 -0
- package/src/bmm-skills/v6-shims/bmad-quick-dev/SKILL.md +19 -0
- package/src/bmm-skills/v6-shims/bmad-sprint-status/SKILL.md +26 -0
- package/src/bmm-skills/v6-shims/bmad-technical-research/SKILL.md +14 -0
- package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-validate-prd/SKILL.md +4 -4
- package/src/core-skills/bmad-advanced-elicitation/SKILL.md +26 -103
- package/src/core-skills/bmad-advanced-elicitation/customize.toml +54 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/pick_methods.py +233 -0
- package/src/core-skills/bmad-advanced-elicitation/scripts/tests/test_pick_methods.py +228 -0
- package/src/core-skills/bmad-brainstorming/SKILL.md +3 -3
- package/src/core-skills/bmad-brainstorming/assets/brain-selector.html +2 -0
- package/src/core-skills/bmad-brainstorming/references/mode-autonomous.md +1 -1
- package/src/core-skills/bmad-brainstorming/scripts/brain.py +36 -6
- package/src/core-skills/bmad-brainstorming/scripts/tests/test_brain.py +22 -0
- package/src/core-skills/bmad-customize/SKILL.md +2 -2
- package/src/core-skills/bmad-deep-recon/SKILL.md +82 -0
- package/src/core-skills/bmad-deep-recon/assets/research.template.md +18 -0
- package/src/core-skills/bmad-deep-recon/customize.toml +212 -0
- package/src/core-skills/bmad-deep-recon/references/draft.md +8 -0
- package/src/core-skills/bmad-deep-recon/references/finalize.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/html-briefing.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/lifecycle.md +11 -0
- package/src/core-skills/bmad-deep-recon/references/process.md +10 -0
- package/src/core-skills/bmad-deep-recon/references/run.md +73 -0
- package/src/core-skills/bmad-deep-recon/references/selection.md +13 -0
- package/src/core-skills/bmad-deep-recon/references/synthesis.md +16 -0
- package/src/core-skills/bmad-deep-recon/references/verification.md +29 -0
- package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +322 -0
- package/src/core-skills/bmad-deep-recon/scripts/tests/test_recon_kit.py +144 -0
- package/src/core-skills/bmad-deep-recon/types/academic-lit.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/competitive.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/domain.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/market.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/technical.md +19 -0
- package/src/core-skills/bmad-deep-recon/types/user-voice.md +19 -0
- package/src/core-skills/bmad-forge-idea/SKILL.md +2 -2
- package/src/core-skills/bmad-forge-idea/scripts/resolve_personas.py +7 -2
- package/src/core-skills/bmad-help/SKILL.md +3 -3
- package/src/core-skills/bmad-party-mode/SKILL.md +2 -2
- package/src/core-skills/bmad-party-mode/customize.toml +1 -1
- package/src/core-skills/bmad-party-mode/scripts/resolve_party.py +14 -4
- package/src/core-skills/bmad-review/SKILL.md +49 -0
- package/src/core-skills/bmad-review/customize.toml +141 -0
- package/src/core-skills/bmad-review/references/editorial-common.md +56 -0
- package/src/core-skills/bmad-review/references/lens-adversarial.md +19 -0
- package/src/core-skills/bmad-review/references/lens-edge-case-hunter.md +54 -0
- package/src/core-skills/bmad-review/references/lens-prose.md +7 -0
- package/src/core-skills/bmad-review/references/lens-structure.md +9 -0
- package/src/core-skills/bmad-review/references/lens-verification-gap.md +92 -0
- package/src/core-skills/bmad-review/references/structure-models.md +44 -0
- package/src/core-skills/bmad-review/scripts/tests/test_word_metrics.py +62 -0
- package/src/core-skills/bmad-review/scripts/word_metrics.py +102 -0
- package/src/core-skills/module-help.csv +4 -8
- package/src/core-skills/module.yaml +5 -0
- package/src/core-skills/v6-shims/README.md +25 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review/customize.toml +31 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-prose/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-editorial-review-structure/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-adversarial-general/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-edge-case-hunter/SKILL.md +6 -0
- package/src/core-skills/v6-shims/bmad-review-verification-gap/SKILL.md +6 -0
- package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
- package/src/scripts/config_utils.py +119 -0
- package/src/scripts/render_skill.py +401 -0
- package/src/scripts/resolve_config.py +32 -136
- package/src/scripts/resolve_customization.py +43 -184
- package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
- package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
- package/src/scripts/tests/test_config_utils.py +85 -0
- package/src/scripts/tests/test_resolve_config.py +89 -0
- package/src/scripts/tests/test_resolve_customization.py +27 -0
- package/tools/installer/cli-utils.js +6 -2
- package/tools/installer/core/installer.js +31 -9
- package/tools/installer/core/manifest-generator.js +1 -1
- package/tools/installer/core/uv-check.js +122 -24
- package/tools/installer/ide/_config-driven.js +1 -1
- package/tools/installer/ide/platform-codes.yaml +7 -0
- package/tools/installer/ide/shared/path-utils.js +2 -2
- package/tools/installer/install-messages.yaml +3 -2
- package/tools/installer/modules/custom-module-manager.js +12 -6
- package/tools/installer/modules/external-manager.js +12 -8
- package/tools/installer/modules/git-env.js +47 -0
- package/tools/installer/modules/official-modules.js +1 -1
- package/tools/installer/prompts.js +41 -102
- package/tools/installer/ui.js +99 -22
- package/tools/skill-validator.md +11 -1
- package/tools/validate-published-implementation-model.mjs +68 -0
- package/tools/validate-skills.js +33 -0
- package/web-bundles/prd-coach/prd-template.md +1 -1
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/SKILL.md +0 -76
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.toml +0 -81
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/explain-concept.md +0 -20
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/mermaid-gen.md +0 -20
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/validate-doc.md +0 -19
- package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/write-document.md +0 -20
- package/src/bmm-skills/1-analysis/bmad-document-project/SKILL.md +0 -62
- package/src/bmm-skills/1-analysis/bmad-document-project/checklist.md +0 -245
- package/src/bmm-skills/1-analysis/bmad-document-project/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/bmad-document-project/documentation-requirements.csv +0 -12
- package/src/bmm-skills/1-analysis/bmad-document-project/instructions.md +0 -128
- package/src/bmm-skills/1-analysis/bmad-document-project/templates/deep-dive-template.md +0 -345
- package/src/bmm-skills/1-analysis/bmad-document-project/templates/index-template.md +0 -169
- package/src/bmm-skills/1-analysis/bmad-document-project/templates/project-overview-template.md +0 -103
- package/src/bmm-skills/1-analysis/bmad-document-project/templates/project-scan-report-schema.json +0 -160
- package/src/bmm-skills/1-analysis/bmad-document-project/templates/source-tree-template.md +0 -135
- package/src/bmm-skills/1-analysis/bmad-document-project/workflows/deep-dive-instructions.md +0 -300
- package/src/bmm-skills/1-analysis/bmad-document-project/workflows/deep-dive-workflow.md +0 -34
- package/src/bmm-skills/1-analysis/bmad-document-project/workflows/full-scan-instructions.md +0 -1108
- package/src/bmm-skills/1-analysis/bmad-document-project/workflows/full-scan-workflow.md +0 -34
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/SKILL.md +0 -96
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-01-init.md +0 -137
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-02-domain-analysis.md +0 -229
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-03-competitive-landscape.md +0 -238
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-04-regulatory-focus.md +0 -206
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-05-technical-trends.md +0 -234
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +0 -450
- package/src/bmm-skills/1-analysis/research/bmad-domain-research/research.template.md +0 -29
- package/src/bmm-skills/1-analysis/research/bmad-market-research/SKILL.md +0 -96
- package/src/bmm-skills/1-analysis/research/bmad-market-research/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/research/bmad-market-research/research.template.md +0 -29
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-01-init.md +0 -184
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +0 -239
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +0 -251
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +0 -261
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +0 -173
- package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +0 -484
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/SKILL.md +0 -96
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/customize.toml +0 -41
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/research.template.md +0 -29
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-01-init.md +0 -137
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-02-technical-overview.md +0 -239
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-03-integration-patterns.md +0 -248
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-04-architectural-patterns.md +0 -202
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-05-implementation-research.md +0 -233
- package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +0 -493
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/SKILL.md +0 -91
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/customize.toml +0 -41
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +0 -179
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +0 -168
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +0 -169
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-04-ux-alignment.md +0 -129
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-05-epic-quality-review.md +0 -241
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +0 -132
- package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/templates/readiness-report-template.md +0 -4
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/SKILL.md +0 -81
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/customize.toml +0 -41
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/project-context-template.md +0 -21
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-01-discover.md +0 -186
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-02-generate.md +0 -321
- package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-03-complete.md +0 -284
- package/src/bmm-skills/4-implementation/bmad-dev-auto/SKILL.md +0 -103
- package/src/bmm-skills/4-implementation/bmad-dev-auto/customize.toml +0 -108
- package/src/bmm-skills/4-implementation/bmad-dev-auto/step-01-clarify-and-route.md +0 -66
- package/src/bmm-skills/4-implementation/bmad-dev-auto/step-02-plan.md +0 -31
- package/src/bmm-skills/4-implementation/bmad-quick-dev/SKILL.md +0 -115
- package/src/bmm-skills/4-implementation/bmad-quick-dev/customize.toml +0 -83
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +0 -82
- package/src/bmm-skills/4-implementation/bmad-quick-dev/sync-sprint-status.md +0 -19
- package/src/bmm-skills/4-implementation/bmad-retrospective/SKILL.md +0 -1527
- package/src/bmm-skills/4-implementation/bmad-sprint-planning/SKILL.md +0 -319
- package/src/bmm-skills/4-implementation/bmad-sprint-planning/checklist.md +0 -34
- package/src/bmm-skills/4-implementation/bmad-sprint-status/SKILL.md +0 -311
- package/src/core-skills/bmad-brainstorming/analysis/catalog-analysis.md +0 -239
- package/src/core-skills/bmad-brainstorming/analysis/method-matrix.csv +0 -109
- package/src/core-skills/bmad-editorial-review-prose/SKILL.md +0 -86
- package/src/core-skills/bmad-editorial-review-structure/SKILL.md +0 -179
- package/src/core-skills/bmad-index-docs/SKILL.md +0 -66
- package/src/core-skills/bmad-review-adversarial-general/SKILL.md +0 -37
- package/src/core-skills/bmad-shard-doc/SKILL.md +0 -105
- /package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-ux-designer/customize.toml +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/assets/spine-template.md +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/references/headless.md +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/references/reviewer-gate.md +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/scripts/lint_spine.py +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/scripts/tests/test_lint_spine.py +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/customize.toml +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-02-design-epics.md +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-03-create-stories.md +0 -0
- /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/templates/epics-template.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/headless-schemas.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/prd-validation-checklist.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/validation-report-template.html +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/references/headless.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/agents/artifact-analyzer.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/agents/web-researcher.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/assets/prfaq-template.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/customize.toml +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/customer-faq.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/internal-faq.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/press-release.md +0 -0
- /package/src/bmm-skills/{1-analysis → plan}/bmad-product-brief/assets/brief-template.md +0 -0
- /package/src/{core-skills → bmm-skills/plan}/bmad-spec/assets/headless-schemas.md +0 -0
- /package/src/bmm-skills/{4-implementation → plan}/bmad-sprint-planning/customize.toml +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-directions.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-example-editorial.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-example-mobile.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-example-shadcn.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/excalidraw-wireframe.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/experience-example-mobile.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/experience-example-shadcn.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/headless-schemas.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/key-screens.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/validation-report-template.html +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/design-md-spec.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/headless.md +0 -0
- /package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/spec-template.md +0 -0
- /package/src/{core-skills/bmad-review-edge-case-hunter → bmm-skills/ship/bmad-build-auto}/references/deletion-check.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/customize.toml +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/generate-trail.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-01-orientation.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-02-walkthrough.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-03-detail-pass.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-04-testing.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-03-triage.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-correct-course/checklist.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-correct-course/customize.toml +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-qa-generate-e2e-tests/checklist.md +0 -0
- /package/src/bmm-skills/{4-implementation → ship}/bmad-qa-generate-e2e-tests/customize.toml +0 -0
- /package/src/bmm-skills/{3-solutioning → v6-shims}/bmad-create-architecture/customize.toml +0 -0
- /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-create-prd/customize.toml +0 -0
- /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/checklist.md +0 -0
- /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/customize.toml +0 -0
- /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/discover-inputs.md +0 -0
- /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/template.md +0 -0
- /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/checklist.md +0 -0
- /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-edit-prd/customize.toml +0 -0
- /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-sprint-status/customize.toml +0 -0
- /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-validate-prd/customize.toml +0 -0
- /package/src/core-skills/bmad-advanced-elicitation/{methods.csv → assets/methods.csv} +0 -0
- /package/src/core-skills/bmad-party-mode/scripts/tests/{test-resolve_party.py → test_resolve_party.py} +0 -0
|
Binary file
|
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
# /// script
|
|
2
|
+
# requires-python = ">=3.10"
|
|
3
|
+
# dependencies = ["pytest>=8.0", "ruamel.yaml>=0.18"]
|
|
4
|
+
# ///
|
|
5
|
+
"""Tests for sprint_plan.py — deterministic sprint-status generation.
|
|
6
|
+
|
|
7
|
+
Run: uv run scripts/tests/test_sprint_plan.py
|
|
8
|
+
or: uv run --with pytest --with ruamel.yaml -m pytest scripts/tests/test_sprint_plan.py
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import importlib.util
|
|
12
|
+
import json
|
|
13
|
+
import sys
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
from ruamel.yaml import YAML
|
|
18
|
+
|
|
19
|
+
SCRIPT = Path(__file__).resolve().parents[1] / "sprint_plan.py"
|
|
20
|
+
TEMPLATE = Path(__file__).resolve().parents[2] / "sprint-status-template.yaml"
|
|
21
|
+
|
|
22
|
+
spec = importlib.util.spec_from_file_location("sprint_plan", SCRIPT)
|
|
23
|
+
mod = importlib.util.module_from_spec(spec)
|
|
24
|
+
spec.loader.exec_module(mod)
|
|
25
|
+
|
|
26
|
+
EPICS_FIXTURE = """\
|
|
27
|
+
# Project Epics
|
|
28
|
+
|
|
29
|
+
## Epic 1: Foundation
|
|
30
|
+
Some prose.
|
|
31
|
+
|
|
32
|
+
### Story 1.1: User Authentication
|
|
33
|
+
Acceptance criteria...
|
|
34
|
+
|
|
35
|
+
### Story 1.2: Account Management
|
|
36
|
+
|
|
37
|
+
## Epic 2: Chat
|
|
38
|
+
### Story 2.1: Personality System
|
|
39
|
+
### Story 2.6a: Split Story, With Punctuation!
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
DATE = "08-01-2026 14:30"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def run_generate(tmp_path, epics_text=EPICS_FIXTURE, existing=None, stories=(), extra=()):
|
|
46
|
+
epic_file = tmp_path / "epics.md"
|
|
47
|
+
epic_file.write_text(epics_text, encoding="utf-8")
|
|
48
|
+
status_file = tmp_path / "impl" / "sprint-status.yaml"
|
|
49
|
+
if existing is not None:
|
|
50
|
+
status_file.parent.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
status_file.write_text(existing, encoding="utf-8")
|
|
52
|
+
stories_dir = tmp_path / "impl"
|
|
53
|
+
stories_dir.mkdir(parents=True, exist_ok=True)
|
|
54
|
+
for name in stories:
|
|
55
|
+
(stories_dir / f"{name}.md").write_text("story", encoding="utf-8")
|
|
56
|
+
argv = [
|
|
57
|
+
"generate", "--epic-file", str(epic_file), "--status-file", str(status_file),
|
|
58
|
+
"--stories-dir", str(stories_dir), "--project", "My Project", "--date", DATE,
|
|
59
|
+
*extra,
|
|
60
|
+
]
|
|
61
|
+
mod.main(argv)
|
|
62
|
+
return status_file
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def load(status_file):
|
|
66
|
+
yaml = YAML()
|
|
67
|
+
with open(status_file, encoding="utf-8") as fh:
|
|
68
|
+
return yaml.load(fh)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def out_json(capsys):
|
|
72
|
+
return json.loads(capsys.readouterr().out)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_fresh_generate_orders_and_defaults(tmp_path, capsys):
|
|
76
|
+
status_file = run_generate(tmp_path)
|
|
77
|
+
result = out_json(capsys)
|
|
78
|
+
data = load(status_file)
|
|
79
|
+
keys = list(data["development_status"].keys())
|
|
80
|
+
assert keys == [
|
|
81
|
+
"epic-1", "1-1-user-authentication", "1-2-account-management", "epic-1-retrospective",
|
|
82
|
+
"epic-2", "2-1-personality-system", "2-6a-split-story-with-punctuation", "epic-2-retrospective",
|
|
83
|
+
]
|
|
84
|
+
assert data["development_status"]["epic-1"] == "backlog"
|
|
85
|
+
assert data["development_status"]["1-1-user-authentication"] == "backlog"
|
|
86
|
+
assert data["development_status"]["epic-1-retrospective"] == "optional"
|
|
87
|
+
assert data["project"] == "My Project"
|
|
88
|
+
assert data["generated"] == DATE and data["last_updated"] == DATE
|
|
89
|
+
assert result["ok"] and result["epics"] == 2 and result["stories"] == 4
|
|
90
|
+
text = status_file.read_text(encoding="utf-8")
|
|
91
|
+
assert "STATUS DEFINITIONS" in text
|
|
92
|
+
assert "\n\n epic-2:" in text # blank line between epic groups
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_header_comment_matches_template():
|
|
96
|
+
"""The template's STATUS DEFINITIONS block and the script's HEADER_COMMENT
|
|
97
|
+
are two copies of one contract; this pins them together."""
|
|
98
|
+
lines = TEMPLATE.read_text(encoding="utf-8").splitlines()
|
|
99
|
+
start = lines.index("# STATUS DEFINITIONS:")
|
|
100
|
+
block = []
|
|
101
|
+
for line in lines[start:]:
|
|
102
|
+
if not line.startswith("#"):
|
|
103
|
+
break
|
|
104
|
+
block.append(line[2:] if line.startswith("# ") else line[1:])
|
|
105
|
+
assert "\n".join(block) + "\n" == mod.HEADER_COMMENT
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
EXISTING = """\
|
|
109
|
+
generated: 01-01-2026 09:00
|
|
110
|
+
last_updated: 01-01-2026 09:00
|
|
111
|
+
project: My Project
|
|
112
|
+
project_key: NOKEY
|
|
113
|
+
tracking_system: file-system
|
|
114
|
+
story_location: impl
|
|
115
|
+
|
|
116
|
+
development_status:
|
|
117
|
+
epic-1: in-progress
|
|
118
|
+
1-1-user-authentication: done
|
|
119
|
+
1-2-account-management: backlog
|
|
120
|
+
epic-1-retrospective: optional
|
|
121
|
+
9-9-ghost-story: done
|
|
122
|
+
|
|
123
|
+
action_items:
|
|
124
|
+
- epic: 1
|
|
125
|
+
action: "Add error-handling review; watch: quotes, commas"
|
|
126
|
+
owner: "Charlie"
|
|
127
|
+
status: open
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def test_merge_preserves_and_never_downgrades(tmp_path, capsys):
|
|
132
|
+
status_file = run_generate(tmp_path, existing=EXISTING)
|
|
133
|
+
result = out_json(capsys)
|
|
134
|
+
data = load(status_file)
|
|
135
|
+
assert data["development_status"]["epic-1"] == "in-progress"
|
|
136
|
+
assert data["development_status"]["1-1-user-authentication"] == "done"
|
|
137
|
+
assert data["generated"] == "01-01-2026 09:00"
|
|
138
|
+
assert data["last_updated"] == DATE
|
|
139
|
+
assert result["dropped_orphans"] == [{"key": "9-9-ghost-story", "status": "done"}]
|
|
140
|
+
assert "9-9-ghost-story" not in data["development_status"]
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def test_legacy_statuses_merge_by_meaning_not_reset(tmp_path, capsys):
|
|
144
|
+
existing = (EXISTING
|
|
145
|
+
.replace("1-2-account-management: backlog", "1-2-account-management: drafted")
|
|
146
|
+
.replace("epic-1: in-progress", "epic-1: contexted"))
|
|
147
|
+
status_file = run_generate(tmp_path, existing=existing)
|
|
148
|
+
result = out_json(capsys)
|
|
149
|
+
data = load(status_file)
|
|
150
|
+
assert data["development_status"]["1-2-account-management"] == "ready-for-dev"
|
|
151
|
+
assert data["development_status"]["epic-1"] == "in-progress"
|
|
152
|
+
assert {"key": "1-2-account-management", "from": "drafted", "to": "ready-for-dev"} in result["legacy_mapped"]
|
|
153
|
+
assert not any("illegal" in w for w in result["warnings"])
|
|
154
|
+
assert result["illegal"] == []
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_metadata_preserved_when_flags_omitted(tmp_path, capsys):
|
|
158
|
+
existing = (EXISTING
|
|
159
|
+
.replace("project_key: NOKEY", "project_key: JIRA-PROJ")
|
|
160
|
+
.replace("tracking_system: file-system", "tracking_system: jira")
|
|
161
|
+
.replace("story_location: impl", "story_location: /custom/stories"))
|
|
162
|
+
status_file = run_generate(tmp_path, existing=existing)
|
|
163
|
+
out_json(capsys)
|
|
164
|
+
data = load(status_file)
|
|
165
|
+
assert data["project_key"] == "JIRA-PROJ"
|
|
166
|
+
assert data["tracking_system"] == "jira"
|
|
167
|
+
assert data["story_location"] == "/custom/stories"
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_unknown_keys_and_comments_survive_regenerate(tmp_path, capsys):
|
|
171
|
+
existing = EXISTING + "\n# my own note\nsprint_goal: Ship the beta\n"
|
|
172
|
+
status_file = run_generate(tmp_path, existing=existing)
|
|
173
|
+
out_json(capsys)
|
|
174
|
+
data = load(status_file)
|
|
175
|
+
assert data["sprint_goal"] == "Ship the beta"
|
|
176
|
+
assert "# my own note" in status_file.read_text(encoding="utf-8")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_fresh_rebuild_ignores_existing_statuses(tmp_path, capsys):
|
|
180
|
+
status_file = run_generate(tmp_path, existing=EXISTING, extra=("--fresh",))
|
|
181
|
+
result = out_json(capsys)
|
|
182
|
+
data = load(status_file)
|
|
183
|
+
assert data["development_status"]["1-1-user-authentication"] == "backlog"
|
|
184
|
+
assert data["development_status"]["epic-1"] == "backlog"
|
|
185
|
+
assert result["fresh"] is True
|
|
186
|
+
# action_items are retro history, not tracking state — carried even on --fresh
|
|
187
|
+
assert data["action_items"][0]["status"] == "open"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def test_set_applies_explicit_statuses_even_downgrades(tmp_path, capsys):
|
|
191
|
+
status_file = run_generate(
|
|
192
|
+
tmp_path, existing=EXISTING,
|
|
193
|
+
extra=("--fresh", "--set", "1-1-user-authentication=in-progress", "--set", "epic-1=in-progress"),
|
|
194
|
+
)
|
|
195
|
+
result = out_json(capsys)
|
|
196
|
+
data = load(status_file)
|
|
197
|
+
assert data["development_status"]["1-1-user-authentication"] == "in-progress"
|
|
198
|
+
assert data["development_status"]["epic-1"] == "in-progress"
|
|
199
|
+
assert "1-1-user-authentication=in-progress" in result["explicit_set"]
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def test_set_rejects_unknown_key_and_illegal_status(tmp_path, capsys):
|
|
203
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
204
|
+
run_generate(tmp_path, extra=("--set", "9-9-nope=done"))
|
|
205
|
+
assert excinfo.value.code == 1
|
|
206
|
+
assert out_json(capsys)["ok"] is False
|
|
207
|
+
with pytest.raises(SystemExit):
|
|
208
|
+
run_generate(tmp_path, extra=("--set", "epic-1=review"))
|
|
209
|
+
assert out_json(capsys)["ok"] is False
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def test_action_items_carried_verbatim(tmp_path):
|
|
213
|
+
status_file = run_generate(tmp_path, existing=EXISTING)
|
|
214
|
+
data = load(status_file)
|
|
215
|
+
assert data["action_items"][0]["action"] == "Add error-handling review; watch: quotes, commas"
|
|
216
|
+
assert data["action_items"][0]["status"] == "open"
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def test_story_file_on_disk_floors_ready_for_dev(tmp_path, capsys):
|
|
220
|
+
status_file = run_generate(tmp_path, stories=["1-2-account-management"])
|
|
221
|
+
result = out_json(capsys)
|
|
222
|
+
data = load(status_file)
|
|
223
|
+
assert data["development_status"]["1-2-account-management"] == "ready-for-dev"
|
|
224
|
+
assert data["development_status"]["1-1-user-authentication"] == "backlog"
|
|
225
|
+
assert result["upgraded_from_disk"] == ["1-2-account-management"]
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def test_story_file_never_downgrades_done(tmp_path):
|
|
229
|
+
status_file = run_generate(tmp_path, existing=EXISTING, stories=["1-1-user-authentication"])
|
|
230
|
+
data = load(status_file)
|
|
231
|
+
assert data["development_status"]["1-1-user-authentication"] == "done"
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def test_illegal_existing_status_warns_and_resets(tmp_path, capsys):
|
|
235
|
+
existing = EXISTING.replace("1-2-account-management: backlog", "1-2-account-management: shipped")
|
|
236
|
+
status_file = run_generate(tmp_path, existing=existing)
|
|
237
|
+
result = out_json(capsys)
|
|
238
|
+
data = load(status_file)
|
|
239
|
+
assert data["development_status"]["1-2-account-management"] == "backlog"
|
|
240
|
+
assert any("illegal status 'shipped'" in w for w in result["warnings"])
|
|
241
|
+
assert {"key": "1-2-account-management", "status": "shipped"} in result["illegal"]
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def test_fenced_code_blocks_are_not_parsed(tmp_path, capsys):
|
|
245
|
+
text = EPICS_FIXTURE + "\n```\n## Epic 9: Example Format\n### Story 9.1: Sample\n```\n"
|
|
246
|
+
status_file = run_generate(tmp_path, epics_text=text)
|
|
247
|
+
result = out_json(capsys)
|
|
248
|
+
data = load(status_file)
|
|
249
|
+
assert "epic-9" not in data["development_status"]
|
|
250
|
+
assert result["epics"] == 2
|
|
251
|
+
assert not any("Epic 9" in w for w in result["warnings"])
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def test_non_ascii_titles_keep_distinct_keys(tmp_path, capsys):
|
|
255
|
+
text = "## Epic 1: 基础\n### Story 1.1: 用户认证\n### Story 1.2: 账户管理\n"
|
|
256
|
+
status_file = run_generate(tmp_path, epics_text=text)
|
|
257
|
+
out_json(capsys)
|
|
258
|
+
keys = list(load(status_file)["development_status"].keys())
|
|
259
|
+
assert "1-1-用户认证" in keys and "1-2-账户管理" in keys
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def test_suspect_heading_is_reported(tmp_path, capsys):
|
|
263
|
+
text = EPICS_FIXTURE + "\n### Story Two point one: Bad Format\n"
|
|
264
|
+
run_generate(tmp_path, epics_text=text)
|
|
265
|
+
result = out_json(capsys)
|
|
266
|
+
assert any("unparsed Epic/Story-like heading" in w for w in result["warnings"])
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def test_dry_run_writes_nothing_and_reports_drift(tmp_path, capsys):
|
|
270
|
+
epic_file = tmp_path / "epics.md"
|
|
271
|
+
epic_file.write_text(EPICS_FIXTURE, encoding="utf-8")
|
|
272
|
+
status_file = tmp_path / "sprint-status.yaml"
|
|
273
|
+
status_file.write_text(EXISTING, encoding="utf-8")
|
|
274
|
+
original = status_file.read_bytes()
|
|
275
|
+
mod.main([
|
|
276
|
+
"generate", "--epic-file", str(epic_file), "--status-file", str(status_file),
|
|
277
|
+
"--stories-dir", str(tmp_path), "--project", "P", "--date", DATE, "--dry-run",
|
|
278
|
+
])
|
|
279
|
+
result = out_json(capsys)
|
|
280
|
+
assert result["dry_run"] is True and result["ok"] is True
|
|
281
|
+
assert result["in_sync"] is False
|
|
282
|
+
assert "epic-2" in result["new_entries"]
|
|
283
|
+
assert result["dropped_orphans"] == [{"key": "9-9-ghost-story", "status": "done"}]
|
|
284
|
+
assert status_file.read_bytes() == original
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def test_dry_run_in_sync_after_generate(tmp_path, capsys):
|
|
288
|
+
status_file = run_generate(tmp_path)
|
|
289
|
+
capsys.readouterr()
|
|
290
|
+
mod.main([
|
|
291
|
+
"generate", "--epic-file", str(tmp_path / "epics.md"), "--status-file", str(status_file),
|
|
292
|
+
"--stories-dir", str(tmp_path / "impl"), "--project", "My Project", "--date", DATE,
|
|
293
|
+
"--dry-run",
|
|
294
|
+
])
|
|
295
|
+
result = out_json(capsys)
|
|
296
|
+
assert result["in_sync"] is True
|
|
297
|
+
assert result["new_entries"] == [] and result["dropped_orphans"] == [] and result["illegal"] == []
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def test_no_epics_fails_with_json(tmp_path, capsys):
|
|
301
|
+
epic_file = tmp_path / "notes.md"
|
|
302
|
+
epic_file.write_text("just prose, no epics", encoding="utf-8")
|
|
303
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
304
|
+
mod.main([
|
|
305
|
+
"generate", "--epic-file", str(epic_file), "--status-file", str(tmp_path / "s.yaml"),
|
|
306
|
+
"--stories-dir", str(tmp_path), "--project", "P", "--date", DATE,
|
|
307
|
+
])
|
|
308
|
+
assert excinfo.value.code == 1
|
|
309
|
+
assert out_json(capsys)["ok"] is False
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_non_mapping_yaml_fails_with_json(tmp_path, capsys):
|
|
313
|
+
epic_file = tmp_path / "epics.md"
|
|
314
|
+
epic_file.write_text(EPICS_FIXTURE, encoding="utf-8")
|
|
315
|
+
status_file = tmp_path / "sprint-status.yaml"
|
|
316
|
+
status_file.write_text("- just\n- a\n- list\n", encoding="utf-8")
|
|
317
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
318
|
+
mod.main([
|
|
319
|
+
"generate", "--epic-file", str(epic_file), "--status-file", str(status_file),
|
|
320
|
+
"--stories-dir", str(tmp_path), "--project", "P", "--date", DATE,
|
|
321
|
+
])
|
|
322
|
+
assert excinfo.value.code == 1
|
|
323
|
+
assert "not a mapping" in out_json(capsys)["error"]
|
|
324
|
+
with pytest.raises(SystemExit):
|
|
325
|
+
mod.main(["status", "--status-file", str(status_file)])
|
|
326
|
+
assert "not a mapping" in out_json(capsys)["error"]
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def test_argument_errors_emit_json(capsys):
|
|
330
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
331
|
+
mod.main(["generate"])
|
|
332
|
+
assert excinfo.value.code == 2
|
|
333
|
+
assert out_json(capsys)["ok"] is False
|
|
334
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
335
|
+
mod.main(["-h"])
|
|
336
|
+
assert excinfo.value.code == 2
|
|
337
|
+
assert out_json(capsys)["ok"] is False
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
STATUS_FIXTURE = """\
|
|
341
|
+
generated: 01-01-2026 09:00
|
|
342
|
+
last_updated: 07-30-2026 09:00
|
|
343
|
+
project: My Project
|
|
344
|
+
project_key: NOKEY
|
|
345
|
+
tracking_system: file-system
|
|
346
|
+
story_location: impl
|
|
347
|
+
|
|
348
|
+
development_status:
|
|
349
|
+
epic-1: in-progress
|
|
350
|
+
1-1-user-authentication: done
|
|
351
|
+
1-2-account-management: drafted
|
|
352
|
+
epic-1-retrospective: optional
|
|
353
|
+
epic-2: backlog
|
|
354
|
+
2-1-personality-system: backlog
|
|
355
|
+
epic-2-retrospective: optional
|
|
356
|
+
|
|
357
|
+
action_items:
|
|
358
|
+
- epic: 1
|
|
359
|
+
action: "Tighten error handling"
|
|
360
|
+
owner: "Charlie"
|
|
361
|
+
status: open
|
|
362
|
+
- epic: 1
|
|
363
|
+
action: "Old item"
|
|
364
|
+
owner: "Charlie"
|
|
365
|
+
status: done
|
|
366
|
+
"""
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def run_status(tmp_path, capsys, fixture=STATUS_FIXTURE, extra=()):
|
|
370
|
+
status_file = tmp_path / "sprint-status.yaml"
|
|
371
|
+
status_file.write_text(fixture, encoding="utf-8")
|
|
372
|
+
mod.main(["status", "--status-file", str(status_file), "--date", DATE, *extra])
|
|
373
|
+
return json.loads(capsys.readouterr().out)
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def test_status_counts_and_recommendation(tmp_path, capsys):
|
|
377
|
+
result = run_status(tmp_path, capsys)
|
|
378
|
+
assert result["stories"] == {"done": 1, "ready-for-dev": 1, "backlog": 1}
|
|
379
|
+
assert result["epics"] == {"in-progress": 1, "backlog": 1}
|
|
380
|
+
assert result["retrospectives"] == {"optional": 2}
|
|
381
|
+
assert result["recommendation"]["skill"] == "bmad-build"
|
|
382
|
+
assert result["recommendation"]["story_key"] == "1-2-account-management"
|
|
383
|
+
assert result["all_done"] is False
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def test_status_maps_legacy_values(tmp_path, capsys):
|
|
387
|
+
result = run_status(tmp_path, capsys)
|
|
388
|
+
assert {"key": "1-2-account-management", "from": "drafted", "to": "ready-for-dev"} in result["legacy_mapped"]
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def test_status_open_action_items(tmp_path, capsys):
|
|
392
|
+
result = run_status(tmp_path, capsys)
|
|
393
|
+
assert len(result["open_action_items"]) == 1
|
|
394
|
+
assert result["open_action_items"][0]["action"] == "Tighten error handling"
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def test_status_malformed_action_items_are_flagged_not_dropped(tmp_path, capsys):
|
|
398
|
+
fixture = STATUS_FIXTURE + " - \"just a string\"\n - epic: 2\n action: \"No status\"\n"
|
|
399
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
400
|
+
assert any("not a mapping" in w for w in result["warnings"])
|
|
401
|
+
assert any("missing or unknown status" in w for w in result["warnings"])
|
|
402
|
+
assert len(result["open_action_items"]) == 1
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def test_status_review_beats_ready(tmp_path, capsys):
|
|
406
|
+
fixture = STATUS_FIXTURE.replace("2-1-personality-system: backlog", "2-1-personality-system: review")
|
|
407
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
408
|
+
assert result["recommendation"]["skill"] == "bmad-code-review"
|
|
409
|
+
assert result["recommendation"]["story_key"] == "2-1-personality-system"
|
|
410
|
+
assert any("review" in r for r in result["risks"])
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def test_status_in_progress_beats_all(tmp_path, capsys):
|
|
414
|
+
fixture = STATUS_FIXTURE.replace("2-1-personality-system: backlog", "2-1-personality-system: in-progress")
|
|
415
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
416
|
+
assert result["recommendation"]["skill"] == "bmad-build"
|
|
417
|
+
assert result["recommendation"]["story_key"] == "2-1-personality-system"
|
|
418
|
+
assert result["recommendation"]["reason"] == "resume the in-progress story"
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def test_status_staleness_and_orphan_risks(tmp_path, capsys):
|
|
422
|
+
fixture = (STATUS_FIXTURE
|
|
423
|
+
.replace("last_updated: 07-30-2026 09:00", "last_updated: 01-02-2026 09:00")
|
|
424
|
+
.replace(" epic-2-retrospective: optional",
|
|
425
|
+
" epic-2-retrospective: optional\n 5-1-ghost: backlog"))
|
|
426
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
427
|
+
assert any("stale" in r for r in result["risks"])
|
|
428
|
+
assert any("orphaned story '5-1-ghost'" in r for r in result["risks"])
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def test_status_unparseable_timestamp_warns_instead_of_silence(tmp_path, capsys):
|
|
432
|
+
fixture = STATUS_FIXTURE.replace("last_updated: 07-30-2026 09:00", "last_updated: whenever")
|
|
433
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
434
|
+
assert any("staleness check skipped" in w for w in result["warnings"])
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def test_status_iso_and_date_typed_stamps_do_not_crash(tmp_path, capsys):
|
|
438
|
+
fixture = (STATUS_FIXTURE
|
|
439
|
+
.replace("generated: 01-01-2026 09:00", "generated: 2026-01-01")
|
|
440
|
+
.replace("last_updated: 07-30-2026 09:00", "last_updated: 2026-01-02"))
|
|
441
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
442
|
+
assert result["ok"] is True
|
|
443
|
+
assert result["generated"] == "2026-01-01"
|
|
444
|
+
assert any("stale" in r for r in result["risks"]) # ISO stamp still parses
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def test_status_all_done_recommends_retro_then_nothing(tmp_path, capsys):
|
|
448
|
+
fixture = (STATUS_FIXTURE
|
|
449
|
+
.replace("1-2-account-management: drafted", "1-2-account-management: done")
|
|
450
|
+
.replace("2-1-personality-system: backlog", "2-1-personality-system: done"))
|
|
451
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
452
|
+
assert result["recommendation"]["skill"] == "bmad-retrospective"
|
|
453
|
+
assert "epic-1-retrospective" in result["recommendation"]["reason"]
|
|
454
|
+
fixture_done = fixture.replace("epic-1-retrospective: optional", "epic-1-retrospective: done") \
|
|
455
|
+
.replace("epic-2-retrospective: optional", "epic-2-retrospective: done")
|
|
456
|
+
result = run_status(tmp_path, capsys, fixture=fixture_done)
|
|
457
|
+
assert result["all_done"] is True and result["recommendation"] is None
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def test_status_odd_retro_key_reports_instead_of_crashing(tmp_path, capsys):
|
|
461
|
+
fixture = (STATUS_FIXTURE
|
|
462
|
+
.replace("1-2-account-management: drafted", "1-2-account-management: done")
|
|
463
|
+
.replace("2-1-personality-system: backlog", "2-1-personality-system: done")
|
|
464
|
+
.replace("epic-1-retrospective: optional", "epic-1-retrospective: done")
|
|
465
|
+
.replace("epic-2-retrospective: optional",
|
|
466
|
+
"epic-2-retrospective: done\n epic-abc-retrospective: optional"))
|
|
467
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
468
|
+
assert result["ok"] is True
|
|
469
|
+
assert {"key": "epic-abc-retrospective", "status": "optional"} in result["unrecognized"]
|
|
470
|
+
assert any("unrecognized key" in r for r in result["risks"])
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def test_status_illegal_status_reported(tmp_path, capsys):
|
|
474
|
+
fixture = STATUS_FIXTURE.replace("2-1-personality-system: backlog", "2-1-personality-system: shipped")
|
|
475
|
+
result = run_status(tmp_path, capsys, fixture=fixture)
|
|
476
|
+
assert {"key": "2-1-personality-system", "status": "shipped"} in result["illegal"]
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def test_status_missing_file_fails_json(tmp_path, capsys):
|
|
480
|
+
with pytest.raises(SystemExit) as excinfo:
|
|
481
|
+
mod.main(["status", "--status-file", str(tmp_path / "nope.yaml")])
|
|
482
|
+
assert excinfo.value.code == 1
|
|
483
|
+
assert json.loads(capsys.readouterr().out)["ok"] is False
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def run_validate(tmp_path, capsys, content):
|
|
487
|
+
status_file = tmp_path / "sprint-status.yaml"
|
|
488
|
+
if content is not None:
|
|
489
|
+
status_file.write_text(content, encoding="utf-8")
|
|
490
|
+
mod.main(["validate", "--status-file", str(status_file)])
|
|
491
|
+
return json.loads(capsys.readouterr().out)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def test_validate_clean_file(tmp_path, capsys):
|
|
495
|
+
clean = STATUS_FIXTURE.replace("1-2-account-management: drafted", "1-2-account-management: backlog")
|
|
496
|
+
result = run_validate(tmp_path, capsys, clean)
|
|
497
|
+
assert result["valid"] is True and result["problems"] == []
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def test_validate_reports_problems_without_crashing(tmp_path, capsys):
|
|
501
|
+
broken = (STATUS_FIXTURE
|
|
502
|
+
.replace("2-1-personality-system: backlog", "2-1-personality-system: shipped")
|
|
503
|
+
.replace("epic-2-retrospective: optional",
|
|
504
|
+
"epic-2-retrospective: optional\n weird-key: done")
|
|
505
|
+
.replace("last_updated: 07-30-2026 09:00", "last_updated: whenever"))
|
|
506
|
+
result = run_validate(tmp_path, capsys, broken)
|
|
507
|
+
assert result["valid"] is False
|
|
508
|
+
assert any("illegal story status 'shipped'" in p for p in result["problems"])
|
|
509
|
+
assert any("unrecognized key 'weird-key'" in p for p in result["problems"])
|
|
510
|
+
assert any("'last_updated' timestamp" in p for p in result["problems"])
|
|
511
|
+
assert {"key": "1-2-account-management", "from": "drafted", "to": "ready-for-dev"} in result["legacy_mapped"]
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
def test_validate_missing_file_and_bad_yaml(tmp_path, capsys):
|
|
515
|
+
result = run_validate(tmp_path, capsys, None)
|
|
516
|
+
assert result["valid"] is False and "does not exist" in result["problems"][0]
|
|
517
|
+
result = run_validate(tmp_path, capsys, "development_status: [unclosed\n")
|
|
518
|
+
assert result["valid"] is False and "not valid YAML" in result["problems"][0]
|
|
519
|
+
result = run_validate(tmp_path, capsys, "- a\n- b\n")
|
|
520
|
+
assert result["valid"] is False and any("not a mapping" in p for p in result["problems"])
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
if __name__ == "__main__":
|
|
524
|
+
sys.exit(pytest.main([__file__, "-q"]))
|
package/src/bmm-skills/{4-implementation → plan}/bmad-sprint-planning/sprint-status-template.yaml
RENAMED
|
@@ -33,19 +33,21 @@
|
|
|
33
33
|
#
|
|
34
34
|
# WORKFLOW NOTES:
|
|
35
35
|
# ===============
|
|
36
|
-
# -
|
|
37
|
-
# -
|
|
38
|
-
# -
|
|
39
|
-
# -
|
|
36
|
+
# - Epic transitions to 'in-progress' automatically when its first story starts (via build's sprint sync)
|
|
37
|
+
# - Stories can be worked in parallel if team capacity allows
|
|
38
|
+
# - Developer typically creates the next story after the previous one is 'done' to incorporate learnings
|
|
39
|
+
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
|
40
|
+
# - Retrospective appends its action items to action_items; the status view surfaces open ones
|
|
40
41
|
|
|
41
42
|
# EXAMPLE STRUCTURE (your actual epics/stories will replace these):
|
|
43
|
+
# Timestamps use MM-DD-YYYY HH:MM.
|
|
42
44
|
|
|
43
|
-
generated: 05-06-
|
|
44
|
-
last_updated: 05-06-
|
|
45
|
+
generated: 05-06-2025 21:30
|
|
46
|
+
last_updated: 05-06-2025 21:30
|
|
45
47
|
project: My Awesome Project
|
|
46
48
|
project_key: NOKEY
|
|
47
49
|
tracking_system: file-system
|
|
48
|
-
story_location: "
|
|
50
|
+
story_location: "docs/stories"
|
|
49
51
|
|
|
50
52
|
development_status:
|
|
51
53
|
epic-1: backlog
|
|
@@ -87,4 +87,4 @@ Outcomes, in order:
|
|
|
87
87
|
- **Key-screen mocks rendered.** Key-screens tool → `.working/` for surfaces where layout drives behavior or anchors visual language.
|
|
88
88
|
- **Mock coverage confirmed.** Walk every IA surface; classify *mocked* vs *spine-only*. Ask: *"These will be built from spine tables alone — any need a visual reference?"* Render more if named; log spine-only choices.
|
|
89
89
|
- **Layout extracted, artifacts promoted.** Distill subagent re-reads each `.working/` and `imports/` artifact; lifts visual decisions into DESIGN.md and behavioral decisions into EXPERIENCE.md. Promote `.working/` keepers to `mockups/` (HTML) or `wireframes/` (Excalidraw); imports stay. Inline relative links at relevant spine sections; state spines-win-on-conflict once.
|
|
90
|
-
- **Polished, handed off, closed.** Apply `{workflow.doc_standards}` in order. Execute `{workflow.external_handoffs}`; surface URLs. Set both files' `status: final`, `updated: {date}`. Log finalization via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type event --text "spines finalized"`. Share paths. Common next: `bmad-architecture`, `bmad-create-epics-and-stories`, `bmad-
|
|
90
|
+
- **Polished, handed off, closed.** Apply `{workflow.doc_standards}` in order. Execute `{workflow.external_handoffs}`; surface URLs. Set both files' `status: final`, `updated: {date}`. Log finalization via `uv run {project-root}/_bmad/scripts/memlog.py append --workspace {doc_workspace} --type event --text "spines finalized"`. Share paths. Common next: `bmad-architecture`, `bmad-create-epics-and-stories`, `bmad-build`. Run `{workflow.on_complete}`.
|
|
@@ -6,4 +6,4 @@ Each variation: header (name + one-line emotional register), token chips for eve
|
|
|
6
6
|
|
|
7
7
|
Inline CSS only, system font stack, no JS, no network. Document concrete hex values in `<style>` comments per variation so the user can lift them if they pick that theme. The spine itself stays semantic.
|
|
8
8
|
|
|
9
|
-
Return to the parent: file path, one-line per variation, mode coverage. Do not dump HTML into the parent context. If interactive, open the file with `
|
|
9
|
+
Return to the parent: file path, one-line per variation, mode coverage. Do not dump HTML into the parent context. If interactive, open the file with the platform opener — `open "PATH"` on macOS, `xdg-open` on Linux, `start ""` on Windows, path always double-quoted. On failure, give the user the path instead.
|
|
@@ -78,9 +78,11 @@ creative_tools = [
|
|
|
78
78
|
# Polish passes applied to DESIGN.md and EXPERIENCE.md at finalize.
|
|
79
79
|
# Entries: `skill:NAME`, `file:PATH`, or plain text directive.
|
|
80
80
|
# Suggested order: structural → content/voice → prose mechanics.
|
|
81
|
+
# The default entry runs bmad-review's two editorial lenses in order:
|
|
82
|
+
# structure, then prose on top of the structure findings. The `lenses=` suffix
|
|
83
|
+
# names them; drop it to let bmad-review pick what fits the content.
|
|
81
84
|
doc_standards = [
|
|
82
|
-
"skill:bmad-
|
|
83
|
-
"skill:bmad-editorial-review-prose",
|
|
85
|
+
"skill:bmad-review lenses=structure,prose",
|
|
84
86
|
]
|
|
85
87
|
|
|
86
88
|
# Information retrieval registry. Consulted on demand when the conversation
|
|
@@ -16,4 +16,4 @@ Every renderer writes to `{doc_workspace}/.working/` with a descriptive filename
|
|
|
16
16
|
|
|
17
17
|
The parent passes the subagent: current `.memlog.md`, relevant prior `.working/` captures, the user's stated intent for this pass, the output path. The subagent writes its artifact under `.working/` and returns ONLY a compact summary (file path, one line per variant, mode coverage). Parent never holds the full payload.
|
|
18
18
|
|
|
19
|
-
For HTML, open in browser when interactive
|
|
19
|
+
For HTML, open in the browser when interactive with the platform opener — `open "PATH"` on macOS, `xdg-open` on Linux, `start ""` on Windows, path always double-quoted. On failure, give the user the path instead. Skip in headless.
|
|
@@ -69,7 +69,7 @@ Under Validate intent, after every reviewer returns, render one consolidated rep
|
|
|
69
69
|
2. Fill `{workflow.validation_report_template}`. No overall grade — the per-category verdicts and severity counts already say what's true. Synthesis paragraph lifts the rubric's overall verdict; add a second if extra reviewers shift the picture. One section per rubric category (open if thin / broken), one per extra reviewer (closed, adversarial voice preserved).
|
|
70
70
|
3. Write `{doc_workspace}/validation-report.html`.
|
|
71
71
|
4. Write the Markdown twin `{doc_workspace}/validation-report.md` — same content grouped by severity.
|
|
72
|
-
5. Open HTML
|
|
72
|
+
5. Open HTML with the platform opener — `open "{doc_workspace}/validation-report.html"` on macOS, `xdg-open` on Linux, `start ""` on Windows, path always double-quoted. On failure, give the user the path instead. Skip headless.
|
|
73
73
|
|
|
74
74
|
Re-running overwrites the consolidated report; individual `review-*.md` files persist.
|
|
75
75
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bmad-build
|
|
3
|
+
description: 'Implements any user intent, requirement, story, bug fix or change request by producing clean working code artifacts that follow the project''s existing architecture, patterns and conventions. Use when the user wants to build, fix, tweak, refactor, add or modify any code, component or feature.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Run the following command exactly once without changing the current working directory. Replace `{project-root}` with the absolute path to the project root and `{skill-root}` with the absolute path to this skill's directory:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv run --no-cache "{project-root}/_bmad/scripts/render_skill.py" --project-root "{project-root}" --skill "{skill-root}"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
- On success, read and follow the one absolute `workflow.md` instruction printed to stdout.
|
|
13
|
+
- On failure (including `uv` being unavailable), report the command output and HALT. Do not run any workflow source directly.
|
package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/compile-epic-context.md
RENAMED
|
@@ -52,7 +52,7 @@ Use these headings:
|
|
|
52
52
|
- **No full copies.** Never quote source documents, section numbers, or paste large blocks verbatim. Always distill.
|
|
53
53
|
- **No story-level details.** The story list is for orientation only. Individual story specs handle the details.
|
|
54
54
|
- **Nothing derivable from the codebase.** Don't document what a developer can learn by reading the code.
|
|
55
|
-
- **Be concise and actionable.** Target 800–1500 tokens total. This file loads into
|
|
55
|
+
- **Be concise and actionable.** Target 800–1500 tokens total. This file loads into build's context alongside other material.
|
|
56
56
|
- **Never hallucinate content.** If source material doesn't say something, don't invent it.
|
|
57
57
|
- **Omit empty sections entirely**, except Goal and Stories, which are always required.
|
|
58
58
|
|