agentvibes 2.12.4 → 2.12.6

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 (429) hide show
  1. package/.claude/hooks/bmad-voice-manager.sh +21 -5
  2. package/.claude/hooks/play-tts.sh +12 -0
  3. package/.claude/hooks/tts-queue.sh +34 -6
  4. package/README.md +17 -10
  5. package/RELEASE_NOTES.md +320 -697
  6. package/mcp-server/install-deps.js +19 -0
  7. package/mcp-server/server.py +58 -36
  8. package/package.json +1 -1
  9. package/scripts/fix-audio-tunnel.sh +22 -6
  10. package/src/commands/bmad-voices.js +14 -1
  11. package/src/installer.js +157 -72
  12. package/test/unit/play-tts.bats +1 -1
  13. package/.bmad/_cfg/agent-manifest.csv +0 -11
  14. package/.bmad/_cfg/agent-voice-map.csv +0 -11
  15. package/.bmad/_cfg/agents/bmm-analyst.customize.yaml +0 -42
  16. package/.bmad/_cfg/agents/bmm-architect.customize.yaml +0 -42
  17. package/.bmad/_cfg/agents/bmm-dev.customize.yaml +0 -42
  18. package/.bmad/_cfg/agents/bmm-frame-expert.customize.yaml +0 -42
  19. package/.bmad/_cfg/agents/bmm-pm.customize.yaml +0 -42
  20. package/.bmad/_cfg/agents/bmm-sm.customize.yaml +0 -42
  21. package/.bmad/_cfg/agents/bmm-tea.customize.yaml +0 -42
  22. package/.bmad/_cfg/agents/bmm-tech-writer.customize.yaml +0 -42
  23. package/.bmad/_cfg/agents/bmm-ux-designer.customize.yaml +0 -42
  24. package/.bmad/_cfg/agents/core-bmad-master.customize.yaml +0 -42
  25. package/.bmad/_cfg/files-manifest.csv +0 -243
  26. package/.bmad/_cfg/ides/claude-code.yaml +0 -6
  27. package/.bmad/_cfg/manifest.yaml +0 -9
  28. package/.bmad/_cfg/task-manifest.csv +0 -5
  29. package/.bmad/_cfg/tool-manifest.csv +0 -2
  30. package/.bmad/_cfg/workflow-manifest.csv +0 -38
  31. package/.bmad/bmm/README.md +0 -128
  32. package/.bmad/bmm/agents/analyst.md +0 -79
  33. package/.bmad/bmm/agents/analyst.md.backup-pre-tts +0 -75
  34. package/.bmad/bmm/agents/architect.md +0 -80
  35. package/.bmad/bmm/agents/dev.md +0 -70
  36. package/.bmad/bmm/agents/frame-expert.md +0 -72
  37. package/.bmad/bmm/agents/pm.md +0 -84
  38. package/.bmad/bmm/agents/sm.md +0 -93
  39. package/.bmad/bmm/agents/tea.md +0 -80
  40. package/.bmad/bmm/agents/tech-writer.md +0 -84
  41. package/.bmad/bmm/agents/ux-designer.md +0 -79
  42. package/.bmad/bmm/config.yaml +0 -17
  43. package/.bmad/bmm/docs/README.md +0 -236
  44. package/.bmad/bmm/docs/agents-guide.md +0 -1058
  45. package/.bmad/bmm/docs/brownfield-guide.md +0 -762
  46. package/.bmad/bmm/docs/enterprise-agentic-development.md +0 -686
  47. package/.bmad/bmm/docs/faq.md +0 -588
  48. package/.bmad/bmm/docs/glossary.md +0 -320
  49. package/.bmad/bmm/docs/party-mode.md +0 -224
  50. package/.bmad/bmm/docs/quick-spec-flow.md +0 -652
  51. package/.bmad/bmm/docs/quick-start.md +0 -376
  52. package/.bmad/bmm/docs/scale-adaptive-system.md +0 -612
  53. package/.bmad/bmm/docs/test-architecture.md +0 -396
  54. package/.bmad/bmm/docs/workflow-architecture-reference.md +0 -366
  55. package/.bmad/bmm/docs/workflow-document-project-reference.md +0 -489
  56. package/.bmad/bmm/docs/workflows-analysis.md +0 -370
  57. package/.bmad/bmm/docs/workflows-implementation.md +0 -286
  58. package/.bmad/bmm/docs/workflows-planning.md +0 -612
  59. package/.bmad/bmm/docs/workflows-solutioning.md +0 -554
  60. package/.bmad/bmm/teams/default-party.csv +0 -20
  61. package/.bmad/bmm/teams/team-fullstack.yaml +0 -13
  62. package/.bmad/bmm/testarch/knowledge/ci-burn-in.md +0 -675
  63. package/.bmad/bmm/testarch/knowledge/component-tdd.md +0 -486
  64. package/.bmad/bmm/testarch/knowledge/contract-testing.md +0 -957
  65. package/.bmad/bmm/testarch/knowledge/data-factories.md +0 -500
  66. package/.bmad/bmm/testarch/knowledge/email-auth.md +0 -721
  67. package/.bmad/bmm/testarch/knowledge/error-handling.md +0 -725
  68. package/.bmad/bmm/testarch/knowledge/feature-flags.md +0 -750
  69. package/.bmad/bmm/testarch/knowledge/fixture-architecture.md +0 -401
  70. package/.bmad/bmm/testarch/knowledge/network-first.md +0 -486
  71. package/.bmad/bmm/testarch/knowledge/nfr-criteria.md +0 -670
  72. package/.bmad/bmm/testarch/knowledge/playwright-config.md +0 -730
  73. package/.bmad/bmm/testarch/knowledge/probability-impact.md +0 -601
  74. package/.bmad/bmm/testarch/knowledge/risk-governance.md +0 -615
  75. package/.bmad/bmm/testarch/knowledge/selective-testing.md +0 -732
  76. package/.bmad/bmm/testarch/knowledge/selector-resilience.md +0 -527
  77. package/.bmad/bmm/testarch/knowledge/test-healing-patterns.md +0 -644
  78. package/.bmad/bmm/testarch/knowledge/test-levels-framework.md +0 -473
  79. package/.bmad/bmm/testarch/knowledge/test-priorities-matrix.md +0 -373
  80. package/.bmad/bmm/testarch/knowledge/test-quality.md +0 -664
  81. package/.bmad/bmm/testarch/knowledge/timing-debugging.md +0 -372
  82. package/.bmad/bmm/testarch/knowledge/visual-debugging.md +0 -524
  83. package/.bmad/bmm/testarch/tea-index.csv +0 -22
  84. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md +0 -112
  85. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md +0 -25
  86. package/.bmad/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -26
  87. package/.bmad/bmm/workflows/1-analysis/domain-research/instructions.md +0 -425
  88. package/.bmad/bmm/workflows/1-analysis/domain-research/template.md +0 -180
  89. package/.bmad/bmm/workflows/1-analysis/domain-research/workflow.yaml +0 -28
  90. package/.bmad/bmm/workflows/1-analysis/product-brief/checklist.md +0 -115
  91. package/.bmad/bmm/workflows/1-analysis/product-brief/instructions.md +0 -524
  92. package/.bmad/bmm/workflows/1-analysis/product-brief/template.md +0 -181
  93. package/.bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml +0 -45
  94. package/.bmad/bmm/workflows/1-analysis/research/checklist-deep-prompt.md +0 -144
  95. package/.bmad/bmm/workflows/1-analysis/research/checklist-technical.md +0 -249
  96. package/.bmad/bmm/workflows/1-analysis/research/checklist.md +0 -299
  97. package/.bmad/bmm/workflows/1-analysis/research/claude-code/injections.yaml +0 -114
  98. package/.bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +0 -438
  99. package/.bmad/bmm/workflows/1-analysis/research/instructions-market.md +0 -675
  100. package/.bmad/bmm/workflows/1-analysis/research/instructions-router.md +0 -134
  101. package/.bmad/bmm/workflows/1-analysis/research/instructions-technical.md +0 -534
  102. package/.bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md +0 -94
  103. package/.bmad/bmm/workflows/1-analysis/research/template-market.md +0 -347
  104. package/.bmad/bmm/workflows/1-analysis/research/template-technical.md +0 -245
  105. package/.bmad/bmm/workflows/1-analysis/research/workflow.yaml +0 -44
  106. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/epics-template.md +0 -80
  107. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/instructions.md +0 -616
  108. package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/workflow.yaml +0 -53
  109. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +0 -310
  110. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +0 -1308
  111. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +0 -145
  112. package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +0 -61
  113. package/.bmad/bmm/workflows/2-plan-workflows/prd/checklist.md +0 -346
  114. package/.bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +0 -13
  115. package/.bmad/bmm/workflows/2-plan-workflows/prd/instructions.md +0 -703
  116. package/.bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +0 -204
  117. package/.bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +0 -11
  118. package/.bmad/bmm/workflows/2-plan-workflows/prd/workflow.yaml +0 -52
  119. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +0 -217
  120. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +0 -74
  121. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions-generate-stories.md +0 -436
  122. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +0 -980
  123. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +0 -181
  124. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +0 -90
  125. package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +0 -58
  126. package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +0 -321
  127. package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-template.md +0 -103
  128. package/.bmad/bmm/workflows/3-solutioning/architecture/checklist.md +0 -240
  129. package/.bmad/bmm/workflows/3-solutioning/architecture/decision-catalog.yaml +0 -222
  130. package/.bmad/bmm/workflows/3-solutioning/architecture/instructions.md +0 -768
  131. package/.bmad/bmm/workflows/3-solutioning/architecture/pattern-categories.csv +0 -13
  132. package/.bmad/bmm/workflows/3-solutioning/architecture/workflow.yaml +0 -55
  133. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +0 -169
  134. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +0 -332
  135. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/template.md +0 -146
  136. package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -62
  137. package/.bmad/bmm/workflows/4-implementation/code-review/backlog_template.md +0 -12
  138. package/.bmad/bmm/workflows/4-implementation/code-review/checklist.md +0 -22
  139. package/.bmad/bmm/workflows/4-implementation/code-review/instructions.md +0 -398
  140. package/.bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +0 -60
  141. package/.bmad/bmm/workflows/4-implementation/correct-course/checklist.md +0 -279
  142. package/.bmad/bmm/workflows/4-implementation/correct-course/instructions.md +0 -206
  143. package/.bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +0 -56
  144. package/.bmad/bmm/workflows/4-implementation/create-story/checklist.md +0 -240
  145. package/.bmad/bmm/workflows/4-implementation/create-story/instructions.md +0 -256
  146. package/.bmad/bmm/workflows/4-implementation/create-story/template.md +0 -51
  147. package/.bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +0 -71
  148. package/.bmad/bmm/workflows/4-implementation/dev-story/checklist.md +0 -38
  149. package/.bmad/bmm/workflows/4-implementation/dev-story/instructions.md +0 -267
  150. package/.bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +0 -56
  151. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/checklist.md +0 -17
  152. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/instructions.md +0 -164
  153. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/template.md +0 -76
  154. package/.bmad/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +0 -57
  155. package/.bmad/bmm/workflows/4-implementation/retrospective/instructions.md +0 -1443
  156. package/.bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +0 -56
  157. package/.bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +0 -33
  158. package/.bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +0 -234
  159. package/.bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +0 -55
  160. package/.bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +0 -49
  161. package/.bmad/bmm/workflows/4-implementation/story-context/checklist.md +0 -16
  162. package/.bmad/bmm/workflows/4-implementation/story-context/context-template.xml +0 -34
  163. package/.bmad/bmm/workflows/4-implementation/story-context/instructions.md +0 -209
  164. package/.bmad/bmm/workflows/4-implementation/story-context/workflow.yaml +0 -61
  165. package/.bmad/bmm/workflows/4-implementation/story-done/instructions.md +0 -111
  166. package/.bmad/bmm/workflows/4-implementation/story-done/workflow.yaml +0 -26
  167. package/.bmad/bmm/workflows/4-implementation/story-ready/instructions.md +0 -117
  168. package/.bmad/bmm/workflows/4-implementation/story-ready/workflow.yaml +0 -23
  169. package/.bmad/bmm/workflows/document-project/checklist.md +0 -245
  170. package/.bmad/bmm/workflows/document-project/documentation-requirements.csv +0 -12
  171. package/.bmad/bmm/workflows/document-project/instructions.md +0 -222
  172. package/.bmad/bmm/workflows/document-project/templates/deep-dive-template.md +0 -345
  173. package/.bmad/bmm/workflows/document-project/templates/index-template.md +0 -169
  174. package/.bmad/bmm/workflows/document-project/templates/project-overview-template.md +0 -103
  175. package/.bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +0 -160
  176. package/.bmad/bmm/workflows/document-project/templates/source-tree-template.md +0 -135
  177. package/.bmad/bmm/workflows/document-project/workflow.yaml +0 -29
  178. package/.bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +0 -298
  179. package/.bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +0 -31
  180. package/.bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +0 -1106
  181. package/.bmad/bmm/workflows/document-project/workflows/full-scan.yaml +0 -31
  182. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-helpers.md +0 -127
  183. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-library.json +0 -90
  184. package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-templates.yaml +0 -127
  185. package/.bmad/bmm/workflows/frame-expert/_shared/validate-json-instructions.md +0 -79
  186. package/.bmad/bmm/workflows/frame-expert/create-dataflow/checklist.md +0 -39
  187. package/.bmad/bmm/workflows/frame-expert/create-dataflow/instructions.md +0 -131
  188. package/.bmad/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -23
  189. package/.bmad/bmm/workflows/frame-expert/create-diagram/checklist.md +0 -43
  190. package/.bmad/bmm/workflows/frame-expert/create-diagram/instructions.md +0 -142
  191. package/.bmad/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -24
  192. package/.bmad/bmm/workflows/frame-expert/create-flowchart/checklist.md +0 -49
  193. package/.bmad/bmm/workflows/frame-expert/create-flowchart/instructions.md +0 -242
  194. package/.bmad/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -27
  195. package/.bmad/bmm/workflows/frame-expert/create-wireframe/checklist.md +0 -38
  196. package/.bmad/bmm/workflows/frame-expert/create-wireframe/instructions.md +0 -133
  197. package/.bmad/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -23
  198. package/.bmad/bmm/workflows/techdoc/documentation-standards.md +0 -262
  199. package/.bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +0 -363
  200. package/.bmad/bmm/workflows/testarch/atdd/checklist.md +0 -373
  201. package/.bmad/bmm/workflows/testarch/atdd/instructions.md +0 -785
  202. package/.bmad/bmm/workflows/testarch/atdd/workflow.yaml +0 -45
  203. package/.bmad/bmm/workflows/testarch/automate/checklist.md +0 -580
  204. package/.bmad/bmm/workflows/testarch/automate/instructions.md +0 -1303
  205. package/.bmad/bmm/workflows/testarch/automate/workflow.yaml +0 -52
  206. package/.bmad/bmm/workflows/testarch/ci/checklist.md +0 -246
  207. package/.bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +0 -165
  208. package/.bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +0 -128
  209. package/.bmad/bmm/workflows/testarch/ci/instructions.md +0 -517
  210. package/.bmad/bmm/workflows/testarch/ci/workflow.yaml +0 -45
  211. package/.bmad/bmm/workflows/testarch/framework/checklist.md +0 -321
  212. package/.bmad/bmm/workflows/testarch/framework/instructions.md +0 -455
  213. package/.bmad/bmm/workflows/testarch/framework/workflow.yaml +0 -47
  214. package/.bmad/bmm/workflows/testarch/nfr-assess/checklist.md +0 -405
  215. package/.bmad/bmm/workflows/testarch/nfr-assess/instructions.md +0 -722
  216. package/.bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +0 -443
  217. package/.bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +0 -47
  218. package/.bmad/bmm/workflows/testarch/test-design/checklist.md +0 -234
  219. package/.bmad/bmm/workflows/testarch/test-design/instructions.md +0 -782
  220. package/.bmad/bmm/workflows/testarch/test-design/test-design-template.md +0 -285
  221. package/.bmad/bmm/workflows/testarch/test-design/workflow.yaml +0 -48
  222. package/.bmad/bmm/workflows/testarch/test-review/checklist.md +0 -470
  223. package/.bmad/bmm/workflows/testarch/test-review/instructions.md +0 -608
  224. package/.bmad/bmm/workflows/testarch/test-review/test-review-template.md +0 -388
  225. package/.bmad/bmm/workflows/testarch/test-review/workflow.yaml +0 -46
  226. package/.bmad/bmm/workflows/testarch/trace/checklist.md +0 -654
  227. package/.bmad/bmm/workflows/testarch/trace/instructions.md +0 -1045
  228. package/.bmad/bmm/workflows/testarch/trace/trace-template.md +0 -673
  229. package/.bmad/bmm/workflows/testarch/trace/workflow.yaml +0 -55
  230. package/.bmad/bmm/workflows/workflow-status/init/instructions.md +0 -334
  231. package/.bmad/bmm/workflows/workflow-status/init/workflow.yaml +0 -28
  232. package/.bmad/bmm/workflows/workflow-status/instructions.md +0 -388
  233. package/.bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +0 -138
  234. package/.bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +0 -126
  235. package/.bmad/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
  236. package/.bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +0 -122
  237. package/.bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +0 -113
  238. package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-brownfield.yaml +0 -58
  239. package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-greenfield.yaml +0 -47
  240. package/.bmad/bmm/workflows/workflow-status/project-levels.yaml +0 -59
  241. package/.bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +0 -24
  242. package/.bmad/bmm/workflows/workflow-status/workflow.yaml +0 -28
  243. package/.bmad/core/agents/bmad-master.md +0 -72
  244. package/.bmad/core/agents/bmad-web-orchestrator.agent.xml +0 -113
  245. package/.bmad/core/config.yaml +0 -11
  246. package/.bmad/core/tasks/adv-elicit-methods.csv +0 -39
  247. package/.bmad/core/tasks/advanced-elicitation-methods.csv +0 -21
  248. package/.bmad/core/tasks/advanced-elicitation.xml +0 -106
  249. package/.bmad/core/tasks/index-docs.xml +0 -65
  250. package/.bmad/core/tasks/validate-workflow.xml +0 -89
  251. package/.bmad/core/tasks/workflow.xml +0 -270
  252. package/.bmad/core/tools/shard-doc.xml +0 -109
  253. package/.bmad/core/workflows/brainstorming/README.md +0 -261
  254. package/.bmad/core/workflows/brainstorming/brain-methods.csv +0 -36
  255. package/.bmad/core/workflows/brainstorming/instructions.md +0 -315
  256. package/.bmad/core/workflows/brainstorming/template.md +0 -106
  257. package/.bmad/core/workflows/brainstorming/workflow.yaml +0 -38
  258. package/.bmad/core/workflows/party-mode/instructions.md +0 -203
  259. package/.bmad/core/workflows/party-mode/workflow.yaml +0 -28
  260. package/.bmad/docs/claude-code-instructions.md +0 -25
  261. package/.claude/commands/BMad/analyst.md +0 -88
  262. package/.claude/commands/BMad/architect.md +0 -89
  263. package/.claude/commands/BMad/bmad-master.md +0 -114
  264. package/.claude/commands/BMad/bmad-orchestrator.md +0 -151
  265. package/.claude/commands/BMad/dev.md +0 -85
  266. package/.claude/commands/BMad/pm.md +0 -88
  267. package/.claude/commands/BMad/po.md +0 -83
  268. package/.claude/commands/BMad/qa.md +0 -91
  269. package/.claude/commands/BMad/sm.md +0 -69
  270. package/.claude/commands/BMad/tasks/advanced-elicitation.md +0 -123
  271. package/.claude/commands/BMad/tasks/apply-qa-fixes.md +0 -154
  272. package/.claude/commands/BMad/tasks/brownfield-create-epic.md +0 -166
  273. package/.claude/commands/BMad/tasks/brownfield-create-story.md +0 -153
  274. package/.claude/commands/BMad/tasks/correct-course.md +0 -76
  275. package/.claude/commands/BMad/tasks/create-brownfield-story.md +0 -318
  276. package/.claude/commands/BMad/tasks/create-deep-research-prompt.md +0 -284
  277. package/.claude/commands/BMad/tasks/create-doc.md +0 -107
  278. package/.claude/commands/BMad/tasks/create-next-story.md +0 -118
  279. package/.claude/commands/BMad/tasks/document-project.md +0 -349
  280. package/.claude/commands/BMad/tasks/execute-checklist.md +0 -92
  281. package/.claude/commands/BMad/tasks/facilitate-brainstorming-session.md +0 -142
  282. package/.claude/commands/BMad/tasks/generate-ai-frontend-prompt.md +0 -57
  283. package/.claude/commands/BMad/tasks/index-docs.md +0 -179
  284. package/.claude/commands/BMad/tasks/kb-mode-interaction.md +0 -81
  285. package/.claude/commands/BMad/tasks/nfr-assess.md +0 -349
  286. package/.claude/commands/BMad/tasks/qa-gate.md +0 -167
  287. package/.claude/commands/BMad/tasks/review-story.md +0 -320
  288. package/.claude/commands/BMad/tasks/risk-profile.md +0 -359
  289. package/.claude/commands/BMad/tasks/shard-doc.md +0 -191
  290. package/.claude/commands/BMad/tasks/test-design.md +0 -180
  291. package/.claude/commands/BMad/tasks/trace-requirements.md +0 -270
  292. package/.claude/commands/BMad/tasks/validate-next-story.md +0 -140
  293. package/.claude/commands/BMad/ux-expert.md +0 -73
  294. package/.claude/commands/bmad/bmm/agents/analyst.md +0 -14
  295. package/.claude/commands/bmad/bmm/agents/architect.md +0 -14
  296. package/.claude/commands/bmad/bmm/agents/dev.md +0 -14
  297. package/.claude/commands/bmad/bmm/agents/frame-expert.md +0 -14
  298. package/.claude/commands/bmad/bmm/agents/pm.md +0 -14
  299. package/.claude/commands/bmad/bmm/agents/sm.md +0 -14
  300. package/.claude/commands/bmad/bmm/agents/tea.md +0 -14
  301. package/.claude/commands/bmad/bmm/agents/tech-writer.md +0 -14
  302. package/.claude/commands/bmad/bmm/agents/ux-designer.md +0 -14
  303. package/.claude/commands/bmad/bmm/workflows/architecture.md +0 -13
  304. package/.claude/commands/bmad/bmm/workflows/brainstorm-project.md +0 -13
  305. package/.claude/commands/bmad/bmm/workflows/code-review.md +0 -13
  306. package/.claude/commands/bmad/bmm/workflows/correct-course.md +0 -13
  307. package/.claude/commands/bmad/bmm/workflows/create-dataflow.md +0 -13
  308. package/.claude/commands/bmad/bmm/workflows/create-diagram.md +0 -13
  309. package/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +0 -13
  310. package/.claude/commands/bmad/bmm/workflows/create-flowchart.md +0 -13
  311. package/.claude/commands/bmad/bmm/workflows/create-story.md +0 -13
  312. package/.claude/commands/bmad/bmm/workflows/create-ux-design.md +0 -13
  313. package/.claude/commands/bmad/bmm/workflows/create-wireframe.md +0 -13
  314. package/.claude/commands/bmad/bmm/workflows/dev-story.md +0 -13
  315. package/.claude/commands/bmad/bmm/workflows/document-project.md +0 -13
  316. package/.claude/commands/bmad/bmm/workflows/domain-research.md +0 -13
  317. package/.claude/commands/bmad/bmm/workflows/epic-tech-context.md +0 -13
  318. package/.claude/commands/bmad/bmm/workflows/implementation-readiness.md +0 -13
  319. package/.claude/commands/bmad/bmm/workflows/prd.md +0 -13
  320. package/.claude/commands/bmad/bmm/workflows/product-brief.md +0 -13
  321. package/.claude/commands/bmad/bmm/workflows/research.md +0 -13
  322. package/.claude/commands/bmad/bmm/workflows/retrospective.md +0 -13
  323. package/.claude/commands/bmad/bmm/workflows/sprint-planning.md +0 -13
  324. package/.claude/commands/bmad/bmm/workflows/story-context.md +0 -13
  325. package/.claude/commands/bmad/bmm/workflows/story-done.md +0 -13
  326. package/.claude/commands/bmad/bmm/workflows/story-ready.md +0 -13
  327. package/.claude/commands/bmad/bmm/workflows/tech-spec.md +0 -13
  328. package/.claude/commands/bmad/bmm/workflows/workflow-init.md +0 -13
  329. package/.claude/commands/bmad/bmm/workflows/workflow-status.md +0 -13
  330. package/.claude/commands/bmad/core/agents/bmad-master.md +0 -14
  331. package/.claude/commands/bmad/core/tasks/advanced-elicitation.md +0 -9
  332. package/.claude/commands/bmad/core/tasks/index-docs.md +0 -9
  333. package/.claude/commands/bmad/core/tools/shard-doc.md +0 -9
  334. package/.claude/commands/bmad/core/workflows/brainstorming.md +0 -13
  335. package/.claude/commands/bmad/core/workflows/party-mode.md +0 -13
  336. package/.claude/github-star-reminder.txt +0 -1
  337. package/.claude/hooks/bmad-party-manager.sh +0 -225
  338. package/.claude/hooks/stop.sh +0 -221
  339. package/.claude/piper-voices-dir.txt +0 -1
  340. package/.mcp.json +0 -88
  341. package/RELEASE_NOTES_v2.4.0_DRAFT.md +0 -116
  342. package/RELEASE_NOTES_v2.4.1_DRAFT.md +0 -61
  343. package/docs/2025-11-15_15-14-33.snagx +0 -0
  344. package/docs/Screenshot 2025-11-15 151325.png +0 -0
  345. package/docs/Screenshot 2025-11-15 151432.png +0 -0
  346. package/docs/macos-piper-issue.md +0 -172
  347. package/docs/stargazer-cms-prd.md +0 -1918
  348. package/docs/whatsapp-plugin-github-issue.md +0 -393
  349. package/docs/whatsapp-tts-plugin-feasibility.md +0 -418
  350. package/docs/whatsapp-tts-standalone-plugin.md +0 -628
  351. package/github-profile-draft.md +0 -57
  352. package/linkedin/vibe-coding-and-pulseaudio.md +0 -121
  353. package/mcp-server/agentvibes.db +0 -0
  354. package/scripts/audio-tunnel.config +0 -17
  355. package/v4-backup/.bmad-core/agent-teams/team-all.yaml +0 -15
  356. package/v4-backup/.bmad-core/agent-teams/team-fullstack.yaml +0 -19
  357. package/v4-backup/.bmad-core/agent-teams/team-ide-minimal.yaml +0 -11
  358. package/v4-backup/.bmad-core/agent-teams/team-no-ui.yaml +0 -14
  359. package/v4-backup/.bmad-core/agents/analyst.md +0 -84
  360. package/v4-backup/.bmad-core/agents/architect.md +0 -85
  361. package/v4-backup/.bmad-core/agents/bmad-master.md +0 -110
  362. package/v4-backup/.bmad-core/agents/bmad-orchestrator.md +0 -147
  363. package/v4-backup/.bmad-core/agents/dev.md +0 -81
  364. package/v4-backup/.bmad-core/agents/pm.md +0 -84
  365. package/v4-backup/.bmad-core/agents/po.md +0 -79
  366. package/v4-backup/.bmad-core/agents/qa.md +0 -87
  367. package/v4-backup/.bmad-core/agents/sm.md +0 -65
  368. package/v4-backup/.bmad-core/agents/ux-expert.md +0 -69
  369. package/v4-backup/.bmad-core/checklists/architect-checklist.md +0 -440
  370. package/v4-backup/.bmad-core/checklists/change-checklist.md +0 -184
  371. package/v4-backup/.bmad-core/checklists/pm-checklist.md +0 -372
  372. package/v4-backup/.bmad-core/checklists/po-master-checklist.md +0 -434
  373. package/v4-backup/.bmad-core/checklists/story-dod-checklist.md +0 -96
  374. package/v4-backup/.bmad-core/checklists/story-draft-checklist.md +0 -155
  375. package/v4-backup/.bmad-core/core-config.yaml +0 -22
  376. package/v4-backup/.bmad-core/data/bmad-kb.md +0 -809
  377. package/v4-backup/.bmad-core/data/brainstorming-techniques.md +0 -38
  378. package/v4-backup/.bmad-core/data/elicitation-methods.md +0 -156
  379. package/v4-backup/.bmad-core/data/technical-preferences.md +0 -5
  380. package/v4-backup/.bmad-core/data/test-levels-framework.md +0 -148
  381. package/v4-backup/.bmad-core/data/test-priorities-matrix.md +0 -174
  382. package/v4-backup/.bmad-core/enhanced-ide-development-workflow.md +0 -248
  383. package/v4-backup/.bmad-core/install-manifest.yaml +0 -230
  384. package/v4-backup/.bmad-core/tasks/advanced-elicitation.md +0 -119
  385. package/v4-backup/.bmad-core/tasks/apply-qa-fixes.md +0 -150
  386. package/v4-backup/.bmad-core/tasks/brownfield-create-epic.md +0 -162
  387. package/v4-backup/.bmad-core/tasks/brownfield-create-story.md +0 -149
  388. package/v4-backup/.bmad-core/tasks/correct-course.md +0 -72
  389. package/v4-backup/.bmad-core/tasks/create-brownfield-story.md +0 -314
  390. package/v4-backup/.bmad-core/tasks/create-deep-research-prompt.md +0 -280
  391. package/v4-backup/.bmad-core/tasks/create-doc.md +0 -103
  392. package/v4-backup/.bmad-core/tasks/create-next-story.md +0 -114
  393. package/v4-backup/.bmad-core/tasks/document-project.md +0 -345
  394. package/v4-backup/.bmad-core/tasks/execute-checklist.md +0 -88
  395. package/v4-backup/.bmad-core/tasks/facilitate-brainstorming-session.md +0 -138
  396. package/v4-backup/.bmad-core/tasks/generate-ai-frontend-prompt.md +0 -53
  397. package/v4-backup/.bmad-core/tasks/index-docs.md +0 -175
  398. package/v4-backup/.bmad-core/tasks/kb-mode-interaction.md +0 -77
  399. package/v4-backup/.bmad-core/tasks/nfr-assess.md +0 -345
  400. package/v4-backup/.bmad-core/tasks/qa-gate.md +0 -163
  401. package/v4-backup/.bmad-core/tasks/review-story.md +0 -316
  402. package/v4-backup/.bmad-core/tasks/risk-profile.md +0 -355
  403. package/v4-backup/.bmad-core/tasks/shard-doc.md +0 -187
  404. package/v4-backup/.bmad-core/tasks/test-design.md +0 -176
  405. package/v4-backup/.bmad-core/tasks/trace-requirements.md +0 -266
  406. package/v4-backup/.bmad-core/tasks/validate-next-story.md +0 -136
  407. package/v4-backup/.bmad-core/templates/architecture-tmpl.yaml +0 -651
  408. package/v4-backup/.bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
  409. package/v4-backup/.bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -477
  410. package/v4-backup/.bmad-core/templates/brownfield-prd-tmpl.yaml +0 -281
  411. package/v4-backup/.bmad-core/templates/competitor-analysis-tmpl.yaml +0 -307
  412. package/v4-backup/.bmad-core/templates/front-end-architecture-tmpl.yaml +0 -219
  413. package/v4-backup/.bmad-core/templates/front-end-spec-tmpl.yaml +0 -350
  414. package/v4-backup/.bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -824
  415. package/v4-backup/.bmad-core/templates/market-research-tmpl.yaml +0 -253
  416. package/v4-backup/.bmad-core/templates/prd-tmpl.yaml +0 -203
  417. package/v4-backup/.bmad-core/templates/project-brief-tmpl.yaml +0 -222
  418. package/v4-backup/.bmad-core/templates/qa-gate-tmpl.yaml +0 -103
  419. package/v4-backup/.bmad-core/templates/story-tmpl.yaml +0 -138
  420. package/v4-backup/.bmad-core/user-guide.md +0 -577
  421. package/v4-backup/.bmad-core/utils/bmad-doc-template.md +0 -327
  422. package/v4-backup/.bmad-core/utils/workflow-management.md +0 -71
  423. package/v4-backup/.bmad-core/workflows/brownfield-fullstack.yaml +0 -298
  424. package/v4-backup/.bmad-core/workflows/brownfield-service.yaml +0 -188
  425. package/v4-backup/.bmad-core/workflows/brownfield-ui.yaml +0 -198
  426. package/v4-backup/.bmad-core/workflows/greenfield-fullstack.yaml +0 -241
  427. package/v4-backup/.bmad-core/workflows/greenfield-service.yaml +0 -207
  428. package/v4-backup/.bmad-core/workflows/greenfield-ui.yaml +0 -236
  429. package/v4-backup/.bmad-core/working-in-the-brownfield.md +0 -606
@@ -17,6 +17,11 @@ function checkPython() {
17
17
  const pythonCommands = ['python3', 'python', 'py'];
18
18
 
19
19
  for (const cmd of pythonCommands) {
20
+ // Security: Validate command is in our allowlist only
21
+ if (!pythonCommands.includes(cmd)) {
22
+ continue;
23
+ }
24
+
20
25
  try {
21
26
  const version = execSync(`${cmd} --version`, { encoding: 'utf8', stdio: 'pipe' });
22
27
  console.log(`✅ Found ${cmd}: ${version.trim()}`);
@@ -31,6 +36,13 @@ function checkPython() {
31
36
 
32
37
  // Function to check if mcp is installed
33
38
  function checkMcpInstalled(pythonCmd) {
39
+ // Security: Validate pythonCmd is in allowlist
40
+ const allowedCommands = ['python3', 'python', 'py'];
41
+ if (!allowedCommands.includes(pythonCmd)) {
42
+ console.error('❌ Invalid Python command');
43
+ return false;
44
+ }
45
+
34
46
  try {
35
47
  execSync(`${pythonCmd} -c "import mcp"`, { stdio: 'pipe' });
36
48
  return true;
@@ -41,6 +53,13 @@ function checkMcpInstalled(pythonCmd) {
41
53
 
42
54
  // Function to install mcp package
43
55
  function installMcp(pythonCmd) {
56
+ // Security: Validate pythonCmd is in allowlist
57
+ const allowedCommands = ['python3', 'python', 'py'];
58
+ if (!allowedCommands.includes(pythonCmd)) {
59
+ console.error('❌ Invalid Python command');
60
+ return false;
61
+ }
62
+
44
63
  try {
45
64
  console.log('\n📦 Installing Python mcp package...');
46
65
  const command = `${pythonCmd} -m pip install --user mcp`;
@@ -147,25 +147,31 @@ class AgentVibesServer:
147
147
  stderr=asyncio.subprocess.PIPE,
148
148
  env=env,
149
149
  )
150
- stdout, stderr = await result.communicate()
151
-
152
- if result.returncode == 0:
153
- output = stdout.decode().strip()
154
- # Extract file path from output
155
- for line in output.split("\n"):
156
- if "Saved to:" in line:
157
- file_path = line.split("Saved to:")[1].strip()
158
- truncated = (
159
- f"{text[:50]}..." if len(text) > 50 else text
160
- )
161
- return f"✅ Spoke: {truncated}\n📁 Audio saved: {file_path}"
162
-
163
- return f"✅ Spoke: {text[:50]}..." if len(text) > 50 else f"✅ Spoke: {text}"
164
- else:
165
- error = stderr.decode().strip()
166
- stdout_output = stdout.decode().strip()
167
- full_error = f"{error}\nStdout: {stdout_output}" if stdout_output else error
168
- return f"❌ TTS failed: {full_error}"
150
+ try:
151
+ stdout, stderr = await result.communicate()
152
+
153
+ if result.returncode == 0:
154
+ output = stdout.decode().strip()
155
+ # Extract file path from output
156
+ for line in output.split("\n"):
157
+ if "Saved to:" in line:
158
+ file_path = line.split("Saved to:")[1].strip()
159
+ truncated = (
160
+ f"{text[:50]}..." if len(text) > 50 else text
161
+ )
162
+ return f"✅ Spoke: {truncated}\n📁 Audio saved: {file_path}"
163
+
164
+ return f"✅ Spoke: {text[:50]}..." if len(text) > 50 else f"✅ Spoke: {text}"
165
+ else:
166
+ error = stderr.decode().strip()
167
+ stdout_output = stdout.decode().strip()
168
+ full_error = f"{error}\nStdout: {stdout_output}" if stdout_output else error
169
+ return f"❌ TTS failed: {full_error}"
170
+ finally:
171
+ # Ensure process cleanup
172
+ if result.returncode is None:
173
+ result.kill()
174
+ await result.wait()
169
175
 
170
176
  finally:
171
177
  # Restore original settings
@@ -513,14 +519,20 @@ class AgentVibesServer:
513
519
  stderr=asyncio.subprocess.PIPE,
514
520
  env=env,
515
521
  )
516
- stdout, stderr = await result.communicate()
517
- if result.returncode == 0:
518
- return stdout.decode().strip()
519
- else:
520
- error_msg = stderr.decode().strip()
521
- if not error_msg: # If stderr is empty, include stdout for debugging
522
- error_msg = f"Return code {result.returncode}. Stdout: {stdout.decode().strip()}"
523
- return error_msg
522
+ try:
523
+ stdout, stderr = await result.communicate()
524
+ if result.returncode == 0:
525
+ return stdout.decode().strip()
526
+ else:
527
+ error_msg = stderr.decode().strip()
528
+ if not error_msg: # If stderr is empty, include stdout for debugging
529
+ error_msg = f"Return code {result.returncode}. Stdout: {stdout.decode().strip()}"
530
+ return error_msg
531
+ finally:
532
+ # Ensure process cleanup
533
+ if result.returncode is None:
534
+ result.kill()
535
+ await result.wait()
524
536
  except Exception as e:
525
537
  return f"Error running script: {e}"
526
538
 
@@ -536,8 +548,13 @@ class AgentVibesServer:
536
548
  # Try global
537
549
  personality_file = Path.home() / ".claude" / "tts-personality.txt"
538
550
 
539
- if personality_file.exists():
540
- return personality_file.read_text().strip()
551
+ try:
552
+ if personality_file.exists():
553
+ return personality_file.read_text().strip()
554
+ except (PermissionError, UnicodeDecodeError, OSError) as e:
555
+ # Log error but don't crash - return default
556
+ import sys
557
+ print(f"Warning: Could not read personality file: {e}", file=sys.stderr)
541
558
  return "normal"
542
559
 
543
560
  async def _get_language(self) -> str:
@@ -551,13 +568,18 @@ class AgentVibesServer:
551
568
  if not provider_file.exists():
552
569
  provider_file = Path.home() / ".claude" / "tts-provider.txt"
553
570
 
554
- if provider_file.exists():
555
- provider = provider_file.read_text().strip()
556
- if provider == "elevenlabs":
557
- return "ElevenLabs (Premium AI)"
558
- elif provider == "piper":
559
- return "Piper TTS (Free, Offline)"
560
- return provider
571
+ try:
572
+ if provider_file.exists():
573
+ provider = provider_file.read_text().strip()
574
+ if provider == "elevenlabs":
575
+ return "ElevenLabs (Premium AI)"
576
+ elif provider == "piper":
577
+ return "Piper TTS (Free, Offline)"
578
+ return provider
579
+ except (PermissionError, UnicodeDecodeError, OSError) as e:
580
+ # Log error but don't crash - return default
581
+ import sys
582
+ print(f"Warning: Could not read provider file: {e}", file=sys.stderr)
561
583
  # Default to Piper (free, offline) instead of ElevenLabs
562
584
  return "Piper TTS (Free, Offline)"
563
585
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "agentvibes",
4
- "version": "2.12.4",
4
+ "version": "2.12.6",
5
5
  "description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code and Claude Desktop (via MCP) with multi-provider support.",
6
6
  "homepage": "https://agentvibes.org",
7
7
  "keywords": [
@@ -18,6 +18,18 @@ else
18
18
  PULSE_SOCKET="${PULSE_SOCKET:-/mnt/wslg/PulseServer}"
19
19
  fi
20
20
 
21
+ # Security: Validate TUNNEL_PORT is numeric only
22
+ if ! [[ "$TUNNEL_PORT" =~ ^[0-9]+$ ]]; then
23
+ echo "❌ Error: TUNNEL_PORT must be numeric (got: $TUNNEL_PORT)"
24
+ exit 1
25
+ fi
26
+
27
+ # Security: Validate REMOTE_HOST doesn't contain dangerous characters
28
+ if [[ "$REMOTE_HOST" =~ [';|&$`<>(){}'] ]]; then
29
+ echo "❌ Error: REMOTE_HOST contains invalid characters"
30
+ exit 1
31
+ fi
32
+
21
33
  echo "🔧 Complete Audio Tunnel Fix"
22
34
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
23
35
  echo ""
@@ -57,14 +69,15 @@ kill_remote_stale_processes() {
57
69
  echo "1️⃣ Checking for stale SSH processes on ${REMOTE_HOST}..."
58
70
 
59
71
  # Get list of processes using the port
60
- STALE_PROCS=$(ssh ${REMOTE_HOST} "sudo lsof -i :${TUNNEL_PORT} 2>/dev/null | grep -v COMMAND || echo 'none'")
72
+ # Security: Variables are now validated at script start, and TUNNEL_PORT is numeric-only
73
+ STALE_PROCS=$(ssh "${REMOTE_HOST}" "sudo lsof -i :${TUNNEL_PORT} 2>/dev/null | grep -v COMMAND || echo 'none'")
61
74
 
62
75
  if [ "$STALE_PROCS" != "none" ] && [ -n "$STALE_PROCS" ]; then
63
76
  echo " 🔍 Found stale processes:"
64
77
  echo "$STALE_PROCS" | sed 's/^/ /'
65
78
  echo ""
66
79
  echo " 🗑️ Killing stale processes..."
67
- ssh ${REMOTE_HOST} "sudo fuser -k ${TUNNEL_PORT}/tcp 2>/dev/null || true"
80
+ ssh "${REMOTE_HOST}" "sudo fuser -k ${TUNNEL_PORT}/tcp 2>/dev/null || true"
68
81
  echo " ✅ Stale processes killed"
69
82
  sleep 2
70
83
  else
@@ -107,6 +120,7 @@ fix_socat_bridge() {
107
120
  kill_local_ssh_tunnels() {
108
121
  echo "3️⃣ Killing local stale SSH tunnels..."
109
122
 
123
+ # Security: Quote REMOTE_HOST to prevent command injection
110
124
  if pgrep -f "ssh.*${REMOTE_HOST}" > /dev/null; then
111
125
  pkill -f "ssh.*${REMOTE_HOST}" 2>/dev/null || true
112
126
  echo " ✅ Killed stale SSH tunnels"
@@ -122,7 +136,8 @@ create_ssh_tunnel() {
122
136
  echo "4️⃣ Creating fresh SSH tunnel..."
123
137
 
124
138
  # Create tunnel in background
125
- ssh -f -N -R ${TUNNEL_PORT}:localhost:${TUNNEL_PORT} ${REMOTE_HOST} 2>/dev/null || {
139
+ # Security: Quote variables to prevent command injection
140
+ ssh -f -N -R "${TUNNEL_PORT}:localhost:${TUNNEL_PORT}" "${REMOTE_HOST}" 2>/dev/null || {
126
141
  echo " ⚠️ Tunnel creation returned warning (this is normal if tunnel already exists)"
127
142
  }
128
143
 
@@ -130,7 +145,7 @@ create_ssh_tunnel() {
130
145
 
131
146
  # Verify tunnel exists on remote
132
147
  echo " 🔍 Verifying tunnel on ${REMOTE_HOST}..."
133
- if ssh ${REMOTE_HOST} "netstat -tlnp 2>/dev/null | grep -q ${TUNNEL_PORT}"; then
148
+ if ssh "${REMOTE_HOST}" "netstat -tlnp 2>/dev/null | grep -q ${TUNNEL_PORT}"; then
134
149
  echo " ✅ SSH tunnel established successfully"
135
150
  else
136
151
  echo " ❌ Failed to establish SSH tunnel"
@@ -144,11 +159,12 @@ test_audio() {
144
159
  echo "5️⃣ Testing audio connection..."
145
160
 
146
161
  # Test PulseAudio connection
147
- if ssh ${REMOTE_HOST} "export PULSE_SERVER=tcp:localhost:${TUNNEL_PORT} && timeout 5 pactl info > /dev/null 2>&1"; then
162
+ # Security: Quote variables to prevent command injection
163
+ if ssh "${REMOTE_HOST}" "export PULSE_SERVER=tcp:localhost:${TUNNEL_PORT} && timeout 5 pactl info > /dev/null 2>&1"; then
148
164
  echo " ✅ PulseAudio connection successful"
149
165
 
150
166
  # Get server info
151
- SERVER_INFO=$(ssh ${REMOTE_HOST} "export PULSE_SERVER=tcp:localhost:${TUNNEL_PORT} && pactl info | head -3")
167
+ SERVER_INFO=$(ssh "${REMOTE_HOST}" "export PULSE_SERVER=tcp:localhost:${TUNNEL_PORT} && pactl info | head -3")
152
168
  echo " 📊 Server Info:"
153
169
  echo "$SERVER_INFO" | sed 's/^/ /'
154
170
  else
@@ -154,6 +154,16 @@ async function writeVoiceAssignments(assignments) {
154
154
  await fs.writeFile(csvPath, lines.join('\n') + '\n', 'utf8');
155
155
  }
156
156
 
157
+ /**
158
+ * Security: Escape shell arguments to prevent command injection
159
+ * @param {string} arg - Argument to escape
160
+ * @returns {string} - Safely escaped argument
161
+ */
162
+ function escapeShellArg(arg) {
163
+ // Replace single quotes with '\'' (end quote, escaped quote, start quote)
164
+ return `'${arg.replace(/'/g, "'\\''")}'`;
165
+ }
166
+
157
167
  /**
158
168
  * Find matching voice name using fuzzy matching
159
169
  * Supports partial matches like "ryan" → "en_US-ryan-high"
@@ -218,7 +228,10 @@ export async function previewVoice(voiceName, options = {}) {
218
228
  }
219
229
 
220
230
  try {
221
- execSync(`bash "${playTtsPath}" "${text}" "${matchedVoice}"`, {
231
+ // Security: Properly escape arguments to prevent command injection
232
+ const escapedText = escapeShellArg(text);
233
+ const escapedVoice = escapeShellArg(matchedVoice);
234
+ execSync(`bash "${playTtsPath}" ${escapedText} ${escapedVoice}`, {
222
235
  stdio: 'inherit',
223
236
  cwd: targetDir,
224
237
  });
package/src/installer.js CHANGED
@@ -128,27 +128,27 @@ function showReleaseInfo() {
128
128
  console.log(
129
129
  boxen(
130
130
  chalk.white.bold('═══════════════════════════════════════════════════════════════\n') +
131
- chalk.cyan.bold(' 📦 AgentVibes v2.12.0 - .agentvibes/ Directory Migration\n') +
131
+ chalk.cyan.bold(' 📦 AgentVibes v2.12.6 - Security & Reliability Improvements\n') +
132
132
  chalk.white.bold('═══════════════════════════════════════════════════════════════\n\n') +
133
133
  chalk.green.bold('🎙️ WHAT\'S NEW:\n\n') +
134
- chalk.cyan('AgentVibes v2.12.0 introduces a comprehensive directory reorganization,\n') +
135
- chalk.cyan('migrating all AgentVibes configuration to a dedicated .agentvibes/ directory.\n') +
136
- chalk.cyan('This eliminates namespace confusion with Claude Code and provides a clear,\n') +
137
- chalk.cyan('predictable location for all AgentVibes state. Migration is fully automatic—\n') +
138
- chalk.cyan('your settings are seamlessly moved during upgrade. Also includes BMAD testing\n') +
139
- chalk.cyan('improvements and enhanced Piper voice installation.\n\n') +
134
+ chalk.cyan('AgentVibes v2.12.6 brings quality improvements based on SonarCloud analysis\n') +
135
+ chalk.cyan('and enhances BMAD party mode. This release improves API key privacy in\n') +
136
+ chalk.cyan('terminal output, adds better cleanup for long-running sessions, includes\n') +
137
+ chalk.cyan('more robust error handling, and ensures BMAD agents each get their unique\n') +
138
+ chalk.cyan('voice. All improvements maintain 100% backward compatibility.\n\n') +
140
139
  chalk.green.bold('✨ KEY HIGHLIGHTS:\n\n') +
141
- chalk.gray(' 📁 Dedicated .agentvibes/ Directory - Clear namespace separation\n') +
142
- chalk.gray(' 🔄 Automatic Migration - Seamless upgrade from old locations\n') +
143
- chalk.gray(' 100% Backward Compatible - No manual intervention needed\n') +
144
- chalk.gray(' 🧪 32 Passing Tests - Comprehensive migration validation\n') +
145
- chalk.gray(' 🎭 npx test-bmad-pr - One-line BMAD PR testing command\n') +
146
- chalk.gray(' 🎤 Enhanced Voice Detection - Better Piper installation status\n\n') +
147
- chalk.cyan('Configuration Migration:\n') +
148
- chalk.gray(' .claude/config/ .agentvibes/config/\n') +
149
- chalk.gray(' .claude/plugins/ .agentvibes/bmad/\n') +
150
- chalk.gray(' Automatic migration runs during update\n') +
151
- chalk.gray(' All settings and voice mappings preserved\n\n') +
140
+ chalk.gray(' 🔒 API Key Privacy - Masked display prevents credential leaks in logs\n') +
141
+ chalk.gray(' 🛡️ Resource Cleanup - Better subprocess management for stability\n') +
142
+ chalk.gray(' Error Handling - Graceful degradation instead of crashes\n') +
143
+ chalk.gray(' 🎭 BMAD Voice Detection - Party mode supports multiple directory paths\n') +
144
+ chalk.gray(' 110/110 Tests Passing - All functionality verified and working\n') +
145
+ chalk.gray(' 🔄 Zero Breaking Changes - Fully backward compatible with v2.12.5\n\n') +
146
+ chalk.cyan('Technical Improvements:\n') +
147
+ chalk.gray(' API keys now masked in terminal output and error messages\n') +
148
+ chalk.gray(' Process cleanup prevents "too many open files" errors\n') +
149
+ chalk.gray(' Enhanced error handling for file operations\n') +
150
+ chalk.gray(' BMAD agents now use unique voices in party mode\n') +
151
+ chalk.gray(' • Shell config deduplication on repeated installs\n\n') +
152
152
  chalk.white.bold('═══════════════════════════════════════════════════════════════\n\n') +
153
153
  chalk.gray('📖 Full Release Notes: RELEASE_NOTES.md\n') +
154
154
  chalk.gray('🌐 Website: https://agentvibes.org\n') +
@@ -200,9 +200,33 @@ function getUserShell() {
200
200
  function execScript(scriptPath, options = {}) {
201
201
  const { shell, shellConfig } = getUserShell();
202
202
 
203
- // Source the shell config to load environment variables, then run the script
204
- // Don't wrap scriptPath in quotes - it may contain arguments
205
- const command = `source "${shellConfig}" 2>/dev/null; ${shell} ${scriptPath}`;
203
+ // Security: Properly escape the scriptPath to prevent command injection
204
+ // Split scriptPath into command and arguments
205
+ const parts = scriptPath.split(/\s+/);
206
+ const scriptFile = parts[0];
207
+ const args = parts.slice(1);
208
+
209
+ // Validate that the script file doesn't contain shell metacharacters
210
+ if (scriptFile.match(/[;&|`$(){}[\]<>]/)) {
211
+ throw new Error('Invalid characters in script path');
212
+ }
213
+
214
+ // Validate path is within expected directory (defense in depth)
215
+ const resolvedPath = path.resolve(scriptFile);
216
+ const allowedDir = path.resolve(__dirname, '..', '.claude', 'hooks');
217
+ if (!resolvedPath.startsWith(allowedDir)) {
218
+ throw new Error('Script path outside allowed directory');
219
+ }
220
+
221
+ // Escape each argument properly
222
+ const escapedArgs = args.map(arg => {
223
+ // Replace single quotes with '\'' (end quote, escaped quote, start quote)
224
+ return `'${arg.replace(/'/g, "'\\''")}'`;
225
+ }).join(' ');
226
+
227
+ // Build command with properly escaped components
228
+ const scriptCommand = escapedArgs ? `'${scriptFile}' ${escapedArgs}` : `'${scriptFile}'`;
229
+ const command = `source "${shellConfig}" 2>/dev/null; ${shell} ${scriptCommand}`;
206
230
 
207
231
  return execSync(command, {
208
232
  shell: shell,
@@ -364,7 +388,7 @@ async function handleElevenLabsApiKey(options) {
364
388
 
365
389
  if (elevenLabsKey) {
366
390
  console.log(chalk.green(`\n✓ ElevenLabs API key detected from environment`));
367
- console.log(chalk.gray(` Key: ${elevenLabsKey.substring(0, 10)}...`));
391
+ console.log(chalk.gray(` Key: ***************...`));
368
392
 
369
393
  if (!options.yes) {
370
394
  const { useExisting } = await inquirer.prompt([
@@ -425,7 +449,7 @@ async function handleElevenLabsApiKey(options) {
425
449
 
426
450
  if (setupMethod === 'manual') {
427
451
  console.log(chalk.yellow('\n⚠️ Remember to add this to your environment variables later:'));
428
- console.log(chalk.gray(` export ELEVENLABS_API_KEY="${apiKey}"\n`));
452
+ console.log(chalk.gray(` export ELEVENLABS_API_KEY="<your-api-key>"\n`));
429
453
  } else if (setupMethod === 'shell') {
430
454
  await addApiKeyToShellConfig(apiKey);
431
455
  }
@@ -444,7 +468,7 @@ async function addApiKeyToShellConfig(apiKey) {
444
468
  if (!shellName || !shellConfig) {
445
469
  console.log(chalk.yellow('\n⚠️ Could not detect shell type'));
446
470
  console.log(chalk.gray(' Please add manually to your shell config:'));
447
- console.log(chalk.gray(` export ELEVENLABS_API_KEY="${apiKey}"\n`));
471
+ console.log(chalk.gray(` export ELEVENLABS_API_KEY="<your-api-key>"\n`));
448
472
  return;
449
473
  }
450
474
 
@@ -462,14 +486,27 @@ async function addApiKeyToShellConfig(apiKey) {
462
486
 
463
487
  if (confirmShell) {
464
488
  try {
465
- const configContent = `\n# ElevenLabs API Key for AgentVibes\nexport ELEVENLABS_API_KEY="${apiKey}"\n`;
466
- await fs.appendFile(shellConfig, configContent);
467
- console.log(chalk.green(`\n✓ API key added to ${shellConfig}`));
468
- console.log(chalk.yellow(' Run this to use immediately: ') + chalk.cyan(`source ${shellConfig}`));
489
+ // Check if already exists to avoid duplicates
490
+ let existingContent = '';
491
+ try {
492
+ existingContent = await fs.readFile(shellConfig, 'utf8');
493
+ } catch (err) {
494
+ // File might not exist yet, which is fine
495
+ }
496
+
497
+ if (existingContent.includes('ELEVENLABS_API_KEY')) {
498
+ console.log(chalk.cyan(`\n→ API key already exists in ${shellConfig}`));
499
+ console.log(chalk.gray(' No changes needed'));
500
+ } else {
501
+ const configContent = `\n# ElevenLabs API Key for AgentVibes\nexport ELEVENLABS_API_KEY="${apiKey}"\n`;
502
+ await fs.appendFile(shellConfig, configContent);
503
+ console.log(chalk.green(`\n✓ API key added to ${shellConfig}`));
504
+ console.log(chalk.yellow(' Run this to use immediately: ') + chalk.cyan(`source ${shellConfig}`));
505
+ }
469
506
  } catch (error) {
470
507
  console.log(chalk.red(`\n✗ Failed to write to ${shellConfig}`));
471
508
  console.log(chalk.gray(' Please add manually:'));
472
- console.log(chalk.gray(` export ELEVENLABS_API_KEY="${apiKey}"\n`));
509
+ console.log(chalk.gray(` export ELEVENLABS_API_KEY="<your-api-key>"\n`));
473
510
  }
474
511
  }
475
512
  }
@@ -486,20 +523,36 @@ async function copyCommandFiles(targetDir, spinner) {
486
523
  const commandsDir = path.join(targetDir, '.claude', 'commands');
487
524
  const agentVibesCommandsDir = path.join(commandsDir, 'agent-vibes');
488
525
 
489
- await fs.mkdir(agentVibesCommandsDir, { recursive: true });
526
+ try {
527
+ await fs.mkdir(agentVibesCommandsDir, { recursive: true });
490
528
 
491
- const commandFiles = await fs.readdir(srcCommandsDir);
492
- console.log(chalk.cyan(`\n📋 Installing ${commandFiles.length} command files:`));
529
+ const commandFiles = await fs.readdir(srcCommandsDir);
530
+ console.log(chalk.cyan(`\n📋 Installing ${commandFiles.length} command files:`));
493
531
 
494
- for (const file of commandFiles) {
495
- const srcPath = path.join(srcCommandsDir, file);
496
- const destPath = path.join(agentVibesCommandsDir, file);
497
- await fs.copyFile(srcPath, destPath);
498
- console.log(chalk.gray(` ✓ agent-vibes/${file}`));
499
- }
532
+ let successCount = 0;
533
+ for (const file of commandFiles) {
534
+ const srcPath = path.join(srcCommandsDir, file);
535
+ const destPath = path.join(agentVibesCommandsDir, file);
536
+ try {
537
+ await fs.copyFile(srcPath, destPath);
538
+ console.log(chalk.gray(` ✓ agent-vibes/${file}`));
539
+ successCount++;
540
+ } catch (err) {
541
+ console.log(chalk.yellow(` ⚠ Failed to copy ${file}: ${err.message}`));
542
+ // Continue with other files
543
+ }
544
+ }
500
545
 
501
- spinner.succeed(chalk.green('Installed /agent-vibes commands!\n'));
502
- return commandFiles.length;
546
+ if (successCount === commandFiles.length) {
547
+ spinner.succeed(chalk.green('Installed /agent-vibes commands!\n'));
548
+ } else {
549
+ spinner.warn(chalk.yellow(`Installed ${successCount}/${commandFiles.length} commands (some failed)\n`));
550
+ }
551
+ return successCount;
552
+ } catch (err) {
553
+ spinner.fail(chalk.red(`Failed to install commands: ${err.message}`));
554
+ throw err;
555
+ }
503
556
  }
504
557
 
505
558
  /**
@@ -513,39 +566,61 @@ async function copyHookFiles(targetDir, spinner) {
513
566
  const srcHooksDir = path.join(__dirname, '..', '.claude', 'hooks');
514
567
  const hooksDir = path.join(targetDir, '.claude', 'hooks');
515
568
 
516
- await fs.mkdir(hooksDir, { recursive: true });
569
+ try {
570
+ await fs.mkdir(hooksDir, { recursive: true });
517
571
 
518
- const allHookFiles = await fs.readdir(srcHooksDir);
519
- const hookFiles = [];
572
+ const allHookFiles = await fs.readdir(srcHooksDir);
573
+ const hookFiles = [];
520
574
 
521
- for (const file of allHookFiles) {
522
- const srcPath = path.join(srcHooksDir, file);
523
- const stat = await fs.stat(srcPath);
575
+ for (const file of allHookFiles) {
576
+ const srcPath = path.join(srcHooksDir, file);
577
+ try {
578
+ const stat = await fs.stat(srcPath);
524
579
 
525
- if (stat.isFile() &&
526
- (file.endsWith('.sh') || file === 'hooks.json') &&
527
- !file.includes('prepare-release') &&
528
- !file.startsWith('.')) {
529
- hookFiles.push(file);
580
+ if (stat.isFile() &&
581
+ (file.endsWith('.sh') || file === 'hooks.json') &&
582
+ !file.includes('prepare-release') &&
583
+ !file.startsWith('.')) {
584
+ hookFiles.push(file);
585
+ }
586
+ } catch (err) {
587
+ console.log(chalk.yellow(` ⚠ Could not check ${file}: ${err.message}`));
588
+ // Continue with other files
589
+ }
530
590
  }
531
- }
532
591
 
533
- console.log(chalk.cyan(`🔧 Installing ${hookFiles.length} TTS scripts:`));
534
- for (const file of hookFiles) {
535
- const srcPath = path.join(srcHooksDir, file);
536
- const destPath = path.join(hooksDir, file);
537
- await fs.copyFile(srcPath, destPath);
592
+ console.log(chalk.cyan(`🔧 Installing ${hookFiles.length} TTS scripts:`));
593
+ let successCount = 0;
594
+ for (const file of hookFiles) {
595
+ const srcPath = path.join(srcHooksDir, file);
596
+ const destPath = path.join(hooksDir, file);
597
+ try {
598
+ await fs.copyFile(srcPath, destPath);
599
+
600
+ if (file.endsWith('.sh')) {
601
+ // Security: Use more restrictive permissions (owner: rwx, group: r-x, others: ---)
602
+ await fs.chmod(destPath, 0o750);
603
+ console.log(chalk.gray(` ✓ ${file} (executable)`));
604
+ } else {
605
+ console.log(chalk.gray(` ✓ ${file}`));
606
+ }
607
+ successCount++;
608
+ } catch (err) {
609
+ console.log(chalk.yellow(` ⚠ Failed to copy ${file}: ${err.message}`));
610
+ // Continue with other files
611
+ }
612
+ }
538
613
 
539
- if (file.endsWith('.sh')) {
540
- await fs.chmod(destPath, 0o755);
541
- console.log(chalk.gray(` ✓ ${file} (executable)`));
614
+ if (successCount === hookFiles.length) {
615
+ spinner.succeed(chalk.green('Installed TTS scripts!\n'));
542
616
  } else {
543
- console.log(chalk.gray(` ${file}`));
617
+ spinner.warn(chalk.yellow(`Installed ${successCount}/${hookFiles.length} scripts (some failed)\n`));
544
618
  }
619
+ return successCount;
620
+ } catch (err) {
621
+ spinner.fail(chalk.red(`Failed to install hook scripts: ${err.message}`));
622
+ throw err;
545
623
  }
546
-
547
- spinner.succeed(chalk.green('Installed TTS scripts!\n'));
548
- return hookFiles.length;
549
624
  }
550
625
 
551
626
  /**
@@ -786,12 +861,30 @@ async function checkAndInstallPiper(targetDir, options) {
786
861
  }
787
862
  }
788
863
 
864
+ /**
865
+ * Security: Validate that a path is safe and doesn't contain traversal sequences
866
+ * @param {string} targetPath - Path to validate
867
+ * @param {string} basePath - Base directory that targetPath must be within
868
+ * @returns {boolean} - True if path is safe
869
+ */
870
+ function isPathSafe(targetPath, basePath) {
871
+ const resolved = path.resolve(targetPath);
872
+ const baseResolved = path.resolve(basePath);
873
+ return resolved.startsWith(baseResolved);
874
+ }
875
+
789
876
  /**
790
877
  * Process TTS_INJECTION markers in BMAD files
791
878
  * Replaces markers with actual TTS instructions for both party mode and individual agents
792
879
  * @param {string} bmadPath - Path to BMAD installation (e.g., .bmad or bmad)
793
880
  */
794
881
  async function processBmadTtsInjections(bmadPath) {
882
+ // Security: Validate bmadPath doesn't contain path traversal
883
+ const cwd = process.cwd();
884
+ if (!isPathSafe(bmadPath, cwd)) {
885
+ console.error(chalk.red('⚠️ Security: Invalid BMAD path detected'));
886
+ return;
887
+ }
795
888
  const partyModeMarker = '<!-- TTS_INJECTION:party-mode -->';
796
889
  const agentTtsMarker = '<!-- TTS_INJECTION:agent-tts -->';
797
890
 
@@ -1395,7 +1488,6 @@ async function install(options = {}) {
1395
1488
  console.log(chalk.yellow(` • ElevenLabs API key: Set manually later`));
1396
1489
  }
1397
1490
  } else {
1398
- console.error(chalk.red(` DEBUG: In Piper block, selectedProvider = ${selectedProvider}`));
1399
1491
  // Check for installed Piper voices
1400
1492
  const piperVoicesDir = path.join(process.env.HOME || process.env.USERPROFILE, '.claude', 'piper-voices');
1401
1493
  let installedVoices = [];
@@ -1411,10 +1503,8 @@ async function install(options = {}) {
1411
1503
  ];
1412
1504
 
1413
1505
  try {
1414
- console.error(chalk.gray(` Debug: Checking ${piperVoicesDir}`));
1415
1506
  if (fsSync.existsSync(piperVoicesDir)) {
1416
1507
  const files = fsSync.readdirSync(piperVoicesDir);
1417
- console.error(chalk.gray(` Debug: Found ${files.length} files`));
1418
1508
  installedVoices = files
1419
1509
  .filter(f => f.endsWith('.onnx'))
1420
1510
  .map(f => {
@@ -1426,12 +1516,10 @@ async function install(options = {}) {
1426
1516
  return { name: voiceName, path: voicePath, size: `${sizeMB}M` };
1427
1517
  } catch (statErr) {
1428
1518
  // Skip files that can't be read (broken symlinks, etc)
1429
- console.error(chalk.gray(` Debug: Skipped ${voiceName} (${statErr.message})`));
1430
1519
  return null;
1431
1520
  }
1432
1521
  })
1433
1522
  .filter(v => v !== null);
1434
- console.error(chalk.gray(` Debug: ${installedVoices.length} valid voices after filtering`));
1435
1523
 
1436
1524
  // Check which common voices are missing
1437
1525
  for (const voice of commonVoices) {
@@ -1439,13 +1527,10 @@ async function install(options = {}) {
1439
1527
  missingVoices.push(voice);
1440
1528
  }
1441
1529
  }
1442
- console.error(chalk.gray(` Debug: ${missingVoices.length} missing voices`));
1443
1530
  } else {
1444
- console.error(chalk.gray(` Debug: Directory does not exist`));
1445
1531
  missingVoices = commonVoices;
1446
1532
  }
1447
1533
  } catch (err) {
1448
- console.error(chalk.gray(` Debug: Error checking voices: ${err.message}`));
1449
1534
  // On error, show default message
1450
1535
  installedVoices = [];
1451
1536
  missingVoices = commonVoices;
@@ -88,5 +88,5 @@ teardown() {
88
88
  run "$PLAY_TTS"
89
89
 
90
90
  [ "$status" -eq 1 ]
91
- assert_output_contains "Usage:"
91
+ assert_output_contains "Error: No text provided"
92
92
  }