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.
Files changed (352) hide show
  1. package/.claude-plugin/marketplace.json +30 -57
  2. package/README.md +49 -82
  3. package/README_CN.md +10 -10
  4. package/README_VN.md +11 -11
  5. package/bmad-modules.yaml +43 -39
  6. package/package.json +7 -3
  7. package/removals.txt +17 -0
  8. package/src/bmm-skills/{1-analysis → agents}/bmad-agent-analyst/SKILL.md +1 -1
  9. package/src/bmm-skills/{1-analysis → agents}/bmad-agent-analyst/customize.toml +22 -7
  10. package/src/bmm-skills/{3-solutioning → agents}/bmad-agent-architect/SKILL.md +1 -1
  11. package/src/bmm-skills/{3-solutioning → agents}/bmad-agent-architect/customize.toml +2 -2
  12. package/src/bmm-skills/{4-implementation → agents}/bmad-agent-dev/SKILL.md +1 -1
  13. package/src/bmm-skills/{4-implementation → agents}/bmad-agent-dev/customize.toml +7 -14
  14. package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-pm/SKILL.md +1 -1
  15. package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-pm/customize.toml +2 -2
  16. package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-ux-designer/SKILL.md +1 -1
  17. package/src/bmm-skills/module-help.csv +14 -26
  18. package/src/bmm-skills/module.yaml +5 -15
  19. package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/SKILL.md +3 -3
  20. package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/customize.toml +4 -2
  21. package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/SKILL.md +1 -1
  22. package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-04-final-validation.md +1 -1
  23. package/src/bmm-skills/plan/bmad-generate-project-context/SKILL.md +10 -0
  24. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/SKILL.md +3 -1
  25. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/prd-template.md +1 -1
  26. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/customize.toml +5 -3
  27. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/references/validate.md +3 -3
  28. package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/SKILL.md +1 -1
  29. package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/bmad-manifest.json +1 -1
  30. package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/verdict.md +1 -1
  31. package/src/bmm-skills/{1-analysis → plan}/bmad-product-brief/SKILL.md +1 -1
  32. package/src/bmm-skills/{1-analysis → plan}/bmad-product-brief/customize.toml +5 -3
  33. package/src/bmm-skills/plan/bmad-project-context/SKILL.md +110 -0
  34. package/src/bmm-skills/plan/bmad-project-context/customize.toml +24 -0
  35. package/src/bmm-skills/plan/bmad-project-context/references/best-practices.md +65 -0
  36. package/src/bmm-skills/plan/bmad-project-context/references/template.md +55 -0
  37. package/src/{core-skills → bmm-skills/plan}/bmad-spec/SKILL.md +18 -3
  38. package/src/{core-skills → bmm-skills/plan}/bmad-spec/assets/spec-template.md +1 -1
  39. package/src/bmm-skills/plan/bmad-spec/assets/stories-schema.md +44 -0
  40. package/src/{core-skills → bmm-skills/plan}/bmad-spec/customize.toml +3 -4
  41. package/src/bmm-skills/plan/bmad-sprint-planning/SKILL.md +62 -0
  42. package/src/bmm-skills/plan/bmad-sprint-planning/references/fix-sprint-status.md +30 -0
  43. package/src/bmm-skills/plan/bmad-sprint-planning/references/generate-tracking.md +25 -0
  44. package/src/bmm-skills/plan/bmad-sprint-planning/references/readiness-gate.md +20 -0
  45. package/src/bmm-skills/plan/bmad-sprint-planning/references/status-view.md +14 -0
  46. package/src/bmm-skills/plan/bmad-sprint-planning/references/validate.md +10 -0
  47. package/src/bmm-skills/plan/bmad-sprint-planning/scripts/__pycache__/sprint_plan.cpython-311.pyc +0 -0
  48. package/src/bmm-skills/plan/bmad-sprint-planning/scripts/sprint_plan.py +697 -0
  49. package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-311-pytest-9.1.1.pyc +0 -0
  50. package/src/bmm-skills/plan/bmad-sprint-planning/scripts/tests/test_sprint_plan.py +524 -0
  51. package/src/bmm-skills/{4-implementation → plan}/bmad-sprint-planning/sprint-status-template.yaml +9 -7
  52. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/SKILL.md +1 -1
  53. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/color-themes.md +1 -1
  54. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/customize.toml +4 -2
  55. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/creative-tools.md +1 -1
  56. package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/validate.md +1 -1
  57. package/src/bmm-skills/ship/bmad-build/SKILL.md +13 -0
  58. package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/compile-epic-context.md +1 -1
  59. package/src/bmm-skills/ship/bmad-build/customize.toml +164 -0
  60. package/src/bmm-skills/ship/bmad-build/references/deletion-check.md +14 -0
  61. package/src/bmm-skills/ship/bmad-build/review-prompts/edge-case-hunter.md +88 -0
  62. package/src/bmm-skills/ship/bmad-build/review-prompts/verification-gap.md +113 -0
  63. package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-01-clarify-and-route.md +20 -19
  64. package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-02-plan.md +5 -9
  65. package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-03-implement.md +10 -6
  66. package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-04-review.md +9 -15
  67. package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/step-05-present.md +10 -13
  68. package/src/bmm-skills/ship/bmad-build/step-oneshot.md +77 -0
  69. package/src/bmm-skills/ship/bmad-build/sync-sprint-status.md +19 -0
  70. package/src/bmm-skills/ship/bmad-build/workflow.md +84 -0
  71. package/src/bmm-skills/ship/bmad-build-auto/SKILL.md +13 -0
  72. package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/compile-epic-context.md +1 -1
  73. package/src/bmm-skills/ship/bmad-build-auto/customize.toml +121 -0
  74. 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
  75. package/src/{core-skills/bmad-review-verification-gap/SKILL.md → bmm-skills/ship/bmad-build-auto/review-prompts/verification-gap.md} +15 -8
  76. package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/spec-template.md +2 -1
  77. package/src/bmm-skills/ship/bmad-build-auto/step-01-clarify-and-route.md +83 -0
  78. package/src/bmm-skills/ship/bmad-build-auto/step-02-plan.md +27 -0
  79. package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/step-03-implement.md +6 -4
  80. package/src/bmm-skills/{4-implementation/bmad-dev-auto → ship/bmad-build-auto}/step-04-review.md +26 -25
  81. package/src/bmm-skills/ship/bmad-build-auto/workflow.md +104 -0
  82. package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/SKILL.md +1 -1
  83. package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-05-wrapup.md +1 -1
  84. package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/SKILL.md +1 -1
  85. package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/customize.toml +37 -17
  86. package/src/bmm-skills/ship/bmad-code-review/references/deletion-check.md +14 -0
  87. package/src/bmm-skills/ship/bmad-code-review/review-prompts/edge-case-hunter.md +88 -0
  88. package/src/bmm-skills/ship/bmad-code-review/review-prompts/verification-gap.md +113 -0
  89. package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-01-gather-context.md +7 -4
  90. package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-02-review.md +1 -1
  91. package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-04-present.md +1 -1
  92. package/src/bmm-skills/{4-implementation → ship}/bmad-correct-course/SKILL.md +7 -8
  93. package/src/bmm-skills/{4-implementation → ship}/bmad-qa-generate-e2e-tests/SKILL.md +2 -2
  94. package/src/bmm-skills/ship/bmad-retrospective/SKILL.md +94 -0
  95. package/src/bmm-skills/{4-implementation → ship}/bmad-retrospective/customize.toml +2 -2
  96. package/src/bmm-skills/ship/bmad-retrospective/references/acceptance-verdict.md +55 -0
  97. package/src/bmm-skills/ship/bmad-retrospective/references/aggregate-views.md +17 -0
  98. package/src/bmm-skills/ship/bmad-retrospective/references/evidence-gathering.md +30 -0
  99. package/src/bmm-skills/ship/bmad-retrospective/references/retro-document.md +84 -0
  100. package/src/bmm-skills/ship/bmad-retrospective/references/team-discussion.md +22 -0
  101. package/src/bmm-skills/ship/bmad-retrospective/scripts/__pycache__/sprint_status.cpython-311.pyc +0 -0
  102. package/src/bmm-skills/ship/bmad-retrospective/scripts/git_evidence.py +304 -0
  103. package/src/bmm-skills/ship/bmad-retrospective/scripts/sprint_status.py +746 -0
  104. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-311-pytest-9.1.1.pyc +0 -0
  105. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-311-pytest-9.1.1.pyc +0 -0
  106. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/fixtures/sprint-status-template.yaml +71 -0
  107. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_git_evidence.py +750 -0
  108. package/src/bmm-skills/ship/bmad-retrospective/scripts/tests/test_sprint_status.py +1579 -0
  109. package/src/bmm-skills/v6-shims/README.md +28 -0
  110. package/src/bmm-skills/{3-solutioning → v6-shims}/bmad-create-architecture/SKILL.md +2 -2
  111. package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-create-prd/SKILL.md +4 -4
  112. package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/SKILL.md +5 -3
  113. package/src/bmm-skills/v6-shims/bmad-dev-auto/SKILL.md +19 -0
  114. package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/SKILL.md +5 -3
  115. package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/customize.toml +3 -0
  116. package/src/bmm-skills/v6-shims/bmad-document-project/SKILL.md +14 -0
  117. package/src/bmm-skills/v6-shims/bmad-domain-research/SKILL.md +14 -0
  118. package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-edit-prd/SKILL.md +4 -4
  119. package/src/bmm-skills/v6-shims/bmad-market-research/SKILL.md +14 -0
  120. package/src/bmm-skills/v6-shims/bmad-quick-dev/SKILL.md +19 -0
  121. package/src/bmm-skills/v6-shims/bmad-sprint-status/SKILL.md +26 -0
  122. package/src/bmm-skills/v6-shims/bmad-technical-research/SKILL.md +14 -0
  123. package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-validate-prd/SKILL.md +4 -4
  124. package/src/core-skills/bmad-advanced-elicitation/SKILL.md +26 -103
  125. package/src/core-skills/bmad-advanced-elicitation/customize.toml +54 -0
  126. package/src/core-skills/bmad-advanced-elicitation/scripts/pick_methods.py +233 -0
  127. package/src/core-skills/bmad-advanced-elicitation/scripts/tests/test_pick_methods.py +228 -0
  128. package/src/core-skills/bmad-brainstorming/SKILL.md +3 -3
  129. package/src/core-skills/bmad-brainstorming/assets/brain-selector.html +2 -0
  130. package/src/core-skills/bmad-brainstorming/references/mode-autonomous.md +1 -1
  131. package/src/core-skills/bmad-brainstorming/scripts/brain.py +36 -6
  132. package/src/core-skills/bmad-brainstorming/scripts/tests/test_brain.py +22 -0
  133. package/src/core-skills/bmad-customize/SKILL.md +2 -2
  134. package/src/core-skills/bmad-deep-recon/SKILL.md +82 -0
  135. package/src/core-skills/bmad-deep-recon/assets/research.template.md +18 -0
  136. package/src/core-skills/bmad-deep-recon/customize.toml +212 -0
  137. package/src/core-skills/bmad-deep-recon/references/draft.md +8 -0
  138. package/src/core-skills/bmad-deep-recon/references/finalize.md +11 -0
  139. package/src/core-skills/bmad-deep-recon/references/html-briefing.md +16 -0
  140. package/src/core-skills/bmad-deep-recon/references/lifecycle.md +11 -0
  141. package/src/core-skills/bmad-deep-recon/references/process.md +10 -0
  142. package/src/core-skills/bmad-deep-recon/references/run.md +73 -0
  143. package/src/core-skills/bmad-deep-recon/references/selection.md +13 -0
  144. package/src/core-skills/bmad-deep-recon/references/synthesis.md +16 -0
  145. package/src/core-skills/bmad-deep-recon/references/verification.md +29 -0
  146. package/src/core-skills/bmad-deep-recon/scripts/recon_kit.py +322 -0
  147. package/src/core-skills/bmad-deep-recon/scripts/tests/test_recon_kit.py +144 -0
  148. package/src/core-skills/bmad-deep-recon/types/academic-lit.md +19 -0
  149. package/src/core-skills/bmad-deep-recon/types/competitive.md +19 -0
  150. package/src/core-skills/bmad-deep-recon/types/domain.md +19 -0
  151. package/src/core-skills/bmad-deep-recon/types/market.md +19 -0
  152. package/src/core-skills/bmad-deep-recon/types/technical.md +19 -0
  153. package/src/core-skills/bmad-deep-recon/types/user-voice.md +19 -0
  154. package/src/core-skills/bmad-forge-idea/SKILL.md +2 -2
  155. package/src/core-skills/bmad-forge-idea/scripts/resolve_personas.py +7 -2
  156. package/src/core-skills/bmad-help/SKILL.md +3 -3
  157. package/src/core-skills/bmad-party-mode/SKILL.md +2 -2
  158. package/src/core-skills/bmad-party-mode/customize.toml +1 -1
  159. package/src/core-skills/bmad-party-mode/scripts/resolve_party.py +14 -4
  160. package/src/core-skills/bmad-review/SKILL.md +49 -0
  161. package/src/core-skills/bmad-review/customize.toml +141 -0
  162. package/src/core-skills/bmad-review/references/editorial-common.md +56 -0
  163. package/src/core-skills/bmad-review/references/lens-adversarial.md +19 -0
  164. package/src/core-skills/bmad-review/references/lens-edge-case-hunter.md +54 -0
  165. package/src/core-skills/bmad-review/references/lens-prose.md +7 -0
  166. package/src/core-skills/bmad-review/references/lens-structure.md +9 -0
  167. package/src/core-skills/bmad-review/references/lens-verification-gap.md +92 -0
  168. package/src/core-skills/bmad-review/references/structure-models.md +44 -0
  169. package/src/core-skills/bmad-review/scripts/tests/test_word_metrics.py +62 -0
  170. package/src/core-skills/bmad-review/scripts/word_metrics.py +102 -0
  171. package/src/core-skills/module-help.csv +4 -8
  172. package/src/core-skills/module.yaml +5 -0
  173. package/src/core-skills/v6-shims/README.md +25 -0
  174. package/src/core-skills/v6-shims/bmad-editorial-review/SKILL.md +6 -0
  175. package/src/core-skills/v6-shims/bmad-editorial-review/customize.toml +31 -0
  176. package/src/core-skills/v6-shims/bmad-editorial-review-prose/SKILL.md +6 -0
  177. package/src/core-skills/v6-shims/bmad-editorial-review-structure/SKILL.md +6 -0
  178. package/src/core-skills/v6-shims/bmad-review-adversarial-general/SKILL.md +6 -0
  179. package/src/core-skills/v6-shims/bmad-review-edge-case-hunter/SKILL.md +6 -0
  180. package/src/core-skills/v6-shims/bmad-review-verification-gap/SKILL.md +6 -0
  181. package/src/scripts/__pycache__/config_utils.cpython-311.pyc +0 -0
  182. package/src/scripts/config_utils.py +119 -0
  183. package/src/scripts/render_skill.py +401 -0
  184. package/src/scripts/resolve_config.py +32 -136
  185. package/src/scripts/resolve_customization.py +43 -184
  186. package/src/scripts/tests/__pycache__/test_config_utils.cpython-311.pyc +0 -0
  187. package/src/scripts/tests/__pycache__/test_resolve_config.cpython-311.pyc +0 -0
  188. package/src/scripts/tests/__pycache__/test_resolve_customization.cpython-311.pyc +0 -0
  189. package/src/scripts/tests/test_config_utils.py +85 -0
  190. package/src/scripts/tests/test_resolve_config.py +89 -0
  191. package/src/scripts/tests/test_resolve_customization.py +27 -0
  192. package/tools/installer/cli-utils.js +6 -2
  193. package/tools/installer/core/installer.js +31 -9
  194. package/tools/installer/core/manifest-generator.js +1 -1
  195. package/tools/installer/core/uv-check.js +122 -24
  196. package/tools/installer/ide/_config-driven.js +1 -1
  197. package/tools/installer/ide/platform-codes.yaml +7 -0
  198. package/tools/installer/ide/shared/path-utils.js +2 -2
  199. package/tools/installer/install-messages.yaml +3 -2
  200. package/tools/installer/modules/custom-module-manager.js +12 -6
  201. package/tools/installer/modules/external-manager.js +12 -8
  202. package/tools/installer/modules/git-env.js +47 -0
  203. package/tools/installer/modules/official-modules.js +1 -1
  204. package/tools/installer/prompts.js +41 -102
  205. package/tools/installer/ui.js +99 -22
  206. package/tools/skill-validator.md +11 -1
  207. package/tools/validate-published-implementation-model.mjs +68 -0
  208. package/tools/validate-skills.js +33 -0
  209. package/web-bundles/prd-coach/prd-template.md +1 -1
  210. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/SKILL.md +0 -76
  211. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/customize.toml +0 -81
  212. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/explain-concept.md +0 -20
  213. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/mermaid-gen.md +0 -20
  214. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/validate-doc.md +0 -19
  215. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/write-document.md +0 -20
  216. package/src/bmm-skills/1-analysis/bmad-document-project/SKILL.md +0 -62
  217. package/src/bmm-skills/1-analysis/bmad-document-project/checklist.md +0 -245
  218. package/src/bmm-skills/1-analysis/bmad-document-project/customize.toml +0 -41
  219. package/src/bmm-skills/1-analysis/bmad-document-project/documentation-requirements.csv +0 -12
  220. package/src/bmm-skills/1-analysis/bmad-document-project/instructions.md +0 -128
  221. package/src/bmm-skills/1-analysis/bmad-document-project/templates/deep-dive-template.md +0 -345
  222. package/src/bmm-skills/1-analysis/bmad-document-project/templates/index-template.md +0 -169
  223. package/src/bmm-skills/1-analysis/bmad-document-project/templates/project-overview-template.md +0 -103
  224. package/src/bmm-skills/1-analysis/bmad-document-project/templates/project-scan-report-schema.json +0 -160
  225. package/src/bmm-skills/1-analysis/bmad-document-project/templates/source-tree-template.md +0 -135
  226. package/src/bmm-skills/1-analysis/bmad-document-project/workflows/deep-dive-instructions.md +0 -300
  227. package/src/bmm-skills/1-analysis/bmad-document-project/workflows/deep-dive-workflow.md +0 -34
  228. package/src/bmm-skills/1-analysis/bmad-document-project/workflows/full-scan-instructions.md +0 -1108
  229. package/src/bmm-skills/1-analysis/bmad-document-project/workflows/full-scan-workflow.md +0 -34
  230. package/src/bmm-skills/1-analysis/research/bmad-domain-research/SKILL.md +0 -96
  231. package/src/bmm-skills/1-analysis/research/bmad-domain-research/customize.toml +0 -41
  232. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-01-init.md +0 -137
  233. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-02-domain-analysis.md +0 -229
  234. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-03-competitive-landscape.md +0 -238
  235. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-04-regulatory-focus.md +0 -206
  236. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-05-technical-trends.md +0 -234
  237. package/src/bmm-skills/1-analysis/research/bmad-domain-research/domain-steps/step-06-research-synthesis.md +0 -450
  238. package/src/bmm-skills/1-analysis/research/bmad-domain-research/research.template.md +0 -29
  239. package/src/bmm-skills/1-analysis/research/bmad-market-research/SKILL.md +0 -96
  240. package/src/bmm-skills/1-analysis/research/bmad-market-research/customize.toml +0 -41
  241. package/src/bmm-skills/1-analysis/research/bmad-market-research/research.template.md +0 -29
  242. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-01-init.md +0 -184
  243. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-02-customer-behavior.md +0 -239
  244. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-03-customer-pain-points.md +0 -251
  245. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-04-customer-decisions.md +0 -261
  246. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-05-competitive-analysis.md +0 -173
  247. package/src/bmm-skills/1-analysis/research/bmad-market-research/steps/step-06-research-completion.md +0 -484
  248. package/src/bmm-skills/1-analysis/research/bmad-technical-research/SKILL.md +0 -96
  249. package/src/bmm-skills/1-analysis/research/bmad-technical-research/customize.toml +0 -41
  250. package/src/bmm-skills/1-analysis/research/bmad-technical-research/research.template.md +0 -29
  251. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-01-init.md +0 -137
  252. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-02-technical-overview.md +0 -239
  253. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-03-integration-patterns.md +0 -248
  254. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-04-architectural-patterns.md +0 -202
  255. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-05-implementation-research.md +0 -233
  256. package/src/bmm-skills/1-analysis/research/bmad-technical-research/technical-steps/step-06-research-synthesis.md +0 -493
  257. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/SKILL.md +0 -91
  258. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/customize.toml +0 -41
  259. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-01-document-discovery.md +0 -179
  260. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-02-prd-analysis.md +0 -168
  261. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +0 -169
  262. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-04-ux-alignment.md +0 -129
  263. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-05-epic-quality-review.md +0 -241
  264. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/steps/step-06-final-assessment.md +0 -132
  265. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/templates/readiness-report-template.md +0 -4
  266. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/SKILL.md +0 -81
  267. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/customize.toml +0 -41
  268. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/project-context-template.md +0 -21
  269. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-01-discover.md +0 -186
  270. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-02-generate.md +0 -321
  271. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/steps/step-03-complete.md +0 -284
  272. package/src/bmm-skills/4-implementation/bmad-dev-auto/SKILL.md +0 -103
  273. package/src/bmm-skills/4-implementation/bmad-dev-auto/customize.toml +0 -108
  274. package/src/bmm-skills/4-implementation/bmad-dev-auto/step-01-clarify-and-route.md +0 -66
  275. package/src/bmm-skills/4-implementation/bmad-dev-auto/step-02-plan.md +0 -31
  276. package/src/bmm-skills/4-implementation/bmad-quick-dev/SKILL.md +0 -115
  277. package/src/bmm-skills/4-implementation/bmad-quick-dev/customize.toml +0 -83
  278. package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +0 -82
  279. package/src/bmm-skills/4-implementation/bmad-quick-dev/sync-sprint-status.md +0 -19
  280. package/src/bmm-skills/4-implementation/bmad-retrospective/SKILL.md +0 -1527
  281. package/src/bmm-skills/4-implementation/bmad-sprint-planning/SKILL.md +0 -319
  282. package/src/bmm-skills/4-implementation/bmad-sprint-planning/checklist.md +0 -34
  283. package/src/bmm-skills/4-implementation/bmad-sprint-status/SKILL.md +0 -311
  284. package/src/core-skills/bmad-brainstorming/analysis/catalog-analysis.md +0 -239
  285. package/src/core-skills/bmad-brainstorming/analysis/method-matrix.csv +0 -109
  286. package/src/core-skills/bmad-editorial-review-prose/SKILL.md +0 -86
  287. package/src/core-skills/bmad-editorial-review-structure/SKILL.md +0 -179
  288. package/src/core-skills/bmad-index-docs/SKILL.md +0 -66
  289. package/src/core-skills/bmad-review-adversarial-general/SKILL.md +0 -37
  290. package/src/core-skills/bmad-shard-doc/SKILL.md +0 -105
  291. /package/src/bmm-skills/{2-plan-workflows → agents}/bmad-agent-ux-designer/customize.toml +0 -0
  292. /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/assets/spine-template.md +0 -0
  293. /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/references/headless.md +0 -0
  294. /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/references/reviewer-gate.md +0 -0
  295. /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/scripts/lint_spine.py +0 -0
  296. /package/src/bmm-skills/{3-solutioning → plan}/bmad-architecture/scripts/tests/test_lint_spine.py +0 -0
  297. /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/customize.toml +0 -0
  298. /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-01-validate-prerequisites.md +0 -0
  299. /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-02-design-epics.md +0 -0
  300. /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/steps/step-03-create-stories.md +0 -0
  301. /package/src/bmm-skills/{3-solutioning → plan}/bmad-create-epics-and-stories/templates/epics-template.md +0 -0
  302. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/headless-schemas.md +0 -0
  303. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/prd-validation-checklist.md +0 -0
  304. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/assets/validation-report-template.html +0 -0
  305. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-prd/references/headless.md +0 -0
  306. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/agents/artifact-analyzer.md +0 -0
  307. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/agents/web-researcher.md +0 -0
  308. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/assets/prfaq-template.md +0 -0
  309. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/customize.toml +0 -0
  310. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/customer-faq.md +0 -0
  311. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/internal-faq.md +0 -0
  312. /package/src/bmm-skills/{1-analysis → plan}/bmad-prfaq/references/press-release.md +0 -0
  313. /package/src/bmm-skills/{1-analysis → plan}/bmad-product-brief/assets/brief-template.md +0 -0
  314. /package/src/{core-skills → bmm-skills/plan}/bmad-spec/assets/headless-schemas.md +0 -0
  315. /package/src/bmm-skills/{4-implementation → plan}/bmad-sprint-planning/customize.toml +0 -0
  316. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-directions.md +0 -0
  317. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-example-editorial.md +0 -0
  318. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-example-mobile.md +0 -0
  319. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/design-example-shadcn.md +0 -0
  320. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/excalidraw-wireframe.md +0 -0
  321. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/experience-example-mobile.md +0 -0
  322. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/experience-example-shadcn.md +0 -0
  323. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/headless-schemas.md +0 -0
  324. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/key-screens.md +0 -0
  325. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/assets/validation-report-template.html +0 -0
  326. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/design-md-spec.md +0 -0
  327. /package/src/bmm-skills/{2-plan-workflows → plan}/bmad-ux/references/headless.md +0 -0
  328. /package/src/bmm-skills/{4-implementation/bmad-quick-dev → ship/bmad-build}/spec-template.md +0 -0
  329. /package/src/{core-skills/bmad-review-edge-case-hunter → bmm-skills/ship/bmad-build-auto}/references/deletion-check.md +0 -0
  330. /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/customize.toml +0 -0
  331. /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/generate-trail.md +0 -0
  332. /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-01-orientation.md +0 -0
  333. /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-02-walkthrough.md +0 -0
  334. /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-03-detail-pass.md +0 -0
  335. /package/src/bmm-skills/{4-implementation → ship}/bmad-checkpoint-preview/step-04-testing.md +0 -0
  336. /package/src/bmm-skills/{4-implementation → ship}/bmad-code-review/steps/step-03-triage.md +0 -0
  337. /package/src/bmm-skills/{4-implementation → ship}/bmad-correct-course/checklist.md +0 -0
  338. /package/src/bmm-skills/{4-implementation → ship}/bmad-correct-course/customize.toml +0 -0
  339. /package/src/bmm-skills/{4-implementation → ship}/bmad-qa-generate-e2e-tests/checklist.md +0 -0
  340. /package/src/bmm-skills/{4-implementation → ship}/bmad-qa-generate-e2e-tests/customize.toml +0 -0
  341. /package/src/bmm-skills/{3-solutioning → v6-shims}/bmad-create-architecture/customize.toml +0 -0
  342. /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-create-prd/customize.toml +0 -0
  343. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/checklist.md +0 -0
  344. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/customize.toml +0 -0
  345. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/discover-inputs.md +0 -0
  346. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-create-story/template.md +0 -0
  347. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-dev-story/checklist.md +0 -0
  348. /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-edit-prd/customize.toml +0 -0
  349. /package/src/bmm-skills/{4-implementation → v6-shims}/bmad-sprint-status/customize.toml +0 -0
  350. /package/src/bmm-skills/{2-plan-workflows → v6-shims}/bmad-validate-prd/customize.toml +0 -0
  351. /package/src/core-skills/bmad-advanced-elicitation/{methods.csv → assets/methods.csv} +0 -0
  352. /package/src/core-skills/bmad-party-mode/scripts/tests/{test-resolve_party.py → test_resolve_party.py} +0 -0
@@ -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"]))
@@ -33,19 +33,21 @@
33
33
  #
34
34
  # WORKFLOW NOTES:
35
35
  # ===============
36
- # - Mark epic as 'in-progress' when starting work on its first story
37
- # - Developer typically creates next story ONLY after previous one is 'done' to incorporate learnings
38
- # - Dev moves story to 'review', then Dev runs code-review (fresh context, ideally different LLM)
39
- # - Retrospective appends its action items to action_items; sprint-status surfaces open ones
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-2-2025 21:30
44
- last_updated: 05-06-2-2025 21:30
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: "{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-dev-story`. Run `{workflow.on_complete}`.
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 `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`.
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-editorial-review-structure",
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: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"`. Skip in headless.
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: `python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('{doc_workspace}/validation-report.html').resolve().as_uri())"`. Skip headless.
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.
@@ -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 quick-dev's context alongside other material.
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