scm-method 1.0.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 (324) hide show
  1. package/.claude-plugin/marketplace.json +77 -0
  2. package/AGENTS.md +12 -0
  3. package/LICENSE +30 -0
  4. package/README.md +109 -0
  5. package/README_CN.md +108 -0
  6. package/package.json +110 -0
  7. package/src/bmm-skills/1-analysis/research/scm-domain-research/SKILL.md +6 -0
  8. package/src/bmm-skills/1-analysis/research/scm-domain-research/domain-steps/step-01-init.md +137 -0
  9. package/src/bmm-skills/1-analysis/research/scm-domain-research/domain-steps/step-02-domain-analysis.md +229 -0
  10. package/src/bmm-skills/1-analysis/research/scm-domain-research/domain-steps/step-03-competitive-landscape.md +238 -0
  11. package/src/bmm-skills/1-analysis/research/scm-domain-research/domain-steps/step-04-regulatory-focus.md +206 -0
  12. package/src/bmm-skills/1-analysis/research/scm-domain-research/domain-steps/step-05-technical-trends.md +234 -0
  13. package/src/bmm-skills/1-analysis/research/scm-domain-research/domain-steps/step-06-research-synthesis.md +444 -0
  14. package/src/bmm-skills/1-analysis/research/scm-domain-research/research.template.md +29 -0
  15. package/src/bmm-skills/1-analysis/research/scm-domain-research/workflow.md +51 -0
  16. package/src/bmm-skills/1-analysis/research/scm-market-research/SKILL.md +6 -0
  17. package/src/bmm-skills/1-analysis/research/scm-market-research/research.template.md +29 -0
  18. package/src/bmm-skills/1-analysis/research/scm-market-research/steps/step-01-init.md +184 -0
  19. package/src/bmm-skills/1-analysis/research/scm-market-research/steps/step-02-customer-behavior.md +239 -0
  20. package/src/bmm-skills/1-analysis/research/scm-market-research/steps/step-03-customer-pain-points.md +251 -0
  21. package/src/bmm-skills/1-analysis/research/scm-market-research/steps/step-04-customer-decisions.md +261 -0
  22. package/src/bmm-skills/1-analysis/research/scm-market-research/steps/step-05-competitive-analysis.md +173 -0
  23. package/src/bmm-skills/1-analysis/research/scm-market-research/steps/step-06-research-completion.md +478 -0
  24. package/src/bmm-skills/1-analysis/research/scm-market-research/workflow.md +51 -0
  25. package/src/bmm-skills/1-analysis/research/scm-technical-research/SKILL.md +6 -0
  26. package/src/bmm-skills/1-analysis/research/scm-technical-research/research.template.md +29 -0
  27. package/src/bmm-skills/1-analysis/research/scm-technical-research/technical-steps/step-01-init.md +137 -0
  28. package/src/bmm-skills/1-analysis/research/scm-technical-research/technical-steps/step-02-technical-overview.md +239 -0
  29. package/src/bmm-skills/1-analysis/research/scm-technical-research/technical-steps/step-03-integration-patterns.md +248 -0
  30. package/src/bmm-skills/1-analysis/research/scm-technical-research/technical-steps/step-04-architectural-patterns.md +202 -0
  31. package/src/bmm-skills/1-analysis/research/scm-technical-research/technical-steps/step-05-implementation-research.md +233 -0
  32. package/src/bmm-skills/1-analysis/research/scm-technical-research/technical-steps/step-06-research-synthesis.md +487 -0
  33. package/src/bmm-skills/1-analysis/research/scm-technical-research/workflow.md +52 -0
  34. package/src/bmm-skills/1-analysis/scm-agent-analyst/SKILL.md +59 -0
  35. package/src/bmm-skills/1-analysis/scm-agent-analyst/scm-skill-manifest.yaml +11 -0
  36. package/src/bmm-skills/1-analysis/scm-agent-tech-writer/SKILL.md +57 -0
  37. package/src/bmm-skills/1-analysis/scm-agent-tech-writer/explain-concept.md +20 -0
  38. package/src/bmm-skills/1-analysis/scm-agent-tech-writer/mermaid-gen.md +20 -0
  39. package/src/bmm-skills/1-analysis/scm-agent-tech-writer/scm-skill-manifest.yaml +11 -0
  40. package/src/bmm-skills/1-analysis/scm-agent-tech-writer/validate-doc.md +19 -0
  41. package/src/bmm-skills/1-analysis/scm-agent-tech-writer/write-document.md +20 -0
  42. package/src/bmm-skills/1-analysis/scm-document-project/SKILL.md +6 -0
  43. package/src/bmm-skills/1-analysis/scm-document-project/checklist.md +245 -0
  44. package/src/bmm-skills/1-analysis/scm-document-project/documentation-requirements.csv +12 -0
  45. package/src/bmm-skills/1-analysis/scm-document-project/instructions.md +128 -0
  46. package/src/bmm-skills/1-analysis/scm-document-project/templates/deep-dive-template.md +345 -0
  47. package/src/bmm-skills/1-analysis/scm-document-project/templates/index-template.md +169 -0
  48. package/src/bmm-skills/1-analysis/scm-document-project/templates/project-overview-template.md +103 -0
  49. package/src/bmm-skills/1-analysis/scm-document-project/templates/project-scan-report-schema.json +160 -0
  50. package/src/bmm-skills/1-analysis/scm-document-project/templates/source-tree-template.md +135 -0
  51. package/src/bmm-skills/1-analysis/scm-document-project/workflow.md +25 -0
  52. package/src/bmm-skills/1-analysis/scm-document-project/workflows/deep-dive-instructions.md +299 -0
  53. package/src/bmm-skills/1-analysis/scm-document-project/workflows/deep-dive-workflow.md +34 -0
  54. package/src/bmm-skills/1-analysis/scm-document-project/workflows/full-scan-instructions.md +1107 -0
  55. package/src/bmm-skills/1-analysis/scm-document-project/workflows/full-scan-workflow.md +34 -0
  56. package/src/bmm-skills/1-analysis/scm-prfaq/SKILL.md +96 -0
  57. package/src/bmm-skills/1-analysis/scm-prfaq/agents/artifact-analyzer.md +60 -0
  58. package/src/bmm-skills/1-analysis/scm-prfaq/agents/web-researcher.md +49 -0
  59. package/src/bmm-skills/1-analysis/scm-prfaq/assets/prfaq-template.md +62 -0
  60. package/src/bmm-skills/1-analysis/scm-prfaq/references/customer-faq.md +55 -0
  61. package/src/bmm-skills/1-analysis/scm-prfaq/references/internal-faq.md +51 -0
  62. package/src/bmm-skills/1-analysis/scm-prfaq/references/press-release.md +60 -0
  63. package/src/bmm-skills/1-analysis/scm-prfaq/references/verdict.md +79 -0
  64. package/src/bmm-skills/1-analysis/scm-prfaq/scm-manifest.json +16 -0
  65. package/src/bmm-skills/1-analysis/scm-product-brief/SKILL.md +82 -0
  66. package/src/bmm-skills/1-analysis/scm-product-brief/agents/artifact-analyzer.md +60 -0
  67. package/src/bmm-skills/1-analysis/scm-product-brief/agents/opportunity-reviewer.md +44 -0
  68. package/src/bmm-skills/1-analysis/scm-product-brief/agents/skeptic-reviewer.md +44 -0
  69. package/src/bmm-skills/1-analysis/scm-product-brief/agents/web-researcher.md +49 -0
  70. package/src/bmm-skills/1-analysis/scm-product-brief/prompts/contextual-discovery.md +57 -0
  71. package/src/bmm-skills/1-analysis/scm-product-brief/prompts/draft-and-review.md +86 -0
  72. package/src/bmm-skills/1-analysis/scm-product-brief/prompts/finalize.md +75 -0
  73. package/src/bmm-skills/1-analysis/scm-product-brief/prompts/guided-elicitation.md +70 -0
  74. package/src/bmm-skills/1-analysis/scm-product-brief/resources/brief-template.md +60 -0
  75. package/src/bmm-skills/1-analysis/scm-product-brief/scm-manifest.json +17 -0
  76. package/src/bmm-skills/2-plan-workflows/scm-agent-pm/SKILL.md +59 -0
  77. package/src/bmm-skills/2-plan-workflows/scm-agent-pm/scm-skill-manifest.yaml +11 -0
  78. package/src/bmm-skills/2-plan-workflows/scm-agent-ux-designer/SKILL.md +55 -0
  79. package/src/bmm-skills/2-plan-workflows/scm-agent-ux-designer/scm-skill-manifest.yaml +11 -0
  80. package/src/bmm-skills/2-plan-workflows/scm-create-prd/SKILL.md +6 -0
  81. package/src/bmm-skills/2-plan-workflows/scm-create-prd/data/domain-complexity.csv +15 -0
  82. package/src/bmm-skills/2-plan-workflows/scm-create-prd/data/prd-purpose.md +197 -0
  83. package/src/bmm-skills/2-plan-workflows/scm-create-prd/data/project-types.csv +11 -0
  84. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-01-init.md +178 -0
  85. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-01b-continue.md +161 -0
  86. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-02-discovery.md +208 -0
  87. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-02b-vision.md +142 -0
  88. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-02c-executive-summary.md +158 -0
  89. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-03-success.md +214 -0
  90. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-04-journeys.md +201 -0
  91. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-05-domain.md +194 -0
  92. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-06-innovation.md +211 -0
  93. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-07-project-type.md +222 -0
  94. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-08-scoping.md +216 -0
  95. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-09-functional.md +219 -0
  96. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-10-nonfunctional.md +230 -0
  97. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-11-polish.md +221 -0
  98. package/src/bmm-skills/2-plan-workflows/scm-create-prd/steps-c/step-12-complete.md +115 -0
  99. package/src/bmm-skills/2-plan-workflows/scm-create-prd/templates/prd-template.md +10 -0
  100. package/src/bmm-skills/2-plan-workflows/scm-create-prd/workflow.md +61 -0
  101. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/SKILL.md +6 -0
  102. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-01-init.md +135 -0
  103. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-01b-continue.md +127 -0
  104. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-02-discovery.md +190 -0
  105. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-03-core-experience.md +217 -0
  106. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-04-emotional-response.md +220 -0
  107. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-05-inspiration.md +235 -0
  108. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-06-design-system.md +253 -0
  109. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-07-defining-experience.md +255 -0
  110. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-08-visual-foundation.md +225 -0
  111. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-09-design-directions.md +225 -0
  112. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-10-user-journeys.md +242 -0
  113. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-11-component-strategy.md +249 -0
  114. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-12-ux-patterns.md +238 -0
  115. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-13-responsive-accessibility.md +265 -0
  116. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/steps/step-14-complete.md +171 -0
  117. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/ux-design-template.md +13 -0
  118. package/src/bmm-skills/2-plan-workflows/scm-create-ux-design/workflow.md +35 -0
  119. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/SKILL.md +6 -0
  120. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/steps-e/step-e-01-discovery.md +242 -0
  121. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/steps-e/step-e-01b-legacy-conversion.md +204 -0
  122. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/steps-e/step-e-02-review.md +245 -0
  123. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/steps-e/step-e-03-edit.md +250 -0
  124. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/steps-e/step-e-04-complete.md +165 -0
  125. package/src/bmm-skills/2-plan-workflows/scm-edit-prd/workflow.md +62 -0
  126. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/SKILL.md +6 -0
  127. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/data/domain-complexity.csv +15 -0
  128. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/data/prd-purpose.md +197 -0
  129. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/data/project-types.csv +11 -0
  130. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-01-discovery.md +221 -0
  131. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-02-format-detection.md +188 -0
  132. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-02b-parity-check.md +206 -0
  133. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-03-density-validation.md +171 -0
  134. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-04-brief-coverage-validation.md +211 -0
  135. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-05-measurability-validation.md +225 -0
  136. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-06-traceability-validation.md +214 -0
  137. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-07-implementation-leakage-validation.md +202 -0
  138. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-08-domain-compliance-validation.md +240 -0
  139. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-09-project-type-validation.md +260 -0
  140. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-10-smart-validation.md +206 -0
  141. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-11-holistic-quality-validation.md +261 -0
  142. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-12-completeness-validation.md +239 -0
  143. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/steps-v/step-v-13-report-complete.md +229 -0
  144. package/src/bmm-skills/2-plan-workflows/scm-validate-prd/workflow.md +61 -0
  145. package/src/bmm-skills/3-solutioning/scm-agent-architect/SKILL.md +54 -0
  146. package/src/bmm-skills/3-solutioning/scm-agent-architect/scm-skill-manifest.yaml +11 -0
  147. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/SKILL.md +6 -0
  148. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/steps/step-01-document-discovery.md +179 -0
  149. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/steps/step-02-prd-analysis.md +168 -0
  150. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/steps/step-03-epic-coverage-validation.md +169 -0
  151. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/steps/step-04-ux-alignment.md +129 -0
  152. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/steps/step-05-epic-quality-review.md +241 -0
  153. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/steps/step-06-final-assessment.md +126 -0
  154. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/templates/readiness-report-template.md +4 -0
  155. package/src/bmm-skills/3-solutioning/scm-check-implementation-readiness/workflow.md +47 -0
  156. package/src/bmm-skills/3-solutioning/scm-create-architecture/SKILL.md +6 -0
  157. package/src/bmm-skills/3-solutioning/scm-create-architecture/architecture-decision-template.md +12 -0
  158. package/src/bmm-skills/3-solutioning/scm-create-architecture/data/domain-complexity.csv +13 -0
  159. package/src/bmm-skills/3-solutioning/scm-create-architecture/data/project-types.csv +7 -0
  160. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-01-init.md +153 -0
  161. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-01b-continue.md +173 -0
  162. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-02-context.md +224 -0
  163. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-03-starter.md +329 -0
  164. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-04-decisions.md +318 -0
  165. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-05-patterns.md +359 -0
  166. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-06-structure.md +379 -0
  167. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-07-validation.md +359 -0
  168. package/src/bmm-skills/3-solutioning/scm-create-architecture/steps/step-08-complete.md +76 -0
  169. package/src/bmm-skills/3-solutioning/scm-create-architecture/workflow.md +32 -0
  170. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/SKILL.md +6 -0
  171. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/steps/step-01-validate-prerequisites.md +255 -0
  172. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/steps/step-02-design-epics.md +212 -0
  173. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/steps/step-03-create-stories.md +255 -0
  174. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/steps/step-04-final-validation.md +131 -0
  175. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/templates/epics-template.md +61 -0
  176. package/src/bmm-skills/3-solutioning/scm-create-epics-and-stories/workflow.md +51 -0
  177. package/src/bmm-skills/3-solutioning/scm-generate-project-context/SKILL.md +6 -0
  178. package/src/bmm-skills/3-solutioning/scm-generate-project-context/project-context-template.md +21 -0
  179. package/src/bmm-skills/3-solutioning/scm-generate-project-context/steps/step-01-discover.md +186 -0
  180. package/src/bmm-skills/3-solutioning/scm-generate-project-context/steps/step-02-generate.md +321 -0
  181. package/src/bmm-skills/3-solutioning/scm-generate-project-context/steps/step-03-complete.md +278 -0
  182. package/src/bmm-skills/3-solutioning/scm-generate-project-context/workflow.md +39 -0
  183. package/src/bmm-skills/4-implementation/scm-agent-dev/SKILL.md +64 -0
  184. package/src/bmm-skills/4-implementation/scm-agent-dev/scm-skill-manifest.yaml +11 -0
  185. package/src/bmm-skills/4-implementation/scm-agent-qa/SKILL.md +61 -0
  186. package/src/bmm-skills/4-implementation/scm-agent-qa/scm-skill-manifest.yaml +11 -0
  187. package/src/bmm-skills/4-implementation/scm-agent-quick-flow-solo-dev/SKILL.md +53 -0
  188. package/src/bmm-skills/4-implementation/scm-agent-quick-flow-solo-dev/scm-skill-manifest.yaml +11 -0
  189. package/src/bmm-skills/4-implementation/scm-agent-sm/SKILL.md +55 -0
  190. package/src/bmm-skills/4-implementation/scm-agent-sm/scm-skill-manifest.yaml +11 -0
  191. package/src/bmm-skills/4-implementation/scm-code-review/SKILL.md +6 -0
  192. package/src/bmm-skills/4-implementation/scm-code-review/steps/step-01-gather-context.md +62 -0
  193. package/src/bmm-skills/4-implementation/scm-code-review/steps/step-02-review.md +34 -0
  194. package/src/bmm-skills/4-implementation/scm-code-review/steps/step-03-triage.md +49 -0
  195. package/src/bmm-skills/4-implementation/scm-code-review/steps/step-04-present.md +129 -0
  196. package/src/bmm-skills/4-implementation/scm-code-review/workflow.md +55 -0
  197. package/src/bmm-skills/4-implementation/scm-correct-course/SKILL.md +6 -0
  198. package/src/bmm-skills/4-implementation/scm-correct-course/checklist.md +288 -0
  199. package/src/bmm-skills/4-implementation/scm-correct-course/workflow.md +267 -0
  200. package/src/bmm-skills/4-implementation/scm-create-story/SKILL.md +6 -0
  201. package/src/bmm-skills/4-implementation/scm-create-story/checklist.md +357 -0
  202. package/src/bmm-skills/4-implementation/scm-create-story/discover-inputs.md +88 -0
  203. package/src/bmm-skills/4-implementation/scm-create-story/template.md +49 -0
  204. package/src/bmm-skills/4-implementation/scm-create-story/workflow.md +380 -0
  205. package/src/bmm-skills/4-implementation/scm-dev-story/SKILL.md +6 -0
  206. package/src/bmm-skills/4-implementation/scm-dev-story/checklist.md +80 -0
  207. package/src/bmm-skills/4-implementation/scm-dev-story/workflow.md +450 -0
  208. package/src/bmm-skills/4-implementation/scm-qa-generate-e2e-tests/SKILL.md +6 -0
  209. package/src/bmm-skills/4-implementation/scm-qa-generate-e2e-tests/checklist.md +33 -0
  210. package/src/bmm-skills/4-implementation/scm-qa-generate-e2e-tests/workflow.md +136 -0
  211. package/src/bmm-skills/4-implementation/scm-quick-dev/SKILL.md +6 -0
  212. package/src/bmm-skills/4-implementation/scm-quick-dev/spec-template.md +88 -0
  213. package/src/bmm-skills/4-implementation/scm-quick-dev/step-01-clarify-and-route.md +66 -0
  214. package/src/bmm-skills/4-implementation/scm-quick-dev/step-02-plan.md +35 -0
  215. package/src/bmm-skills/4-implementation/scm-quick-dev/step-03-implement.md +37 -0
  216. package/src/bmm-skills/4-implementation/scm-quick-dev/step-04-review.md +49 -0
  217. package/src/bmm-skills/4-implementation/scm-quick-dev/step-05-present.md +63 -0
  218. package/src/bmm-skills/4-implementation/scm-quick-dev/step-oneshot.md +62 -0
  219. package/src/bmm-skills/4-implementation/scm-quick-dev/workflow.md +79 -0
  220. package/src/bmm-skills/4-implementation/scm-retrospective/SKILL.md +6 -0
  221. package/src/bmm-skills/4-implementation/scm-retrospective/workflow.md +1479 -0
  222. package/src/bmm-skills/4-implementation/scm-sprint-planning/SKILL.md +6 -0
  223. package/src/bmm-skills/4-implementation/scm-sprint-planning/checklist.md +33 -0
  224. package/src/bmm-skills/4-implementation/scm-sprint-planning/sprint-status-template.yaml +56 -0
  225. package/src/bmm-skills/4-implementation/scm-sprint-planning/workflow.md +263 -0
  226. package/src/bmm-skills/4-implementation/scm-sprint-status/SKILL.md +6 -0
  227. package/src/bmm-skills/4-implementation/scm-sprint-status/workflow.md +261 -0
  228. package/src/bmm-skills/module-help.csv +31 -0
  229. package/src/bmm-skills/module.yaml +50 -0
  230. package/src/core-skills/module-help.csv +11 -0
  231. package/src/core-skills/module.yaml +25 -0
  232. package/src/core-skills/scm-advanced-elicitation/SKILL.md +136 -0
  233. package/src/core-skills/scm-advanced-elicitation/methods.csv +51 -0
  234. package/src/core-skills/scm-brainstorming/SKILL.md +6 -0
  235. package/src/core-skills/scm-brainstorming/brain-methods.csv +62 -0
  236. package/src/core-skills/scm-brainstorming/steps/step-01-session-setup.md +214 -0
  237. package/src/core-skills/scm-brainstorming/steps/step-01b-continue.md +124 -0
  238. package/src/core-skills/scm-brainstorming/steps/step-02a-user-selected.md +229 -0
  239. package/src/core-skills/scm-brainstorming/steps/step-02b-ai-recommended.md +239 -0
  240. package/src/core-skills/scm-brainstorming/steps/step-02c-random-selection.md +211 -0
  241. package/src/core-skills/scm-brainstorming/steps/step-02d-progressive-flow.md +266 -0
  242. package/src/core-skills/scm-brainstorming/steps/step-03-technique-execution.md +401 -0
  243. package/src/core-skills/scm-brainstorming/steps/step-04-idea-organization.md +305 -0
  244. package/src/core-skills/scm-brainstorming/template.md +15 -0
  245. package/src/core-skills/scm-brainstorming/workflow.md +53 -0
  246. package/src/core-skills/scm-distillator/SKILL.md +177 -0
  247. package/src/core-skills/scm-distillator/agents/distillate-compressor.md +116 -0
  248. package/src/core-skills/scm-distillator/agents/round-trip-reconstructor.md +68 -0
  249. package/src/core-skills/scm-distillator/resources/compression-rules.md +51 -0
  250. package/src/core-skills/scm-distillator/resources/distillate-format-reference.md +227 -0
  251. package/src/core-skills/scm-distillator/resources/splitting-strategy.md +78 -0
  252. package/src/core-skills/scm-distillator/scripts/analyze_sources.py +300 -0
  253. package/src/core-skills/scm-distillator/scripts/tests/test_analyze_sources.py +204 -0
  254. package/src/core-skills/scm-editorial-review-prose/SKILL.md +86 -0
  255. package/src/core-skills/scm-editorial-review-structure/SKILL.md +179 -0
  256. package/src/core-skills/scm-help/SKILL.md +73 -0
  257. package/src/core-skills/scm-index-docs/SKILL.md +66 -0
  258. package/src/core-skills/scm-party-mode/SKILL.md +125 -0
  259. package/src/core-skills/scm-review-adversarial-general/SKILL.md +37 -0
  260. package/src/core-skills/scm-review-edge-case-hunter/SKILL.md +67 -0
  261. package/src/core-skills/scm-shard-doc/SKILL.md +105 -0
  262. package/tools/format-workflow-md.js +263 -0
  263. package/tools/installer/README.md +60 -0
  264. package/tools/installer/cli-utils.js +181 -0
  265. package/tools/installer/commands/install.js +80 -0
  266. package/tools/installer/commands/status.js +65 -0
  267. package/tools/installer/commands/uninstall.js +167 -0
  268. package/tools/installer/core/config.js +52 -0
  269. package/tools/installer/core/custom-module-cache.js +260 -0
  270. package/tools/installer/core/existing-install.js +127 -0
  271. package/tools/installer/core/install-paths.js +129 -0
  272. package/tools/installer/core/installer.js +1790 -0
  273. package/tools/installer/core/manifest-generator.js +701 -0
  274. package/tools/installer/core/manifest.js +1040 -0
  275. package/tools/installer/custom-handler.js +112 -0
  276. package/tools/installer/external-official-modules.yaml +63 -0
  277. package/tools/installer/file-ops.js +204 -0
  278. package/tools/installer/ide/_config-driven.js +536 -0
  279. package/tools/installer/ide/manager.js +247 -0
  280. package/tools/installer/ide/platform-codes.js +37 -0
  281. package/tools/installer/ide/platform-codes.yaml +192 -0
  282. package/tools/installer/ide/shared/agent-command-generator.js +180 -0
  283. package/tools/installer/ide/shared/module-injections.js +136 -0
  284. package/tools/installer/ide/shared/path-utils.js +364 -0
  285. package/tools/installer/ide/shared/scm-artifacts.js +208 -0
  286. package/tools/installer/ide/shared/skill-manifest.js +72 -0
  287. package/tools/installer/ide/templates/agent-command-template.md +14 -0
  288. package/tools/installer/ide/templates/combined/antigravity.md +8 -0
  289. package/tools/installer/ide/templates/combined/default-agent.md +15 -0
  290. package/tools/installer/ide/templates/combined/default-task.md +10 -0
  291. package/tools/installer/ide/templates/combined/default-tool.md +10 -0
  292. package/tools/installer/ide/templates/combined/default-workflow.md +6 -0
  293. package/tools/installer/ide/templates/combined/gemini-agent.toml +14 -0
  294. package/tools/installer/ide/templates/combined/gemini-task.toml +11 -0
  295. package/tools/installer/ide/templates/combined/gemini-tool.toml +11 -0
  296. package/tools/installer/ide/templates/combined/gemini-workflow-yaml.toml +16 -0
  297. package/tools/installer/ide/templates/combined/gemini-workflow.toml +14 -0
  298. package/tools/installer/ide/templates/combined/kiro-agent.md +16 -0
  299. package/tools/installer/ide/templates/combined/kiro-task.md +9 -0
  300. package/tools/installer/ide/templates/combined/kiro-tool.md +9 -0
  301. package/tools/installer/ide/templates/combined/kiro-workflow.md +7 -0
  302. package/tools/installer/ide/templates/combined/opencode-agent.md +15 -0
  303. package/tools/installer/ide/templates/combined/opencode-task.md +13 -0
  304. package/tools/installer/ide/templates/combined/opencode-tool.md +13 -0
  305. package/tools/installer/ide/templates/combined/opencode-workflow-yaml.md +16 -0
  306. package/tools/installer/ide/templates/combined/opencode-workflow.md +16 -0
  307. package/tools/installer/ide/templates/combined/rovodev.md +9 -0
  308. package/tools/installer/ide/templates/combined/trae.md +9 -0
  309. package/tools/installer/ide/templates/combined/windsurf-workflow.md +10 -0
  310. package/tools/installer/ide/templates/split/.gitkeep +0 -0
  311. package/tools/installer/install-messages.yaml +35 -0
  312. package/tools/installer/message-loader.js +83 -0
  313. package/tools/installer/modules/custom-modules.js +197 -0
  314. package/tools/installer/modules/external-manager.js +354 -0
  315. package/tools/installer/modules/official-modules.js +2043 -0
  316. package/tools/installer/project-root.js +77 -0
  317. package/tools/installer/prompts.js +809 -0
  318. package/tools/installer/scm-cli.js +108 -0
  319. package/tools/installer/ui.js +1683 -0
  320. package/tools/installer/yaml-format.js +245 -0
  321. package/tools/javascript-conventions.md +5 -0
  322. package/tools/migrate-custom-module-paths.js +124 -0
  323. package/tools/platform-codes.yaml +169 -0
  324. package/tools/validate-skills.js +736 -0
@@ -0,0 +1,300 @@
1
+ # /// script
2
+ # /// requires-python = ">=3.10"
3
+ # /// dependencies = []
4
+ # ///
5
+ """Analyze source documents for the distillation generator.
6
+
7
+ Enumerates files from paths/folders/globs, computes sizes and token estimates,
8
+ detects document types from naming conventions, and suggests groupings for
9
+ related documents (e.g., a brief paired with its discovery notes).
10
+
11
+ Accepts: file paths, folder paths (scans recursively for .md/.txt/.yaml/.yml/.json),
12
+ or glob patterns. Skips node_modules, .git, __pycache__, .venv, _scm-output.
13
+
14
+ Output JSON structure:
15
+ status: "ok" | "error"
16
+ files[]: path, filename, size_bytes, estimated_tokens, doc_type
17
+ summary: total_files, total_size_bytes, total_estimated_tokens
18
+ groups[]: group_key, files[] with role (primary/companion/standalone)
19
+ - Groups related docs by naming convention (e.g., brief + discovery-notes)
20
+ routing: recommendation ("single" | "fan-out"), reason
21
+ - single: ≤3 files AND ≤15K estimated tokens
22
+ - fan-out: >3 files OR >15K estimated tokens
23
+ split_prediction: prediction ("likely" | "unlikely"), reason, estimated_distillate_tokens
24
+ - Estimates distillate at ~1/3 source size; splits if >5K tokens
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ import argparse
30
+ import glob
31
+ import json
32
+ import os
33
+ import re
34
+ import sys
35
+ from pathlib import Path
36
+
37
+ # Extensions to include when scanning folders
38
+ INCLUDE_EXTENSIONS = {".md", ".txt", ".yaml", ".yml", ".json"}
39
+
40
+ # Directories to skip when scanning folders
41
+ SKIP_DIRS = {
42
+ "node_modules", ".git", "__pycache__", ".venv", "venv",
43
+ ".claude", "_scm-output", ".cursor", ".vscode",
44
+ }
45
+
46
+ # Approximate chars per token for estimation
47
+ CHARS_PER_TOKEN = 4
48
+
49
+ # Thresholds
50
+ SINGLE_COMPRESSOR_MAX_TOKENS = 15_000
51
+ SINGLE_DISTILLATE_MAX_TOKENS = 5_000
52
+
53
+ # Naming patterns for document type detection
54
+ DOC_TYPE_PATTERNS = [
55
+ (r"discovery[_-]notes", "discovery-notes"),
56
+ (r"product[_-]brief", "product-brief"),
57
+ (r"research[_-]report", "research-report"),
58
+ (r"architecture", "architecture-doc"),
59
+ (r"prd", "prd"),
60
+ (r"distillate", "distillate"),
61
+ (r"changelog", "changelog"),
62
+ (r"readme", "readme"),
63
+ (r"spec", "specification"),
64
+ (r"requirements", "requirements"),
65
+ (r"design[_-]doc", "design-doc"),
66
+ (r"meeting[_-]notes", "meeting-notes"),
67
+ (r"brainstorm", "brainstorming"),
68
+ (r"interview", "interview-notes"),
69
+ ]
70
+
71
+ # Patterns for grouping related documents
72
+ GROUP_PATTERNS = [
73
+ # base document + discovery notes
74
+ (r"^(.+?)(?:-discovery-notes|-discovery_notes)\.(\w+)$", r"\1.\2"),
75
+ # base document + appendix
76
+ (r"^(.+?)(?:-appendix|-addendum)(?:-\w+)?\.(\w+)$", r"\1.\2"),
77
+ # base document + review/feedback
78
+ (r"^(.+?)(?:-review|-feedback)\.(\w+)$", r"\1.\2"),
79
+ ]
80
+
81
+
82
+ def resolve_inputs(inputs: list[str]) -> list[Path]:
83
+ """Resolve input arguments to a flat list of file paths."""
84
+ files: list[Path] = []
85
+ for inp in inputs:
86
+ path = Path(inp)
87
+ if path.is_file():
88
+ files.append(path.resolve())
89
+ elif path.is_dir():
90
+ for root, dirs, filenames in os.walk(path):
91
+ dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
92
+ for fn in sorted(filenames):
93
+ fp = Path(root) / fn
94
+ if fp.suffix.lower() in INCLUDE_EXTENSIONS:
95
+ files.append(fp.resolve())
96
+ else:
97
+ # Try as glob
98
+ matches = glob.glob(inp, recursive=True)
99
+ for m in sorted(matches):
100
+ mp = Path(m)
101
+ if mp.is_file() and mp.suffix.lower() in INCLUDE_EXTENSIONS:
102
+ files.append(mp.resolve())
103
+ # Deduplicate while preserving order
104
+ seen: set[Path] = set()
105
+ deduped: list[Path] = []
106
+ for f in files:
107
+ if f not in seen:
108
+ seen.add(f)
109
+ deduped.append(f)
110
+ return deduped
111
+
112
+
113
+ def detect_doc_type(filename: str) -> str:
114
+ """Detect document type from filename."""
115
+ name_lower = filename.lower()
116
+ for pattern, doc_type in DOC_TYPE_PATTERNS:
117
+ if re.search(pattern, name_lower):
118
+ return doc_type
119
+ return "unknown"
120
+
121
+
122
+ def suggest_groups(files: list[Path]) -> list[dict]:
123
+ """Suggest document groupings based on naming conventions."""
124
+ groups: dict[str, list[dict]] = {}
125
+ ungrouped: list[dict] = []
126
+
127
+ file_map = {f.name: f for f in files}
128
+
129
+ assigned: set[str] = set()
130
+
131
+ for f in files:
132
+ if f.name in assigned:
133
+ continue
134
+
135
+ matched = False
136
+ for pattern, base_pattern in GROUP_PATTERNS:
137
+ m = re.match(pattern, f.name, re.IGNORECASE)
138
+ if m:
139
+ # This file is a companion — find its base
140
+ base_name = re.sub(pattern, base_pattern, f.name, flags=re.IGNORECASE)
141
+ group_key = base_name
142
+ if group_key not in groups:
143
+ groups[group_key] = []
144
+ # Add the base file if it exists
145
+ if base_name in file_map and base_name not in assigned:
146
+ groups[group_key].append({
147
+ "path": str(file_map[base_name]),
148
+ "filename": base_name,
149
+ "role": "primary",
150
+ })
151
+ assigned.add(base_name)
152
+ groups[group_key].append({
153
+ "path": str(f),
154
+ "filename": f.name,
155
+ "role": "companion",
156
+ })
157
+ assigned.add(f.name)
158
+ matched = True
159
+ break
160
+
161
+ if not matched:
162
+ # Check if this file is a base that already has companions
163
+ if f.name in groups:
164
+ continue # Already added as primary
165
+ ungrouped.append({
166
+ "path": str(f),
167
+ "filename": f.name,
168
+ })
169
+
170
+ result = []
171
+ for group_key, members in groups.items():
172
+ result.append({
173
+ "group_key": group_key,
174
+ "files": members,
175
+ })
176
+ for ug in ungrouped:
177
+ if ug["filename"] not in assigned:
178
+ result.append({
179
+ "group_key": ug["filename"],
180
+ "files": [{"path": ug["path"], "filename": ug["filename"], "role": "standalone"}],
181
+ })
182
+
183
+ return result
184
+
185
+
186
+ def analyze(inputs: list[str], output_path: str | None = None) -> None:
187
+ """Main analysis function."""
188
+ files = resolve_inputs(inputs)
189
+
190
+ if not files:
191
+ result = {
192
+ "status": "error",
193
+ "error": "No readable files found from provided inputs",
194
+ "inputs": inputs,
195
+ }
196
+ output_json(result, output_path)
197
+ return
198
+
199
+ # Analyze each file
200
+ file_details = []
201
+ total_chars = 0
202
+ for f in files:
203
+ size = f.stat().st_size
204
+ total_chars += size
205
+ file_details.append({
206
+ "path": str(f),
207
+ "filename": f.name,
208
+ "size_bytes": size,
209
+ "estimated_tokens": size // CHARS_PER_TOKEN,
210
+ "doc_type": detect_doc_type(f.name),
211
+ })
212
+
213
+ total_tokens = total_chars // CHARS_PER_TOKEN
214
+ groups = suggest_groups(files)
215
+
216
+ # Routing recommendation
217
+ if len(files) <= 3 and total_tokens <= SINGLE_COMPRESSOR_MAX_TOKENS:
218
+ routing = "single"
219
+ routing_reason = (
220
+ f"{len(files)} file(s), ~{total_tokens:,} estimated tokens — "
221
+ f"within single compressor threshold"
222
+ )
223
+ else:
224
+ routing = "fan-out"
225
+ routing_reason = (
226
+ f"{len(files)} file(s), ~{total_tokens:,} estimated tokens — "
227
+ f"exceeds single compressor threshold "
228
+ f"({'>' + str(SINGLE_COMPRESSOR_MAX_TOKENS) + ' tokens' if total_tokens > SINGLE_COMPRESSOR_MAX_TOKENS else '> 3 files'})"
229
+ )
230
+
231
+ # Split prediction
232
+ estimated_distillate_tokens = total_tokens // 3 # rough: distillate is ~1/3 of source
233
+ if estimated_distillate_tokens > SINGLE_DISTILLATE_MAX_TOKENS:
234
+ split_prediction = "likely"
235
+ split_reason = (
236
+ f"Estimated distillate ~{estimated_distillate_tokens:,} tokens "
237
+ f"exceeds {SINGLE_DISTILLATE_MAX_TOKENS:,} threshold"
238
+ )
239
+ else:
240
+ split_prediction = "unlikely"
241
+ split_reason = (
242
+ f"Estimated distillate ~{estimated_distillate_tokens:,} tokens "
243
+ f"within {SINGLE_DISTILLATE_MAX_TOKENS:,} threshold"
244
+ )
245
+
246
+ result = {
247
+ "status": "ok",
248
+ "files": file_details,
249
+ "summary": {
250
+ "total_files": len(files),
251
+ "total_size_bytes": total_chars,
252
+ "total_estimated_tokens": total_tokens,
253
+ },
254
+ "groups": groups,
255
+ "routing": {
256
+ "recommendation": routing,
257
+ "reason": routing_reason,
258
+ },
259
+ "split_prediction": {
260
+ "prediction": split_prediction,
261
+ "reason": split_reason,
262
+ "estimated_distillate_tokens": estimated_distillate_tokens,
263
+ },
264
+ }
265
+
266
+ output_json(result, output_path)
267
+
268
+
269
+ def output_json(data: dict, output_path: str | None) -> None:
270
+ """Write JSON to file or stdout."""
271
+ json_str = json.dumps(data, indent=2)
272
+ if output_path:
273
+ Path(output_path).parent.mkdir(parents=True, exist_ok=True)
274
+ Path(output_path).write_text(json_str + "\n")
275
+ print(f"Results written to {output_path}", file=sys.stderr)
276
+ else:
277
+ print(json_str)
278
+
279
+
280
+ def main() -> None:
281
+ parser = argparse.ArgumentParser(
282
+ description=__doc__,
283
+ formatter_class=argparse.RawDescriptionHelpFormatter,
284
+ )
285
+ parser.add_argument(
286
+ "inputs",
287
+ nargs="+",
288
+ help="File paths, folder paths, or glob patterns to analyze",
289
+ )
290
+ parser.add_argument(
291
+ "-o", "--output",
292
+ help="Output JSON to file instead of stdout",
293
+ )
294
+ args = parser.parse_args()
295
+ analyze(args.inputs, args.output)
296
+ sys.exit(0)
297
+
298
+
299
+ if __name__ == "__main__":
300
+ main()
@@ -0,0 +1,204 @@
1
+ """Tests for analyze_sources.py"""
2
+
3
+ import json
4
+ import os
5
+ import tempfile
6
+ from pathlib import Path
7
+ from unittest.mock import patch
8
+
9
+ import pytest
10
+
11
+ # Add parent dir to path so we can import the script
12
+ import sys
13
+ sys.path.insert(0, str(Path(__file__).parent.parent))
14
+
15
+ from analyze_sources import (
16
+ resolve_inputs,
17
+ detect_doc_type,
18
+ suggest_groups,
19
+ analyze,
20
+ INCLUDE_EXTENSIONS,
21
+ SKIP_DIRS,
22
+ )
23
+
24
+
25
+ @pytest.fixture
26
+ def temp_dir():
27
+ """Create a temp directory with sample files."""
28
+ with tempfile.TemporaryDirectory() as d:
29
+ # Create sample files
30
+ (Path(d) / "product-brief-foo.md").write_text("# Product Brief\nContent here")
31
+ (Path(d) / "product-brief-foo-discovery-notes.md").write_text("# Discovery\nNotes")
32
+ (Path(d) / "architecture-doc.md").write_text("# Architecture\nDesign here")
33
+ (Path(d) / "research-report.md").write_text("# Research\nFindings")
34
+ (Path(d) / "random.txt").write_text("Some text content")
35
+ (Path(d) / "image.png").write_bytes(b"\x89PNG")
36
+ # Create a subdirectory with more files
37
+ sub = Path(d) / "subdir"
38
+ sub.mkdir()
39
+ (sub / "prd-v2.md").write_text("# PRD\nRequirements")
40
+ # Create a skip directory
41
+ skip = Path(d) / "node_modules"
42
+ skip.mkdir()
43
+ (skip / "junk.md").write_text("Should be skipped")
44
+ yield d
45
+
46
+
47
+ class TestResolveInputs:
48
+ def test_single_file(self, temp_dir):
49
+ f = str(Path(temp_dir) / "product-brief-foo.md")
50
+ result = resolve_inputs([f])
51
+ assert len(result) == 1
52
+ assert result[0].name == "product-brief-foo.md"
53
+
54
+ def test_folder_recursion(self, temp_dir):
55
+ result = resolve_inputs([temp_dir])
56
+ names = {f.name for f in result}
57
+ assert "product-brief-foo.md" in names
58
+ assert "prd-v2.md" in names
59
+ assert "random.txt" in names
60
+
61
+ def test_folder_skips_excluded_dirs(self, temp_dir):
62
+ result = resolve_inputs([temp_dir])
63
+ names = {f.name for f in result}
64
+ assert "junk.md" not in names
65
+
66
+ def test_folder_skips_non_text_files(self, temp_dir):
67
+ result = resolve_inputs([temp_dir])
68
+ names = {f.name for f in result}
69
+ assert "image.png" not in names
70
+
71
+ def test_glob_pattern(self, temp_dir):
72
+ pattern = str(Path(temp_dir) / "product-brief-*.md")
73
+ result = resolve_inputs([pattern])
74
+ assert len(result) == 2
75
+ names = {f.name for f in result}
76
+ assert "product-brief-foo.md" in names
77
+ assert "product-brief-foo-discovery-notes.md" in names
78
+
79
+ def test_deduplication(self, temp_dir):
80
+ f = str(Path(temp_dir) / "product-brief-foo.md")
81
+ result = resolve_inputs([f, f, f])
82
+ assert len(result) == 1
83
+
84
+ def test_mixed_inputs(self, temp_dir):
85
+ file_path = str(Path(temp_dir) / "architecture-doc.md")
86
+ folder_path = str(Path(temp_dir) / "subdir")
87
+ result = resolve_inputs([file_path, folder_path])
88
+ names = {f.name for f in result}
89
+ assert "architecture-doc.md" in names
90
+ assert "prd-v2.md" in names
91
+
92
+ def test_nonexistent_path(self):
93
+ result = resolve_inputs(["/nonexistent/path/file.md"])
94
+ assert len(result) == 0
95
+
96
+
97
+ class TestDetectDocType:
98
+ @pytest.mark.parametrize("filename,expected", [
99
+ ("product-brief-foo.md", "product-brief"),
100
+ ("product_brief_bar.md", "product-brief"),
101
+ ("foo-discovery-notes.md", "discovery-notes"),
102
+ ("foo-discovery_notes.md", "discovery-notes"),
103
+ ("architecture-overview.md", "architecture-doc"),
104
+ ("my-prd.md", "prd"),
105
+ ("research-report-q4.md", "research-report"),
106
+ ("foo-distillate.md", "distillate"),
107
+ ("changelog.md", "changelog"),
108
+ ("readme.md", "readme"),
109
+ ("api-spec.md", "specification"),
110
+ ("design-doc-v2.md", "design-doc"),
111
+ ("meeting-notes-2026.md", "meeting-notes"),
112
+ ("brainstorm-session.md", "brainstorming"),
113
+ ("user-interview-notes.md", "interview-notes"),
114
+ ("random-file.md", "unknown"),
115
+ ])
116
+ def test_detection(self, filename, expected):
117
+ assert detect_doc_type(filename) == expected
118
+
119
+
120
+ class TestSuggestGroups:
121
+ def test_groups_brief_with_discovery_notes(self, temp_dir):
122
+ files = [
123
+ Path(temp_dir) / "product-brief-foo.md",
124
+ Path(temp_dir) / "product-brief-foo-discovery-notes.md",
125
+ ]
126
+ groups = suggest_groups(files)
127
+ # Should produce one group with both files
128
+ paired = [g for g in groups if len(g["files"]) > 1]
129
+ assert len(paired) == 1
130
+ filenames = {f["filename"] for f in paired[0]["files"]}
131
+ assert "product-brief-foo.md" in filenames
132
+ assert "product-brief-foo-discovery-notes.md" in filenames
133
+
134
+ def test_standalone_files(self, temp_dir):
135
+ files = [
136
+ Path(temp_dir) / "architecture-doc.md",
137
+ Path(temp_dir) / "research-report.md",
138
+ ]
139
+ groups = suggest_groups(files)
140
+ assert len(groups) == 2
141
+ for g in groups:
142
+ assert len(g["files"]) == 1
143
+
144
+ def test_mixed_grouped_and_standalone(self, temp_dir):
145
+ files = [
146
+ Path(temp_dir) / "product-brief-foo.md",
147
+ Path(temp_dir) / "product-brief-foo-discovery-notes.md",
148
+ Path(temp_dir) / "architecture-doc.md",
149
+ ]
150
+ groups = suggest_groups(files)
151
+ paired = [g for g in groups if len(g["files"]) > 1]
152
+ standalone = [g for g in groups if len(g["files"]) == 1]
153
+ assert len(paired) == 1
154
+ assert len(standalone) == 1
155
+
156
+
157
+ class TestAnalyze:
158
+ def test_basic_analysis(self, temp_dir):
159
+ f = str(Path(temp_dir) / "product-brief-foo.md")
160
+ output_file = str(Path(temp_dir) / "output.json")
161
+ analyze([f], output_file)
162
+ result = json.loads(Path(output_file).read_text())
163
+ assert result["status"] == "ok"
164
+ assert result["summary"]["total_files"] == 1
165
+ assert result["files"][0]["doc_type"] == "product-brief"
166
+ assert result["files"][0]["estimated_tokens"] > 0
167
+
168
+ def test_routing_single_small_input(self, temp_dir):
169
+ f = str(Path(temp_dir) / "product-brief-foo.md")
170
+ output_file = str(Path(temp_dir) / "output.json")
171
+ analyze([f], output_file)
172
+ result = json.loads(Path(output_file).read_text())
173
+ assert result["routing"]["recommendation"] == "single"
174
+
175
+ def test_routing_fanout_many_files(self, temp_dir):
176
+ # Create enough files to trigger fan-out (> 3 files)
177
+ for i in range(5):
178
+ (Path(temp_dir) / f"doc-{i}.md").write_text("x" * 1000)
179
+ output_file = str(Path(temp_dir) / "output.json")
180
+ analyze([temp_dir], output_file)
181
+ result = json.loads(Path(output_file).read_text())
182
+ assert result["routing"]["recommendation"] == "fan-out"
183
+
184
+ def test_folder_analysis(self, temp_dir):
185
+ output_file = str(Path(temp_dir) / "output.json")
186
+ analyze([temp_dir], output_file)
187
+ result = json.loads(Path(output_file).read_text())
188
+ assert result["status"] == "ok"
189
+ assert result["summary"]["total_files"] >= 4 # at least the base files
190
+ assert len(result["groups"]) > 0
191
+
192
+ def test_no_files_found(self):
193
+ output_file = "/tmp/test_analyze_empty.json"
194
+ analyze(["/nonexistent/path"], output_file)
195
+ result = json.loads(Path(output_file).read_text())
196
+ assert result["status"] == "error"
197
+ os.unlink(output_file)
198
+
199
+ def test_stdout_output(self, temp_dir, capsys):
200
+ f = str(Path(temp_dir) / "product-brief-foo.md")
201
+ analyze([f])
202
+ captured = capsys.readouterr()
203
+ result = json.loads(captured.out)
204
+ assert result["status"] == "ok"
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: scm-editorial-review-prose
3
+ description: 'Clinical copy-editor that reviews text for communication issues. Use when user says review for prose or improve the prose'
4
+ ---
5
+
6
+ # Editorial Review - Prose
7
+
8
+ **Goal:** Review text for communication issues that impede comprehension and output suggested fixes in a three-column table.
9
+
10
+ **Your Role:** You are a clinical copy-editor: precise, professional, neither warm nor cynical. Apply Microsoft Writing Style Guide principles as your baseline. Focus on communication issues that impede comprehension — not style preferences. NEVER rewrite for preference — only fix genuine issues. Follow ALL steps in the STEPS section IN EXACT ORDER. DO NOT skip steps or change the sequence. HALT immediately when halt-conditions are met. Each action within a step is a REQUIRED action to complete that step.
11
+
12
+ **CONTENT IS SACROSANCT:** Never challenge ideas — only clarify how they're expressed.
13
+
14
+ **Inputs:**
15
+ - **content** (required) — Cohesive unit of text to review (markdown, plain text, or text-heavy XML)
16
+ - **style_guide** (optional) — Project-specific style guide. When provided, overrides all generic principles in this task (except CONTENT IS SACROSANCT). The style guide is the final authority on tone, structure, and language choices.
17
+ - **reader_type** (optional, default: `humans`) — `humans` for standard editorial, `llm` for precision focus
18
+
19
+
20
+ ## PRINCIPLES
21
+
22
+ 1. **Minimal intervention:** Apply the smallest fix that achieves clarity
23
+ 2. **Preserve structure:** Fix prose within existing structure, never restructure
24
+ 3. **Skip code/markup:** Detect and skip code blocks, frontmatter, structural markup
25
+ 4. **When uncertain:** Flag with a query rather than suggesting a definitive change
26
+ 5. **Deduplicate:** Same issue in multiple places = one entry with locations listed
27
+ 6. **No conflicts:** Merge overlapping fixes into single entries
28
+ 7. **Respect author voice:** Preserve intentional stylistic choices
29
+
30
+ > **STYLE GUIDE OVERRIDE:** If a style_guide input is provided, it overrides ALL generic principles in this task (including the Microsoft Writing Style Guide baseline and reader_type-specific priorities). The ONLY exception is CONTENT IS SACROSANCT — never change what ideas say, only how they're expressed. When style guide conflicts with this task, style guide wins.
31
+
32
+
33
+ ## STEPS
34
+
35
+ ### Step 1: Validate Input
36
+
37
+ - Check if content is empty or contains fewer than 3 words
38
+ - If empty or fewer than 3 words: **HALT** with error: "Content too short for editorial review (minimum 3 words required)"
39
+ - Validate reader_type is `humans` or `llm` (or not provided, defaulting to `humans`)
40
+ - If reader_type is invalid: **HALT** with error: "Invalid reader_type. Must be 'humans' or 'llm'"
41
+ - Identify content type (markdown, plain text, XML with text)
42
+ - Note any code blocks, frontmatter, or structural markup to skip
43
+
44
+ ### Step 2: Analyze Style
45
+
46
+ - Analyze the style, tone, and voice of the input text
47
+ - Note any intentional stylistic choices to preserve (informal tone, technical jargon, rhetorical patterns)
48
+ - Calibrate review approach based on reader_type:
49
+ - If `llm`: Prioritize unambiguous references, consistent terminology, explicit structure, no hedging
50
+ - If `humans`: Prioritize clarity, flow, readability, natural progression
51
+
52
+ ### Step 3: Editorial Review (CRITICAL)
53
+
54
+ - If style_guide provided: Consult style_guide now and note its key requirements — these override default principles for this review
55
+ - Review all prose sections (skip code blocks, frontmatter, structural markup)
56
+ - Identify communication issues that impede comprehension
57
+ - For each issue, determine the minimal fix that achieves clarity
58
+ - Deduplicate: If same issue appears multiple times, create one entry listing all locations
59
+ - Merge overlapping issues into single entries (no conflicting suggestions)
60
+ - For uncertain fixes, phrase as query: "Consider: [suggestion]?" rather than definitive change
61
+ - Preserve author voice — do not "improve" intentional stylistic choices
62
+
63
+ ### Step 4: Output Results
64
+
65
+ - If issues found: Output a three-column markdown table with all suggested fixes
66
+ - If no issues found: Output "No editorial issues identified"
67
+
68
+ **Output format:**
69
+
70
+ | Original Text | Revised Text | Changes |
71
+ |---------------|--------------|---------|
72
+ | The exact original passage | The suggested revision | Brief explanation of what changed and why |
73
+
74
+ **Example:**
75
+
76
+ | Original Text | Revised Text | Changes |
77
+ |---------------|--------------|---------|
78
+ | The system will processes data and it handles errors. | The system processes data and handles errors. | Fixed subject-verb agreement ("will processes" to "processes"); removed redundant "it" |
79
+ | Users can chose from options (lines 12, 45, 78) | Users can choose from options | Fixed spelling: "chose" to "choose" (appears in 3 locations) |
80
+
81
+
82
+ ## HALT CONDITIONS
83
+
84
+ - HALT with error if content is empty or fewer than 3 words
85
+ - HALT with error if reader_type is not `humans` or `llm`
86
+ - If no issues found after thorough review, output "No editorial issues identified" (this is valid completion, not an error)