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.
- package/.claude/hooks/bmad-voice-manager.sh +21 -5
- package/.claude/hooks/play-tts.sh +12 -0
- package/.claude/hooks/tts-queue.sh +34 -6
- package/README.md +17 -10
- package/RELEASE_NOTES.md +320 -697
- package/mcp-server/install-deps.js +19 -0
- package/mcp-server/server.py +58 -36
- package/package.json +1 -1
- package/scripts/fix-audio-tunnel.sh +22 -6
- package/src/commands/bmad-voices.js +14 -1
- package/src/installer.js +157 -72
- package/test/unit/play-tts.bats +1 -1
- package/.bmad/_cfg/agent-manifest.csv +0 -11
- package/.bmad/_cfg/agent-voice-map.csv +0 -11
- package/.bmad/_cfg/agents/bmm-analyst.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-architect.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-dev.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-frame-expert.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-pm.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-sm.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-tea.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-tech-writer.customize.yaml +0 -42
- package/.bmad/_cfg/agents/bmm-ux-designer.customize.yaml +0 -42
- package/.bmad/_cfg/agents/core-bmad-master.customize.yaml +0 -42
- package/.bmad/_cfg/files-manifest.csv +0 -243
- package/.bmad/_cfg/ides/claude-code.yaml +0 -6
- package/.bmad/_cfg/manifest.yaml +0 -9
- package/.bmad/_cfg/task-manifest.csv +0 -5
- package/.bmad/_cfg/tool-manifest.csv +0 -2
- package/.bmad/_cfg/workflow-manifest.csv +0 -38
- package/.bmad/bmm/README.md +0 -128
- package/.bmad/bmm/agents/analyst.md +0 -79
- package/.bmad/bmm/agents/analyst.md.backup-pre-tts +0 -75
- package/.bmad/bmm/agents/architect.md +0 -80
- package/.bmad/bmm/agents/dev.md +0 -70
- package/.bmad/bmm/agents/frame-expert.md +0 -72
- package/.bmad/bmm/agents/pm.md +0 -84
- package/.bmad/bmm/agents/sm.md +0 -93
- package/.bmad/bmm/agents/tea.md +0 -80
- package/.bmad/bmm/agents/tech-writer.md +0 -84
- package/.bmad/bmm/agents/ux-designer.md +0 -79
- package/.bmad/bmm/config.yaml +0 -17
- package/.bmad/bmm/docs/README.md +0 -236
- package/.bmad/bmm/docs/agents-guide.md +0 -1058
- package/.bmad/bmm/docs/brownfield-guide.md +0 -762
- package/.bmad/bmm/docs/enterprise-agentic-development.md +0 -686
- package/.bmad/bmm/docs/faq.md +0 -588
- package/.bmad/bmm/docs/glossary.md +0 -320
- package/.bmad/bmm/docs/party-mode.md +0 -224
- package/.bmad/bmm/docs/quick-spec-flow.md +0 -652
- package/.bmad/bmm/docs/quick-start.md +0 -376
- package/.bmad/bmm/docs/scale-adaptive-system.md +0 -612
- package/.bmad/bmm/docs/test-architecture.md +0 -396
- package/.bmad/bmm/docs/workflow-architecture-reference.md +0 -366
- package/.bmad/bmm/docs/workflow-document-project-reference.md +0 -489
- package/.bmad/bmm/docs/workflows-analysis.md +0 -370
- package/.bmad/bmm/docs/workflows-implementation.md +0 -286
- package/.bmad/bmm/docs/workflows-planning.md +0 -612
- package/.bmad/bmm/docs/workflows-solutioning.md +0 -554
- package/.bmad/bmm/teams/default-party.csv +0 -20
- package/.bmad/bmm/teams/team-fullstack.yaml +0 -13
- package/.bmad/bmm/testarch/knowledge/ci-burn-in.md +0 -675
- package/.bmad/bmm/testarch/knowledge/component-tdd.md +0 -486
- package/.bmad/bmm/testarch/knowledge/contract-testing.md +0 -957
- package/.bmad/bmm/testarch/knowledge/data-factories.md +0 -500
- package/.bmad/bmm/testarch/knowledge/email-auth.md +0 -721
- package/.bmad/bmm/testarch/knowledge/error-handling.md +0 -725
- package/.bmad/bmm/testarch/knowledge/feature-flags.md +0 -750
- package/.bmad/bmm/testarch/knowledge/fixture-architecture.md +0 -401
- package/.bmad/bmm/testarch/knowledge/network-first.md +0 -486
- package/.bmad/bmm/testarch/knowledge/nfr-criteria.md +0 -670
- package/.bmad/bmm/testarch/knowledge/playwright-config.md +0 -730
- package/.bmad/bmm/testarch/knowledge/probability-impact.md +0 -601
- package/.bmad/bmm/testarch/knowledge/risk-governance.md +0 -615
- package/.bmad/bmm/testarch/knowledge/selective-testing.md +0 -732
- package/.bmad/bmm/testarch/knowledge/selector-resilience.md +0 -527
- package/.bmad/bmm/testarch/knowledge/test-healing-patterns.md +0 -644
- package/.bmad/bmm/testarch/knowledge/test-levels-framework.md +0 -473
- package/.bmad/bmm/testarch/knowledge/test-priorities-matrix.md +0 -373
- package/.bmad/bmm/testarch/knowledge/test-quality.md +0 -664
- package/.bmad/bmm/testarch/knowledge/timing-debugging.md +0 -372
- package/.bmad/bmm/testarch/knowledge/visual-debugging.md +0 -524
- package/.bmad/bmm/testarch/tea-index.csv +0 -22
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md +0 -112
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md +0 -25
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +0 -26
- package/.bmad/bmm/workflows/1-analysis/domain-research/instructions.md +0 -425
- package/.bmad/bmm/workflows/1-analysis/domain-research/template.md +0 -180
- package/.bmad/bmm/workflows/1-analysis/domain-research/workflow.yaml +0 -28
- package/.bmad/bmm/workflows/1-analysis/product-brief/checklist.md +0 -115
- package/.bmad/bmm/workflows/1-analysis/product-brief/instructions.md +0 -524
- package/.bmad/bmm/workflows/1-analysis/product-brief/template.md +0 -181
- package/.bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml +0 -45
- package/.bmad/bmm/workflows/1-analysis/research/checklist-deep-prompt.md +0 -144
- package/.bmad/bmm/workflows/1-analysis/research/checklist-technical.md +0 -249
- package/.bmad/bmm/workflows/1-analysis/research/checklist.md +0 -299
- package/.bmad/bmm/workflows/1-analysis/research/claude-code/injections.yaml +0 -114
- package/.bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +0 -438
- package/.bmad/bmm/workflows/1-analysis/research/instructions-market.md +0 -675
- package/.bmad/bmm/workflows/1-analysis/research/instructions-router.md +0 -134
- package/.bmad/bmm/workflows/1-analysis/research/instructions-technical.md +0 -534
- package/.bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md +0 -94
- package/.bmad/bmm/workflows/1-analysis/research/template-market.md +0 -347
- package/.bmad/bmm/workflows/1-analysis/research/template-technical.md +0 -245
- package/.bmad/bmm/workflows/1-analysis/research/workflow.yaml +0 -44
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/epics-template.md +0 -80
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/instructions.md +0 -616
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/workflow.yaml +0 -53
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +0 -310
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +0 -1308
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +0 -145
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +0 -61
- package/.bmad/bmm/workflows/2-plan-workflows/prd/checklist.md +0 -346
- package/.bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +0 -13
- package/.bmad/bmm/workflows/2-plan-workflows/prd/instructions.md +0 -703
- package/.bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +0 -204
- package/.bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +0 -11
- package/.bmad/bmm/workflows/2-plan-workflows/prd/workflow.yaml +0 -52
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +0 -217
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +0 -74
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions-generate-stories.md +0 -436
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +0 -980
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +0 -181
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +0 -90
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +0 -58
- package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +0 -321
- package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-template.md +0 -103
- package/.bmad/bmm/workflows/3-solutioning/architecture/checklist.md +0 -240
- package/.bmad/bmm/workflows/3-solutioning/architecture/decision-catalog.yaml +0 -222
- package/.bmad/bmm/workflows/3-solutioning/architecture/instructions.md +0 -768
- package/.bmad/bmm/workflows/3-solutioning/architecture/pattern-categories.csv +0 -13
- package/.bmad/bmm/workflows/3-solutioning/architecture/workflow.yaml +0 -55
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +0 -169
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +0 -332
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/template.md +0 -146
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +0 -62
- package/.bmad/bmm/workflows/4-implementation/code-review/backlog_template.md +0 -12
- package/.bmad/bmm/workflows/4-implementation/code-review/checklist.md +0 -22
- package/.bmad/bmm/workflows/4-implementation/code-review/instructions.md +0 -398
- package/.bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +0 -60
- package/.bmad/bmm/workflows/4-implementation/correct-course/checklist.md +0 -279
- package/.bmad/bmm/workflows/4-implementation/correct-course/instructions.md +0 -206
- package/.bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +0 -56
- package/.bmad/bmm/workflows/4-implementation/create-story/checklist.md +0 -240
- package/.bmad/bmm/workflows/4-implementation/create-story/instructions.md +0 -256
- package/.bmad/bmm/workflows/4-implementation/create-story/template.md +0 -51
- package/.bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +0 -71
- package/.bmad/bmm/workflows/4-implementation/dev-story/checklist.md +0 -38
- package/.bmad/bmm/workflows/4-implementation/dev-story/instructions.md +0 -267
- package/.bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +0 -56
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/checklist.md +0 -17
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/instructions.md +0 -164
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/template.md +0 -76
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +0 -57
- package/.bmad/bmm/workflows/4-implementation/retrospective/instructions.md +0 -1443
- package/.bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +0 -56
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +0 -33
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +0 -234
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +0 -55
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +0 -49
- package/.bmad/bmm/workflows/4-implementation/story-context/checklist.md +0 -16
- package/.bmad/bmm/workflows/4-implementation/story-context/context-template.xml +0 -34
- package/.bmad/bmm/workflows/4-implementation/story-context/instructions.md +0 -209
- package/.bmad/bmm/workflows/4-implementation/story-context/workflow.yaml +0 -61
- package/.bmad/bmm/workflows/4-implementation/story-done/instructions.md +0 -111
- package/.bmad/bmm/workflows/4-implementation/story-done/workflow.yaml +0 -26
- package/.bmad/bmm/workflows/4-implementation/story-ready/instructions.md +0 -117
- package/.bmad/bmm/workflows/4-implementation/story-ready/workflow.yaml +0 -23
- package/.bmad/bmm/workflows/document-project/checklist.md +0 -245
- package/.bmad/bmm/workflows/document-project/documentation-requirements.csv +0 -12
- package/.bmad/bmm/workflows/document-project/instructions.md +0 -222
- package/.bmad/bmm/workflows/document-project/templates/deep-dive-template.md +0 -345
- package/.bmad/bmm/workflows/document-project/templates/index-template.md +0 -169
- package/.bmad/bmm/workflows/document-project/templates/project-overview-template.md +0 -103
- package/.bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +0 -160
- package/.bmad/bmm/workflows/document-project/templates/source-tree-template.md +0 -135
- package/.bmad/bmm/workflows/document-project/workflow.yaml +0 -29
- package/.bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +0 -298
- package/.bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +0 -31
- package/.bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +0 -1106
- package/.bmad/bmm/workflows/document-project/workflows/full-scan.yaml +0 -31
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-helpers.md +0 -127
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-library.json +0 -90
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-templates.yaml +0 -127
- package/.bmad/bmm/workflows/frame-expert/_shared/validate-json-instructions.md +0 -79
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/checklist.md +0 -39
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/instructions.md +0 -131
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +0 -23
- package/.bmad/bmm/workflows/frame-expert/create-diagram/checklist.md +0 -43
- package/.bmad/bmm/workflows/frame-expert/create-diagram/instructions.md +0 -142
- package/.bmad/bmm/workflows/frame-expert/create-diagram/workflow.yaml +0 -24
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/checklist.md +0 -49
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/instructions.md +0 -242
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +0 -27
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/checklist.md +0 -38
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/instructions.md +0 -133
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +0 -23
- package/.bmad/bmm/workflows/techdoc/documentation-standards.md +0 -262
- package/.bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +0 -363
- package/.bmad/bmm/workflows/testarch/atdd/checklist.md +0 -373
- package/.bmad/bmm/workflows/testarch/atdd/instructions.md +0 -785
- package/.bmad/bmm/workflows/testarch/atdd/workflow.yaml +0 -45
- package/.bmad/bmm/workflows/testarch/automate/checklist.md +0 -580
- package/.bmad/bmm/workflows/testarch/automate/instructions.md +0 -1303
- package/.bmad/bmm/workflows/testarch/automate/workflow.yaml +0 -52
- package/.bmad/bmm/workflows/testarch/ci/checklist.md +0 -246
- package/.bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +0 -165
- package/.bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +0 -128
- package/.bmad/bmm/workflows/testarch/ci/instructions.md +0 -517
- package/.bmad/bmm/workflows/testarch/ci/workflow.yaml +0 -45
- package/.bmad/bmm/workflows/testarch/framework/checklist.md +0 -321
- package/.bmad/bmm/workflows/testarch/framework/instructions.md +0 -455
- package/.bmad/bmm/workflows/testarch/framework/workflow.yaml +0 -47
- package/.bmad/bmm/workflows/testarch/nfr-assess/checklist.md +0 -405
- package/.bmad/bmm/workflows/testarch/nfr-assess/instructions.md +0 -722
- package/.bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +0 -443
- package/.bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +0 -47
- package/.bmad/bmm/workflows/testarch/test-design/checklist.md +0 -234
- package/.bmad/bmm/workflows/testarch/test-design/instructions.md +0 -782
- package/.bmad/bmm/workflows/testarch/test-design/test-design-template.md +0 -285
- package/.bmad/bmm/workflows/testarch/test-design/workflow.yaml +0 -48
- package/.bmad/bmm/workflows/testarch/test-review/checklist.md +0 -470
- package/.bmad/bmm/workflows/testarch/test-review/instructions.md +0 -608
- package/.bmad/bmm/workflows/testarch/test-review/test-review-template.md +0 -388
- package/.bmad/bmm/workflows/testarch/test-review/workflow.yaml +0 -46
- package/.bmad/bmm/workflows/testarch/trace/checklist.md +0 -654
- package/.bmad/bmm/workflows/testarch/trace/instructions.md +0 -1045
- package/.bmad/bmm/workflows/testarch/trace/trace-template.md +0 -673
- package/.bmad/bmm/workflows/testarch/trace/workflow.yaml +0 -55
- package/.bmad/bmm/workflows/workflow-status/init/instructions.md +0 -334
- package/.bmad/bmm/workflows/workflow-status/init/workflow.yaml +0 -28
- package/.bmad/bmm/workflows/workflow-status/instructions.md +0 -388
- package/.bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +0 -138
- package/.bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +0 -126
- package/.bmad/bmm/workflows/workflow-status/paths/game-design.yaml +0 -52
- package/.bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +0 -122
- package/.bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +0 -113
- package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-brownfield.yaml +0 -58
- package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-greenfield.yaml +0 -47
- package/.bmad/bmm/workflows/workflow-status/project-levels.yaml +0 -59
- package/.bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +0 -24
- package/.bmad/bmm/workflows/workflow-status/workflow.yaml +0 -28
- package/.bmad/core/agents/bmad-master.md +0 -72
- package/.bmad/core/agents/bmad-web-orchestrator.agent.xml +0 -113
- package/.bmad/core/config.yaml +0 -11
- package/.bmad/core/tasks/adv-elicit-methods.csv +0 -39
- package/.bmad/core/tasks/advanced-elicitation-methods.csv +0 -21
- package/.bmad/core/tasks/advanced-elicitation.xml +0 -106
- package/.bmad/core/tasks/index-docs.xml +0 -65
- package/.bmad/core/tasks/validate-workflow.xml +0 -89
- package/.bmad/core/tasks/workflow.xml +0 -270
- package/.bmad/core/tools/shard-doc.xml +0 -109
- package/.bmad/core/workflows/brainstorming/README.md +0 -261
- package/.bmad/core/workflows/brainstorming/brain-methods.csv +0 -36
- package/.bmad/core/workflows/brainstorming/instructions.md +0 -315
- package/.bmad/core/workflows/brainstorming/template.md +0 -106
- package/.bmad/core/workflows/brainstorming/workflow.yaml +0 -38
- package/.bmad/core/workflows/party-mode/instructions.md +0 -203
- package/.bmad/core/workflows/party-mode/workflow.yaml +0 -28
- package/.bmad/docs/claude-code-instructions.md +0 -25
- package/.claude/commands/BMad/analyst.md +0 -88
- package/.claude/commands/BMad/architect.md +0 -89
- package/.claude/commands/BMad/bmad-master.md +0 -114
- package/.claude/commands/BMad/bmad-orchestrator.md +0 -151
- package/.claude/commands/BMad/dev.md +0 -85
- package/.claude/commands/BMad/pm.md +0 -88
- package/.claude/commands/BMad/po.md +0 -83
- package/.claude/commands/BMad/qa.md +0 -91
- package/.claude/commands/BMad/sm.md +0 -69
- package/.claude/commands/BMad/tasks/advanced-elicitation.md +0 -123
- package/.claude/commands/BMad/tasks/apply-qa-fixes.md +0 -154
- package/.claude/commands/BMad/tasks/brownfield-create-epic.md +0 -166
- package/.claude/commands/BMad/tasks/brownfield-create-story.md +0 -153
- package/.claude/commands/BMad/tasks/correct-course.md +0 -76
- package/.claude/commands/BMad/tasks/create-brownfield-story.md +0 -318
- package/.claude/commands/BMad/tasks/create-deep-research-prompt.md +0 -284
- package/.claude/commands/BMad/tasks/create-doc.md +0 -107
- package/.claude/commands/BMad/tasks/create-next-story.md +0 -118
- package/.claude/commands/BMad/tasks/document-project.md +0 -349
- package/.claude/commands/BMad/tasks/execute-checklist.md +0 -92
- package/.claude/commands/BMad/tasks/facilitate-brainstorming-session.md +0 -142
- package/.claude/commands/BMad/tasks/generate-ai-frontend-prompt.md +0 -57
- package/.claude/commands/BMad/tasks/index-docs.md +0 -179
- package/.claude/commands/BMad/tasks/kb-mode-interaction.md +0 -81
- package/.claude/commands/BMad/tasks/nfr-assess.md +0 -349
- package/.claude/commands/BMad/tasks/qa-gate.md +0 -167
- package/.claude/commands/BMad/tasks/review-story.md +0 -320
- package/.claude/commands/BMad/tasks/risk-profile.md +0 -359
- package/.claude/commands/BMad/tasks/shard-doc.md +0 -191
- package/.claude/commands/BMad/tasks/test-design.md +0 -180
- package/.claude/commands/BMad/tasks/trace-requirements.md +0 -270
- package/.claude/commands/BMad/tasks/validate-next-story.md +0 -140
- package/.claude/commands/BMad/ux-expert.md +0 -73
- package/.claude/commands/bmad/bmm/agents/analyst.md +0 -14
- package/.claude/commands/bmad/bmm/agents/architect.md +0 -14
- package/.claude/commands/bmad/bmm/agents/dev.md +0 -14
- package/.claude/commands/bmad/bmm/agents/frame-expert.md +0 -14
- package/.claude/commands/bmad/bmm/agents/pm.md +0 -14
- package/.claude/commands/bmad/bmm/agents/sm.md +0 -14
- package/.claude/commands/bmad/bmm/agents/tea.md +0 -14
- package/.claude/commands/bmad/bmm/agents/tech-writer.md +0 -14
- package/.claude/commands/bmad/bmm/agents/ux-designer.md +0 -14
- package/.claude/commands/bmad/bmm/workflows/architecture.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/brainstorm-project.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/code-review.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/correct-course.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-dataflow.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-diagram.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-flowchart.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-story.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-ux-design.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/create-wireframe.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/dev-story.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/document-project.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/domain-research.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/epic-tech-context.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/implementation-readiness.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/prd.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/product-brief.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/research.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/retrospective.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/sprint-planning.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/story-context.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/story-done.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/story-ready.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/tech-spec.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/workflow-init.md +0 -13
- package/.claude/commands/bmad/bmm/workflows/workflow-status.md +0 -13
- package/.claude/commands/bmad/core/agents/bmad-master.md +0 -14
- package/.claude/commands/bmad/core/tasks/advanced-elicitation.md +0 -9
- package/.claude/commands/bmad/core/tasks/index-docs.md +0 -9
- package/.claude/commands/bmad/core/tools/shard-doc.md +0 -9
- package/.claude/commands/bmad/core/workflows/brainstorming.md +0 -13
- package/.claude/commands/bmad/core/workflows/party-mode.md +0 -13
- package/.claude/github-star-reminder.txt +0 -1
- package/.claude/hooks/bmad-party-manager.sh +0 -225
- package/.claude/hooks/stop.sh +0 -221
- package/.claude/piper-voices-dir.txt +0 -1
- package/.mcp.json +0 -88
- package/RELEASE_NOTES_v2.4.0_DRAFT.md +0 -116
- package/RELEASE_NOTES_v2.4.1_DRAFT.md +0 -61
- package/docs/2025-11-15_15-14-33.snagx +0 -0
- package/docs/Screenshot 2025-11-15 151325.png +0 -0
- package/docs/Screenshot 2025-11-15 151432.png +0 -0
- package/docs/macos-piper-issue.md +0 -172
- package/docs/stargazer-cms-prd.md +0 -1918
- package/docs/whatsapp-plugin-github-issue.md +0 -393
- package/docs/whatsapp-tts-plugin-feasibility.md +0 -418
- package/docs/whatsapp-tts-standalone-plugin.md +0 -628
- package/github-profile-draft.md +0 -57
- package/linkedin/vibe-coding-and-pulseaudio.md +0 -121
- package/mcp-server/agentvibes.db +0 -0
- package/scripts/audio-tunnel.config +0 -17
- package/v4-backup/.bmad-core/agent-teams/team-all.yaml +0 -15
- package/v4-backup/.bmad-core/agent-teams/team-fullstack.yaml +0 -19
- package/v4-backup/.bmad-core/agent-teams/team-ide-minimal.yaml +0 -11
- package/v4-backup/.bmad-core/agent-teams/team-no-ui.yaml +0 -14
- package/v4-backup/.bmad-core/agents/analyst.md +0 -84
- package/v4-backup/.bmad-core/agents/architect.md +0 -85
- package/v4-backup/.bmad-core/agents/bmad-master.md +0 -110
- package/v4-backup/.bmad-core/agents/bmad-orchestrator.md +0 -147
- package/v4-backup/.bmad-core/agents/dev.md +0 -81
- package/v4-backup/.bmad-core/agents/pm.md +0 -84
- package/v4-backup/.bmad-core/agents/po.md +0 -79
- package/v4-backup/.bmad-core/agents/qa.md +0 -87
- package/v4-backup/.bmad-core/agents/sm.md +0 -65
- package/v4-backup/.bmad-core/agents/ux-expert.md +0 -69
- package/v4-backup/.bmad-core/checklists/architect-checklist.md +0 -440
- package/v4-backup/.bmad-core/checklists/change-checklist.md +0 -184
- package/v4-backup/.bmad-core/checklists/pm-checklist.md +0 -372
- package/v4-backup/.bmad-core/checklists/po-master-checklist.md +0 -434
- package/v4-backup/.bmad-core/checklists/story-dod-checklist.md +0 -96
- package/v4-backup/.bmad-core/checklists/story-draft-checklist.md +0 -155
- package/v4-backup/.bmad-core/core-config.yaml +0 -22
- package/v4-backup/.bmad-core/data/bmad-kb.md +0 -809
- package/v4-backup/.bmad-core/data/brainstorming-techniques.md +0 -38
- package/v4-backup/.bmad-core/data/elicitation-methods.md +0 -156
- package/v4-backup/.bmad-core/data/technical-preferences.md +0 -5
- package/v4-backup/.bmad-core/data/test-levels-framework.md +0 -148
- package/v4-backup/.bmad-core/data/test-priorities-matrix.md +0 -174
- package/v4-backup/.bmad-core/enhanced-ide-development-workflow.md +0 -248
- package/v4-backup/.bmad-core/install-manifest.yaml +0 -230
- package/v4-backup/.bmad-core/tasks/advanced-elicitation.md +0 -119
- package/v4-backup/.bmad-core/tasks/apply-qa-fixes.md +0 -150
- package/v4-backup/.bmad-core/tasks/brownfield-create-epic.md +0 -162
- package/v4-backup/.bmad-core/tasks/brownfield-create-story.md +0 -149
- package/v4-backup/.bmad-core/tasks/correct-course.md +0 -72
- package/v4-backup/.bmad-core/tasks/create-brownfield-story.md +0 -314
- package/v4-backup/.bmad-core/tasks/create-deep-research-prompt.md +0 -280
- package/v4-backup/.bmad-core/tasks/create-doc.md +0 -103
- package/v4-backup/.bmad-core/tasks/create-next-story.md +0 -114
- package/v4-backup/.bmad-core/tasks/document-project.md +0 -345
- package/v4-backup/.bmad-core/tasks/execute-checklist.md +0 -88
- package/v4-backup/.bmad-core/tasks/facilitate-brainstorming-session.md +0 -138
- package/v4-backup/.bmad-core/tasks/generate-ai-frontend-prompt.md +0 -53
- package/v4-backup/.bmad-core/tasks/index-docs.md +0 -175
- package/v4-backup/.bmad-core/tasks/kb-mode-interaction.md +0 -77
- package/v4-backup/.bmad-core/tasks/nfr-assess.md +0 -345
- package/v4-backup/.bmad-core/tasks/qa-gate.md +0 -163
- package/v4-backup/.bmad-core/tasks/review-story.md +0 -316
- package/v4-backup/.bmad-core/tasks/risk-profile.md +0 -355
- package/v4-backup/.bmad-core/tasks/shard-doc.md +0 -187
- package/v4-backup/.bmad-core/tasks/test-design.md +0 -176
- package/v4-backup/.bmad-core/tasks/trace-requirements.md +0 -266
- package/v4-backup/.bmad-core/tasks/validate-next-story.md +0 -136
- package/v4-backup/.bmad-core/templates/architecture-tmpl.yaml +0 -651
- package/v4-backup/.bmad-core/templates/brainstorming-output-tmpl.yaml +0 -156
- package/v4-backup/.bmad-core/templates/brownfield-architecture-tmpl.yaml +0 -477
- package/v4-backup/.bmad-core/templates/brownfield-prd-tmpl.yaml +0 -281
- package/v4-backup/.bmad-core/templates/competitor-analysis-tmpl.yaml +0 -307
- package/v4-backup/.bmad-core/templates/front-end-architecture-tmpl.yaml +0 -219
- package/v4-backup/.bmad-core/templates/front-end-spec-tmpl.yaml +0 -350
- package/v4-backup/.bmad-core/templates/fullstack-architecture-tmpl.yaml +0 -824
- package/v4-backup/.bmad-core/templates/market-research-tmpl.yaml +0 -253
- package/v4-backup/.bmad-core/templates/prd-tmpl.yaml +0 -203
- package/v4-backup/.bmad-core/templates/project-brief-tmpl.yaml +0 -222
- package/v4-backup/.bmad-core/templates/qa-gate-tmpl.yaml +0 -103
- package/v4-backup/.bmad-core/templates/story-tmpl.yaml +0 -138
- package/v4-backup/.bmad-core/user-guide.md +0 -577
- package/v4-backup/.bmad-core/utils/bmad-doc-template.md +0 -327
- package/v4-backup/.bmad-core/utils/workflow-management.md +0 -71
- package/v4-backup/.bmad-core/workflows/brownfield-fullstack.yaml +0 -298
- package/v4-backup/.bmad-core/workflows/brownfield-service.yaml +0 -188
- package/v4-backup/.bmad-core/workflows/brownfield-ui.yaml +0 -198
- package/v4-backup/.bmad-core/workflows/greenfield-fullstack.yaml +0 -241
- package/v4-backup/.bmad-core/workflows/greenfield-service.yaml +0 -207
- package/v4-backup/.bmad-core/workflows/greenfield-ui.yaml +0 -236
- 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`;
|
package/mcp-server/server.py
CHANGED
|
@@ -147,25 +147,31 @@ class AgentVibesServer:
|
|
|
147
147
|
stderr=asyncio.subprocess.PIPE,
|
|
148
148
|
env=env,
|
|
149
149
|
)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
error_msg
|
|
523
|
-
|
|
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
|
-
|
|
540
|
-
|
|
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
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
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
|
+
"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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
135
|
-
chalk.cyan('
|
|
136
|
-
chalk.cyan('
|
|
137
|
-
chalk.cyan('
|
|
138
|
-
chalk.cyan('
|
|
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('
|
|
142
|
-
chalk.gray('
|
|
143
|
-
chalk.gray('
|
|
144
|
-
chalk.gray('
|
|
145
|
-
chalk.gray('
|
|
146
|
-
chalk.gray('
|
|
147
|
-
chalk.cyan('
|
|
148
|
-
chalk.gray('
|
|
149
|
-
chalk.gray('
|
|
150
|
-
chalk.gray('
|
|
151
|
-
chalk.gray('
|
|
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
|
-
//
|
|
204
|
-
//
|
|
205
|
-
const
|
|
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:
|
|
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="
|
|
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="
|
|
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
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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="
|
|
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
|
-
|
|
526
|
+
try {
|
|
527
|
+
await fs.mkdir(agentVibesCommandsDir, { recursive: true });
|
|
490
528
|
|
|
491
|
-
|
|
492
|
-
|
|
529
|
+
const commandFiles = await fs.readdir(srcCommandsDir);
|
|
530
|
+
console.log(chalk.cyan(`\n📋 Installing ${commandFiles.length} command files:`));
|
|
493
531
|
|
|
494
|
-
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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
|
-
|
|
502
|
-
|
|
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
|
-
|
|
569
|
+
try {
|
|
570
|
+
await fs.mkdir(hooksDir, { recursive: true });
|
|
517
571
|
|
|
518
|
-
|
|
519
|
-
|
|
572
|
+
const allHookFiles = await fs.readdir(srcHooksDir);
|
|
573
|
+
const hookFiles = [];
|
|
520
574
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
-
|
|
534
|
-
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
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 (
|
|
540
|
-
|
|
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
|
-
|
|
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;
|
package/test/unit/play-tts.bats
CHANGED