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,701 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const yaml = require('yaml');
4
+ const crypto = require('node:crypto');
5
+ const csv = require('csv-parse/sync');
6
+ const { getSourcePath, getModulePath } = require('../project-root');
7
+ const prompts = require('../prompts');
8
+ const {
9
+ loadSkillManifest: loadSkillManifestShared,
10
+ getCanonicalId: getCanonicalIdShared,
11
+ getArtifactType: getArtifactTypeShared,
12
+ getInstallToBmad: getInstallToBmadShared,
13
+ } = require('../ide/shared/skill-manifest');
14
+
15
+ // Load package.json for version info
16
+ const packageJson = require('../../../package.json');
17
+
18
+ /**
19
+ * Generates manifest files for installed skills and agents
20
+ */
21
+ class ManifestGenerator {
22
+ constructor() {
23
+ this.skills = [];
24
+ this.agents = [];
25
+ this.modules = [];
26
+ this.files = [];
27
+ this.selectedIdes = [];
28
+ }
29
+
30
+ /** Delegate to shared skill-manifest module */
31
+ async loadSkillManifest(dirPath) {
32
+ return loadSkillManifestShared(dirPath);
33
+ }
34
+
35
+ /** Delegate to shared skill-manifest module */
36
+ getCanonicalId(manifest, filename) {
37
+ return getCanonicalIdShared(manifest, filename);
38
+ }
39
+
40
+ /** Delegate to shared skill-manifest module */
41
+ getArtifactType(manifest, filename) {
42
+ return getArtifactTypeShared(manifest, filename);
43
+ }
44
+
45
+ /** Delegate to shared skill-manifest module */
46
+ getInstallToBmad(manifest, filename) {
47
+ return getInstallToBmadShared(manifest, filename);
48
+ }
49
+
50
+ /**
51
+ * Clean text for CSV output by normalizing whitespace.
52
+ * Note: Quote escaping is handled by escapeCsv() at write time.
53
+ * @param {string} text - Text to clean
54
+ * @returns {string} Cleaned text
55
+ */
56
+ cleanForCSV(text) {
57
+ if (!text) return '';
58
+ return text.trim().replaceAll(/\s+/g, ' '); // Normalize all whitespace (including newlines) to single space
59
+ }
60
+
61
+ /**
62
+ * Generate all manifests for the installation
63
+ * @param {string} scmDir - _scm
64
+ * @param {Array} selectedModules - Selected modules for installation
65
+ * @param {Array} installedFiles - All installed files (optional, for hash tracking)
66
+ */
67
+ async generateManifests(scmDir, selectedModules, installedFiles = [], options = {}) {
68
+ // Create _config directory if it doesn't exist
69
+ const cfgDir = path.join(scmDir, '_config');
70
+ await fs.ensureDir(cfgDir);
71
+
72
+ // Store modules list (all modules including preserved ones)
73
+ const preservedModules = options.preservedModules || [];
74
+
75
+ // Scan the scm directory to find all actually installed modules
76
+ const installedModules = await this.scanInstalledModules(scmDir);
77
+
78
+ // Since custom modules are now installed the same way as regular modules,
79
+ // we don't need to exclude them from manifest generation
80
+ const allModules = [...new Set(['core', ...selectedModules, ...preservedModules, ...installedModules])];
81
+
82
+ this.modules = allModules;
83
+ this.updatedModules = allModules; // Include ALL modules (including custom) for scanning
84
+
85
+ this.scmDir = scmDir;
86
+ this.scmFolderName = path.basename(scmDir); // Get the actual folder name (e.g., '_scm' or 'scm')
87
+ this.allInstalledFiles = installedFiles;
88
+
89
+ if (!Object.prototype.hasOwnProperty.call(options, 'ides')) {
90
+ throw new Error('ManifestGenerator requires `options.ides` to be provided – installer should supply the selected IDEs array.');
91
+ }
92
+
93
+ const resolvedIdes = options.ides ?? [];
94
+ if (!Array.isArray(resolvedIdes)) {
95
+ throw new TypeError('ManifestGenerator expected `options.ides` to be an array.');
96
+ }
97
+
98
+ // Filter out any undefined/null values from IDE list
99
+ this.selectedIdes = resolvedIdes.filter((ide) => ide && typeof ide === 'string');
100
+
101
+ // Reset files list (defensive: prevent stale data if instance is reused)
102
+ this.files = [];
103
+
104
+ // Collect skills first (populates skillClaimedDirs before legacy collectors run)
105
+ await this.collectSkills();
106
+
107
+ // Collect agent data - use updatedModules which includes all installed modules
108
+ await this.collectAgents(this.updatedModules);
109
+
110
+ // Write manifest files and collect their paths
111
+ const manifestFiles = [
112
+ await this.writeMainManifest(cfgDir),
113
+ await this.writeSkillManifest(cfgDir),
114
+ await this.writeAgentManifest(cfgDir),
115
+ await this.writeFilesManifest(cfgDir),
116
+ ];
117
+
118
+ return {
119
+ skills: this.skills.length,
120
+ agents: this.agents.length,
121
+ files: this.files.length,
122
+ manifestFiles: manifestFiles,
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Recursively walk a module directory tree, collecting native SKILL.md entrypoints.
128
+ * A directory is discovered as a skill when it contains a SKILL.md file with
129
+ * valid name/description frontmatter (name must match directory name).
130
+ * Manifest YAML is loaded only when present — for install_to_scm and agent metadata.
131
+ * Populates this.skills[] and this.skillClaimedDirs (Set of absolute paths).
132
+ */
133
+ async collectSkills() {
134
+ this.skills = [];
135
+ this.skillClaimedDirs = new Set();
136
+ const debug = process.env.SCM_DEBUG_MANIFEST === 'true';
137
+
138
+ for (const moduleName of this.updatedModules) {
139
+ const modulePath = path.join(this.scmDir, moduleName);
140
+ if (!(await fs.pathExists(modulePath))) continue;
141
+
142
+ // Recursive walk skipping . and _ prefixed dirs
143
+ const walk = async (dir) => {
144
+ let entries;
145
+ try {
146
+ entries = await fs.readdir(dir, { withFileTypes: true });
147
+ } catch {
148
+ return;
149
+ }
150
+
151
+ // SKILL.md with valid frontmatter is the primary discovery gate
152
+ const skillFile = 'SKILL.md';
153
+ const skillMdPath = path.join(dir, skillFile);
154
+ const dirName = path.basename(dir);
155
+
156
+ const skillMeta = await this.parseSkillMd(skillMdPath, dir, dirName, debug);
157
+
158
+ if (skillMeta) {
159
+ // Load manifest when present (for install_to_scm and agent metadata)
160
+ const manifest = await this.loadSkillManifest(dir);
161
+ const artifactType = this.getArtifactType(manifest, skillFile);
162
+
163
+ // Build path relative from module root (points to SKILL.md — the permanent entrypoint)
164
+ const relativePath = path.relative(modulePath, dir).split(path.sep).join('/');
165
+ const installPath = relativePath
166
+ ? `${this.scmFolderName}/${moduleName}/${relativePath}/${skillFile}`
167
+ : `${this.scmFolderName}/${moduleName}/${skillFile}`;
168
+
169
+ // Native SKILL.md entrypoints derive canonicalId from directory name.
170
+ // Agent entrypoints may keep canonicalId metadata for compatibility, so
171
+ // only warn for non-agent SKILL.md directories.
172
+ if (manifest && manifest.__single && manifest.__single.canonicalId && artifactType !== 'agent') {
173
+ console.warn(
174
+ `Warning: Native entrypoint manifest at ${dir}/scm-skill-manifest.yaml contains canonicalId — this field is ignored for SKILL.md directories (directory name is the canonical ID)`,
175
+ );
176
+ }
177
+ const canonicalId = dirName;
178
+
179
+ this.skills.push({
180
+ name: skillMeta.name,
181
+ description: this.cleanForCSV(skillMeta.description),
182
+ module: moduleName,
183
+ path: installPath,
184
+ canonicalId,
185
+ install_to_scm: this.getInstallToscm(manifest, skillFile),
186
+ });
187
+
188
+ // Add to files list
189
+ this.files.push({
190
+ type: 'skill',
191
+ name: skillMeta.name,
192
+ module: moduleName,
193
+ path: installPath,
194
+ });
195
+
196
+ this.skillClaimedDirs.add(dir);
197
+
198
+ if (debug) {
199
+ console.log(`[DEBUG] collectSkills: claimed skill "${skillMeta.name}" as ${canonicalId} at ${dir}`);
200
+ }
201
+ }
202
+
203
+ // Recurse into subdirectories
204
+ for (const entry of entries) {
205
+ if (!entry.isDirectory()) continue;
206
+ if (entry.name.startsWith('.') || entry.name.startsWith('_')) continue;
207
+ await walk(path.join(dir, entry.name));
208
+ }
209
+ };
210
+
211
+ await walk(modulePath);
212
+ }
213
+
214
+ if (debug) {
215
+ console.log(`[DEBUG] collectSkills: total skills found: ${this.skills.length}, claimed dirs: ${this.skillClaimedDirs.size}`);
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Parse and validate SKILL.md for a skill directory.
221
+ * Returns parsed frontmatter object with name/description, or null if invalid.
222
+ * @param {string} skillMdPath - Absolute path to SKILL.md
223
+ * @param {string} dir - Skill directory path (for error messages)
224
+ * @param {string} dirName - Expected name (must match frontmatter name)
225
+ * @param {boolean} debug - Whether to emit debug-level messages
226
+ * @returns {Promise<Object|null>} Parsed frontmatter or null
227
+ */
228
+ async parseSkillMd(skillMdPath, dir, dirName, debug = false) {
229
+ if (!(await fs.pathExists(skillMdPath))) {
230
+ if (debug) console.log(`[DEBUG] parseSkillMd: "${dir}" is missing SKILL.md — skipping`);
231
+ return null;
232
+ }
233
+
234
+ try {
235
+ const rawContent = await fs.readFile(skillMdPath, 'utf8');
236
+ const content = rawContent.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
237
+
238
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
239
+ if (frontmatterMatch) {
240
+ const skillMeta = yaml.parse(frontmatterMatch[1]);
241
+
242
+ if (
243
+ !skillMeta ||
244
+ typeof skillMeta !== 'object' ||
245
+ typeof skillMeta.name !== 'string' ||
246
+ typeof skillMeta.description !== 'string' ||
247
+ !skillMeta.name ||
248
+ !skillMeta.description
249
+ ) {
250
+ if (debug) console.log(`[DEBUG] parseSkillMd: SKILL.md in "${dir}" is missing name or description (or wrong type) — skipping`);
251
+ return null;
252
+ }
253
+
254
+ if (skillMeta.name !== dirName) {
255
+ console.error(`Error: SKILL.md name "${skillMeta.name}" does not match directory name "${dirName}" — skipping`);
256
+ return null;
257
+ }
258
+
259
+ return skillMeta;
260
+ }
261
+
262
+ if (debug) console.log(`[DEBUG] parseSkillMd: SKILL.md in "${dir}" has no frontmatter — skipping`);
263
+ return null;
264
+ } catch (error) {
265
+ if (debug) console.log(`[DEBUG] parseSkillMd: failed to parse SKILL.md in "${dir}": ${error.message} — skipping`);
266
+ return null;
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Collect all agents from selected modules by walking their directory trees.
272
+ */
273
+ async collectAgents(selectedModules) {
274
+ this.agents = [];
275
+ const debug = process.env.SCM_DEBUG_MANIFEST === 'true';
276
+
277
+ // Walk each module's full directory tree looking for type:agent manifests
278
+ for (const moduleName of this.updatedModules) {
279
+ const modulePath = path.join(this.scmDir, moduleName);
280
+ if (!(await fs.pathExists(modulePath))) continue;
281
+
282
+ const moduleAgents = await this.getAgentsFromDirRecursive(modulePath, moduleName, '', debug);
283
+ this.agents.push(...moduleAgents);
284
+ }
285
+
286
+ // Get standalone agents from scm/agents/ directory
287
+ const standaloneAgentsDir = path.join(this.scmDir, 'agents');
288
+ if (await fs.pathExists(standaloneAgentsDir)) {
289
+ const standaloneAgents = await this.getAgentsFromDirRecursive(standaloneAgentsDir, 'standalone', '', debug);
290
+ this.agents.push(...standaloneAgents);
291
+ }
292
+
293
+ if (debug) {
294
+ console.log(`[DEBUG] collectAgents: total agents found: ${this.agents.length}`);
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Recursively walk a directory tree collecting agents.
300
+ * Discovers agents via directory with scm-skill-manifest.yaml containing type: agent
301
+ *
302
+ * @param {string} dirPath - Current directory being scanned
303
+ * @param {string} moduleName - Module this directory belongs to
304
+ * @param {string} relativePath - Path relative to the module root (for install path construction)
305
+ * @param {boolean} debug - Emit debug messages
306
+ */
307
+ async getAgentsFromDirRecursive(dirPath, moduleName, relativePath = '', debug = false) {
308
+ const agents = [];
309
+ let entries;
310
+ try {
311
+ entries = await fs.readdir(dirPath, { withFileTypes: true });
312
+ } catch {
313
+ return agents;
314
+ }
315
+
316
+ for (const entry of entries) {
317
+ if (!entry.isDirectory()) continue;
318
+ if (entry.name.startsWith('.') || entry.name.startsWith('_')) continue;
319
+
320
+ const fullPath = path.join(dirPath, entry.name);
321
+
322
+ // Check for type:agent manifest BEFORE checking skillClaimedDirs —
323
+ // agent dirs may be claimed by collectSkills for IDE installation,
324
+ // but we still need them in agent-manifest.csv.
325
+ const dirManifest = await this.loadSkillManifest(fullPath);
326
+ if (dirManifest && dirManifest.__single && dirManifest.__single.type === 'agent') {
327
+ const m = dirManifest.__single;
328
+ const dirRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
329
+ const agentModule = m.module || moduleName;
330
+ const installPath = `${this.scmFolderName}/${agentModule}/${dirRelativePath}`;
331
+
332
+ agents.push({
333
+ name: m.name || entry.name,
334
+ displayName: m.displayName || m.name || entry.name,
335
+ title: m.title || '',
336
+ icon: m.icon || '',
337
+ capabilities: m.capabilities ? this.cleanForCSV(m.capabilities) : '',
338
+ role: m.role ? this.cleanForCSV(m.role) : '',
339
+ identity: m.identity ? this.cleanForCSV(m.identity) : '',
340
+ communicationStyle: m.communicationStyle ? this.cleanForCSV(m.communicationStyle) : '',
341
+ principles: m.principles ? this.cleanForCSV(m.principles) : '',
342
+ module: agentModule,
343
+ path: installPath,
344
+ canonicalId: m.canonicalId || '',
345
+ });
346
+
347
+ this.files.push({
348
+ type: 'agent',
349
+ name: m.name || entry.name,
350
+ module: agentModule,
351
+ path: installPath,
352
+ });
353
+
354
+ if (debug) {
355
+ console.log(`[DEBUG] collectAgents: found type:agent "${m.name || entry.name}" at ${fullPath}`);
356
+ }
357
+ continue;
358
+ }
359
+
360
+ // Skip directories claimed by collectSkills (non-agent type skills) —
361
+ // avoids recursing into skill trees that can't contain agents.
362
+ if (this.skillClaimedDirs && this.skillClaimedDirs.has(fullPath)) continue;
363
+
364
+ // Recurse into subdirectories
365
+ const newRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
366
+ const subDirAgents = await this.getAgentsFromDirRecursive(fullPath, moduleName, newRelativePath, debug);
367
+ agents.push(...subDirAgents);
368
+ }
369
+
370
+ return agents;
371
+ }
372
+
373
+ /**
374
+ * Write main manifest as YAML with installation info only
375
+ * Fetches fresh version info for all modules
376
+ * @returns {string} Path to the manifest file
377
+ */
378
+ async writeMainManifest(cfgDir) {
379
+ const manifestPath = path.join(cfgDir, 'manifest.yaml');
380
+
381
+ // Read existing manifest to preserve install date
382
+ let existingInstallDate = null;
383
+ const existingModulesMap = new Map();
384
+
385
+ if (await fs.pathExists(manifestPath)) {
386
+ try {
387
+ const existingContent = await fs.readFile(manifestPath, 'utf8');
388
+ const existingManifest = yaml.parse(existingContent);
389
+
390
+ // Preserve original install date
391
+ if (existingManifest.installation?.installDate) {
392
+ existingInstallDate = existingManifest.installation.installDate;
393
+ }
394
+
395
+ // Build map of existing modules for quick lookup
396
+ if (existingManifest.modules && Array.isArray(existingManifest.modules)) {
397
+ for (const m of existingManifest.modules) {
398
+ if (typeof m === 'object' && m.name) {
399
+ existingModulesMap.set(m.name, m);
400
+ } else if (typeof m === 'string') {
401
+ existingModulesMap.set(m, { installDate: existingInstallDate });
402
+ }
403
+ }
404
+ }
405
+ } catch {
406
+ // If we can't read existing manifest, continue with defaults
407
+ }
408
+ }
409
+
410
+ // Fetch fresh version info for all modules
411
+ const { Manifest } = require('./manifest');
412
+ const manifestObj = new Manifest();
413
+ const updatedModules = [];
414
+
415
+ for (const moduleName of this.modules) {
416
+ // Get fresh version info from source
417
+ const versionInfo = await manifestObj.getModuleVersionInfo(moduleName, this.scmDir);
418
+
419
+ // Get existing install date if available
420
+ const existing = existingModulesMap.get(moduleName);
421
+
422
+ updatedModules.push({
423
+ name: moduleName,
424
+ version: versionInfo.version,
425
+ installDate: existing?.installDate || new Date().toISOString(),
426
+ lastUpdated: new Date().toISOString(),
427
+ source: versionInfo.source,
428
+ npmPackage: versionInfo.npmPackage,
429
+ repoUrl: versionInfo.repoUrl,
430
+ });
431
+ }
432
+
433
+ const manifest = {
434
+ installation: {
435
+ version: packageJson.version,
436
+ installDate: existingInstallDate || new Date().toISOString(),
437
+ lastUpdated: new Date().toISOString(),
438
+ },
439
+ modules: updatedModules,
440
+ ides: this.selectedIdes,
441
+ };
442
+
443
+ // Clean the manifest to remove any non-serializable values
444
+ const cleanManifest = structuredClone(manifest);
445
+
446
+ const yamlStr = yaml.stringify(cleanManifest, {
447
+ indent: 2,
448
+ lineWidth: 0,
449
+ sortKeys: false,
450
+ });
451
+
452
+ // Ensure POSIX-compliant final newline
453
+ const content = yamlStr.endsWith('\n') ? yamlStr : yamlStr + '\n';
454
+ await fs.writeFile(manifestPath, content);
455
+ return manifestPath;
456
+ }
457
+
458
+ /**
459
+ * Write skill manifest CSV
460
+ * @returns {string} Path to the manifest file
461
+ */
462
+ async writeSkillManifest(cfgDir) {
463
+ const csvPath = path.join(cfgDir, 'skill-manifest.csv');
464
+ const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
465
+
466
+ let csvContent = 'canonicalId,name,description,module,path,install_to_scm\n';
467
+
468
+ for (const skill of this.skills) {
469
+ const row = [
470
+ escapeCsv(skill.canonicalId),
471
+ escapeCsv(skill.name),
472
+ escapeCsv(skill.description),
473
+ escapeCsv(skill.module),
474
+ escapeCsv(skill.path),
475
+ escapeCsv(skill.install_to_scm),
476
+ ].join(',');
477
+ csvContent += row + '\n';
478
+ }
479
+
480
+ await fs.writeFile(csvPath, csvContent);
481
+ return csvPath;
482
+ }
483
+
484
+ /**
485
+ * Write agent manifest CSV
486
+ * @returns {string} Path to the manifest file
487
+ */
488
+ async writeAgentManifest(cfgDir) {
489
+ const csvPath = path.join(cfgDir, 'agent-manifest.csv');
490
+ const escapeCsv = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
491
+
492
+ // Read existing manifest to preserve entries
493
+ const existingEntries = new Map();
494
+ if (await fs.pathExists(csvPath)) {
495
+ const content = await fs.readFile(csvPath, 'utf8');
496
+ const records = csv.parse(content, {
497
+ columns: true,
498
+ skip_empty_lines: true,
499
+ });
500
+ for (const record of records) {
501
+ existingEntries.set(`${record.module}:${record.name}`, record);
502
+ }
503
+ }
504
+
505
+ // Create CSV header with persona fields and canonicalId
506
+ let csvContent = 'name,displayName,title,icon,capabilities,role,identity,communicationStyle,principles,module,path,canonicalId\n';
507
+
508
+ // Combine existing and new agents, preferring new data for duplicates
509
+ const allAgents = new Map();
510
+
511
+ // Add existing entries
512
+ for (const [key, value] of existingEntries) {
513
+ allAgents.set(key, value);
514
+ }
515
+
516
+ // Add/update new agents
517
+ for (const agent of this.agents) {
518
+ const key = `${agent.module}:${agent.name}`;
519
+ allAgents.set(key, {
520
+ name: agent.name,
521
+ displayName: agent.displayName,
522
+ title: agent.title,
523
+ icon: agent.icon,
524
+ capabilities: agent.capabilities,
525
+ role: agent.role,
526
+ identity: agent.identity,
527
+ communicationStyle: agent.communicationStyle,
528
+ principles: agent.principles,
529
+ module: agent.module,
530
+ path: agent.path,
531
+ canonicalId: agent.canonicalId || '',
532
+ });
533
+ }
534
+
535
+ // Write all agents
536
+ for (const [, record] of allAgents) {
537
+ const row = [
538
+ escapeCsv(record.name),
539
+ escapeCsv(record.displayName),
540
+ escapeCsv(record.title),
541
+ escapeCsv(record.icon),
542
+ escapeCsv(record.capabilities),
543
+ escapeCsv(record.role),
544
+ escapeCsv(record.identity),
545
+ escapeCsv(record.communicationStyle),
546
+ escapeCsv(record.principles),
547
+ escapeCsv(record.module),
548
+ escapeCsv(record.path),
549
+ escapeCsv(record.canonicalId),
550
+ ].join(',');
551
+ csvContent += row + '\n';
552
+ }
553
+
554
+ await fs.writeFile(csvPath, csvContent);
555
+ return csvPath;
556
+ }
557
+
558
+ /**
559
+ * Write files manifest CSV
560
+ */
561
+ /**
562
+ * Calculate SHA256 hash of a file
563
+ * @param {string} filePath - Path to file
564
+ * @returns {string} SHA256 hash
565
+ */
566
+ async calculateFileHash(filePath) {
567
+ try {
568
+ const content = await fs.readFile(filePath);
569
+ return crypto.createHash('sha256').update(content).digest('hex');
570
+ } catch {
571
+ return '';
572
+ }
573
+ }
574
+
575
+ /**
576
+ * @returns {string} Path to the manifest file
577
+ */
578
+ async writeFilesManifest(cfgDir) {
579
+ const csvPath = path.join(cfgDir, 'files-manifest.csv');
580
+
581
+ // Create CSV header with hash column
582
+ let csv = 'type,name,module,path,hash\n';
583
+
584
+ // If we have ALL installed files, use those instead of just workflows/agents/tasks
585
+ const allFiles = [];
586
+ if (this.allInstalledFiles && this.allInstalledFiles.length > 0) {
587
+ // Process all installed files
588
+ for (const filePath of this.allInstalledFiles) {
589
+ // Store paths relative to scmDir (no folder prefix)
590
+ const relativePath = filePath.replace(this.scmDir, '').replaceAll('\\', '/').replace(/^\//, '');
591
+ const ext = path.extname(filePath).toLowerCase();
592
+ const fileName = path.basename(filePath, ext);
593
+
594
+ // Determine module from path (first directory component)
595
+ const pathParts = relativePath.split('/');
596
+ const module = pathParts.length > 0 ? pathParts[0] : 'unknown';
597
+
598
+ // Calculate hash
599
+ const hash = await this.calculateFileHash(filePath);
600
+
601
+ allFiles.push({
602
+ type: ext.slice(1) || 'file',
603
+ name: fileName,
604
+ module: module,
605
+ path: relativePath,
606
+ hash: hash,
607
+ });
608
+ }
609
+ } else {
610
+ // Fallback: use the collected workflows/agents/tasks
611
+ for (const file of this.files) {
612
+ // Strip the folder prefix if present (for consistency)
613
+ const relPath = file.path.replace(this.scmFolderName + '/', '');
614
+ const filePath = path.join(this.scmDir, relPath);
615
+ const hash = await this.calculateFileHash(filePath);
616
+ allFiles.push({
617
+ ...file,
618
+ path: relPath,
619
+ hash: hash,
620
+ });
621
+ }
622
+ }
623
+
624
+ // Sort files by module, then type, then name
625
+ allFiles.sort((a, b) => {
626
+ if (a.module !== b.module) return a.module.localeCompare(b.module);
627
+ if (a.type !== b.type) return a.type.localeCompare(b.type);
628
+ return a.name.localeCompare(b.name);
629
+ });
630
+
631
+ // Add all files
632
+ for (const file of allFiles) {
633
+ csv += `"${file.type}","${file.name}","${file.module}","${file.path}","${file.hash}"\n`;
634
+ }
635
+
636
+ await fs.writeFile(csvPath, csv);
637
+ return csvPath;
638
+ }
639
+
640
+ /**
641
+ * Scan the scm directory to find all installed modules
642
+ * @param {string} scmDir - Path to scm directory
643
+ * @returns {Array} List of module names
644
+ */
645
+ async scanInstalledModules(scmDir) {
646
+ const modules = [];
647
+
648
+ try {
649
+ const entries = await fs.readdir(scmDir, { withFileTypes: true });
650
+
651
+ for (const entry of entries) {
652
+ // Skip if not a directory or is a special directory
653
+ if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === '_config') {
654
+ continue;
655
+ }
656
+
657
+ // Check if this looks like a module (has agents directory or skill manifests)
658
+ const modulePath = path.join(scmDir, entry.name);
659
+ const hasAgents = await fs.pathExists(path.join(modulePath, 'agents'));
660
+ const hasSkills = await this._hasSkillMdRecursive(modulePath);
661
+
662
+ if (hasAgents || hasSkills) {
663
+ modules.push(entry.name);
664
+ }
665
+ }
666
+ } catch (error) {
667
+ await prompts.log.warn(`Could not scan for installed modules: ${error.message}`);
668
+ }
669
+
670
+ return modules;
671
+ }
672
+
673
+ /**
674
+ * Recursively check if a directory tree contains a SKILL.md file.
675
+ * Skips directories starting with . or _.
676
+ * @param {string} dir - Directory to search
677
+ * @returns {boolean} True if a SKILL.md is found
678
+ */
679
+ async _hasSkillMdRecursive(dir) {
680
+ let entries;
681
+ try {
682
+ entries = await fs.readdir(dir, { withFileTypes: true });
683
+ } catch {
684
+ return false;
685
+ }
686
+
687
+ // Check for SKILL.md in this directory
688
+ if (entries.some((e) => !e.isDirectory() && e.name === 'SKILL.md')) return true;
689
+
690
+ // Recurse into subdirectories
691
+ for (const entry of entries) {
692
+ if (!entry.isDirectory()) continue;
693
+ if (entry.name.startsWith('.') || entry.name.startsWith('_')) continue;
694
+ if (await this._hasSkillMdRecursive(path.join(dir, entry.name))) return true;
695
+ }
696
+
697
+ return false;
698
+ }
699
+ }
700
+
701
+ module.exports = { ManifestGenerator };