agentvibes 2.17.3 → 2.17.4

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 (339) hide show
  1. package/.bmad/_cfg/agent-manifest.csv +11 -0
  2. package/.bmad/_cfg/agent-voice-map.csv +11 -0
  3. package/.bmad/_cfg/agents/bmm-analyst.customize.yaml +42 -0
  4. package/.bmad/_cfg/agents/bmm-architect.customize.yaml +42 -0
  5. package/.bmad/_cfg/agents/bmm-dev.customize.yaml +42 -0
  6. package/.bmad/_cfg/agents/bmm-frame-expert.customize.yaml +42 -0
  7. package/.bmad/_cfg/agents/bmm-pm.customize.yaml +42 -0
  8. package/.bmad/_cfg/agents/bmm-sm.customize.yaml +42 -0
  9. package/.bmad/_cfg/agents/bmm-tea.customize.yaml +42 -0
  10. package/.bmad/_cfg/agents/bmm-tech-writer.customize.yaml +42 -0
  11. package/.bmad/_cfg/agents/bmm-ux-designer.customize.yaml +42 -0
  12. package/.bmad/_cfg/agents/core-bmad-master.customize.yaml +42 -0
  13. package/.bmad/_cfg/files-manifest.csv +243 -0
  14. package/.bmad/_cfg/ides/claude-code.yaml +6 -0
  15. package/.bmad/_cfg/manifest.yaml +9 -0
  16. package/.bmad/_cfg/task-manifest.csv +5 -0
  17. package/.bmad/_cfg/tool-manifest.csv +2 -0
  18. package/.bmad/_cfg/workflow-manifest.csv +38 -0
  19. package/.bmad/bmm/README.md +128 -0
  20. package/.bmad/bmm/agents/analyst.md +79 -0
  21. package/.bmad/bmm/agents/analyst.md.backup-pre-tts +75 -0
  22. package/.bmad/bmm/agents/architect.md +80 -0
  23. package/.bmad/bmm/agents/dev.md +70 -0
  24. package/.bmad/bmm/agents/frame-expert.md +72 -0
  25. package/.bmad/bmm/agents/pm.md +84 -0
  26. package/.bmad/bmm/agents/sm.md +93 -0
  27. package/.bmad/bmm/agents/tea.md +80 -0
  28. package/.bmad/bmm/agents/tech-writer.md +84 -0
  29. package/.bmad/bmm/agents/ux-designer.md +79 -0
  30. package/.bmad/bmm/config.yaml +17 -0
  31. package/.bmad/bmm/docs/README.md +236 -0
  32. package/.bmad/bmm/docs/agents-guide.md +1058 -0
  33. package/.bmad/bmm/docs/brownfield-guide.md +762 -0
  34. package/.bmad/bmm/docs/enterprise-agentic-development.md +686 -0
  35. package/.bmad/bmm/docs/faq.md +588 -0
  36. package/.bmad/bmm/docs/glossary.md +320 -0
  37. package/.bmad/bmm/docs/party-mode.md +224 -0
  38. package/.bmad/bmm/docs/quick-spec-flow.md +652 -0
  39. package/.bmad/bmm/docs/quick-start.md +376 -0
  40. package/.bmad/bmm/docs/scale-adaptive-system.md +612 -0
  41. package/.bmad/bmm/docs/test-architecture.md +396 -0
  42. package/.bmad/bmm/docs/workflow-architecture-reference.md +366 -0
  43. package/.bmad/bmm/docs/workflow-document-project-reference.md +489 -0
  44. package/.bmad/bmm/docs/workflows-analysis.md +370 -0
  45. package/.bmad/bmm/docs/workflows-implementation.md +286 -0
  46. package/.bmad/bmm/docs/workflows-planning.md +612 -0
  47. package/.bmad/bmm/docs/workflows-solutioning.md +554 -0
  48. package/.bmad/bmm/teams/default-party.csv +20 -0
  49. package/.bmad/bmm/teams/team-fullstack.yaml +13 -0
  50. package/.bmad/bmm/testarch/knowledge/ci-burn-in.md +675 -0
  51. package/.bmad/bmm/testarch/knowledge/component-tdd.md +486 -0
  52. package/.bmad/bmm/testarch/knowledge/contract-testing.md +957 -0
  53. package/.bmad/bmm/testarch/knowledge/data-factories.md +500 -0
  54. package/.bmad/bmm/testarch/knowledge/email-auth.md +721 -0
  55. package/.bmad/bmm/testarch/knowledge/error-handling.md +725 -0
  56. package/.bmad/bmm/testarch/knowledge/feature-flags.md +750 -0
  57. package/.bmad/bmm/testarch/knowledge/fixture-architecture.md +401 -0
  58. package/.bmad/bmm/testarch/knowledge/network-first.md +486 -0
  59. package/.bmad/bmm/testarch/knowledge/nfr-criteria.md +670 -0
  60. package/.bmad/bmm/testarch/knowledge/playwright-config.md +730 -0
  61. package/.bmad/bmm/testarch/knowledge/probability-impact.md +601 -0
  62. package/.bmad/bmm/testarch/knowledge/risk-governance.md +615 -0
  63. package/.bmad/bmm/testarch/knowledge/selective-testing.md +732 -0
  64. package/.bmad/bmm/testarch/knowledge/selector-resilience.md +527 -0
  65. package/.bmad/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
  66. package/.bmad/bmm/testarch/knowledge/test-levels-framework.md +473 -0
  67. package/.bmad/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
  68. package/.bmad/bmm/testarch/knowledge/test-quality.md +664 -0
  69. package/.bmad/bmm/testarch/knowledge/timing-debugging.md +372 -0
  70. package/.bmad/bmm/testarch/knowledge/visual-debugging.md +524 -0
  71. package/.bmad/bmm/testarch/tea-index.csv +22 -0
  72. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md +112 -0
  73. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md +25 -0
  74. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +26 -0
  75. package/.bmad/bmm/workflows/1-analysis/domain-research/instructions.md +425 -0
  76. package/.bmad/bmm/workflows/1-analysis/domain-research/template.md +180 -0
  77. package/.bmad/bmm/workflows/1-analysis/domain-research/workflow.yaml +28 -0
  78. package/.bmad/bmm/workflows/1-analysis/product-brief/checklist.md +115 -0
  79. package/.bmad/bmm/workflows/1-analysis/product-brief/instructions.md +524 -0
  80. package/.bmad/bmm/workflows/1-analysis/product-brief/template.md +181 -0
  81. package/.bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml +45 -0
  82. package/.bmad/bmm/workflows/1-analysis/research/checklist-deep-prompt.md +144 -0
  83. package/.bmad/bmm/workflows/1-analysis/research/checklist-technical.md +249 -0
  84. package/.bmad/bmm/workflows/1-analysis/research/checklist.md +299 -0
  85. package/.bmad/bmm/workflows/1-analysis/research/claude-code/injections.yaml +114 -0
  86. package/.bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +438 -0
  87. package/.bmad/bmm/workflows/1-analysis/research/instructions-market.md +675 -0
  88. package/.bmad/bmm/workflows/1-analysis/research/instructions-router.md +134 -0
  89. package/.bmad/bmm/workflows/1-analysis/research/instructions-technical.md +534 -0
  90. package/.bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md +94 -0
  91. package/.bmad/bmm/workflows/1-analysis/research/template-market.md +347 -0
  92. package/.bmad/bmm/workflows/1-analysis/research/template-technical.md +245 -0
  93. package/.bmad/bmm/workflows/1-analysis/research/workflow.yaml +44 -0
  94. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/epics-template.md +80 -0
  95. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/instructions.md +616 -0
  96. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/workflow.yaml +53 -0
  97. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +310 -0
  98. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +1308 -0
  99. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +145 -0
  100. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +61 -0
  101. package/.bmad/bmm/workflows/2-plan-workflows/prd/checklist.md +346 -0
  102. package/.bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +13 -0
  103. package/.bmad/bmm/workflows/2-plan-workflows/prd/instructions.md +703 -0
  104. package/.bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +204 -0
  105. package/.bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +11 -0
  106. package/.bmad/bmm/workflows/2-plan-workflows/prd/workflow.yaml +52 -0
  107. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +217 -0
  108. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +74 -0
  109. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions-generate-stories.md +436 -0
  110. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +980 -0
  111. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +181 -0
  112. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +90 -0
  113. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +58 -0
  114. package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +321 -0
  115. package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-template.md +103 -0
  116. package/.bmad/bmm/workflows/3-solutioning/architecture/checklist.md +240 -0
  117. package/.bmad/bmm/workflows/3-solutioning/architecture/decision-catalog.yaml +222 -0
  118. package/.bmad/bmm/workflows/3-solutioning/architecture/instructions.md +768 -0
  119. package/.bmad/bmm/workflows/3-solutioning/architecture/pattern-categories.csv +13 -0
  120. package/.bmad/bmm/workflows/3-solutioning/architecture/workflow.yaml +55 -0
  121. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +169 -0
  122. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +332 -0
  123. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/template.md +146 -0
  124. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +62 -0
  125. package/.bmad/bmm/workflows/4-implementation/code-review/backlog_template.md +12 -0
  126. package/.bmad/bmm/workflows/4-implementation/code-review/checklist.md +22 -0
  127. package/.bmad/bmm/workflows/4-implementation/code-review/instructions.md +398 -0
  128. package/.bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +60 -0
  129. package/.bmad/bmm/workflows/4-implementation/correct-course/checklist.md +279 -0
  130. package/.bmad/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
  131. package/.bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +56 -0
  132. package/.bmad/bmm/workflows/4-implementation/create-story/checklist.md +240 -0
  133. package/.bmad/bmm/workflows/4-implementation/create-story/instructions.md +256 -0
  134. package/.bmad/bmm/workflows/4-implementation/create-story/template.md +51 -0
  135. package/.bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +71 -0
  136. package/.bmad/bmm/workflows/4-implementation/dev-story/checklist.md +38 -0
  137. package/.bmad/bmm/workflows/4-implementation/dev-story/instructions.md +267 -0
  138. package/.bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +56 -0
  139. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/checklist.md +17 -0
  140. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/instructions.md +164 -0
  141. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/template.md +76 -0
  142. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +57 -0
  143. package/.bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
  144. package/.bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +56 -0
  145. package/.bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
  146. package/.bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +234 -0
  147. package/.bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
  148. package/.bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +49 -0
  149. package/.bmad/bmm/workflows/4-implementation/story-context/checklist.md +16 -0
  150. package/.bmad/bmm/workflows/4-implementation/story-context/context-template.xml +34 -0
  151. package/.bmad/bmm/workflows/4-implementation/story-context/instructions.md +209 -0
  152. package/.bmad/bmm/workflows/4-implementation/story-context/workflow.yaml +61 -0
  153. package/.bmad/bmm/workflows/4-implementation/story-done/instructions.md +111 -0
  154. package/.bmad/bmm/workflows/4-implementation/story-done/workflow.yaml +26 -0
  155. package/.bmad/bmm/workflows/4-implementation/story-ready/instructions.md +117 -0
  156. package/.bmad/bmm/workflows/4-implementation/story-ready/workflow.yaml +23 -0
  157. package/.bmad/bmm/workflows/document-project/checklist.md +245 -0
  158. package/.bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -0
  159. package/.bmad/bmm/workflows/document-project/instructions.md +222 -0
  160. package/.bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
  161. package/.bmad/bmm/workflows/document-project/templates/index-template.md +169 -0
  162. package/.bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
  163. package/.bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
  164. package/.bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
  165. package/.bmad/bmm/workflows/document-project/workflow.yaml +29 -0
  166. package/.bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
  167. package/.bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
  168. package/.bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
  169. package/.bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
  170. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-helpers.md +127 -0
  171. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-library.json +90 -0
  172. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-templates.yaml +127 -0
  173. package/.bmad/bmm/workflows/frame-expert/_shared/validate-json-instructions.md +79 -0
  174. package/.bmad/bmm/workflows/frame-expert/create-dataflow/checklist.md +39 -0
  175. package/.bmad/bmm/workflows/frame-expert/create-dataflow/instructions.md +131 -0
  176. package/.bmad/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +23 -0
  177. package/.bmad/bmm/workflows/frame-expert/create-diagram/checklist.md +43 -0
  178. package/.bmad/bmm/workflows/frame-expert/create-diagram/instructions.md +142 -0
  179. package/.bmad/bmm/workflows/frame-expert/create-diagram/workflow.yaml +24 -0
  180. package/.bmad/bmm/workflows/frame-expert/create-flowchart/checklist.md +49 -0
  181. package/.bmad/bmm/workflows/frame-expert/create-flowchart/instructions.md +242 -0
  182. package/.bmad/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +27 -0
  183. package/.bmad/bmm/workflows/frame-expert/create-wireframe/checklist.md +38 -0
  184. package/.bmad/bmm/workflows/frame-expert/create-wireframe/instructions.md +133 -0
  185. package/.bmad/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +23 -0
  186. package/.bmad/bmm/workflows/techdoc/documentation-standards.md +262 -0
  187. package/.bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
  188. package/.bmad/bmm/workflows/testarch/atdd/checklist.md +373 -0
  189. package/.bmad/bmm/workflows/testarch/atdd/instructions.md +785 -0
  190. package/.bmad/bmm/workflows/testarch/atdd/workflow.yaml +45 -0
  191. package/.bmad/bmm/workflows/testarch/automate/checklist.md +580 -0
  192. package/.bmad/bmm/workflows/testarch/automate/instructions.md +1303 -0
  193. package/.bmad/bmm/workflows/testarch/automate/workflow.yaml +52 -0
  194. package/.bmad/bmm/workflows/testarch/ci/checklist.md +246 -0
  195. package/.bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +165 -0
  196. package/.bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +128 -0
  197. package/.bmad/bmm/workflows/testarch/ci/instructions.md +517 -0
  198. package/.bmad/bmm/workflows/testarch/ci/workflow.yaml +45 -0
  199. package/.bmad/bmm/workflows/testarch/framework/checklist.md +321 -0
  200. package/.bmad/bmm/workflows/testarch/framework/instructions.md +455 -0
  201. package/.bmad/bmm/workflows/testarch/framework/workflow.yaml +47 -0
  202. package/.bmad/bmm/workflows/testarch/nfr-assess/checklist.md +405 -0
  203. package/.bmad/bmm/workflows/testarch/nfr-assess/instructions.md +722 -0
  204. package/.bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +443 -0
  205. package/.bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +47 -0
  206. package/.bmad/bmm/workflows/testarch/test-design/checklist.md +234 -0
  207. package/.bmad/bmm/workflows/testarch/test-design/instructions.md +782 -0
  208. package/.bmad/bmm/workflows/testarch/test-design/test-design-template.md +285 -0
  209. package/.bmad/bmm/workflows/testarch/test-design/workflow.yaml +48 -0
  210. package/.bmad/bmm/workflows/testarch/test-review/checklist.md +470 -0
  211. package/.bmad/bmm/workflows/testarch/test-review/instructions.md +608 -0
  212. package/.bmad/bmm/workflows/testarch/test-review/test-review-template.md +388 -0
  213. package/.bmad/bmm/workflows/testarch/test-review/workflow.yaml +46 -0
  214. package/.bmad/bmm/workflows/testarch/trace/checklist.md +654 -0
  215. package/.bmad/bmm/workflows/testarch/trace/instructions.md +1045 -0
  216. package/.bmad/bmm/workflows/testarch/trace/trace-template.md +673 -0
  217. package/.bmad/bmm/workflows/testarch/trace/workflow.yaml +55 -0
  218. package/.bmad/bmm/workflows/workflow-status/init/instructions.md +334 -0
  219. package/.bmad/bmm/workflows/workflow-status/init/workflow.yaml +28 -0
  220. package/.bmad/bmm/workflows/workflow-status/instructions.md +388 -0
  221. package/.bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +138 -0
  222. package/.bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +126 -0
  223. package/.bmad/bmm/workflows/workflow-status/paths/game-design.yaml +52 -0
  224. package/.bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +122 -0
  225. package/.bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +113 -0
  226. package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-brownfield.yaml +58 -0
  227. package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-greenfield.yaml +47 -0
  228. package/.bmad/bmm/workflows/workflow-status/project-levels.yaml +59 -0
  229. package/.bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -0
  230. package/.bmad/bmm/workflows/workflow-status/workflow.yaml +28 -0
  231. package/.bmad/core/agents/bmad-master.md +72 -0
  232. package/.bmad/core/agents/bmad-web-orchestrator.agent.xml +113 -0
  233. package/.bmad/core/config.yaml +1 -0
  234. package/.bmad/core/tasks/adv-elicit-methods.csv +39 -0
  235. package/.bmad/core/tasks/advanced-elicitation-methods.csv +21 -0
  236. package/.bmad/core/tasks/advanced-elicitation.xml +106 -0
  237. package/.bmad/core/tasks/index-docs.xml +65 -0
  238. package/.bmad/core/tasks/validate-workflow.xml +89 -0
  239. package/.bmad/core/tasks/workflow.xml +270 -0
  240. package/.bmad/core/tools/shard-doc.xml +109 -0
  241. package/.bmad/core/workflows/brainstorming/README.md +261 -0
  242. package/.bmad/core/workflows/brainstorming/brain-methods.csv +36 -0
  243. package/.bmad/core/workflows/brainstorming/instructions.md +315 -0
  244. package/.bmad/core/workflows/brainstorming/template.md +106 -0
  245. package/.bmad/core/workflows/brainstorming/workflow.yaml +38 -0
  246. package/.bmad/core/workflows/party-mode/instructions.md +203 -0
  247. package/.bmad/core/workflows/party-mode/workflow.yaml +28 -0
  248. package/.bmad/docs/claude-code-instructions.md +25 -0
  249. package/.claude/commands/BMad/analyst.md +88 -0
  250. package/.claude/commands/BMad/architect.md +89 -0
  251. package/.claude/commands/BMad/bmad-master.md +114 -0
  252. package/.claude/commands/BMad/bmad-orchestrator.md +151 -0
  253. package/.claude/commands/BMad/dev.md +85 -0
  254. package/.claude/commands/BMad/pm.md +88 -0
  255. package/.claude/commands/BMad/po.md +83 -0
  256. package/.claude/commands/BMad/qa.md +91 -0
  257. package/.claude/commands/BMad/sm.md +69 -0
  258. package/.claude/commands/BMad/tasks/advanced-elicitation.md +123 -0
  259. package/.claude/commands/BMad/tasks/apply-qa-fixes.md +154 -0
  260. package/.claude/commands/BMad/tasks/brownfield-create-epic.md +166 -0
  261. package/.claude/commands/BMad/tasks/brownfield-create-story.md +153 -0
  262. package/.claude/commands/BMad/tasks/correct-course.md +76 -0
  263. package/.claude/commands/BMad/tasks/create-brownfield-story.md +318 -0
  264. package/.claude/commands/BMad/tasks/create-deep-research-prompt.md +284 -0
  265. package/.claude/commands/BMad/tasks/create-doc.md +107 -0
  266. package/.claude/commands/BMad/tasks/create-next-story.md +118 -0
  267. package/.claude/commands/BMad/tasks/document-project.md +349 -0
  268. package/.claude/commands/BMad/tasks/execute-checklist.md +92 -0
  269. package/.claude/commands/BMad/tasks/facilitate-brainstorming-session.md +142 -0
  270. package/.claude/commands/BMad/tasks/generate-ai-frontend-prompt.md +57 -0
  271. package/.claude/commands/BMad/tasks/index-docs.md +179 -0
  272. package/.claude/commands/BMad/tasks/kb-mode-interaction.md +81 -0
  273. package/.claude/commands/BMad/tasks/nfr-assess.md +349 -0
  274. package/.claude/commands/BMad/tasks/qa-gate.md +167 -0
  275. package/.claude/commands/BMad/tasks/review-story.md +320 -0
  276. package/.claude/commands/BMad/tasks/risk-profile.md +359 -0
  277. package/.claude/commands/BMad/tasks/shard-doc.md +191 -0
  278. package/.claude/commands/BMad/tasks/test-design.md +180 -0
  279. package/.claude/commands/BMad/tasks/trace-requirements.md +270 -0
  280. package/.claude/commands/BMad/tasks/validate-next-story.md +140 -0
  281. package/.claude/commands/BMad/ux-expert.md +73 -0
  282. package/.claude/commands/bmad/bmm/agents/analyst.md +14 -0
  283. package/.claude/commands/bmad/bmm/agents/architect.md +14 -0
  284. package/.claude/commands/bmad/bmm/agents/dev.md +14 -0
  285. package/.claude/commands/bmad/bmm/agents/frame-expert.md +14 -0
  286. package/.claude/commands/bmad/bmm/agents/pm.md +14 -0
  287. package/.claude/commands/bmad/bmm/agents/sm.md +14 -0
  288. package/.claude/commands/bmad/bmm/agents/tea.md +14 -0
  289. package/.claude/commands/bmad/bmm/agents/tech-writer.md +14 -0
  290. package/.claude/commands/bmad/bmm/agents/ux-designer.md +14 -0
  291. package/.claude/commands/bmad/bmm/workflows/architecture.md +13 -0
  292. package/.claude/commands/bmad/bmm/workflows/brainstorm-project.md +13 -0
  293. package/.claude/commands/bmad/bmm/workflows/code-review.md +13 -0
  294. package/.claude/commands/bmad/bmm/workflows/correct-course.md +13 -0
  295. package/.claude/commands/bmad/bmm/workflows/create-dataflow.md +13 -0
  296. package/.claude/commands/bmad/bmm/workflows/create-diagram.md +13 -0
  297. package/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +13 -0
  298. package/.claude/commands/bmad/bmm/workflows/create-flowchart.md +13 -0
  299. package/.claude/commands/bmad/bmm/workflows/create-story.md +13 -0
  300. package/.claude/commands/bmad/bmm/workflows/create-ux-design.md +13 -0
  301. package/.claude/commands/bmad/bmm/workflows/create-wireframe.md +13 -0
  302. package/.claude/commands/bmad/bmm/workflows/dev-story.md +13 -0
  303. package/.claude/commands/bmad/bmm/workflows/document-project.md +13 -0
  304. package/.claude/commands/bmad/bmm/workflows/domain-research.md +13 -0
  305. package/.claude/commands/bmad/bmm/workflows/epic-tech-context.md +13 -0
  306. package/.claude/commands/bmad/bmm/workflows/implementation-readiness.md +13 -0
  307. package/.claude/commands/bmad/bmm/workflows/prd.md +13 -0
  308. package/.claude/commands/bmad/bmm/workflows/product-brief.md +13 -0
  309. package/.claude/commands/bmad/bmm/workflows/research.md +13 -0
  310. package/.claude/commands/bmad/bmm/workflows/retrospective.md +13 -0
  311. package/.claude/commands/bmad/bmm/workflows/sprint-planning.md +13 -0
  312. package/.claude/commands/bmad/bmm/workflows/story-context.md +13 -0
  313. package/.claude/commands/bmad/bmm/workflows/story-done.md +13 -0
  314. package/.claude/commands/bmad/bmm/workflows/story-ready.md +13 -0
  315. package/.claude/commands/bmad/bmm/workflows/tech-spec.md +13 -0
  316. package/.claude/commands/bmad/bmm/workflows/workflow-init.md +13 -0
  317. package/.claude/commands/bmad/bmm/workflows/workflow-status.md +13 -0
  318. package/.claude/commands/bmad/core/agents/bmad-master.md +14 -0
  319. package/.claude/commands/bmad/core/tasks/advanced-elicitation.md +9 -0
  320. package/.claude/commands/bmad/core/tasks/index-docs.md +9 -0
  321. package/.claude/commands/bmad/core/tools/shard-doc.md +9 -0
  322. package/.claude/commands/bmad/core/workflows/brainstorming.md +13 -0
  323. package/.claude/commands/bmad/core/workflows/party-mode.md +13 -0
  324. package/.claude/config/background-music-position.txt +26 -0
  325. package/.claude/config/background-music-volume.txt +1 -0
  326. package/.claude/config/background-music.cfg +1 -0
  327. package/.claude/config/tts-verbosity.txt +1 -0
  328. package/.claude/github-star-reminder.txt +1 -0
  329. package/.claude/hooks/background-music-manager.sh +1 -1
  330. package/.claude/hooks/bmad-party-manager.sh +225 -0
  331. package/.claude/hooks/bmad-voice-manager.sh +116 -4
  332. package/.claude/piper-voices-dir.txt +1 -0
  333. package/.mcp.json +30 -0
  334. package/README.md +166 -13
  335. package/mcp-server/server.py +53 -41
  336. package/package.json +6 -2
  337. package/src/commands/install-mcp.js +151 -90
  338. package/src/installer.js +432 -285
  339. package/src/utils/dependency-checker.js +193 -132
package/src/installer.js CHANGED
@@ -117,9 +117,56 @@ function createPageHeaderFooter(pageTitle, currentPage, totalPages, pageOffset =
117
117
  * @param {Object} options - Options for pagination (yes, continueLabel, pageOffset, totalPages, showPreviousOnFirst)
118
118
  * @returns {Promise<void>}
119
119
  */
120
+ /**
121
+ * Build navigation choices for paginated content
122
+ * @param {number} currentPage - Current page index
123
+ * @param {number} totalPages - Total number of pages
124
+ * @param {string} continueLabel - Label for continue button
125
+ * @param {boolean} showPreviousOnFirst - Show previous on first page
126
+ * @returns {Array} Navigation choices
127
+ */
128
+ function buildNavigationChoices(currentPage, totalPages, continueLabel, showPreviousOnFirst) {
129
+ const choices = [];
130
+ const isLastPage = currentPage >= totalPages - 1;
131
+
132
+ if (!isLastPage) {
133
+ choices.push({ name: chalk.green('Next →'), value: 'next' });
134
+ } else {
135
+ choices.push({ name: chalk.cyan(`✓ ${continueLabel.replace('✓ ', '')}`), value: 'continue' });
136
+ }
137
+
138
+ if (currentPage > 0 || showPreviousOnFirst) {
139
+ choices.push({ name: chalk.magentaBright('← Previous'), value: 'prev' });
140
+ }
141
+
142
+ return choices;
143
+ }
144
+
145
+ /**
146
+ * Handle navigation action in paginated content
147
+ * @param {string} action - Navigation action (prev, next, continue)
148
+ * @param {number} currentPage - Current page index
149
+ * @param {boolean} showPreviousOnFirst - Show previous on first page
150
+ * @returns {Object} Navigation result {newPage, shouldExit, shouldReturn}
151
+ */
152
+ function handleNavigationAction(action, currentPage, showPreviousOnFirst) {
153
+ if (action === 'prev') {
154
+ if (currentPage > 0) {
155
+ return { newPage: currentPage - 1, shouldExit: false, shouldReturn: false };
156
+ }
157
+ if (showPreviousOnFirst) {
158
+ return { newPage: currentPage, shouldExit: false, shouldReturn: true };
159
+ }
160
+ } else if (action === 'next') {
161
+ return { newPage: currentPage + 1, shouldExit: false, shouldReturn: false };
162
+ }
163
+
164
+ // Continue action - exit loop
165
+ return { newPage: currentPage, shouldExit: true, shouldReturn: false };
166
+ }
167
+
120
168
  async function showPaginatedContent(pages, options = {}) {
121
169
  if (options.yes || pages.length === 0) {
122
- // In non-interactive mode or no pages, just display all content
123
170
  pages.forEach(page => console.log(page.content));
124
171
  return;
125
172
  }
@@ -131,7 +178,6 @@ async function showPaginatedContent(pages, options = {}) {
131
178
  let currentPage = 0;
132
179
 
133
180
  while (currentPage >= 0 && currentPage < pages.length) {
134
- // Clear screen and show current page with header/footer
135
181
  console.clear();
136
182
 
137
183
  const { header, footer } = createPageHeaderFooter(
@@ -145,35 +191,12 @@ async function showPaginatedContent(pages, options = {}) {
145
191
  console.log('');
146
192
  console.log(pages[currentPage].content);
147
193
 
148
- // Build navigation message with Previous/Next on same line
149
- let navMessage = '';
150
- if (currentPage > 0 && currentPage < pages.length - 1) {
151
- navMessage = `${chalk.cyan('←')} Previous | Next ${chalk.cyan('→')} | ${continueLabel}`;
152
- } else if (currentPage > 0) {
153
- navMessage = `${chalk.cyan('←')} Previous | ${continueLabel}`;
154
- } else if (currentPage < pages.length - 1) {
155
- navMessage = `Next ${chalk.cyan('→')} | ${continueLabel}`;
156
- } else {
157
- navMessage = continueLabel;
158
- }
159
-
160
- // Build navigation choices with colors
161
- const choices = [];
162
- if (currentPage < pages.length - 1) {
163
- choices.push({ name: chalk.green('Next →'), value: 'next' });
164
- } else {
165
- // Only show "Start Installation" on the last page
166
- choices.push({ name: chalk.cyan(`✓ ${continueLabel.replace('✓ ', '')}`), value: 'continue' });
167
- }
168
- if (currentPage > 0 || showPreviousOnFirst) {
169
- choices.push({ name: chalk.magentaBright('← Previous'), value: 'prev' });
170
- }
194
+ const choices = buildNavigationChoices(currentPage, pages.length, continueLabel, showPreviousOnFirst);
171
195
 
172
196
  console.log('');
173
197
  console.log(footer);
174
198
  console.log('');
175
199
 
176
- // Show navigation prompt
177
200
  const { action } = await inquirer.prompt([{
178
201
  type: 'list',
179
202
  name: 'action',
@@ -182,23 +205,123 @@ async function showPaginatedContent(pages, options = {}) {
182
205
  default: currentPage < pages.length - 1 ? 'next' : 'continue'
183
206
  }]);
184
207
 
185
- if (action === 'prev') {
186
- if (currentPage > 0) {
187
- currentPage--;
188
- } else if (showPreviousOnFirst) {
189
- // User clicked Previous on first page - signal to caller
190
- return 'prev';
191
- }
192
- } else if (action === 'next') {
193
- currentPage++;
194
- } else {
195
- // Continue - exit loop
208
+ const navResult = handleNavigationAction(action, currentPage, showPreviousOnFirst);
209
+
210
+ if (navResult.shouldReturn) {
211
+ return 'prev';
212
+ }
213
+
214
+ if (navResult.shouldExit) {
196
215
  console.clear();
197
216
  break;
198
217
  }
218
+
219
+ currentPage = navResult.newPage;
199
220
  }
200
221
  }
201
222
 
223
+ /**
224
+ * Get page title by page number
225
+ * @param {number} pageNum - Page number (0-4)
226
+ * @returns {string} Page title
227
+ */
228
+ function getPageTitle(pageNum) {
229
+ const titles = {
230
+ 0: 'System Dependencies',
231
+ 1: 'TTS Provider Configuration',
232
+ 2: 'Voice Selection',
233
+ 3: 'Audio Settings',
234
+ 4: 'Verbosity Settings'
235
+ };
236
+ return titles[pageNum] || 'Configuration';
237
+ }
238
+
239
+ /**
240
+ * Handle Page 0: System Dependencies display
241
+ * @returns {Promise<void>}
242
+ */
243
+ async function handleSystemDependenciesPage() {
244
+ const { checkDependencies, getInstallCommands } = await import('./utils/dependency-checker.js');
245
+ const depResults = checkDependencies();
246
+
247
+ let depContent = chalk.gray('System dependencies are tools AgentVibes needs to function properly.\n');
248
+ depContent += chalk.gray('Required tools must be installed, optional tools enable extra features.\n\n');
249
+
250
+ // Satisfied dependencies
251
+ if (depResults.core.node?.isCompatible) {
252
+ depContent += chalk.green(`✓ Node.js ${depResults.core.node.version}\n`);
253
+ }
254
+ if (depResults.core.python?.isCompatible) {
255
+ depContent += chalk.green(`✓ Python ${depResults.core.python.version}\n`);
256
+ }
257
+ if (depResults.core.bash?.isModern) {
258
+ depContent += chalk.green(`✓ Bash ${depResults.core.bash.version}\n`);
259
+ }
260
+ if (depResults.optional.curl) {
261
+ depContent += chalk.green('✓ curl\n');
262
+ }
263
+ if (depResults.optional.sox) {
264
+ depContent += chalk.green('✓ sox\n');
265
+ }
266
+ if (depResults.optional.ffmpeg) {
267
+ depContent += chalk.green('✓ ffmpeg\n');
268
+ }
269
+ if (depResults.optional.bc) {
270
+ depContent += chalk.green('✓ bc\n');
271
+ }
272
+ if (depResults.optional.flock) {
273
+ depContent += chalk.green('✓ flock\n');
274
+ }
275
+ if (depResults.optional.pipx) {
276
+ depContent += chalk.green('✓ pipx\n');
277
+ }
278
+ if (depResults.optional.audioPlayer) {
279
+ depContent += chalk.green('✓ audio player (paplay/aplay/mpv)\n');
280
+ }
281
+
282
+ // Missing dependencies
283
+ if (Object.keys(depResults.missing).length > 0) {
284
+ depContent += '\n' + chalk.gray('─'.repeat(50)) + '\n\n';
285
+ depContent += chalk.yellow.bold('Missing (Optional):\n\n');
286
+
287
+ if (depResults.missing.curl) depContent += chalk.yellow('⚠ curl - needed for downloads\n');
288
+ if (depResults.missing.sox) depContent += chalk.yellow('⚠ sox - audio effects\n');
289
+ if (depResults.missing.ffmpeg) depContent += chalk.yellow('⚠ ffmpeg - background music\n');
290
+ if (depResults.missing.bc) depContent += chalk.yellow('⚠ bc - audio calculations\n');
291
+ if (depResults.missing.flock) depContent += chalk.yellow('⚠ flock - TTS queue locking\n');
292
+ if (depResults.missing.pipx) depContent += chalk.yellow('⚠ pipx - Piper TTS installation\n');
293
+ if (depResults.missing.audioPlayer) depContent += chalk.yellow('⚠ audio player - playback\n');
294
+
295
+ depContent += '\n' + chalk.gray('TTS will still work without optional tools');
296
+
297
+ // Add install commands
298
+ const os = await import('os');
299
+ const platform = os.platform();
300
+ const installCmds = getInstallCommands(depResults.missing, platform);
301
+
302
+ if (installCmds.length > 0) {
303
+ depContent += '\n\n' + chalk.gray('─'.repeat(50)) + '\n\n';
304
+ depContent += chalk.cyan.bold('To Install Missing Tools:\n\n');
305
+
306
+ installCmds.forEach(({ label, command }) => {
307
+ depContent += chalk.cyan(`${label}:\n`);
308
+ depContent += chalk.white(` ${command}\n\n`);
309
+ });
310
+ }
311
+ }
312
+
313
+ const depsBoxen = boxen(depContent.trim(), {
314
+ padding: 1,
315
+ margin: 1,
316
+ borderStyle: 'round',
317
+ borderColor: Object.keys(depResults.missing).length > 0 ? 'yellow' : 'green',
318
+ title: chalk.bold('🔧 System Dependencies'),
319
+ titleAlignment: 'center'
320
+ });
321
+
322
+ console.log(depsBoxen);
323
+ }
324
+
202
325
  /**
203
326
  * Collect all configuration answers through paginated question flow
204
327
  * @param {Object} options - Installation options (yes, pageOffset, totalPages)
@@ -240,97 +363,13 @@ async function collectConfiguration(options = {}) {
240
363
  console.clear();
241
364
 
242
365
  // Show header
243
- const pageTitle = currentPage === 0 ? 'System Dependencies' :
244
- currentPage === 1 ? 'TTS Provider Configuration' :
245
- currentPage === 2 ? 'Voice Selection' :
246
- currentPage === 3 ? 'Audio Settings' :
247
- 'Verbosity Settings';
366
+ const pageTitle = getPageTitle(currentPage);
248
367
  const { header, footer } = createPageHeaderFooter(pageTitle, currentPage, totalPages, pageOffset);
249
368
  console.log(header);
250
369
  console.log('');
251
370
 
252
371
  if (currentPage === 0) {
253
- // Page 1: System Dependencies Check
254
- const { checkDependencies } = await import('./utils/dependency-checker.js');
255
- const depResults = checkDependencies();
256
-
257
- let depContent = chalk.gray('System dependencies are tools AgentVibes needs to function properly.\n');
258
- depContent += chalk.gray('Required tools must be installed, optional tools enable extra features.\n\n');
259
-
260
- // Satisfied dependencies
261
- if (depResults.core.node?.isCompatible) {
262
- depContent += chalk.green(`✓ Node.js ${depResults.core.node.version}\n`);
263
- }
264
- if (depResults.core.python?.isCompatible) {
265
- depContent += chalk.green(`✓ Python ${depResults.core.python.version}\n`);
266
- }
267
- if (depResults.core.bash?.isModern) {
268
- depContent += chalk.green(`✓ Bash ${depResults.core.bash.version}\n`);
269
- }
270
- if (depResults.optional.curl) {
271
- depContent += chalk.green('✓ curl\n');
272
- }
273
- if (depResults.optional.sox) {
274
- depContent += chalk.green('✓ sox\n');
275
- }
276
- if (depResults.optional.ffmpeg) {
277
- depContent += chalk.green('✓ ffmpeg\n');
278
- }
279
- if (depResults.optional.bc) {
280
- depContent += chalk.green('✓ bc\n');
281
- }
282
- if (depResults.optional.flock) {
283
- depContent += chalk.green('✓ flock\n');
284
- }
285
- if (depResults.optional.pipx) {
286
- depContent += chalk.green('✓ pipx\n');
287
- }
288
- if (depResults.optional.audioPlayer) {
289
- depContent += chalk.green('✓ audio player (paplay/aplay/mpv)\n');
290
- }
291
-
292
- // Missing dependencies
293
- if (Object.keys(depResults.missing).length > 0) {
294
- depContent += '\n' + chalk.gray('─'.repeat(50)) + '\n\n';
295
- depContent += chalk.yellow.bold('Missing (Optional):\n\n');
296
-
297
- if (depResults.missing.curl) depContent += chalk.yellow('⚠ curl - needed for downloads\n');
298
- if (depResults.missing.sox) depContent += chalk.yellow('⚠ sox - audio effects\n');
299
- if (depResults.missing.ffmpeg) depContent += chalk.yellow('⚠ ffmpeg - background music\n');
300
- if (depResults.missing.bc) depContent += chalk.yellow('⚠ bc - audio calculations\n');
301
- if (depResults.missing.flock) depContent += chalk.yellow('⚠ flock - TTS queue locking\n');
302
- if (depResults.missing.pipx) depContent += chalk.yellow('⚠ pipx - Piper TTS installation\n');
303
- if (depResults.missing.audioPlayer) depContent += chalk.yellow('⚠ audio player - playback\n');
304
-
305
- depContent += '\n' + chalk.gray('TTS will still work without optional tools');
306
-
307
- // Add install commands
308
- const os = await import('os');
309
- const { getInstallCommands } = await import('./utils/dependency-checker.js');
310
- const platform = os.platform();
311
- const installCmds = getInstallCommands(depResults.missing, platform);
312
-
313
- if (installCmds.length > 0) {
314
- depContent += '\n\n' + chalk.gray('─'.repeat(50)) + '\n\n';
315
- depContent += chalk.cyan.bold('To Install Missing Tools:\n\n');
316
-
317
- installCmds.forEach(({ label, command }) => {
318
- depContent += chalk.cyan(`${label}:\n`);
319
- depContent += chalk.white(` ${command}\n\n`);
320
- });
321
- }
322
- }
323
-
324
- const depsBoxen = boxen(depContent.trim(), {
325
- padding: 1,
326
- margin: 1,
327
- borderStyle: 'round',
328
- borderColor: Object.keys(depResults.missing).length > 0 ? 'yellow' : 'green',
329
- title: chalk.bold('🔧 System Dependencies'),
330
- titleAlignment: 'center'
331
- });
332
-
333
- console.log(depsBoxen);
372
+ await handleSystemDependenciesPage();
334
373
  } else if (currentPage === 1) {
335
374
  // Page 2: TTS Provider & Voice Storage
336
375
 
@@ -767,19 +806,20 @@ function showWelcome() {
767
806
  * Shown during install and update commands
768
807
  */
769
808
  function getReleaseInfoBoxen() {
770
- return chalk.cyan.bold('📦 AgentVibes v2.17.0 - Installer UX Revolution\n\n') +
809
+ return chalk.cyan.bold('📦 AgentVibes v2.17.4 - Code Quality & Maintainability\n\n') +
771
810
  chalk.green.bold('🎙️ WHAT\'S NEW:\n\n') +
772
- chalk.cyan('AgentVibes v2.17.0 delivers a complete installer user experience transformation\n') +
773
- chalk.cyan('with intelligent system dependency checking, paginated configuration flow, and\n') +
774
- chalk.cyan('comprehensive inline help with command examples throughout.\n\n') +
811
+ chalk.cyan('AgentVibes v2.17.4 focuses on code quality and maintainability with extensive\n') +
812
+ chalk.cyan('SonarCloud-driven refactoring across the entire codebase. This release reduces\n') +
813
+ chalk.cyan('cognitive complexity in critical files by up to 90%, making the codebase more\n') +
814
+ chalk.cyan('maintainable and easier to understand.\n\n') +
775
815
  chalk.green.bold('✨ KEY HIGHLIGHTS:\n\n') +
776
- chalk.gray(' 🔧 System Dependency Checker - Validates Node, Python, bash, sox, ffmpeg, curl, etc.\n') +
777
- chalk.gray(' 📄 Paginated Configuration - Beautiful headers with Agent Vibes branding on every page\n') +
778
- chalk.gray(' 💡 Inline Help & Commands - TTS explanations and examples throughout installer\n') +
779
- chalk.gray(' 🎵 New Music Track - Salsa v2 background music now available\n') +
780
- chalk.gray(' 🎨 Professional UI - Consistent sunshine yellow styling and dynamic page numbering\n') +
781
- chalk.gray(' 📋 Enhanced Navigation - Previous button, accurate page counts, README links\n') +
782
- chalk.gray(' Quality Assurance - 140 tests passing, SonarCloud integration\n\n') +
816
+ chalk.gray(' ⚙️ Major Code Refactoring - Cognitive complexity reduced by up to 90% across critical files\n') +
817
+ chalk.gray(' 🧪 Comprehensive Testing - 377 new party mode tests added, 225 total tests passing\n') +
818
+ chalk.gray(' 📚 Improved Documentation - New Prerequisites and FAQ sections clarify installation\n') +
819
+ chalk.gray(' 🎭 Conversational Agent Intros - BMAD party mode now uses "Hi! I\'m John, your Product Manager"\n') +
820
+ chalk.gray(' 🔊 Better Audio Balance - Background music reduced 15% for clearer TTS voice\n') +
821
+ chalk.gray(' 🏗️ installer.js: 84 ~8 complexity (90% reduction)\n') +
822
+ chalk.gray(' 📦 dependency-checker.js: 43 ~5, 23 → ~8 (88% & 65% reductions)\n\n') +
783
823
  chalk.gray('📖 Full Release Notes: RELEASE_NOTES.md\n') +
784
824
  chalk.gray('🌐 Website: https://agentvibes.org\n') +
785
825
  chalk.gray('📦 Repository: https://github.com/paulpreibisch/AgentVibes\n\n') +
@@ -1300,6 +1340,103 @@ async function copyCommandFiles(targetDir, spinner) {
1300
1340
  }
1301
1341
  }
1302
1342
 
1343
+ /**
1344
+ * Check if a file should be included as a hook file
1345
+ * @param {string} file - Filename to check
1346
+ * @param {Object} stat - File stats object
1347
+ * @returns {boolean} True if file should be included
1348
+ */
1349
+ function shouldIncludeHookFile(file, stat) {
1350
+ return stat.isFile() &&
1351
+ (file.endsWith('.sh') || file === 'hooks.json') &&
1352
+ !file.includes('prepare-release') &&
1353
+ !file.startsWith('.');
1354
+ }
1355
+
1356
+ /**
1357
+ * Filter hook files from directory
1358
+ * @param {string} srcHooksDir - Source hooks directory
1359
+ * @param {Array} allFiles - All files in directory
1360
+ * @returns {Promise<Array>} Filtered hook files
1361
+ */
1362
+ async function filterHookFiles(srcHooksDir, allFiles) {
1363
+ const hookFiles = [];
1364
+
1365
+ for (const file of allFiles) {
1366
+ const srcPath = path.join(srcHooksDir, file);
1367
+ try {
1368
+ const stat = await fs.stat(srcPath);
1369
+ if (shouldIncludeHookFile(file, stat)) {
1370
+ hookFiles.push(file);
1371
+ }
1372
+ } catch (err) {
1373
+ console.log(chalk.yellow(` ⚠ Could not check ${file}: ${err.message}`));
1374
+ }
1375
+ }
1376
+
1377
+ return hookFiles;
1378
+ }
1379
+
1380
+ /**
1381
+ * Copy a single hook file and set permissions
1382
+ * @param {string} srcPath - Source file path
1383
+ * @param {string} destPath - Destination file path
1384
+ * @param {string} filename - Name of the file
1385
+ * @returns {Promise<Object>} Result object with success/error info
1386
+ */
1387
+ async function copyHookFile(srcPath, destPath, filename) {
1388
+ try {
1389
+ await fs.copyFile(srcPath, destPath);
1390
+
1391
+ if (filename.endsWith('.sh')) {
1392
+ await fs.chmod(destPath, 0o750);
1393
+ return { success: true, name: filename, executable: true };
1394
+ }
1395
+
1396
+ return { success: true, name: filename, executable: false };
1397
+ } catch (err) {
1398
+ return { success: false, name: filename, error: err.message };
1399
+ }
1400
+ }
1401
+
1402
+ /**
1403
+ * Build boxen content for hook installation results
1404
+ * @param {Array} installedFiles - Successfully installed files
1405
+ * @param {Array} failedFiles - Failed files
1406
+ * @returns {string} Boxen formatted content
1407
+ */
1408
+ function buildHookInstallationBoxen(installedFiles, failedFiles) {
1409
+ let content = chalk.bold(`${installedFiles.length} TTS Hook Scripts Installed\n\n`);
1410
+ content += chalk.gray('Hook scripts automatically run at key moments during your\n');
1411
+ content += chalk.gray('Claude Code sessions to provide TTS feedback and manage audio.\n\n');
1412
+
1413
+ installedFiles.forEach(file => {
1414
+ content += chalk.green(`✓ ${file.name}`);
1415
+ if (file.executable) {
1416
+ content += chalk.gray(' (executable)');
1417
+ }
1418
+ content += '\n';
1419
+ });
1420
+
1421
+ if (failedFiles.length > 0) {
1422
+ content += '\n' + chalk.gray('─'.repeat(60)) + '\n\n';
1423
+ content += chalk.bold.yellow(`${failedFiles.length} Failed\n\n`);
1424
+ failedFiles.forEach(file => {
1425
+ content += chalk.yellow(`⚠ ${file.name}\n`);
1426
+ content += chalk.dim(` ${file.error}\n`);
1427
+ });
1428
+ }
1429
+
1430
+ return boxen(content.trim(), {
1431
+ padding: 1,
1432
+ margin: 1,
1433
+ borderStyle: 'round',
1434
+ borderColor: 'green',
1435
+ title: chalk.bold('🔧 TTS Scripts'),
1436
+ titleAlignment: 'center'
1437
+ });
1438
+ }
1439
+
1303
1440
  /**
1304
1441
  * Copy hook files to target directory
1305
1442
  * @param {string} targetDir - Target installation directory
@@ -1315,87 +1452,36 @@ async function copyHookFiles(targetDir, spinner) {
1315
1452
  await fs.mkdir(hooksDir, { recursive: true });
1316
1453
 
1317
1454
  const allHookFiles = await fs.readdir(srcHooksDir);
1318
- const hookFiles = [];
1319
-
1320
- for (const file of allHookFiles) {
1321
- const srcPath = path.join(srcHooksDir, file);
1322
- try {
1323
- const stat = await fs.stat(srcPath);
1324
-
1325
- if (stat.isFile() &&
1326
- (file.endsWith('.sh') || file === 'hooks.json') &&
1327
- !file.includes('prepare-release') &&
1328
- !file.startsWith('.')) {
1329
- hookFiles.push(file);
1330
- }
1331
- } catch (err) {
1332
- console.log(chalk.yellow(` ⚠ Could not check ${file}: ${err.message}`));
1333
- // Continue with other files
1334
- }
1335
- }
1455
+ const hookFiles = await filterHookFiles(srcHooksDir, allHookFiles);
1336
1456
 
1337
1457
  spinner.start(`Installing ${hookFiles.length} TTS scripts...`);
1338
- let successCount = 0;
1339
- let installedFiles = [];
1340
- let failedFiles = [];
1458
+
1459
+ const installedFiles = [];
1460
+ const failedFiles = [];
1341
1461
 
1342
1462
  for (const file of hookFiles) {
1343
1463
  const srcPath = path.join(srcHooksDir, file);
1344
1464
  const destPath = path.join(hooksDir, file);
1345
- try {
1346
- await fs.copyFile(srcPath, destPath);
1465
+ const result = await copyHookFile(srcPath, destPath, file);
1347
1466
 
1348
- if (file.endsWith('.sh')) {
1349
- // Security: Use more restrictive permissions (owner: rwx, group: r-x, others: ---)
1350
- await fs.chmod(destPath, 0o750);
1351
- installedFiles.push({ name: file, executable: true });
1352
- } else {
1353
- installedFiles.push({ name: file, executable: false });
1354
- }
1355
- successCount++;
1356
- } catch (err) {
1357
- failedFiles.push({ name: file, error: err.message });
1467
+ if (result.success) {
1468
+ installedFiles.push({ name: result.name, executable: result.executable });
1469
+ } else {
1470
+ failedFiles.push({ name: result.name, error: result.error });
1358
1471
  }
1359
1472
  }
1360
1473
 
1474
+ const successCount = installedFiles.length;
1475
+
1361
1476
  if (successCount === hookFiles.length) {
1362
1477
  spinner.succeed(chalk.green('Installed TTS scripts!\n'));
1363
1478
  } else {
1364
1479
  spinner.warn(chalk.yellow(`Installed ${successCount}/${hookFiles.length} scripts (some failed)\n`));
1365
1480
  }
1366
1481
 
1367
- // Create boxen content (don't print yet - will be shown in pagination)
1368
- let boxenContent = null;
1369
- if (installedFiles.length > 0) {
1370
- let content = chalk.bold(`${installedFiles.length} TTS Hook Scripts Installed\n\n`);
1371
- content += chalk.gray('Hook scripts automatically run at key moments during your\n');
1372
- content += chalk.gray('Claude Code sessions to provide TTS feedback and manage audio.\n\n');
1373
- installedFiles.forEach(file => {
1374
- content += chalk.green(`✓ ${file.name}`);
1375
- if (file.executable) {
1376
- content += chalk.gray(' (executable)');
1377
- }
1378
- content += '\n';
1379
- });
1380
-
1381
- if (failedFiles.length > 0) {
1382
- content += '\n' + chalk.gray('─'.repeat(60)) + '\n\n';
1383
- content += chalk.bold.yellow(`${failedFiles.length} Failed\n\n`);
1384
- failedFiles.forEach(file => {
1385
- content += chalk.yellow(`⚠ ${file.name}\n`);
1386
- content += chalk.dim(` ${file.error}\n`);
1387
- });
1388
- }
1389
-
1390
- boxenContent = boxen(content.trim(), {
1391
- padding: 1,
1392
- margin: 1,
1393
- borderStyle: 'round',
1394
- borderColor: 'green',
1395
- title: chalk.bold('🔧 TTS Scripts'),
1396
- titleAlignment: 'center'
1397
- });
1398
- }
1482
+ const boxenContent = installedFiles.length > 0
1483
+ ? buildHookInstallationBoxen(installedFiles, failedFiles)
1484
+ : null;
1399
1485
 
1400
1486
  return { count: successCount, boxen: boxenContent };
1401
1487
  } catch (err) {
@@ -1779,7 +1865,7 @@ async function checkAndInstallPiper(targetDir, options) {
1779
1865
  const { execSync } = await import('node:child_process');
1780
1866
 
1781
1867
  try {
1782
- execSync('command -v piper', { stdio: 'ignore' });
1868
+ execSync('command -v piper', { stdio: 'ignore' }); // NOSONAR - Safe: fixed command, no user input
1783
1869
  console.log(chalk.green('✅ Piper TTS is already installed\n'));
1784
1870
  return;
1785
1871
  } catch {
@@ -2190,36 +2276,31 @@ frame-expert,en_GB-alan-medium
2190
2276
  * @param {Object} spinner - Ora spinner instance
2191
2277
  * @returns {Promise<boolean>} True if migration was performed
2192
2278
  */
2193
- async function detectAndMigrateOldConfig(targetDir, spinner) {
2194
- const oldConfigPaths = [
2195
- path.join(targetDir, '.claude', 'config', 'agentvibes.json'),
2196
- path.join(targetDir, '.claude', 'config', 'bmad-voices.md'),
2197
- path.join(targetDir, '.claude', 'config', 'bmad-voices-enabled.flag'),
2198
- path.join(targetDir, '.claude', 'plugins', 'bmad-voices-enabled.flag'),
2199
- path.join(targetDir, '.claude', 'plugins', 'bmad-party-mode-disabled.flag'),
2200
- ];
2201
-
2202
- // Check if any old config exists
2203
- let hasOldConfig = false;
2204
- for (const oldPath of oldConfigPaths) {
2279
+ /**
2280
+ * Check if any old config files exist
2281
+ * @param {string[]} paths - Array of paths to check
2282
+ * @returns {Promise<boolean>} True if any old config exists
2283
+ */
2284
+ async function hasOldConfigFiles(paths) {
2285
+ for (const oldPath of paths) {
2205
2286
  try {
2206
2287
  await fs.access(oldPath);
2207
- hasOldConfig = true;
2208
- break;
2288
+ return true;
2209
2289
  } catch {
2210
2290
  // File doesn't exist, continue
2211
2291
  }
2212
2292
  }
2293
+ return false;
2294
+ }
2213
2295
 
2214
- if (!hasOldConfig) {
2215
- return false; // No migration needed
2216
- }
2217
-
2218
- spinner.info(chalk.yellow('🔄 Old configuration detected - migrating to .agentvibes/'));
2219
-
2220
- // Run migration script
2221
- const migrationScript = path.join(targetDir, '.claude', 'hooks', 'migrate-to-agentvibes.sh');
2222
-
2296
+ /**
2297
+ * Execute migration script
2298
+ * @param {string} migrationScript - Path to migration script
2299
+ * @param {string} targetDir - Target directory
2300
+ * @param {Object} spinner - Ora spinner instance
2301
+ * @returns {Promise<boolean>} True if migration succeeded
2302
+ */
2303
+ async function executeMigrationScript(migrationScript, targetDir, spinner) {
2223
2304
  try {
2224
2305
  await fs.access(migrationScript);
2225
2306
 
@@ -2244,6 +2325,27 @@ async function detectAndMigrateOldConfig(targetDir, spinner) {
2244
2325
  }
2245
2326
  }
2246
2327
 
2328
+ async function detectAndMigrateOldConfig(targetDir, spinner) {
2329
+ const oldConfigPaths = [
2330
+ path.join(targetDir, '.claude', 'config', 'agentvibes.json'),
2331
+ path.join(targetDir, '.claude', 'config', 'bmad-voices.md'),
2332
+ path.join(targetDir, '.claude', 'config', 'bmad-voices-enabled.flag'),
2333
+ path.join(targetDir, '.claude', 'plugins', 'bmad-voices-enabled.flag'),
2334
+ path.join(targetDir, '.claude', 'plugins', 'bmad-party-mode-disabled.flag'),
2335
+ ];
2336
+
2337
+ // Check if any old config exists
2338
+ if (!await hasOldConfigFiles(oldConfigPaths)) {
2339
+ return false; // No migration needed
2340
+ }
2341
+
2342
+ spinner.info(chalk.yellow('🔄 Old configuration detected - migrating to .agentvibes/'));
2343
+
2344
+ // Run migration script
2345
+ const migrationScript = path.join(targetDir, '.claude', 'hooks', 'migrate-to-agentvibes.sh');
2346
+ return await executeMigrationScript(migrationScript, targetDir, spinner);
2347
+ }
2348
+
2247
2349
  /**
2248
2350
  * Handle BMAD integration (detection and TTS injection)
2249
2351
  * @param {string} targetDir - Target installation directory
@@ -2300,7 +2402,7 @@ async function handleBmadIntegration(targetDir) {
2300
2402
  async function showRecentChanges(sourceDir) {
2301
2403
  try {
2302
2404
  const { execSync } = await import('node:child_process');
2303
- const gitLog = execSync(
2405
+ const gitLog = execSync( // NOSONAR - Safe: fixed command with controlled cwd, no user input
2304
2406
  'git log --oneline --no-decorate -5',
2305
2407
  { cwd: sourceDir, encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }
2306
2408
  ).trim();
@@ -2387,84 +2489,129 @@ async function updatePersonalityFiles(targetDir, srcPersonalitiesDir) {
2387
2489
  }
2388
2490
 
2389
2491
  /**
2390
- * Update AgentVibes files in target directory
2492
+ * Create a silent spinner for update operations
2493
+ * @returns {Object} Mock spinner object
2494
+ */
2495
+ function createSilentSpinner() {
2496
+ return { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} };
2497
+ }
2498
+
2499
+ /**
2500
+ * Update command files
2391
2501
  * @param {string} targetDir - Target installation directory
2392
- * @param {Object} options - Update options
2502
+ * @param {Object} spinner - Ora spinner instance
2503
+ * @returns {Promise<number>} Number of commands updated
2393
2504
  */
2394
- async function updateAgentVibes(targetDir, options) {
2395
- const spinner = ora('Updating AgentVibes...').start();
2505
+ async function updateCommandFiles(targetDir, spinner) {
2506
+ spinner.text = 'Updating commands...';
2507
+ const commandsDir = path.join(targetDir, '.claude', 'commands', 'agent-vibes');
2508
+ const srcCommandsDir = path.join(__dirname, '..', '.claude', 'commands', 'agent-vibes');
2509
+ const commandFiles = await fs.readdir(srcCommandsDir);
2396
2510
 
2397
- try {
2398
- const claudeDir = path.join(targetDir, '.claude');
2399
- const commandsDir = path.join(targetDir, '.claude', 'commands', 'agent-vibes');
2511
+ for (const file of commandFiles) {
2512
+ const srcPath = path.join(srcCommandsDir, file);
2513
+ const destPath = path.join(commandsDir, file);
2514
+ await fs.copyFile(srcPath, destPath);
2515
+ }
2400
2516
 
2401
- // Update commands
2402
- spinner.text = 'Updating commands...';
2403
- const srcCommandsDir = path.join(__dirname, '..', '.claude', 'commands', 'agent-vibes');
2404
- const commandFiles = await fs.readdir(srcCommandsDir);
2517
+ return commandFiles.length;
2518
+ }
2405
2519
 
2406
- for (const file of commandFiles) {
2407
- const srcPath = path.join(srcCommandsDir, file);
2408
- const destPath = path.join(commandsDir, file);
2409
- await fs.copyFile(srcPath, destPath);
2410
- }
2411
- console.log(chalk.green(`\n✓ Updated ${commandFiles.length} commands`));
2520
+ /**
2521
+ * Perform all update operations
2522
+ * @param {string} targetDir - Target installation directory
2523
+ * @param {Object} spinner - Ora spinner instance
2524
+ * @returns {Promise<Object>} Update results
2525
+ */
2526
+ async function performUpdateOperations(targetDir, spinner) {
2527
+ const silentSpinner = createSilentSpinner();
2412
2528
 
2413
- // Update hooks
2414
- spinner.text = 'Updating TTS scripts...';
2415
- const hookResult = await copyHookFiles(targetDir, { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} });
2416
- console.log(chalk.green(`✓ Updated ${hookResult.count} TTS scripts`));
2529
+ // Update commands
2530
+ const commandCount = await updateCommandFiles(targetDir, spinner);
2531
+ console.log(chalk.green(`\n✓ Updated ${commandCount} commands`));
2417
2532
 
2418
- // Update personalities
2419
- spinner.text = 'Updating personality templates...';
2420
- const srcPersonalitiesDir = path.join(__dirname, '..', '.claude', 'personalities');
2421
- const personalityResult = await updatePersonalityFiles(targetDir, srcPersonalitiesDir);
2422
- console.log(chalk.green(`✓ Updated ${personalityResult.updated} personalities, added ${personalityResult.new} new`));
2533
+ // Update hooks
2534
+ spinner.text = 'Updating TTS scripts...';
2535
+ const hookResult = await copyHookFiles(targetDir, silentSpinner);
2536
+ console.log(chalk.green(`✓ Updated ${hookResult.count} TTS scripts`));
2423
2537
 
2424
- // Output styles removed - deprecated in favor of SessionStart hook system
2538
+ // Update personalities
2539
+ spinner.text = 'Updating personality templates...';
2540
+ const srcPersonalitiesDir = path.join(__dirname, '..', '.claude', 'personalities');
2541
+ const personalityResult = await updatePersonalityFiles(targetDir, srcPersonalitiesDir);
2542
+ console.log(chalk.green(`✓ Updated ${personalityResult.updated} personalities, added ${personalityResult.new} new`));
2425
2543
 
2426
- // Update plugin files
2427
- const pluginFileCount = await copyPluginFiles(targetDir, { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} });
2428
- if (pluginFileCount > 0) {
2429
- console.log(chalk.green(`✓ Updated ${pluginFileCount} BMAD plugin files`));
2430
- }
2544
+ // Update plugin files
2545
+ const pluginFileCount = await copyPluginFiles(targetDir, silentSpinner);
2546
+ if (pluginFileCount > 0) {
2547
+ console.log(chalk.green(`✓ Updated ${pluginFileCount} BMAD plugin files`));
2548
+ }
2431
2549
 
2432
- // Update BMAD config files
2433
- const bmadConfigFileCount = await copyBmadConfigFiles(targetDir, { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} });
2434
- if (bmadConfigFileCount > 0) {
2435
- console.log(chalk.green(`✓ Updated ${bmadConfigFileCount} BMAD config files`));
2436
- }
2550
+ // Update BMAD config files
2551
+ const bmadConfigFileCount = await copyBmadConfigFiles(targetDir, silentSpinner);
2552
+ if (bmadConfigFileCount > 0) {
2553
+ console.log(chalk.green(`✓ Updated ${bmadConfigFileCount} BMAD config files`));
2554
+ }
2437
2555
 
2438
- // Update background music files
2439
- const backgroundMusicUpdateResult = await copyBackgroundMusicFiles(targetDir, { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} });
2440
- if (backgroundMusicUpdateResult.count > 0) {
2441
- console.log(chalk.green(`✓ Installed ${backgroundMusicUpdateResult.count} background music track${backgroundMusicUpdateResult.count === 1 ? '' : 's'}`));
2442
- }
2556
+ // Update background music files
2557
+ const backgroundMusicUpdateResult = await copyBackgroundMusicFiles(targetDir, silentSpinner);
2558
+ if (backgroundMusicUpdateResult.count > 0) {
2559
+ console.log(chalk.green(`✓ Installed ${backgroundMusicUpdateResult.count} background music track${backgroundMusicUpdateResult.count === 1 ? '' : 's'}`));
2560
+ }
2443
2561
 
2444
- // Update config files
2445
- const configFileCount = await copyConfigFiles(targetDir, { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} });
2446
- if (configFileCount > 0) {
2447
- console.log(chalk.green(`✓ Installed ${configFileCount} config file${configFileCount === 1 ? '' : 's'}`));
2448
- }
2562
+ // Update config files
2563
+ const configFileCount = await copyConfigFiles(targetDir, silentSpinner);
2564
+ if (configFileCount > 0) {
2565
+ console.log(chalk.green(`✓ Installed ${configFileCount} config file${configFileCount === 1 ? '' : 's'}`));
2566
+ }
2449
2567
 
2450
- // Update settings.json
2451
- spinner.text = 'Updating AgentVibes hook configuration...';
2452
- await configureSessionStartHook(targetDir, { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} });
2568
+ // Update settings.json
2569
+ spinner.text = 'Updating AgentVibes hook configuration...';
2570
+ await configureSessionStartHook(targetDir, silentSpinner);
2453
2571
 
2454
- // Detect and migrate old configuration
2455
- spinner.text = 'Checking for old configuration...';
2456
- await detectAndMigrateOldConfig(targetDir, spinner);
2572
+ // Detect and migrate old configuration
2573
+ spinner.text = 'Checking for old configuration...';
2574
+ await detectAndMigrateOldConfig(targetDir, spinner);
2575
+
2576
+ return {
2577
+ commandCount,
2578
+ hookCount: hookResult.count,
2579
+ personalityResult,
2580
+ pluginFileCount
2581
+ };
2582
+ }
2583
+
2584
+ /**
2585
+ * Display update summary
2586
+ * @param {Object} results - Update results
2587
+ */
2588
+ function displayUpdateSummary(results) {
2589
+ console.log(chalk.cyan('📦 Update Summary:'));
2590
+ console.log(chalk.white(` • ${results.commandCount} commands updated`));
2591
+ console.log(chalk.white(` • ${results.hookCount} TTS scripts updated`));
2592
+ console.log(chalk.white(` • ${results.personalityResult.new + results.personalityResult.updated} personality templates (${results.personalityResult.new} new, ${results.personalityResult.updated} updated)`));
2593
+ if (results.pluginFileCount > 0) {
2594
+ console.log(chalk.white(` • ${results.pluginFileCount} BMAD plugin files updated`));
2595
+ }
2596
+ console.log('');
2597
+ }
2598
+
2599
+ /**
2600
+ * Update AgentVibes files in target directory
2601
+ * @param {string} targetDir - Target installation directory
2602
+ * @param {Object} options - Update options
2603
+ */
2604
+ async function updateAgentVibes(targetDir, options) {
2605
+ const spinner = ora('Updating AgentVibes...').start();
2606
+
2607
+ try {
2608
+ // Perform all update operations
2609
+ const updateResults = await performUpdateOperations(targetDir, spinner);
2457
2610
 
2458
2611
  spinner.succeed(chalk.green.bold('\n✨ Update complete!\n'));
2459
2612
 
2460
- console.log(chalk.cyan('📦 Update Summary:'));
2461
- console.log(chalk.white(` • ${commandFiles.length} commands updated`));
2462
- console.log(chalk.white(` • ${hookResult.count} TTS scripts updated`));
2463
- console.log(chalk.white(` • ${personalityResult.new + personalityResult.updated} personality templates (${personalityResult.new} new, ${personalityResult.updated} updated)`));
2464
- if (pluginFileCount > 0) {
2465
- console.log(chalk.white(` • ${pluginFileCount} BMAD plugin files updated`));
2466
- }
2467
- console.log('');
2613
+ // Display summary
2614
+ displayUpdateSummary(updateResults);
2468
2615
 
2469
2616
  // Show recent changes
2470
2617
  await showRecentChanges(path.join(__dirname, '..'));