bmad-method 6.0.0-alpha.13 → 6.0.0-alpha.15

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 (355) hide show
  1. package/.coderabbit.yaml +36 -0
  2. package/.github/CODE_OF_CONDUCT.md +128 -0
  3. package/.github/ISSUE_TEMPLATE/idea_submission.md +1 -1
  4. package/.github/scripts/discord-helpers.sh +15 -0
  5. package/.github/workflows/discord.yaml +278 -8
  6. package/.github/workflows/quality.yaml +19 -0
  7. package/.markdownlint-cli2.yaml +42 -0
  8. package/.prettierignore +3 -0
  9. package/CHANGELOG.md +183 -360
  10. package/README.md +4 -1
  11. package/docs/agent-customization-guide.md +2 -2
  12. package/docs/custom-content-installation.md +245 -0
  13. package/docs/document-sharding-guide.md +1 -1
  14. package/docs/index.md +2 -2
  15. package/docs/installers-bundlers/installers-modules-platforms-reference.md +6 -5
  16. package/docs/web-bundles-gemini-gpt-guide.md +1 -1
  17. package/eslint.config.mjs +14 -0
  18. package/example-custom-content/README.md +8 -0
  19. package/{custom/src → example-custom-content}/agents/commit-poet/commit-poet.agent.yaml +1 -1
  20. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/instructions.md +5 -5
  21. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/docs.md +1 -1
  22. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/installers.md +1 -1
  23. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/modules.md +2 -2
  24. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/memories.md +1 -1
  25. package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith.agent.yaml +18 -17
  26. package/example-custom-content/module.yaml +4 -0
  27. package/example-custom-content/workflows/quiz-master/steps/step-01-init.md +168 -0
  28. package/example-custom-content/workflows/quiz-master/steps/step-02-q1.md +155 -0
  29. package/example-custom-content/workflows/quiz-master/steps/step-03-q2.md +89 -0
  30. package/example-custom-content/workflows/quiz-master/steps/step-04-q3.md +36 -0
  31. package/example-custom-content/workflows/quiz-master/steps/step-05-q4.md +36 -0
  32. package/example-custom-content/workflows/quiz-master/steps/step-06-q5.md +36 -0
  33. package/example-custom-content/workflows/quiz-master/steps/step-07-q6.md +36 -0
  34. package/example-custom-content/workflows/quiz-master/steps/step-08-q7.md +36 -0
  35. package/example-custom-content/workflows/quiz-master/steps/step-09-q8.md +36 -0
  36. package/example-custom-content/workflows/quiz-master/steps/step-10-q9.md +36 -0
  37. package/example-custom-content/workflows/quiz-master/steps/step-11-q10.md +36 -0
  38. package/example-custom-content/workflows/quiz-master/steps/step-12-results.md +150 -0
  39. package/example-custom-content/workflows/quiz-master/templates/csv-headers.template +1 -0
  40. package/example-custom-content/workflows/quiz-master/workflow.md +54 -0
  41. package/example-custom-content/workflows/wassup/workflow.md +26 -0
  42. package/example-custom-module/mwm/README.md +9 -0
  43. package/example-custom-module/mwm/agents/cbt-coach/cbt-coach-sidecar/cognitive-distortions.md +47 -0
  44. package/example-custom-module/mwm/agents/cbt-coach/cbt-coach-sidecar/thought-records.md +17 -0
  45. package/example-custom-module/mwm/agents/cbt-coach/cbt-coach.agent.yaml +151 -0
  46. package/example-custom-module/mwm/agents/crisis-navigator.agent.yaml +138 -0
  47. package/example-custom-module/mwm/agents/meditation-guide.agent.yaml +138 -0
  48. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/insights.md +13 -0
  49. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/instructions.md +30 -0
  50. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/memories.md +13 -0
  51. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion-sidecar/patterns.md +17 -0
  52. package/example-custom-module/mwm/agents/wellness-companion/wellness-companion.agent.yaml +125 -0
  53. package/example-custom-module/mwm/module.yaml +28 -0
  54. package/example-custom-module/mwm/workflows/cbt-thought-record/README.md +31 -0
  55. package/example-custom-module/mwm/workflows/cbt-thought-record/workflow.md +45 -0
  56. package/example-custom-module/mwm/workflows/crisis-support/README.md +31 -0
  57. package/example-custom-module/mwm/workflows/crisis-support/workflow.md +45 -0
  58. package/example-custom-module/mwm/workflows/daily-checkin/README.md +32 -0
  59. package/example-custom-module/mwm/workflows/daily-checkin/workflow.md +45 -0
  60. package/example-custom-module/mwm/workflows/guided-meditation/README.md +31 -0
  61. package/example-custom-module/mwm/workflows/guided-meditation/workflow.md +45 -0
  62. package/example-custom-module/mwm/workflows/wellness-journal/README.md +31 -0
  63. package/example-custom-module/mwm/workflows/wellness-journal/workflow.md +45 -0
  64. package/package.json +9 -4
  65. package/src/core/_module-installer/installer.js +1 -1
  66. package/src/core/{_module-installer/install-config.yaml → module.yaml} +5 -1
  67. package/src/core/resources/excalidraw/library-loader.md +2 -2
  68. package/src/core/workflows/brainstorming/steps/step-01-session-setup.md +1 -1
  69. package/src/core/workflows/brainstorming/workflow.md +1 -1
  70. package/src/core/workflows/party-mode/steps/step-03-graceful-exit.md +0 -1
  71. package/src/core/workflows/party-mode/workflow.md +2 -3
  72. package/src/modules/bmb/README.md +1 -1
  73. package/src/modules/bmb/_module-installer/installer.js +76 -0
  74. package/src/modules/bmb/agents/bmad-builder.agent.yaml +32 -9
  75. package/src/modules/bmb/docs/agents/agent-menu-patterns.md +5 -5
  76. package/src/modules/bmb/docs/agents/expert-agent-architecture.md +20 -20
  77. package/src/modules/bmb/docs/agents/index.md +1 -1
  78. package/src/modules/bmb/docs/agents/module-agent-architecture.md +45 -45
  79. package/src/modules/bmb/docs/agents/simple-agent-architecture.md +7 -3
  80. package/src/modules/bmb/docs/workflows/architecture.md +1 -1
  81. package/src/modules/bmb/docs/workflows/templates/step-01-init-continuable-template.md +241 -0
  82. package/src/modules/bmb/docs/workflows/templates/step-1b-template.md +223 -0
  83. package/src/modules/bmb/{workflows/create-workflow → docs/workflows}/templates/step-file.md +4 -4
  84. package/src/modules/bmb/docs/workflows/{step-template.md → templates/step-template.md} +40 -33
  85. package/src/modules/bmb/docs/workflows/templates/workflow-template.md +104 -0
  86. package/src/modules/bmb/{workflows/create-workflow → docs/workflows}/templates/workflow.md +1 -1
  87. package/src/modules/bmb/{_module-installer/install-config.yaml → module.yaml} +4 -9
  88. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/README.md +4 -4
  89. package/src/modules/bmb/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +8 -8
  90. package/src/modules/bmb/reference/agents/module-examples/security-engineer.agent.yaml +6 -6
  91. package/src/modules/bmb/reference/agents/module-examples/trend-analyst.agent.yaml +7 -7
  92. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01-init.md +2 -3
  93. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-01b-continue.md +10 -40
  94. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-02-profile.md +1 -1
  95. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-03-assessment.md +1 -0
  96. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-04-strategy.md +2 -2
  97. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +2 -2
  98. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/steps/step-06-prep-schedule.md +2 -2
  99. package/src/modules/bmb/reference/workflows/meal-prep-nutrition/workflow.md +2 -2
  100. package/src/modules/bmb/workflows/create-agent/data/info-and-installation-guide.md +16 -4
  101. package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/README.md +4 -4
  102. package/src/modules/bmb/workflows/create-agent/data/reference/agents/expert-examples/journal-keeper/journal-keeper.agent.yaml +7 -7
  103. package/src/modules/bmb/workflows/create-agent/data/reference/workflows/meal-prep-nutrition/steps/step-05-shopping.md +1 -1
  104. package/src/modules/bmb/workflows/create-agent/data/validation-complete.md +3 -3
  105. package/src/modules/bmb/workflows/create-agent/steps/step-01-brainstorm.md +3 -3
  106. package/src/modules/bmb/workflows/create-agent/steps/step-02-discover.md +3 -3
  107. package/src/modules/bmb/workflows/create-agent/steps/step-03-persona.md +3 -3
  108. package/src/modules/bmb/workflows/create-agent/steps/step-04-commands.md +6 -6
  109. package/src/modules/bmb/workflows/create-agent/steps/step-05-name.md +2 -2
  110. package/src/modules/bmb/workflows/create-agent/steps/step-06-build.md +3 -3
  111. package/src/modules/bmb/workflows/create-agent/steps/step-07-validate.md +3 -3
  112. package/src/modules/bmb/workflows/create-agent/steps/step-08-setup.md +2 -2
  113. package/src/modules/bmb/workflows/create-agent/steps/step-09-customize.md +3 -3
  114. package/src/modules/bmb/workflows/create-agent/steps/step-10-build-tools.md +2 -2
  115. package/src/modules/bmb/workflows/create-agent/steps/step-11-celebrate.md +2 -2
  116. package/src/modules/bmb/workflows/create-agent/workflow.md +11 -11
  117. package/src/modules/bmb/workflows/create-module/steps/step-01-init.md +155 -0
  118. package/src/modules/bmb/workflows/create-module/steps/step-01b-continue.md +169 -0
  119. package/src/modules/bmb/workflows/create-module/steps/step-02-concept.md +217 -0
  120. package/src/modules/bmb/workflows/create-module/steps/step-03-components.md +267 -0
  121. package/src/modules/bmb/workflows/create-module/steps/step-04-structure.md +228 -0
  122. package/src/modules/bmb/workflows/create-module/steps/step-05-config.md +233 -0
  123. package/src/modules/bmb/workflows/create-module/steps/step-06-agents.md +296 -0
  124. package/src/modules/bmb/workflows/create-module/steps/step-07-workflows.md +228 -0
  125. package/src/modules/bmb/workflows/create-module/steps/step-08-installer.md +186 -0
  126. package/src/modules/bmb/workflows/create-module/steps/step-09-documentation.md +309 -0
  127. package/src/modules/bmb/workflows/create-module/steps/step-10-roadmap.md +337 -0
  128. package/src/modules/bmb/workflows/create-module/steps/step-11-validate.md +335 -0
  129. package/src/modules/bmb/workflows/create-module/templates/agent.template.md +317 -0
  130. package/src/modules/bmb/workflows/create-module/templates/installer.template.js +47 -0
  131. package/src/modules/bmb/workflows/create-module/templates/module-plan.template.md +5 -0
  132. package/src/modules/bmb/workflows/create-module/templates/module.template.yaml +53 -0
  133. package/src/modules/bmb/workflows/create-module/templates/workflow-plan-template.md +23 -0
  134. package/src/modules/bmb/workflows/create-module/validation.md +126 -0
  135. package/src/modules/bmb/workflows/create-module/workflow.md +55 -0
  136. package/src/modules/bmb/workflows/create-workflow/steps/step-01-init.md +45 -56
  137. package/src/modules/bmb/workflows/create-workflow/steps/step-02-gather.md +9 -31
  138. package/src/modules/bmb/workflows/create-workflow/steps/step-03-tools-configuration.md +250 -0
  139. package/src/modules/bmb/workflows/create-workflow/steps/step-04-plan-review.md +216 -0
  140. package/src/modules/bmb/workflows/create-workflow/steps/step-05-output-format-design.md +289 -0
  141. package/src/modules/bmb/workflows/create-workflow/steps/{step-09-design.md → step-06-design.md} +76 -44
  142. package/src/modules/bmb/workflows/create-workflow/steps/{step-11-build.md → step-07-build.md} +71 -25
  143. package/src/modules/bmb/workflows/create-workflow/steps/{step-12-review.md → step-08-review.md} +30 -16
  144. package/src/modules/bmb/workflows/create-workflow/steps/step-09-complete.md +187 -0
  145. package/src/modules/bmb/workflows/create-workflow/workflow.md +2 -2
  146. package/src/modules/bmb/workflows/edit-agent/steps/step-01-discover-intent.md +2 -2
  147. package/src/modules/bmb/workflows/edit-agent/steps/step-02-analyze-agent.md +14 -14
  148. package/src/modules/bmb/workflows/edit-agent/steps/step-03-propose-changes.md +4 -4
  149. package/src/modules/bmb/workflows/edit-agent/steps/step-04-apply-changes.md +2 -2
  150. package/src/modules/bmb/workflows/edit-agent/steps/step-05-validate.md +4 -4
  151. package/src/modules/bmb/workflows/edit-agent/workflow.md +1 -1
  152. package/src/modules/bmb/workflows/edit-workflow/steps/step-01-analyze.md +2 -6
  153. package/src/modules/bmb/workflows/edit-workflow/steps/step-03-improve.md +2 -2
  154. package/src/modules/bmb/workflows/edit-workflow/steps/step-04-validate.md +1 -1
  155. package/src/modules/bmb/workflows/edit-workflow/workflow.md +1 -1
  156. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-01-validate-goal.md +2 -2
  157. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-02-workflow-validation.md +5 -5
  158. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-03-step-validation.md +7 -7
  159. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-04-file-validation.md +3 -3
  160. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-05-intent-spectrum-validation.md +3 -3
  161. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-06-web-subprocess-validation.md +3 -3
  162. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-07-holistic-analysis.md +3 -3
  163. package/src/modules/bmb/workflows/workflow-compliance-check/steps/step-08-generate-report.md +2 -2
  164. package/src/modules/bmb/workflows/workflow-compliance-check/workflow.md +1 -1
  165. package/src/modules/bmb/workflows-legacy/edit-module/checklist.md +0 -1
  166. package/src/modules/bmgd/README.md +2 -1
  167. package/src/modules/bmgd/workflows/3-technical/game-architecture/instructions.md +8 -8
  168. package/src/modules/bmm/_module-installer/installer.js +1 -1
  169. package/src/modules/bmm/_module-installer/platform-specifics/claude-code.js +1 -1
  170. package/src/modules/bmm/_module-installer/platform-specifics/windsurf.js +1 -1
  171. package/src/modules/bmm/agents/analyst.agent.yaml +11 -8
  172. package/src/modules/bmm/agents/architect.agent.yaml +1 -5
  173. package/src/modules/bmm/agents/pm.agent.yaml +5 -5
  174. package/src/modules/bmm/docs/README.md +23 -1
  175. package/src/modules/bmm/docs/agents-guide.md +16 -35
  176. package/src/modules/bmm/docs/brownfield-guide.md +17 -30
  177. package/src/modules/bmm/docs/enterprise-agentic-development.md +2 -2
  178. package/src/modules/bmm/docs/faq.md +6 -39
  179. package/src/modules/bmm/docs/glossary.md +11 -24
  180. package/src/modules/bmm/docs/images/README.md +37 -0
  181. package/src/modules/bmm/docs/images/workflow-method-greenfield.excalidraw +62 -202
  182. package/src/modules/bmm/docs/images/workflow-method-greenfield.svg +3 -1
  183. package/src/modules/bmm/docs/quick-spec-flow.md +652 -0
  184. package/src/modules/bmm/docs/quick-start.md +9 -25
  185. package/src/modules/bmm/docs/test-architecture.md +6 -6
  186. package/src/modules/bmm/docs/troubleshooting.md +680 -0
  187. package/src/modules/bmm/docs/workflow-document-project-reference.md +1 -1
  188. package/src/modules/bmm/docs/workflows-implementation.md +143 -3
  189. package/src/modules/bmm/docs/workflows-solutioning.md +2 -2
  190. package/src/modules/bmm/{_module-installer/install-config.yaml → module.yaml} +1 -1
  191. package/src/modules/bmm/tasks/daily-standup.xml +85 -0
  192. package/src/modules/bmm/testarch/knowledge/ci-burn-in.md +1 -1
  193. package/src/modules/bmm/testarch/knowledge/overview.md +1 -1
  194. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-02-vision.md +2 -2
  195. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-03-users.md +2 -2
  196. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-04-metrics.md +2 -2
  197. package/src/modules/bmm/workflows/1-analysis/product-brief/steps/step-05-scope.md +2 -2
  198. package/src/modules/bmm/workflows/1-analysis/product-brief/workflow.md +1 -1
  199. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +8 -8
  200. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +18 -18
  201. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +18 -18
  202. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +18 -18
  203. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +17 -17
  204. package/src/modules/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +35 -36
  205. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +5 -6
  206. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +20 -19
  207. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +21 -20
  208. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +20 -19
  209. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +21 -20
  210. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +16 -15
  211. package/src/modules/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +36 -37
  212. package/src/modules/bmm/workflows/1-analysis/research/research.template.md +0 -1
  213. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +8 -8
  214. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +19 -18
  215. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +20 -19
  216. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +21 -20
  217. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +19 -18
  218. package/src/modules/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +38 -39
  219. package/src/modules/bmm/workflows/1-analysis/research/workflow.md +14 -8
  220. package/src/modules/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +6 -0
  221. package/src/modules/bmm/workflows/2-plan-workflows/prd/prd-template.md +7 -0
  222. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01-init.md +138 -56
  223. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-01b-continue.md +93 -51
  224. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-02-discovery.md +223 -78
  225. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-03-success.md +20 -2
  226. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-04-journeys.md +18 -0
  227. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-05-domain.md +21 -0
  228. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-06-innovation.md +21 -0
  229. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-07-project-type.md +21 -0
  230. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-08-scoping.md +18 -0
  231. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-09-functional.md +18 -0
  232. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-10-nonfunctional.md +18 -0
  233. package/src/modules/bmm/workflows/2-plan-workflows/prd/steps/step-11-complete.md +13 -0
  234. package/src/modules/bmm/workflows/2-plan-workflows/prd/workflow.md +2 -2
  235. package/src/modules/bmm/workflows/3-solutioning/architecture/steps/step-03-starter.md +14 -14
  236. package/src/modules/bmm/workflows/3-solutioning/architecture/steps/step-04-decisions.md +7 -7
  237. package/src/modules/bmm/workflows/3-solutioning/architecture/workflow.md +2 -1
  238. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +258 -0
  239. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +232 -0
  240. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +271 -0
  241. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +144 -0
  242. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
  243. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +58 -0
  244. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-01-document-discovery.md +189 -0
  245. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-02-prd-analysis.md +177 -0
  246. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-03-epic-coverage-validation.md +178 -0
  247. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-04-ux-alignment.md +138 -0
  248. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-05-epic-quality-review.md +251 -0
  249. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/steps/step-06-final-assessment.md +132 -0
  250. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/templates/readiness-report-template.md +4 -0
  251. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/workflow.md +54 -0
  252. package/src/modules/{bmgd/workflows/4-production → bmm/workflows/4-implementation}/code-review/checklist.md +2 -1
  253. package/src/modules/bmm/workflows/4-implementation/code-review/instructions.xml +51 -3
  254. package/src/modules/bmm/workflows/4-implementation/code-review/workflow.yaml +1 -1
  255. package/src/modules/bmm/workflows/4-implementation/create-story/instructions.xml +32 -2
  256. package/src/modules/bmm/workflows/4-implementation/retrospective/instructions.md +3 -3
  257. package/src/modules/bmm/workflows/4-implementation/sprint-planning/instructions.md +19 -21
  258. package/src/modules/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +10 -10
  259. package/src/modules/bmm/workflows/4-implementation/sprint-status/instructions.md +174 -0
  260. package/src/modules/bmm/workflows/4-implementation/sprint-status/workflow.yaml +35 -0
  261. package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/instructions.md +104 -7
  262. package/src/modules/bmm/workflows/bmad-quick-flow/quick-dev/workflow.yaml +4 -0
  263. package/src/modules/bmm/workflows/document-project/instructions.md +1 -1
  264. package/src/modules/bmm/workflows/document-project/workflows/deep-dive-instructions.md +2 -2
  265. package/src/modules/bmm/workflows/generate-project-context/workflow.md +1 -1
  266. package/src/modules/bmm/workflows/testarch/atdd/atdd-checklist-template.md +1 -1
  267. package/src/modules/bmm/workflows/testarch/ci/checklist.md +1 -1
  268. package/src/modules/bmm/workflows/testarch/ci/github-actions-template.yaml +36 -3
  269. package/src/modules/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +25 -4
  270. package/src/modules/bmm/workflows/testarch/ci/instructions.md +2 -2
  271. package/src/modules/bmm/workflows/testarch/test-review/instructions.md +1 -1
  272. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +1 -6
  273. package/src/modules/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +1 -6
  274. package/src/modules/bmm/workflows/workflow-status/paths/method-brownfield.yaml +1 -6
  275. package/src/modules/bmm/workflows/workflow-status/paths/method-greenfield.yaml +1 -7
  276. package/src/modules/cis/_module-installer/installer.js +1 -1
  277. package/tools/cli/README.md +7 -7
  278. package/tools/cli/commands/build.js +9 -184
  279. package/tools/cli/commands/install.js +1 -6
  280. package/tools/cli/installers/lib/core/config-collector.js +80 -12
  281. package/tools/cli/installers/lib/core/custom-module-cache.js +239 -0
  282. package/tools/cli/installers/lib/core/detector.js +8 -4
  283. package/tools/cli/installers/lib/core/installer.js +933 -376
  284. package/tools/cli/installers/lib/core/manifest-generator.js +265 -41
  285. package/tools/cli/installers/lib/core/manifest.js +47 -0
  286. package/tools/cli/installers/lib/core/post-install-sidecar-replacement.js +79 -0
  287. package/tools/cli/installers/lib/custom/handler.js +396 -0
  288. package/tools/cli/installers/lib/ide/_base-ide.js +10 -0
  289. package/tools/cli/installers/lib/ide/auggie.js +19 -7
  290. package/tools/cli/installers/lib/ide/crush.js +19 -6
  291. package/tools/cli/installers/lib/ide/cursor.js +29 -13
  292. package/tools/cli/installers/lib/ide/gemini.js +49 -1
  293. package/tools/cli/installers/lib/ide/iflow.js +20 -1
  294. package/tools/cli/installers/lib/ide/kiro-cli.js +327 -0
  295. package/tools/cli/installers/lib/ide/opencode.js +3 -3
  296. package/tools/cli/installers/lib/ide/roo.js +120 -184
  297. package/tools/cli/installers/lib/ide/rovo-dev.js +1 -1
  298. package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +8 -2
  299. package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +34 -19
  300. package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +18 -14
  301. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +1 -1
  302. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +5 -0
  303. package/tools/cli/installers/lib/modules/manager.js +535 -56
  304. package/tools/cli/lib/agent/compiler.js +57 -16
  305. package/tools/cli/lib/agent/installer.js +129 -28
  306. package/tools/cli/lib/cli-utils.js +21 -4
  307. package/tools/cli/lib/config.js +2 -1
  308. package/tools/cli/lib/ui.js +561 -12
  309. package/tools/cli/lib/yaml-xml-builder.js +0 -15
  310. package/tools/maintainer/review-pr-README.md +55 -0
  311. package/tools/maintainer/review-pr.md +242 -0
  312. package/tools/migrate-custom-module-paths.js +124 -0
  313. package/tools/schema/agent.js +149 -89
  314. package/tools/validate-svg-changes.sh +356 -0
  315. package/custom/src/agents/commit-poet/installation-guide.md +0 -36
  316. package/custom/src/agents/toolsmith/installation-guide.md +0 -36
  317. package/docs/custom-agent-installation.md +0 -183
  318. package/src/modules/bmb/docs/workflows/workflow-template.md +0 -152
  319. package/src/modules/bmb/workflows/create-workflow/steps/step-03-tools-overview.md +0 -127
  320. package/src/modules/bmb/workflows/create-workflow/steps/step-04-core-tools.md +0 -145
  321. package/src/modules/bmb/workflows/create-workflow/steps/step-05-memory-requirements.md +0 -136
  322. package/src/modules/bmb/workflows/create-workflow/steps/step-06-external-tools.md +0 -154
  323. package/src/modules/bmb/workflows/create-workflow/steps/step-07-installation-guidance.md +0 -159
  324. package/src/modules/bmb/workflows/create-workflow/steps/step-08-tools-summary.md +0 -167
  325. package/src/modules/bmb/workflows/create-workflow/steps/step-10-plan-review.md +0 -215
  326. package/src/modules/bmb/workflows/create-workflow/templates/build-summary.md +0 -36
  327. package/src/modules/bmb/workflows/create-workflow/templates/completion-section.md +0 -39
  328. package/src/modules/bmb/workflows/create-workflow/templates/content-template.md +0 -21
  329. package/src/modules/bmb/workflows/create-workflow/templates/design-section.md +0 -53
  330. package/src/modules/bmb/workflows/create-workflow/templates/project-info.md +0 -18
  331. package/src/modules/bmb/workflows/create-workflow/templates/requirements-section.md +0 -47
  332. package/src/modules/bmb/workflows/create-workflow/templates/review-section.md +0 -56
  333. package/src/modules/bmb/workflows/create-workflow/templates/workflow-plan.md +0 -54
  334. package/src/modules/bmb/workflows-legacy/create-module/README.md +0 -229
  335. package/src/modules/bmb/workflows-legacy/create-module/brainstorm-context.md +0 -137
  336. package/src/modules/bmb/workflows-legacy/create-module/checklist.md +0 -235
  337. package/src/modules/bmb/workflows-legacy/create-module/installer-templates/install-config.yaml +0 -92
  338. package/src/modules/bmb/workflows-legacy/create-module/installer-templates/installer.js +0 -231
  339. package/src/modules/bmb/workflows-legacy/create-module/instructions.md +0 -577
  340. package/src/modules/bmb/workflows-legacy/create-module/module-structure.md +0 -400
  341. package/src/modules/bmb/workflows-legacy/create-module/workflow.yaml +0 -52
  342. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/epics-template.md +0 -80
  343. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/instructions.md +0 -387
  344. package/src/modules/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.yaml +0 -53
  345. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +0 -169
  346. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +0 -332
  347. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/template.md +0 -146
  348. package/src/modules/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -64
  349. package/tools/cli/commands/agent-install.js +0 -409
  350. package/tools/cli/commands/cleanup.js +0 -141
  351. /package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/bundlers.md +0 -0
  352. /package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/deploy.md +0 -0
  353. /package/{custom/src → example-custom-content}/agents/toolsmith/toolsmith-sidecar/knowledge/tests.md +0 -0
  354. /package/src/modules/bmgd/{_module-installer/install-config.yaml → module.yaml} +0 -0
  355. /package/src/modules/cis/{_module-installer/install-config.yaml → module.yaml} +0 -0
@@ -59,6 +59,17 @@ class UI {
59
59
  const bmadDir = await installer.findBmadDir(confirmedDirectory);
60
60
  const hasExistingInstall = await fs.pathExists(bmadDir);
61
61
 
62
+ // Always ask for custom content, but we'll handle it differently for new installs
63
+ let customContentConfig = { hasCustomContent: false };
64
+ if (hasExistingInstall) {
65
+ // Existing installation - prompt to add/update custom content
66
+ customContentConfig = await this.promptCustomContentForExisting();
67
+ } else {
68
+ // New installation - we'll prompt after creating the directory structure
69
+ // For now, set a flag to indicate we should ask later
70
+ customContentConfig._shouldAsk = true;
71
+ }
72
+
62
73
  // Track action type (only set if there's an existing installation)
63
74
  let actionType;
64
75
 
@@ -85,9 +96,11 @@ class UI {
85
96
 
86
97
  // Handle quick update separately
87
98
  if (actionType === 'quick-update') {
99
+ // Quick update doesn't install custom content - just updates existing modules
88
100
  return {
89
101
  actionType: 'quick-update',
90
102
  directory: confirmedDirectory,
103
+ customContent: { hasCustomContent: false },
91
104
  };
92
105
  }
93
106
 
@@ -116,8 +129,120 @@ class UI {
116
129
 
117
130
  const { installedModuleIds } = await this.getExistingInstallation(confirmedDirectory);
118
131
  const coreConfig = await this.collectCoreConfig(confirmedDirectory);
119
- const moduleChoices = await this.getModuleChoices(installedModuleIds);
120
- const selectedModules = await this.selectModules(moduleChoices);
132
+
133
+ // For new installations, create the directory structure first so we can cache custom content
134
+ if (!hasExistingInstall && customContentConfig._shouldAsk) {
135
+ // Create the bmad directory based on core config
136
+ const path = require('node:path');
137
+ const fs = require('fs-extra');
138
+ const bmadFolderName = coreConfig.bmad_folder || 'bmad';
139
+ const bmadDir = path.join(confirmedDirectory, bmadFolderName);
140
+
141
+ await fs.ensureDir(bmadDir);
142
+ await fs.ensureDir(path.join(bmadDir, '_cfg'));
143
+ await fs.ensureDir(path.join(bmadDir, '_cfg', 'custom'));
144
+
145
+ // Now prompt for custom content
146
+ customContentConfig = await this.promptCustomContentLocation();
147
+
148
+ // If custom content found, cache it
149
+ if (customContentConfig.hasCustomContent) {
150
+ const { CustomModuleCache } = require('../installers/lib/core/custom-module-cache');
151
+ const cache = new CustomModuleCache(bmadDir);
152
+
153
+ const { CustomHandler } = require('../installers/lib/custom/handler');
154
+ const customHandler = new CustomHandler();
155
+ const customFiles = await customHandler.findCustomContent(customContentConfig.customPath);
156
+
157
+ for (const customFile of customFiles) {
158
+ const customInfo = await customHandler.getCustomInfo(customFile);
159
+ if (customInfo && customInfo.id) {
160
+ // Cache the module source
161
+ await cache.cacheModule(customInfo.id, customInfo.path, {
162
+ name: customInfo.name,
163
+ type: 'custom',
164
+ });
165
+
166
+ console.log(chalk.dim(` Cached ${customInfo.name} to _cfg/custom/${customInfo.id}`));
167
+ }
168
+ }
169
+
170
+ // Update config to use cached modules
171
+ customContentConfig.cachedModules = [];
172
+ for (const customFile of customFiles) {
173
+ const customInfo = await customHandler.getCustomInfo(customFile);
174
+ if (customInfo && customInfo.id) {
175
+ customContentConfig.cachedModules.push({
176
+ id: customInfo.id,
177
+ cachePath: path.join(bmadDir, '_cfg', 'custom', customInfo.id),
178
+ // Store relative path from cache for the manifest
179
+ relativePath: path.join('_cfg', 'custom', customInfo.id),
180
+ });
181
+ }
182
+ }
183
+
184
+ console.log(chalk.green(`✓ Cached ${customFiles.length} custom module(s)`));
185
+ }
186
+
187
+ // Clear the flag
188
+ delete customContentConfig._shouldAsk;
189
+ }
190
+
191
+ // Skip module selection during update/reinstall - keep existing modules
192
+ let selectedModules;
193
+ if (actionType === 'update' || actionType === 'reinstall') {
194
+ // Keep all existing installed modules during update/reinstall
195
+ selectedModules = [...installedModuleIds];
196
+ console.log(chalk.cyan('\n📦 Keeping existing modules: ') + selectedModules.join(', '));
197
+ } else {
198
+ // Only show module selection for new installs
199
+ const moduleChoices = await this.getModuleChoices(installedModuleIds, customContentConfig);
200
+ selectedModules = await this.selectModules(moduleChoices);
201
+
202
+ // Check which custom content items were selected
203
+ const selectedCustomContent = selectedModules.filter((mod) => mod.startsWith('__CUSTOM_CONTENT__'));
204
+
205
+ // For cached modules (new installs), check if any cached modules were selected
206
+ let selectedCachedModules = [];
207
+ if (customContentConfig.cachedModules) {
208
+ selectedCachedModules = selectedModules.filter(
209
+ (mod) => !mod.startsWith('__CUSTOM_CONTENT__') && customContentConfig.cachedModules.some((cm) => cm.id === mod),
210
+ );
211
+ }
212
+
213
+ if (selectedCustomContent.length > 0 || selectedCachedModules.length > 0) {
214
+ customContentConfig.selected = true;
215
+
216
+ // Handle directory-based custom content (existing installs)
217
+ if (selectedCustomContent.length > 0) {
218
+ customContentConfig.selectedFiles = selectedCustomContent.map((mod) => mod.replace('__CUSTOM_CONTENT__', ''));
219
+ // Convert custom content to module IDs for installation
220
+ const customContentModuleIds = [];
221
+ const { CustomHandler } = require('../installers/lib/custom/handler');
222
+ const customHandler = new CustomHandler();
223
+ for (const customFile of customContentConfig.selectedFiles) {
224
+ // Get the module info to extract the ID
225
+ const customInfo = await customHandler.getCustomInfo(customFile);
226
+ if (customInfo) {
227
+ customContentModuleIds.push(customInfo.id);
228
+ }
229
+ }
230
+ // Filter out custom content markers and add module IDs
231
+ selectedModules = [...selectedModules.filter((mod) => !mod.startsWith('__CUSTOM_CONTENT__')), ...customContentModuleIds];
232
+ }
233
+
234
+ // For cached modules, they're already module IDs, just mark as selected
235
+ if (selectedCachedModules.length > 0) {
236
+ customContentConfig.selectedCachedModules = selectedCachedModules;
237
+ // No need to filter since they're already proper module IDs
238
+ }
239
+ } else if (customContentConfig.hasCustomContent) {
240
+ // User provided custom content but didn't select any
241
+ customContentConfig.selected = false;
242
+ customContentConfig.selectedFiles = [];
243
+ customContentConfig.selectedCachedModules = [];
244
+ }
245
+ }
121
246
 
122
247
  // Prompt for AgentVibes TTS integration
123
248
  const agentVibesConfig = await this.promptAgentVibes(confirmedDirectory);
@@ -137,7 +262,9 @@ class UI {
137
262
  ides: toolSelection.ides,
138
263
  skipIde: toolSelection.skipIde,
139
264
  coreConfig: coreConfig, // Pass collected core config to installer
140
- enableAgentVibes: agentVibesConfig.enabled, // AgentVibes TTS integration
265
+ // Custom content configuration
266
+ customContent: customContentConfig,
267
+ enableAgentVibes: agentVibesConfig.enabled,
141
268
  agentVibesInstalled: agentVibesConfig.alreadyInstalled,
142
269
  };
143
270
  }
@@ -363,11 +490,60 @@ class UI {
363
490
  `🔧 Tools Configured: ${result.ides?.length > 0 ? result.ides.join(', ') : 'none'}`,
364
491
  ];
365
492
 
493
+ // Add AgentVibes TTS info if enabled
494
+ if (result.agentVibesEnabled) {
495
+ summary.push(`🎤 AgentVibes TTS: Enabled`);
496
+ }
497
+
366
498
  CLIUtils.displayBox(summary.join('\n\n'), {
367
499
  borderColor: 'green',
368
500
  borderStyle: 'round',
369
501
  });
370
502
 
503
+ // Display TTS injection details if present
504
+ if (result.ttsInjectedFiles && result.ttsInjectedFiles.length > 0) {
505
+ console.log('\n' + chalk.cyan.bold('═══════════════════════════════════════════════════'));
506
+ console.log(chalk.cyan.bold(' AgentVibes TTS Injection Summary'));
507
+ console.log(chalk.cyan.bold('═══════════════════════════════════════════════════\n'));
508
+
509
+ // Explain what TTS injection is
510
+ console.log(chalk.white.bold('What is TTS Injection?\n'));
511
+ console.log(chalk.dim(' TTS (Text-to-Speech) injection adds voice instructions to BMAD agents,'));
512
+ console.log(chalk.dim(' enabling them to speak their responses aloud using AgentVibes.\n'));
513
+ console.log(chalk.dim(' Example: When you activate the PM agent, it will greet you with'));
514
+ console.log(chalk.dim(' spoken audio like "Hey! I\'m your Project Manager. How can I help?"\n'));
515
+
516
+ console.log(chalk.green(`✅ TTS injection applied to ${result.ttsInjectedFiles.length} file(s):\n`));
517
+
518
+ // Group by type
519
+ const partyModeFiles = result.ttsInjectedFiles.filter((f) => f.type === 'party-mode');
520
+ const agentTTSFiles = result.ttsInjectedFiles.filter((f) => f.type === 'agent-tts');
521
+
522
+ if (partyModeFiles.length > 0) {
523
+ console.log(chalk.yellow(' Party Mode (multi-agent conversations):'));
524
+ for (const file of partyModeFiles) {
525
+ console.log(chalk.dim(` • ${file.path}`));
526
+ }
527
+ }
528
+
529
+ if (agentTTSFiles.length > 0) {
530
+ console.log(chalk.yellow(' Agent TTS (individual agent voices):'));
531
+ for (const file of agentTTSFiles) {
532
+ console.log(chalk.dim(` • ${file.path}`));
533
+ }
534
+ }
535
+
536
+ // Show backup info and restore command
537
+ console.log('\n' + chalk.white.bold('Backups & Recovery:\n'));
538
+ console.log(chalk.dim(' Pre-injection backups are stored in:'));
539
+ console.log(chalk.cyan(' ~/.bmad-tts-backups/\n'));
540
+ console.log(chalk.dim(' To restore original files (removes TTS instructions):'));
541
+ console.log(chalk.cyan(` bmad-tts-injector.sh --restore ${result.path}\n`));
542
+
543
+ console.log(chalk.cyan('💡 BMAD agents will now speak when activated!'));
544
+ console.log(chalk.dim(' Ensure AgentVibes is installed: https://agentvibes.org'));
545
+ }
546
+
371
547
  console.log('\n' + chalk.green.bold('✨ BMAD is ready to use!'));
372
548
  }
373
549
 
@@ -424,19 +600,144 @@ class UI {
424
600
  /**
425
601
  * Get module choices for selection
426
602
  * @param {Set} installedModuleIds - Currently installed module IDs
603
+ * @param {Object} customContentConfig - Custom content configuration
427
604
  * @returns {Array} Module choices for inquirer
428
605
  */
429
- async getModuleChoices(installedModuleIds) {
606
+ async getModuleChoices(installedModuleIds, customContentConfig = null) {
607
+ const moduleChoices = [];
608
+ const isNewInstallation = installedModuleIds.size === 0;
609
+
610
+ const customContentItems = [];
611
+ const hasCustomContentItems = false;
612
+
613
+ // Add custom content items
614
+ if (customContentConfig && customContentConfig.hasCustomContent) {
615
+ if (customContentConfig.cachedModules) {
616
+ // New installation - show cached modules
617
+ for (const cachedModule of customContentConfig.cachedModules) {
618
+ // Get the module info from cache
619
+ const yaml = require('js-yaml');
620
+ const fs = require('fs-extra');
621
+
622
+ // Try multiple possible config file locations
623
+ const possibleConfigPaths = [
624
+ path.join(cachedModule.cachePath, 'module.yaml'),
625
+ path.join(cachedModule.cachePath, 'custom.yaml'),
626
+ path.join(cachedModule.cachePath, '_module-installer', 'module.yaml'),
627
+ path.join(cachedModule.cachePath, '_module-installer', 'custom.yaml'),
628
+ ];
629
+
630
+ let moduleData = null;
631
+ let foundPath = null;
632
+
633
+ for (const configPath of possibleConfigPaths) {
634
+ if (await fs.pathExists(configPath)) {
635
+ try {
636
+ const yamlContent = await fs.readFile(configPath, 'utf8');
637
+ moduleData = yaml.load(yamlContent);
638
+ foundPath = configPath;
639
+ break;
640
+ } catch {
641
+ // Continue to next path
642
+ }
643
+ }
644
+ }
645
+
646
+ if (moduleData) {
647
+ // Use the name from the custom info if we have it
648
+ const moduleName = cachedModule.name || moduleData.name || cachedModule.id;
649
+
650
+ customContentItems.push({
651
+ name: `${chalk.cyan('✓')} ${moduleName} ${chalk.gray('(cached)')}`,
652
+ value: cachedModule.id, // Use module ID directly
653
+ checked: true, // Default to selected
654
+ cached: true,
655
+ });
656
+ } else {
657
+ // Debug: show what paths we tried to check
658
+ console.log(chalk.dim(`DEBUG: No module config found for ${cachedModule.id}`));
659
+ console.log(
660
+ chalk.dim(
661
+ `DEBUG: Tried paths:`,
662
+ possibleConfigPaths.map((p) => p.replace(cachedModule.cachePath, '.')),
663
+ ),
664
+ );
665
+ console.log(chalk.dim(`DEBUG: cachedModule:`, JSON.stringify(cachedModule, null, 2)));
666
+ }
667
+ }
668
+ } else if (customContentConfig.customPath) {
669
+ // Existing installation - show from directory
670
+ const { CustomHandler } = require('../installers/lib/custom/handler');
671
+ const customHandler = new CustomHandler();
672
+ const customFiles = await customHandler.findCustomContent(customContentConfig.customPath);
673
+
674
+ for (const customFile of customFiles) {
675
+ const customInfo = await customHandler.getCustomInfo(customFile);
676
+ if (customInfo) {
677
+ customContentItems.push({
678
+ name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`,
679
+ value: `__CUSTOM_CONTENT__${customFile}`, // Unique value for each custom content
680
+ checked: true, // Default to selected since user chose to provide custom content
681
+ path: customInfo.path, // Track path to avoid duplicates
682
+ });
683
+ }
684
+ }
685
+ }
686
+ }
687
+
688
+ // Add official modules
430
689
  const { ModuleManager } = require('../installers/lib/modules/manager');
431
- const moduleManager = new ModuleManager();
432
- const availableModules = await moduleManager.listAvailable();
690
+ // For new installations, don't scan project yet (will do after custom content is discovered)
691
+ // For existing installations, scan if user selected custom content
692
+ const shouldScanProject =
693
+ !isNewInstallation && customContentConfig && customContentConfig.hasCustomContent && customContentConfig.selected;
694
+ const moduleManager = new ModuleManager({
695
+ scanProjectForModules: shouldScanProject,
696
+ });
697
+ const { modules: availableModules, customModules: customModulesFromProject } = await moduleManager.listAvailable();
433
698
 
434
- const isNewInstallation = installedModuleIds.size === 0;
435
- return availableModules.map((mod) => ({
436
- name: mod.name,
437
- value: mod.id,
438
- checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id),
439
- }));
699
+ // First, add all items to appropriate sections
700
+ const allCustomModules = [];
701
+
702
+ // Add custom content items from directory
703
+ allCustomModules.push(...customContentItems);
704
+
705
+ // Add custom modules from project scan (if scanning is enabled)
706
+ for (const mod of customModulesFromProject) {
707
+ // Skip if this module is already in customContentItems (by path)
708
+ const isDuplicate = allCustomModules.some((item) => item.path && mod.path && path.resolve(item.path) === path.resolve(mod.path));
709
+
710
+ if (!isDuplicate) {
711
+ allCustomModules.push({
712
+ name: `${chalk.cyan('✓')} ${mod.name} ${chalk.gray(`(${mod.source})`)}`,
713
+ value: mod.id,
714
+ checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id),
715
+ });
716
+ }
717
+ }
718
+
719
+ // Add separators and modules in correct order
720
+ if (allCustomModules.length > 0) {
721
+ // Add separator for custom content, all custom modules, and official content separator
722
+ moduleChoices.push(
723
+ new inquirer.Separator('── Custom Content ──'),
724
+ ...allCustomModules,
725
+ new inquirer.Separator('── Official Content ──'),
726
+ );
727
+ }
728
+
729
+ // Add official modules (only non-custom ones)
730
+ for (const mod of availableModules) {
731
+ if (!mod.isCustom) {
732
+ moduleChoices.push({
733
+ name: mod.name,
734
+ value: mod.id,
735
+ checked: isNewInstallation ? mod.defaultSelected || false : installedModuleIds.has(mod.id),
736
+ });
737
+ }
738
+ }
739
+
740
+ return moduleChoices;
440
741
  }
441
742
 
442
743
  /**
@@ -513,6 +814,116 @@ class UI {
513
814
  }
514
815
  }
515
816
 
817
+ /**
818
+ * Prompt for custom content location
819
+ * @returns {Object} Custom content configuration
820
+ */
821
+ async promptCustomContentLocation() {
822
+ try {
823
+ CLIUtils.displaySection('Custom Content', 'Optional: Add custom agents, workflows, and modules');
824
+
825
+ const { hasCustomContent } = await inquirer.prompt([
826
+ {
827
+ type: 'list',
828
+ name: 'hasCustomContent',
829
+ message: 'Do you have custom content to install?',
830
+ choices: [
831
+ { name: 'No (skip custom content)', value: 'none' },
832
+ { name: 'Enter a directory path', value: 'directory' },
833
+ { name: 'Enter a URL', value: 'url' },
834
+ ],
835
+ default: 'none',
836
+ },
837
+ ]);
838
+
839
+ if (hasCustomContent === 'none') {
840
+ return { hasCustomContent: false };
841
+ }
842
+
843
+ if (hasCustomContent === 'url') {
844
+ console.log(chalk.yellow('\nURL-based custom content installation is coming soon!'));
845
+ console.log(chalk.cyan('For now, please download your custom content and choose "Enter a directory path".\n'));
846
+ return { hasCustomContent: false };
847
+ }
848
+
849
+ if (hasCustomContent === 'directory') {
850
+ let customPath;
851
+ while (!customPath) {
852
+ let expandedPath;
853
+ const { directory } = await inquirer.prompt([
854
+ {
855
+ type: 'input',
856
+ name: 'directory',
857
+ message: 'Enter directory to search for custom content (will scan subfolders):',
858
+ default: process.cwd(), // Use actual current working directory
859
+ validate: async (input) => {
860
+ if (!input || input.trim() === '') {
861
+ return 'Please enter a directory path';
862
+ }
863
+
864
+ try {
865
+ expandedPath = this.expandUserPath(input.trim());
866
+ } catch (error) {
867
+ return error.message;
868
+ }
869
+
870
+ // Check if the path exists
871
+ const pathExists = await fs.pathExists(expandedPath);
872
+ if (!pathExists) {
873
+ return 'Directory does not exist';
874
+ }
875
+
876
+ return true;
877
+ },
878
+ },
879
+ ]);
880
+
881
+ // Now expand the path for use after the prompt
882
+ expandedPath = this.expandUserPath(directory.trim());
883
+
884
+ // Check if directory has custom content
885
+ const { CustomHandler } = require('../installers/lib/custom/handler');
886
+ const customHandler = new CustomHandler();
887
+ const customFiles = await customHandler.findCustomContent(expandedPath);
888
+
889
+ if (customFiles.length === 0) {
890
+ console.log(chalk.yellow(`\nNo custom content found in ${expandedPath}`));
891
+
892
+ const { tryAgain } = await inquirer.prompt([
893
+ {
894
+ type: 'confirm',
895
+ name: 'tryAgain',
896
+ message: 'Try a different directory?',
897
+ default: true,
898
+ },
899
+ ]);
900
+
901
+ if (tryAgain) {
902
+ continue;
903
+ } else {
904
+ return { hasCustomContent: false };
905
+ }
906
+ }
907
+
908
+ customPath = expandedPath;
909
+ console.log(chalk.green(`\n✓ Found ${customFiles.length} custom content item(s):`));
910
+ for (const file of customFiles) {
911
+ const relativePath = path.relative(expandedPath, path.dirname(file));
912
+ const folderName = path.dirname(file).split(path.sep).pop();
913
+ console.log(chalk.dim(` • ${folderName} ${chalk.gray(`(${relativePath})`)}`));
914
+ }
915
+ }
916
+
917
+ return { hasCustomContent: true, customPath };
918
+ }
919
+
920
+ return { hasCustomContent: false };
921
+ } catch (error) {
922
+ console.error(chalk.red('Error in custom content prompt:'), error);
923
+ return { hasCustomContent: false };
924
+ }
925
+ }
926
+
516
927
  /**
517
928
  * Confirm directory selection
518
929
  * @param {string} directory - The directory path
@@ -798,6 +1209,144 @@ class UI {
798
1209
 
799
1210
  return (await fs.pathExists(hookPath)) && (await fs.pathExists(playTtsPath));
800
1211
  }
1212
+
1213
+ /**
1214
+ * Prompt for custom content for existing installations
1215
+ * @returns {Object} Custom content configuration
1216
+ */
1217
+ async promptCustomContentForExisting() {
1218
+ try {
1219
+ CLIUtils.displaySection('Custom Content', 'Add new custom agents, workflows, or modules to your installation');
1220
+
1221
+ const { hasCustomContent } = await inquirer.prompt([
1222
+ {
1223
+ type: 'list',
1224
+ name: 'hasCustomContent',
1225
+ message: 'Do you want to add or update custom content?',
1226
+ choices: [
1227
+ {
1228
+ name: 'No, continue with current installation only',
1229
+ value: false,
1230
+ },
1231
+ {
1232
+ name: 'Yes, I have custom content to add or update',
1233
+ value: true,
1234
+ },
1235
+ ],
1236
+ default: false,
1237
+ },
1238
+ ]);
1239
+
1240
+ if (!hasCustomContent) {
1241
+ return { hasCustomContent: false };
1242
+ }
1243
+
1244
+ // Get directory path
1245
+ const { customPath } = await inquirer.prompt([
1246
+ {
1247
+ type: 'input',
1248
+ name: 'customPath',
1249
+ message: 'Enter directory to search for custom content (will scan subfolders):',
1250
+ default: process.cwd(),
1251
+ validate: async (input) => {
1252
+ if (!input || input.trim() === '') {
1253
+ return 'Please enter a directory path';
1254
+ }
1255
+
1256
+ // Normalize and check if path exists
1257
+ const expandedPath = CLIUtils.expandPath(input.trim());
1258
+ const pathExists = await fs.pathExists(expandedPath);
1259
+ if (!pathExists) {
1260
+ return 'Directory does not exist';
1261
+ }
1262
+
1263
+ // Check if it's actually a directory
1264
+ const stats = await fs.stat(expandedPath);
1265
+ if (!stats.isDirectory()) {
1266
+ return 'Path must be a directory';
1267
+ }
1268
+
1269
+ return true;
1270
+ },
1271
+ transformer: (input) => {
1272
+ return CLIUtils.expandPath(input);
1273
+ },
1274
+ },
1275
+ ]);
1276
+
1277
+ const resolvedPath = CLIUtils.expandPath(customPath);
1278
+
1279
+ // Find custom content
1280
+ const { CustomHandler } = require('../installers/lib/custom/handler');
1281
+ const customHandler = new CustomHandler();
1282
+ const customFiles = await customHandler.findCustomContent(resolvedPath);
1283
+
1284
+ if (customFiles.length === 0) {
1285
+ console.log(chalk.yellow(`\nNo custom content found in ${resolvedPath}`));
1286
+
1287
+ const { tryDifferent } = await inquirer.prompt([
1288
+ {
1289
+ type: 'confirm',
1290
+ name: 'tryDifferent',
1291
+ message: 'Try a different directory?',
1292
+ default: true,
1293
+ },
1294
+ ]);
1295
+
1296
+ if (tryDifferent) {
1297
+ return await this.promptCustomContentForExisting();
1298
+ }
1299
+
1300
+ return { hasCustomContent: false };
1301
+ }
1302
+
1303
+ // Display found items
1304
+ console.log(chalk.cyan(`\nFound ${customFiles.length} custom content file(s):`));
1305
+ const { CustomHandler: CustomHandler2 } = require('../installers/lib/custom/handler');
1306
+ const customHandler2 = new CustomHandler2();
1307
+ const customContentItems = [];
1308
+
1309
+ for (const customFile of customFiles) {
1310
+ const customInfo = await customHandler2.getCustomInfo(customFile);
1311
+ if (customInfo) {
1312
+ customContentItems.push({
1313
+ name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`,
1314
+ value: `__CUSTOM_CONTENT__${customFile}`,
1315
+ checked: true,
1316
+ });
1317
+ }
1318
+ }
1319
+
1320
+ // Add option to keep existing custom content
1321
+ console.log(chalk.yellow('\nExisting custom modules will be preserved unless you remove them'));
1322
+
1323
+ const { selectedFiles } = await inquirer.prompt([
1324
+ {
1325
+ type: 'checkbox',
1326
+ name: 'selectedFiles',
1327
+ message: 'Select custom content to add:',
1328
+ choices: customContentItems,
1329
+ pageSize: 15,
1330
+ validate: (answer) => {
1331
+ if (answer.length === 0) {
1332
+ return 'You must select at least one item';
1333
+ }
1334
+ return true;
1335
+ },
1336
+ },
1337
+ ]);
1338
+
1339
+ return {
1340
+ hasCustomContent: true,
1341
+ customPath: resolvedPath,
1342
+ selected: true,
1343
+ selectedFiles: selectedFiles,
1344
+ };
1345
+ } catch (error) {
1346
+ console.error(chalk.red('Error configuring custom content:'), error);
1347
+ return { hasCustomContent: false };
1348
+ }
1349
+ }
801
1350
  }
802
1351
 
803
1352
  module.exports = { UI };
@@ -232,21 +232,6 @@ class YamlXmlBuilder {
232
232
  return xml;
233
233
  }
234
234
 
235
- /**
236
- * Build metadata comment
237
- */
238
- buildMetadataComment(metadata) {
239
- const lines = ['<!-- BUILD-META', ` source: ${metadata.sourceFile || 'unknown'} (hash: ${metadata.sourceHash || 'unknown'})`];
240
-
241
- if (metadata.customizeFile) {
242
- lines.push(` customize: ${metadata.customizeFile} (hash: ${metadata.customizeHash || 'unknown'})`);
243
- }
244
-
245
- lines.push(` built: ${new Date().toISOString()}`, ` builder-version: ${metadata.builderVersion || '1.0.0'}`, '-->\n');
246
-
247
- return lines.join('\n');
248
- }
249
-
250
235
  /**
251
236
  * Build persona XML section
252
237
  */