agentvibes 2.17.2 → 2.17.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bmad/_cfg/agent-manifest.csv +11 -0
- package/.bmad/_cfg/agent-voice-map.csv +11 -0
- package/.bmad/_cfg/agents/bmm-analyst.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-architect.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-dev.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-frame-expert.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-pm.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-sm.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-tea.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-tech-writer.customize.yaml +42 -0
- package/.bmad/_cfg/agents/bmm-ux-designer.customize.yaml +42 -0
- package/.bmad/_cfg/agents/core-bmad-master.customize.yaml +42 -0
- package/.bmad/_cfg/files-manifest.csv +243 -0
- package/.bmad/_cfg/ides/claude-code.yaml +6 -0
- package/.bmad/_cfg/manifest.yaml +9 -0
- package/.bmad/_cfg/task-manifest.csv +5 -0
- package/.bmad/_cfg/tool-manifest.csv +2 -0
- package/.bmad/_cfg/workflow-manifest.csv +38 -0
- package/.bmad/bmm/README.md +128 -0
- package/.bmad/bmm/agents/analyst.md +79 -0
- package/.bmad/bmm/agents/analyst.md.backup-pre-tts +75 -0
- package/.bmad/bmm/agents/architect.md +80 -0
- package/.bmad/bmm/agents/dev.md +70 -0
- package/.bmad/bmm/agents/frame-expert.md +72 -0
- package/.bmad/bmm/agents/pm.md +84 -0
- package/.bmad/bmm/agents/sm.md +93 -0
- package/.bmad/bmm/agents/tea.md +80 -0
- package/.bmad/bmm/agents/tech-writer.md +84 -0
- package/.bmad/bmm/agents/ux-designer.md +79 -0
- package/.bmad/bmm/config.yaml +17 -0
- package/.bmad/bmm/docs/README.md +236 -0
- package/.bmad/bmm/docs/agents-guide.md +1058 -0
- package/.bmad/bmm/docs/brownfield-guide.md +762 -0
- package/.bmad/bmm/docs/enterprise-agentic-development.md +686 -0
- package/.bmad/bmm/docs/faq.md +588 -0
- package/.bmad/bmm/docs/glossary.md +320 -0
- package/.bmad/bmm/docs/party-mode.md +224 -0
- package/.bmad/bmm/docs/quick-spec-flow.md +652 -0
- package/.bmad/bmm/docs/quick-start.md +376 -0
- package/.bmad/bmm/docs/scale-adaptive-system.md +612 -0
- package/.bmad/bmm/docs/test-architecture.md +396 -0
- package/.bmad/bmm/docs/workflow-architecture-reference.md +366 -0
- package/.bmad/bmm/docs/workflow-document-project-reference.md +489 -0
- package/.bmad/bmm/docs/workflows-analysis.md +370 -0
- package/.bmad/bmm/docs/workflows-implementation.md +286 -0
- package/.bmad/bmm/docs/workflows-planning.md +612 -0
- package/.bmad/bmm/docs/workflows-solutioning.md +554 -0
- package/.bmad/bmm/teams/default-party.csv +20 -0
- package/.bmad/bmm/teams/team-fullstack.yaml +13 -0
- package/.bmad/bmm/testarch/knowledge/ci-burn-in.md +675 -0
- package/.bmad/bmm/testarch/knowledge/component-tdd.md +486 -0
- package/.bmad/bmm/testarch/knowledge/contract-testing.md +957 -0
- package/.bmad/bmm/testarch/knowledge/data-factories.md +500 -0
- package/.bmad/bmm/testarch/knowledge/email-auth.md +721 -0
- package/.bmad/bmm/testarch/knowledge/error-handling.md +725 -0
- package/.bmad/bmm/testarch/knowledge/feature-flags.md +750 -0
- package/.bmad/bmm/testarch/knowledge/fixture-architecture.md +401 -0
- package/.bmad/bmm/testarch/knowledge/network-first.md +486 -0
- package/.bmad/bmm/testarch/knowledge/nfr-criteria.md +670 -0
- package/.bmad/bmm/testarch/knowledge/playwright-config.md +730 -0
- package/.bmad/bmm/testarch/knowledge/probability-impact.md +601 -0
- package/.bmad/bmm/testarch/knowledge/risk-governance.md +615 -0
- package/.bmad/bmm/testarch/knowledge/selective-testing.md +732 -0
- package/.bmad/bmm/testarch/knowledge/selector-resilience.md +527 -0
- package/.bmad/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
- package/.bmad/bmm/testarch/knowledge/test-levels-framework.md +473 -0
- package/.bmad/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/.bmad/bmm/testarch/knowledge/test-quality.md +664 -0
- package/.bmad/bmm/testarch/knowledge/timing-debugging.md +372 -0
- package/.bmad/bmm/testarch/knowledge/visual-debugging.md +524 -0
- package/.bmad/bmm/testarch/tea-index.csv +22 -0
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/instructions.md +112 -0
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/project-context.md +25 -0
- package/.bmad/bmm/workflows/1-analysis/brainstorm-project/workflow.yaml +26 -0
- package/.bmad/bmm/workflows/1-analysis/domain-research/instructions.md +425 -0
- package/.bmad/bmm/workflows/1-analysis/domain-research/template.md +180 -0
- package/.bmad/bmm/workflows/1-analysis/domain-research/workflow.yaml +28 -0
- package/.bmad/bmm/workflows/1-analysis/product-brief/checklist.md +115 -0
- package/.bmad/bmm/workflows/1-analysis/product-brief/instructions.md +524 -0
- package/.bmad/bmm/workflows/1-analysis/product-brief/template.md +181 -0
- package/.bmad/bmm/workflows/1-analysis/product-brief/workflow.yaml +45 -0
- package/.bmad/bmm/workflows/1-analysis/research/checklist-deep-prompt.md +144 -0
- package/.bmad/bmm/workflows/1-analysis/research/checklist-technical.md +249 -0
- package/.bmad/bmm/workflows/1-analysis/research/checklist.md +299 -0
- package/.bmad/bmm/workflows/1-analysis/research/claude-code/injections.yaml +114 -0
- package/.bmad/bmm/workflows/1-analysis/research/instructions-deep-prompt.md +438 -0
- package/.bmad/bmm/workflows/1-analysis/research/instructions-market.md +675 -0
- package/.bmad/bmm/workflows/1-analysis/research/instructions-router.md +134 -0
- package/.bmad/bmm/workflows/1-analysis/research/instructions-technical.md +534 -0
- package/.bmad/bmm/workflows/1-analysis/research/template-deep-prompt.md +94 -0
- package/.bmad/bmm/workflows/1-analysis/research/template-market.md +347 -0
- package/.bmad/bmm/workflows/1-analysis/research/template-technical.md +245 -0
- package/.bmad/bmm/workflows/1-analysis/research/workflow.yaml +44 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/epics-template.md +80 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/instructions.md +616 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-epics-and-stories/workflow.yaml +53 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/checklist.md +310 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/instructions.md +1308 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +145 -0
- package/.bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.yaml +61 -0
- package/.bmad/bmm/workflows/2-plan-workflows/prd/checklist.md +346 -0
- package/.bmad/bmm/workflows/2-plan-workflows/prd/domain-complexity.csv +13 -0
- package/.bmad/bmm/workflows/2-plan-workflows/prd/instructions.md +703 -0
- package/.bmad/bmm/workflows/2-plan-workflows/prd/prd-template.md +204 -0
- package/.bmad/bmm/workflows/2-plan-workflows/prd/project-types.csv +11 -0
- package/.bmad/bmm/workflows/2-plan-workflows/prd/workflow.yaml +52 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/checklist.md +217 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/epics-template.md +74 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions-generate-stories.md +436 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/instructions.md +980 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/tech-spec-template.md +181 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/user-story-template.md +90 -0
- package/.bmad/bmm/workflows/2-plan-workflows/tech-spec/workflow.yaml +58 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-patterns.yaml +321 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/architecture-template.md +103 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/checklist.md +240 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/decision-catalog.yaml +222 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/instructions.md +768 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/pattern-categories.csv +13 -0
- package/.bmad/bmm/workflows/3-solutioning/architecture/workflow.yaml +55 -0
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/checklist.md +169 -0
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/instructions.md +332 -0
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/template.md +146 -0
- package/.bmad/bmm/workflows/3-solutioning/implementation-readiness/workflow.yaml +62 -0
- package/.bmad/bmm/workflows/4-implementation/code-review/backlog_template.md +12 -0
- package/.bmad/bmm/workflows/4-implementation/code-review/checklist.md +22 -0
- package/.bmad/bmm/workflows/4-implementation/code-review/instructions.md +398 -0
- package/.bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +60 -0
- package/.bmad/bmm/workflows/4-implementation/correct-course/checklist.md +279 -0
- package/.bmad/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
- package/.bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +56 -0
- package/.bmad/bmm/workflows/4-implementation/create-story/checklist.md +240 -0
- package/.bmad/bmm/workflows/4-implementation/create-story/instructions.md +256 -0
- package/.bmad/bmm/workflows/4-implementation/create-story/template.md +51 -0
- package/.bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +71 -0
- package/.bmad/bmm/workflows/4-implementation/dev-story/checklist.md +38 -0
- package/.bmad/bmm/workflows/4-implementation/dev-story/instructions.md +267 -0
- package/.bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +56 -0
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/checklist.md +17 -0
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/instructions.md +164 -0
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/template.md +76 -0
- package/.bmad/bmm/workflows/4-implementation/epic-tech-context/workflow.yaml +57 -0
- package/.bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
- package/.bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +56 -0
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +234 -0
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/.bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +49 -0
- package/.bmad/bmm/workflows/4-implementation/story-context/checklist.md +16 -0
- package/.bmad/bmm/workflows/4-implementation/story-context/context-template.xml +34 -0
- package/.bmad/bmm/workflows/4-implementation/story-context/instructions.md +209 -0
- package/.bmad/bmm/workflows/4-implementation/story-context/workflow.yaml +61 -0
- package/.bmad/bmm/workflows/4-implementation/story-done/instructions.md +111 -0
- package/.bmad/bmm/workflows/4-implementation/story-done/workflow.yaml +26 -0
- package/.bmad/bmm/workflows/4-implementation/story-ready/instructions.md +117 -0
- package/.bmad/bmm/workflows/4-implementation/story-ready/workflow.yaml +23 -0
- package/.bmad/bmm/workflows/document-project/checklist.md +245 -0
- package/.bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/.bmad/bmm/workflows/document-project/instructions.md +222 -0
- package/.bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/.bmad/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/.bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/.bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/.bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/.bmad/bmm/workflows/document-project/workflow.yaml +29 -0
- package/.bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/.bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/.bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/.bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-helpers.md +127 -0
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-library.json +90 -0
- package/.bmad/bmm/workflows/frame-expert/_shared/excalidraw-templates.yaml +127 -0
- package/.bmad/bmm/workflows/frame-expert/_shared/validate-json-instructions.md +79 -0
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/checklist.md +39 -0
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/instructions.md +131 -0
- package/.bmad/bmm/workflows/frame-expert/create-dataflow/workflow.yaml +23 -0
- package/.bmad/bmm/workflows/frame-expert/create-diagram/checklist.md +43 -0
- package/.bmad/bmm/workflows/frame-expert/create-diagram/instructions.md +142 -0
- package/.bmad/bmm/workflows/frame-expert/create-diagram/workflow.yaml +24 -0
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/checklist.md +49 -0
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/instructions.md +242 -0
- package/.bmad/bmm/workflows/frame-expert/create-flowchart/workflow.yaml +27 -0
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/checklist.md +38 -0
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/instructions.md +133 -0
- package/.bmad/bmm/workflows/frame-expert/create-wireframe/workflow.yaml +23 -0
- package/.bmad/bmm/workflows/techdoc/documentation-standards.md +262 -0
- package/.bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
- package/.bmad/bmm/workflows/testarch/atdd/checklist.md +373 -0
- package/.bmad/bmm/workflows/testarch/atdd/instructions.md +785 -0
- package/.bmad/bmm/workflows/testarch/atdd/workflow.yaml +45 -0
- package/.bmad/bmm/workflows/testarch/automate/checklist.md +580 -0
- package/.bmad/bmm/workflows/testarch/automate/instructions.md +1303 -0
- package/.bmad/bmm/workflows/testarch/automate/workflow.yaml +52 -0
- package/.bmad/bmm/workflows/testarch/ci/checklist.md +246 -0
- package/.bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +165 -0
- package/.bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +128 -0
- package/.bmad/bmm/workflows/testarch/ci/instructions.md +517 -0
- package/.bmad/bmm/workflows/testarch/ci/workflow.yaml +45 -0
- package/.bmad/bmm/workflows/testarch/framework/checklist.md +321 -0
- package/.bmad/bmm/workflows/testarch/framework/instructions.md +455 -0
- package/.bmad/bmm/workflows/testarch/framework/workflow.yaml +47 -0
- package/.bmad/bmm/workflows/testarch/nfr-assess/checklist.md +405 -0
- package/.bmad/bmm/workflows/testarch/nfr-assess/instructions.md +722 -0
- package/.bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +443 -0
- package/.bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +47 -0
- package/.bmad/bmm/workflows/testarch/test-design/checklist.md +234 -0
- package/.bmad/bmm/workflows/testarch/test-design/instructions.md +782 -0
- package/.bmad/bmm/workflows/testarch/test-design/test-design-template.md +285 -0
- package/.bmad/bmm/workflows/testarch/test-design/workflow.yaml +48 -0
- package/.bmad/bmm/workflows/testarch/test-review/checklist.md +470 -0
- package/.bmad/bmm/workflows/testarch/test-review/instructions.md +608 -0
- package/.bmad/bmm/workflows/testarch/test-review/test-review-template.md +388 -0
- package/.bmad/bmm/workflows/testarch/test-review/workflow.yaml +46 -0
- package/.bmad/bmm/workflows/testarch/trace/checklist.md +654 -0
- package/.bmad/bmm/workflows/testarch/trace/instructions.md +1045 -0
- package/.bmad/bmm/workflows/testarch/trace/trace-template.md +673 -0
- package/.bmad/bmm/workflows/testarch/trace/workflow.yaml +55 -0
- package/.bmad/bmm/workflows/workflow-status/init/instructions.md +334 -0
- package/.bmad/bmm/workflows/workflow-status/init/workflow.yaml +28 -0
- package/.bmad/bmm/workflows/workflow-status/instructions.md +388 -0
- package/.bmad/bmm/workflows/workflow-status/paths/enterprise-brownfield.yaml +138 -0
- package/.bmad/bmm/workflows/workflow-status/paths/enterprise-greenfield.yaml +126 -0
- package/.bmad/bmm/workflows/workflow-status/paths/game-design.yaml +52 -0
- package/.bmad/bmm/workflows/workflow-status/paths/method-brownfield.yaml +122 -0
- package/.bmad/bmm/workflows/workflow-status/paths/method-greenfield.yaml +113 -0
- package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-brownfield.yaml +58 -0
- package/.bmad/bmm/workflows/workflow-status/paths/quick-flow-greenfield.yaml +47 -0
- package/.bmad/bmm/workflows/workflow-status/project-levels.yaml +59 -0
- package/.bmad/bmm/workflows/workflow-status/workflow-status-template.yaml +24 -0
- package/.bmad/bmm/workflows/workflow-status/workflow.yaml +28 -0
- package/.bmad/core/agents/bmad-master.md +72 -0
- package/.bmad/core/agents/bmad-web-orchestrator.agent.xml +113 -0
- package/.bmad/core/config.yaml +1 -0
- package/.bmad/core/tasks/adv-elicit-methods.csv +39 -0
- package/.bmad/core/tasks/advanced-elicitation-methods.csv +21 -0
- package/.bmad/core/tasks/advanced-elicitation.xml +106 -0
- package/.bmad/core/tasks/index-docs.xml +65 -0
- package/.bmad/core/tasks/validate-workflow.xml +89 -0
- package/.bmad/core/tasks/workflow.xml +270 -0
- package/.bmad/core/tools/shard-doc.xml +109 -0
- package/.bmad/core/workflows/brainstorming/README.md +261 -0
- package/.bmad/core/workflows/brainstorming/brain-methods.csv +36 -0
- package/.bmad/core/workflows/brainstorming/instructions.md +315 -0
- package/.bmad/core/workflows/brainstorming/template.md +106 -0
- package/.bmad/core/workflows/brainstorming/workflow.yaml +38 -0
- package/.bmad/core/workflows/party-mode/instructions.md +203 -0
- package/.bmad/core/workflows/party-mode/workflow.yaml +28 -0
- package/.bmad/docs/claude-code-instructions.md +25 -0
- package/.claude/commands/BMad/analyst.md +88 -0
- package/.claude/commands/BMad/architect.md +89 -0
- package/.claude/commands/BMad/bmad-master.md +114 -0
- package/.claude/commands/BMad/bmad-orchestrator.md +151 -0
- package/.claude/commands/BMad/dev.md +85 -0
- package/.claude/commands/BMad/pm.md +88 -0
- package/.claude/commands/BMad/po.md +83 -0
- package/.claude/commands/BMad/qa.md +91 -0
- package/.claude/commands/BMad/sm.md +69 -0
- package/.claude/commands/BMad/tasks/advanced-elicitation.md +123 -0
- package/.claude/commands/BMad/tasks/apply-qa-fixes.md +154 -0
- package/.claude/commands/BMad/tasks/brownfield-create-epic.md +166 -0
- package/.claude/commands/BMad/tasks/brownfield-create-story.md +153 -0
- package/.claude/commands/BMad/tasks/correct-course.md +76 -0
- package/.claude/commands/BMad/tasks/create-brownfield-story.md +318 -0
- package/.claude/commands/BMad/tasks/create-deep-research-prompt.md +284 -0
- package/.claude/commands/BMad/tasks/create-doc.md +107 -0
- package/.claude/commands/BMad/tasks/create-next-story.md +118 -0
- package/.claude/commands/BMad/tasks/document-project.md +349 -0
- package/.claude/commands/BMad/tasks/execute-checklist.md +92 -0
- package/.claude/commands/BMad/tasks/facilitate-brainstorming-session.md +142 -0
- package/.claude/commands/BMad/tasks/generate-ai-frontend-prompt.md +57 -0
- package/.claude/commands/BMad/tasks/index-docs.md +179 -0
- package/.claude/commands/BMad/tasks/kb-mode-interaction.md +81 -0
- package/.claude/commands/BMad/tasks/nfr-assess.md +349 -0
- package/.claude/commands/BMad/tasks/qa-gate.md +167 -0
- package/.claude/commands/BMad/tasks/review-story.md +320 -0
- package/.claude/commands/BMad/tasks/risk-profile.md +359 -0
- package/.claude/commands/BMad/tasks/shard-doc.md +191 -0
- package/.claude/commands/BMad/tasks/test-design.md +180 -0
- package/.claude/commands/BMad/tasks/trace-requirements.md +270 -0
- package/.claude/commands/BMad/tasks/validate-next-story.md +140 -0
- package/.claude/commands/BMad/ux-expert.md +73 -0
- package/.claude/commands/bmad/bmm/agents/analyst.md +14 -0
- package/.claude/commands/bmad/bmm/agents/architect.md +14 -0
- package/.claude/commands/bmad/bmm/agents/dev.md +14 -0
- package/.claude/commands/bmad/bmm/agents/frame-expert.md +14 -0
- package/.claude/commands/bmad/bmm/agents/pm.md +14 -0
- package/.claude/commands/bmad/bmm/agents/sm.md +14 -0
- package/.claude/commands/bmad/bmm/agents/tea.md +14 -0
- package/.claude/commands/bmad/bmm/agents/tech-writer.md +14 -0
- package/.claude/commands/bmad/bmm/agents/ux-designer.md +14 -0
- package/.claude/commands/bmad/bmm/workflows/architecture.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/brainstorm-project.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/code-review.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/correct-course.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-dataflow.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-diagram.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-epics-and-stories.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-flowchart.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-story.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-ux-design.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/create-wireframe.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/dev-story.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/document-project.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/domain-research.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/epic-tech-context.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/implementation-readiness.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/prd.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/product-brief.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/research.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/retrospective.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/sprint-planning.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/story-context.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/story-done.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/story-ready.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/tech-spec.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/workflow-init.md +13 -0
- package/.claude/commands/bmad/bmm/workflows/workflow-status.md +13 -0
- package/.claude/commands/bmad/core/agents/bmad-master.md +14 -0
- package/.claude/commands/bmad/core/tasks/advanced-elicitation.md +9 -0
- package/.claude/commands/bmad/core/tasks/index-docs.md +9 -0
- package/.claude/commands/bmad/core/tools/shard-doc.md +9 -0
- package/.claude/commands/bmad/core/workflows/brainstorming.md +13 -0
- package/.claude/commands/bmad/core/workflows/party-mode.md +13 -0
- package/.claude/config/background-music-position.txt +26 -0
- package/.claude/config/background-music-volume.txt +1 -0
- package/.claude/config/background-music.cfg +1 -0
- package/.claude/config/tts-verbosity.txt +1 -0
- package/.claude/github-star-reminder.txt +1 -0
- package/.claude/hooks/background-music-manager.sh +1 -1
- package/.claude/hooks/bmad-party-manager.sh +225 -0
- package/.claude/hooks/bmad-voice-manager.sh +116 -4
- package/.claude/piper-voices-dir.txt +1 -0
- package/.mcp.json +30 -0
- package/README.md +166 -13
- package/mcp-server/server.py +53 -41
- package/package.json +6 -2
- package/src/commands/install-mcp.js +151 -90
- package/src/installer.js +531 -298
- package/src/utils/dependency-checker.js +193 -132
package/src/installer.js
CHANGED
|
@@ -117,9 +117,56 @@ function createPageHeaderFooter(pageTitle, currentPage, totalPages, pageOffset =
|
|
|
117
117
|
* @param {Object} options - Options for pagination (yes, continueLabel, pageOffset, totalPages, showPreviousOnFirst)
|
|
118
118
|
* @returns {Promise<void>}
|
|
119
119
|
*/
|
|
120
|
+
/**
|
|
121
|
+
* Build navigation choices for paginated content
|
|
122
|
+
* @param {number} currentPage - Current page index
|
|
123
|
+
* @param {number} totalPages - Total number of pages
|
|
124
|
+
* @param {string} continueLabel - Label for continue button
|
|
125
|
+
* @param {boolean} showPreviousOnFirst - Show previous on first page
|
|
126
|
+
* @returns {Array} Navigation choices
|
|
127
|
+
*/
|
|
128
|
+
function buildNavigationChoices(currentPage, totalPages, continueLabel, showPreviousOnFirst) {
|
|
129
|
+
const choices = [];
|
|
130
|
+
const isLastPage = currentPage >= totalPages - 1;
|
|
131
|
+
|
|
132
|
+
if (!isLastPage) {
|
|
133
|
+
choices.push({ name: chalk.green('Next →'), value: 'next' });
|
|
134
|
+
} else {
|
|
135
|
+
choices.push({ name: chalk.cyan(`✓ ${continueLabel.replace('✓ ', '')}`), value: 'continue' });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (currentPage > 0 || showPreviousOnFirst) {
|
|
139
|
+
choices.push({ name: chalk.magentaBright('← Previous'), value: 'prev' });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return choices;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Handle navigation action in paginated content
|
|
147
|
+
* @param {string} action - Navigation action (prev, next, continue)
|
|
148
|
+
* @param {number} currentPage - Current page index
|
|
149
|
+
* @param {boolean} showPreviousOnFirst - Show previous on first page
|
|
150
|
+
* @returns {Object} Navigation result {newPage, shouldExit, shouldReturn}
|
|
151
|
+
*/
|
|
152
|
+
function handleNavigationAction(action, currentPage, showPreviousOnFirst) {
|
|
153
|
+
if (action === 'prev') {
|
|
154
|
+
if (currentPage > 0) {
|
|
155
|
+
return { newPage: currentPage - 1, shouldExit: false, shouldReturn: false };
|
|
156
|
+
}
|
|
157
|
+
if (showPreviousOnFirst) {
|
|
158
|
+
return { newPage: currentPage, shouldExit: false, shouldReturn: true };
|
|
159
|
+
}
|
|
160
|
+
} else if (action === 'next') {
|
|
161
|
+
return { newPage: currentPage + 1, shouldExit: false, shouldReturn: false };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Continue action - exit loop
|
|
165
|
+
return { newPage: currentPage, shouldExit: true, shouldReturn: false };
|
|
166
|
+
}
|
|
167
|
+
|
|
120
168
|
async function showPaginatedContent(pages, options = {}) {
|
|
121
169
|
if (options.yes || pages.length === 0) {
|
|
122
|
-
// In non-interactive mode or no pages, just display all content
|
|
123
170
|
pages.forEach(page => console.log(page.content));
|
|
124
171
|
return;
|
|
125
172
|
}
|
|
@@ -131,7 +178,6 @@ async function showPaginatedContent(pages, options = {}) {
|
|
|
131
178
|
let currentPage = 0;
|
|
132
179
|
|
|
133
180
|
while (currentPage >= 0 && currentPage < pages.length) {
|
|
134
|
-
// Clear screen and show current page with header/footer
|
|
135
181
|
console.clear();
|
|
136
182
|
|
|
137
183
|
const { header, footer } = createPageHeaderFooter(
|
|
@@ -145,35 +191,12 @@ async function showPaginatedContent(pages, options = {}) {
|
|
|
145
191
|
console.log('');
|
|
146
192
|
console.log(pages[currentPage].content);
|
|
147
193
|
|
|
148
|
-
|
|
149
|
-
let navMessage = '';
|
|
150
|
-
if (currentPage > 0 && currentPage < pages.length - 1) {
|
|
151
|
-
navMessage = `${chalk.cyan('←')} Previous | Next ${chalk.cyan('→')} | ${continueLabel}`;
|
|
152
|
-
} else if (currentPage > 0) {
|
|
153
|
-
navMessage = `${chalk.cyan('←')} Previous | ${continueLabel}`;
|
|
154
|
-
} else if (currentPage < pages.length - 1) {
|
|
155
|
-
navMessage = `Next ${chalk.cyan('→')} | ${continueLabel}`;
|
|
156
|
-
} else {
|
|
157
|
-
navMessage = continueLabel;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Build navigation choices with colors
|
|
161
|
-
const choices = [];
|
|
162
|
-
if (currentPage < pages.length - 1) {
|
|
163
|
-
choices.push({ name: chalk.green('Next →'), value: 'next' });
|
|
164
|
-
} else {
|
|
165
|
-
// Only show "Start Installation" on the last page
|
|
166
|
-
choices.push({ name: chalk.cyan(`✓ ${continueLabel.replace('✓ ', '')}`), value: 'continue' });
|
|
167
|
-
}
|
|
168
|
-
if (currentPage > 0 || showPreviousOnFirst) {
|
|
169
|
-
choices.push({ name: chalk.magentaBright('← Previous'), value: 'prev' });
|
|
170
|
-
}
|
|
194
|
+
const choices = buildNavigationChoices(currentPage, pages.length, continueLabel, showPreviousOnFirst);
|
|
171
195
|
|
|
172
196
|
console.log('');
|
|
173
197
|
console.log(footer);
|
|
174
198
|
console.log('');
|
|
175
199
|
|
|
176
|
-
// Show navigation prompt
|
|
177
200
|
const { action } = await inquirer.prompt([{
|
|
178
201
|
type: 'list',
|
|
179
202
|
name: 'action',
|
|
@@ -182,21 +205,121 @@ async function showPaginatedContent(pages, options = {}) {
|
|
|
182
205
|
default: currentPage < pages.length - 1 ? 'next' : 'continue'
|
|
183
206
|
}]);
|
|
184
207
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
} else if (action === 'next') {
|
|
193
|
-
currentPage++;
|
|
194
|
-
} else {
|
|
195
|
-
// Continue - exit loop
|
|
208
|
+
const navResult = handleNavigationAction(action, currentPage, showPreviousOnFirst);
|
|
209
|
+
|
|
210
|
+
if (navResult.shouldReturn) {
|
|
211
|
+
return 'prev';
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (navResult.shouldExit) {
|
|
196
215
|
console.clear();
|
|
197
216
|
break;
|
|
198
217
|
}
|
|
218
|
+
|
|
219
|
+
currentPage = navResult.newPage;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get page title by page number
|
|
225
|
+
* @param {number} pageNum - Page number (0-4)
|
|
226
|
+
* @returns {string} Page title
|
|
227
|
+
*/
|
|
228
|
+
function getPageTitle(pageNum) {
|
|
229
|
+
const titles = {
|
|
230
|
+
0: 'System Dependencies',
|
|
231
|
+
1: 'TTS Provider Configuration',
|
|
232
|
+
2: 'Voice Selection',
|
|
233
|
+
3: 'Audio Settings',
|
|
234
|
+
4: 'Verbosity Settings'
|
|
235
|
+
};
|
|
236
|
+
return titles[pageNum] || 'Configuration';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Handle Page 0: System Dependencies display
|
|
241
|
+
* @returns {Promise<void>}
|
|
242
|
+
*/
|
|
243
|
+
async function handleSystemDependenciesPage() {
|
|
244
|
+
const { checkDependencies, getInstallCommands } = await import('./utils/dependency-checker.js');
|
|
245
|
+
const depResults = checkDependencies();
|
|
246
|
+
|
|
247
|
+
let depContent = chalk.gray('System dependencies are tools AgentVibes needs to function properly.\n');
|
|
248
|
+
depContent += chalk.gray('Required tools must be installed, optional tools enable extra features.\n\n');
|
|
249
|
+
|
|
250
|
+
// Satisfied dependencies
|
|
251
|
+
if (depResults.core.node?.isCompatible) {
|
|
252
|
+
depContent += chalk.green(`✓ Node.js ${depResults.core.node.version}\n`);
|
|
253
|
+
}
|
|
254
|
+
if (depResults.core.python?.isCompatible) {
|
|
255
|
+
depContent += chalk.green(`✓ Python ${depResults.core.python.version}\n`);
|
|
256
|
+
}
|
|
257
|
+
if (depResults.core.bash?.isModern) {
|
|
258
|
+
depContent += chalk.green(`✓ Bash ${depResults.core.bash.version}\n`);
|
|
259
|
+
}
|
|
260
|
+
if (depResults.optional.curl) {
|
|
261
|
+
depContent += chalk.green('✓ curl\n');
|
|
262
|
+
}
|
|
263
|
+
if (depResults.optional.sox) {
|
|
264
|
+
depContent += chalk.green('✓ sox\n');
|
|
265
|
+
}
|
|
266
|
+
if (depResults.optional.ffmpeg) {
|
|
267
|
+
depContent += chalk.green('✓ ffmpeg\n');
|
|
268
|
+
}
|
|
269
|
+
if (depResults.optional.bc) {
|
|
270
|
+
depContent += chalk.green('✓ bc\n');
|
|
271
|
+
}
|
|
272
|
+
if (depResults.optional.flock) {
|
|
273
|
+
depContent += chalk.green('✓ flock\n');
|
|
274
|
+
}
|
|
275
|
+
if (depResults.optional.pipx) {
|
|
276
|
+
depContent += chalk.green('✓ pipx\n');
|
|
277
|
+
}
|
|
278
|
+
if (depResults.optional.audioPlayer) {
|
|
279
|
+
depContent += chalk.green('✓ audio player (paplay/aplay/mpv)\n');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Missing dependencies
|
|
283
|
+
if (Object.keys(depResults.missing).length > 0) {
|
|
284
|
+
depContent += '\n' + chalk.gray('─'.repeat(50)) + '\n\n';
|
|
285
|
+
depContent += chalk.yellow.bold('Missing (Optional):\n\n');
|
|
286
|
+
|
|
287
|
+
if (depResults.missing.curl) depContent += chalk.yellow('⚠ curl - needed for downloads\n');
|
|
288
|
+
if (depResults.missing.sox) depContent += chalk.yellow('⚠ sox - audio effects\n');
|
|
289
|
+
if (depResults.missing.ffmpeg) depContent += chalk.yellow('⚠ ffmpeg - background music\n');
|
|
290
|
+
if (depResults.missing.bc) depContent += chalk.yellow('⚠ bc - audio calculations\n');
|
|
291
|
+
if (depResults.missing.flock) depContent += chalk.yellow('⚠ flock - TTS queue locking\n');
|
|
292
|
+
if (depResults.missing.pipx) depContent += chalk.yellow('⚠ pipx - Piper TTS installation\n');
|
|
293
|
+
if (depResults.missing.audioPlayer) depContent += chalk.yellow('⚠ audio player - playback\n');
|
|
294
|
+
|
|
295
|
+
depContent += '\n' + chalk.gray('TTS will still work without optional tools');
|
|
296
|
+
|
|
297
|
+
// Add install commands
|
|
298
|
+
const os = await import('os');
|
|
299
|
+
const platform = os.platform();
|
|
300
|
+
const installCmds = getInstallCommands(depResults.missing, platform);
|
|
301
|
+
|
|
302
|
+
if (installCmds.length > 0) {
|
|
303
|
+
depContent += '\n\n' + chalk.gray('─'.repeat(50)) + '\n\n';
|
|
304
|
+
depContent += chalk.cyan.bold('To Install Missing Tools:\n\n');
|
|
305
|
+
|
|
306
|
+
installCmds.forEach(({ label, command }) => {
|
|
307
|
+
depContent += chalk.cyan(`${label}:\n`);
|
|
308
|
+
depContent += chalk.white(` ${command}\n\n`);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
199
311
|
}
|
|
312
|
+
|
|
313
|
+
const depsBoxen = boxen(depContent.trim(), {
|
|
314
|
+
padding: 1,
|
|
315
|
+
margin: 1,
|
|
316
|
+
borderStyle: 'round',
|
|
317
|
+
borderColor: Object.keys(depResults.missing).length > 0 ? 'yellow' : 'green',
|
|
318
|
+
title: chalk.bold('🔧 System Dependencies'),
|
|
319
|
+
titleAlignment: 'center'
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
console.log(depsBoxen);
|
|
200
323
|
}
|
|
201
324
|
|
|
202
325
|
/**
|
|
@@ -208,6 +331,7 @@ async function collectConfiguration(options = {}) {
|
|
|
208
331
|
const config = {
|
|
209
332
|
provider: null,
|
|
210
333
|
piperPath: null,
|
|
334
|
+
defaultVoice: null,
|
|
211
335
|
reverb: 'light',
|
|
212
336
|
backgroundMusic: {
|
|
213
337
|
enabled: true,
|
|
@@ -219,13 +343,14 @@ async function collectConfiguration(options = {}) {
|
|
|
219
343
|
if (options.yes) {
|
|
220
344
|
// Non-interactive mode - use defaults
|
|
221
345
|
config.provider = process.platform === 'darwin' ? 'macos' : 'piper';
|
|
346
|
+
config.defaultVoice = process.platform === 'darwin' ? 'Samantha' : 'en_US-ryan-high';
|
|
222
347
|
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
223
348
|
config.piperPath = path.join(homeDir, '.claude', 'piper-voices');
|
|
224
349
|
return config;
|
|
225
350
|
}
|
|
226
351
|
|
|
227
352
|
let currentPage = 0;
|
|
228
|
-
const sectionPages =
|
|
353
|
+
const sectionPages = 5; // System Dependencies, Provider, Voice Selection, Audio Settings, Verbosity
|
|
229
354
|
const pageOffset = options.pageOffset || 0;
|
|
230
355
|
const totalPages = options.totalPages || sectionPages;
|
|
231
356
|
|
|
@@ -238,96 +363,13 @@ async function collectConfiguration(options = {}) {
|
|
|
238
363
|
console.clear();
|
|
239
364
|
|
|
240
365
|
// Show header
|
|
241
|
-
const pageTitle = currentPage
|
|
242
|
-
currentPage === 1 ? 'TTS Provider Configuration' :
|
|
243
|
-
currentPage === 2 ? 'Audio Settings' :
|
|
244
|
-
'Verbosity Settings';
|
|
366
|
+
const pageTitle = getPageTitle(currentPage);
|
|
245
367
|
const { header, footer } = createPageHeaderFooter(pageTitle, currentPage, totalPages, pageOffset);
|
|
246
368
|
console.log(header);
|
|
247
369
|
console.log('');
|
|
248
370
|
|
|
249
371
|
if (currentPage === 0) {
|
|
250
|
-
|
|
251
|
-
const { checkDependencies } = await import('./utils/dependency-checker.js');
|
|
252
|
-
const depResults = checkDependencies();
|
|
253
|
-
|
|
254
|
-
let depContent = chalk.gray('System dependencies are tools AgentVibes needs to function properly.\n');
|
|
255
|
-
depContent += chalk.gray('Required tools must be installed, optional tools enable extra features.\n\n');
|
|
256
|
-
|
|
257
|
-
// Satisfied dependencies
|
|
258
|
-
if (depResults.core.node?.isCompatible) {
|
|
259
|
-
depContent += chalk.green(`✓ Node.js ${depResults.core.node.version}\n`);
|
|
260
|
-
}
|
|
261
|
-
if (depResults.core.python?.isCompatible) {
|
|
262
|
-
depContent += chalk.green(`✓ Python ${depResults.core.python.version}\n`);
|
|
263
|
-
}
|
|
264
|
-
if (depResults.core.bash?.isModern) {
|
|
265
|
-
depContent += chalk.green(`✓ Bash ${depResults.core.bash.version}\n`);
|
|
266
|
-
}
|
|
267
|
-
if (depResults.optional.curl) {
|
|
268
|
-
depContent += chalk.green('✓ curl\n');
|
|
269
|
-
}
|
|
270
|
-
if (depResults.optional.sox) {
|
|
271
|
-
depContent += chalk.green('✓ sox\n');
|
|
272
|
-
}
|
|
273
|
-
if (depResults.optional.ffmpeg) {
|
|
274
|
-
depContent += chalk.green('✓ ffmpeg\n');
|
|
275
|
-
}
|
|
276
|
-
if (depResults.optional.bc) {
|
|
277
|
-
depContent += chalk.green('✓ bc\n');
|
|
278
|
-
}
|
|
279
|
-
if (depResults.optional.flock) {
|
|
280
|
-
depContent += chalk.green('✓ flock\n');
|
|
281
|
-
}
|
|
282
|
-
if (depResults.optional.pipx) {
|
|
283
|
-
depContent += chalk.green('✓ pipx\n');
|
|
284
|
-
}
|
|
285
|
-
if (depResults.optional.audioPlayer) {
|
|
286
|
-
depContent += chalk.green('✓ audio player (paplay/aplay/mpv)\n');
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Missing dependencies
|
|
290
|
-
if (Object.keys(depResults.missing).length > 0) {
|
|
291
|
-
depContent += '\n' + chalk.gray('─'.repeat(50)) + '\n\n';
|
|
292
|
-
depContent += chalk.yellow.bold('Missing (Optional):\n\n');
|
|
293
|
-
|
|
294
|
-
if (depResults.missing.curl) depContent += chalk.yellow('⚠ curl - needed for downloads\n');
|
|
295
|
-
if (depResults.missing.sox) depContent += chalk.yellow('⚠ sox - audio effects\n');
|
|
296
|
-
if (depResults.missing.ffmpeg) depContent += chalk.yellow('⚠ ffmpeg - background music\n');
|
|
297
|
-
if (depResults.missing.bc) depContent += chalk.yellow('⚠ bc - audio calculations\n');
|
|
298
|
-
if (depResults.missing.flock) depContent += chalk.yellow('⚠ flock - TTS queue locking\n');
|
|
299
|
-
if (depResults.missing.pipx) depContent += chalk.yellow('⚠ pipx - Piper TTS installation\n');
|
|
300
|
-
if (depResults.missing.audioPlayer) depContent += chalk.yellow('⚠ audio player - playback\n');
|
|
301
|
-
|
|
302
|
-
depContent += '\n' + chalk.gray('TTS will still work without optional tools');
|
|
303
|
-
|
|
304
|
-
// Add install commands
|
|
305
|
-
const os = await import('os');
|
|
306
|
-
const { getInstallCommands } = await import('./utils/dependency-checker.js');
|
|
307
|
-
const platform = os.platform();
|
|
308
|
-
const installCmds = getInstallCommands(depResults.missing, platform);
|
|
309
|
-
|
|
310
|
-
if (installCmds.length > 0) {
|
|
311
|
-
depContent += '\n\n' + chalk.gray('─'.repeat(50)) + '\n\n';
|
|
312
|
-
depContent += chalk.cyan.bold('To Install Missing Tools:\n\n');
|
|
313
|
-
|
|
314
|
-
installCmds.forEach(({ label, command }) => {
|
|
315
|
-
depContent += chalk.cyan(`${label}:\n`);
|
|
316
|
-
depContent += chalk.white(` ${command}\n\n`);
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const depsBoxen = boxen(depContent.trim(), {
|
|
322
|
-
padding: 1,
|
|
323
|
-
margin: 1,
|
|
324
|
-
borderStyle: 'round',
|
|
325
|
-
borderColor: Object.keys(depResults.missing).length > 0 ? 'yellow' : 'green',
|
|
326
|
-
title: chalk.bold('🔧 System Dependencies'),
|
|
327
|
-
titleAlignment: 'center'
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
console.log(depsBoxen);
|
|
372
|
+
await handleSystemDependenciesPage();
|
|
331
373
|
} else if (currentPage === 1) {
|
|
332
374
|
// Page 2: TTS Provider & Voice Storage
|
|
333
375
|
|
|
@@ -453,7 +495,86 @@ async function collectConfiguration(options = {}) {
|
|
|
453
495
|
}
|
|
454
496
|
|
|
455
497
|
} else if (currentPage === 2) {
|
|
456
|
-
// Page 3:
|
|
498
|
+
// Page 3: Voice Selection
|
|
499
|
+
console.log(boxen(
|
|
500
|
+
chalk.white('Choose a default voice for your AgentVibes.\n\n') +
|
|
501
|
+
chalk.gray('This will be used when no specific voice is configured.\n') +
|
|
502
|
+
chalk.gray('You can change this anytime with: ') + chalk.cyan('/agent-vibes:voice switch <name>'),
|
|
503
|
+
{
|
|
504
|
+
padding: 1,
|
|
505
|
+
margin: 1,
|
|
506
|
+
borderStyle: 'round',
|
|
507
|
+
borderColor: 'gray',
|
|
508
|
+
title: chalk.bold('🎤 Default Voice'),
|
|
509
|
+
titleAlignment: 'center'
|
|
510
|
+
}
|
|
511
|
+
));
|
|
512
|
+
|
|
513
|
+
if (config.provider === 'piper') {
|
|
514
|
+
// Piper voices - popular selections
|
|
515
|
+
const piperVoices = [
|
|
516
|
+
{ name: chalk.cyan('en_US-ryan-high') + chalk.gray(' (Male, American, High Quality)'), value: 'en_US-ryan-high' },
|
|
517
|
+
{ name: chalk.magenta('en_US-amy-medium') + chalk.gray(' (Female, American, Clear)'), value: 'en_US-amy-medium' },
|
|
518
|
+
{ name: chalk.cyan('en_US-joe-medium') + chalk.gray(' (Male, American, Warm)'), value: 'en_US-joe-medium' },
|
|
519
|
+
{ name: chalk.magenta('en_US-lessac-medium') + chalk.gray(' (Female, American, Professional)'), value: 'en_US-lessac-medium' },
|
|
520
|
+
{ name: chalk.cyan('en_GB-alan-medium') + chalk.gray(' (Male, British, Refined)'), value: 'en_GB-alan-medium' },
|
|
521
|
+
{ name: chalk.magenta('en_GB-southern_english_female-medium') + chalk.gray(' (Female, British)'), value: 'en_GB-southern_english_female-medium' },
|
|
522
|
+
new inquirer.Separator(),
|
|
523
|
+
{ name: chalk.yellow('Skip - I\'ll set this later'), value: '__skip__' },
|
|
524
|
+
{ name: chalk.magentaBright('← Back to Provider Selection'), value: '__back__' }
|
|
525
|
+
];
|
|
526
|
+
|
|
527
|
+
const { selectedVoice } = await inquirer.prompt([{
|
|
528
|
+
type: 'list',
|
|
529
|
+
name: 'selectedVoice',
|
|
530
|
+
message: chalk.yellow('Select your default Piper voice:'),
|
|
531
|
+
choices: piperVoices,
|
|
532
|
+
default: 'en_US-ryan-high',
|
|
533
|
+
pageSize: 12
|
|
534
|
+
}]);
|
|
535
|
+
|
|
536
|
+
if (selectedVoice === '__back__') {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (selectedVoice !== '__skip__') {
|
|
541
|
+
config.defaultVoice = selectedVoice;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
} else if (config.provider === 'macos') {
|
|
545
|
+
// macOS Say voices - popular selections
|
|
546
|
+
const macOSVoices = [
|
|
547
|
+
{ name: chalk.cyan('Samantha') + chalk.gray(' (Female, American)'), value: 'Samantha' },
|
|
548
|
+
{ name: chalk.cyan('Alex') + chalk.gray(' (Male, American)'), value: 'Alex' },
|
|
549
|
+
{ name: chalk.magenta('Flo') + chalk.gray(' (Female, American, Expressive)'), value: 'Flo' },
|
|
550
|
+
{ name: chalk.cyan('Tom') + chalk.gray(' (Male, American)'), value: 'Tom' },
|
|
551
|
+
{ name: chalk.magenta('Karen') + chalk.gray(' (Female, Australian)'), value: 'Karen' },
|
|
552
|
+
{ name: chalk.cyan('Daniel') + chalk.gray(' (Male, British)'), value: 'Daniel' },
|
|
553
|
+
new inquirer.Separator(),
|
|
554
|
+
{ name: chalk.yellow('Skip - I\'ll set this later'), value: '__skip__' },
|
|
555
|
+
{ name: chalk.magentaBright('← Back to Provider Selection'), value: '__back__' }
|
|
556
|
+
];
|
|
557
|
+
|
|
558
|
+
const { selectedVoice } = await inquirer.prompt([{
|
|
559
|
+
type: 'list',
|
|
560
|
+
name: 'selectedVoice',
|
|
561
|
+
message: chalk.yellow('Select your default macOS voice:'),
|
|
562
|
+
choices: macOSVoices,
|
|
563
|
+
default: 'Samantha',
|
|
564
|
+
pageSize: 12
|
|
565
|
+
}]);
|
|
566
|
+
|
|
567
|
+
if (selectedVoice === '__back__') {
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
if (selectedVoice !== '__skip__') {
|
|
572
|
+
config.defaultVoice = selectedVoice;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
} else if (currentPage === 3) {
|
|
577
|
+
// Page 4: Audio Settings (Reverb + Background Music)
|
|
457
578
|
console.log(boxen(
|
|
458
579
|
chalk.white('Configure audio effects and background music for your Agents.\n\n') +
|
|
459
580
|
chalk.yellow('Reverb:\n') +
|
|
@@ -541,8 +662,8 @@ async function collectConfiguration(options = {}) {
|
|
|
541
662
|
config.backgroundMusic.track = selectedTrack;
|
|
542
663
|
}
|
|
543
664
|
|
|
544
|
-
} else if (currentPage ===
|
|
545
|
-
// Page
|
|
665
|
+
} else if (currentPage === 4) {
|
|
666
|
+
// Page 5: Verbosity Settings
|
|
546
667
|
console.log(boxen(
|
|
547
668
|
chalk.white('Choose how much Claude speaks during interactions.\n\n') +
|
|
548
669
|
chalk.yellow('🔊 High:\n') +
|
|
@@ -685,19 +806,20 @@ function showWelcome() {
|
|
|
685
806
|
* Shown during install and update commands
|
|
686
807
|
*/
|
|
687
808
|
function getReleaseInfoBoxen() {
|
|
688
|
-
return chalk.cyan.bold('📦 AgentVibes v2.17.
|
|
809
|
+
return chalk.cyan.bold('📦 AgentVibes v2.17.4 - Code Quality & Maintainability\n\n') +
|
|
689
810
|
chalk.green.bold('🎙️ WHAT\'S NEW:\n\n') +
|
|
690
|
-
chalk.cyan('AgentVibes v2.17.
|
|
691
|
-
chalk.cyan('
|
|
692
|
-
chalk.cyan('
|
|
811
|
+
chalk.cyan('AgentVibes v2.17.4 focuses on code quality and maintainability with extensive\n') +
|
|
812
|
+
chalk.cyan('SonarCloud-driven refactoring across the entire codebase. This release reduces\n') +
|
|
813
|
+
chalk.cyan('cognitive complexity in critical files by up to 90%, making the codebase more\n') +
|
|
814
|
+
chalk.cyan('maintainable and easier to understand.\n\n') +
|
|
693
815
|
chalk.green.bold('✨ KEY HIGHLIGHTS:\n\n') +
|
|
694
|
-
chalk.gray('
|
|
695
|
-
chalk.gray('
|
|
696
|
-
chalk.gray('
|
|
697
|
-
chalk.gray('
|
|
698
|
-
chalk.gray('
|
|
699
|
-
chalk.gray('
|
|
700
|
-
chalk.gray('
|
|
816
|
+
chalk.gray(' ⚙️ Major Code Refactoring - Cognitive complexity reduced by up to 90% across critical files\n') +
|
|
817
|
+
chalk.gray(' 🧪 Comprehensive Testing - 377 new party mode tests added, 225 total tests passing\n') +
|
|
818
|
+
chalk.gray(' 📚 Improved Documentation - New Prerequisites and FAQ sections clarify installation\n') +
|
|
819
|
+
chalk.gray(' 🎭 Conversational Agent Intros - BMAD party mode now uses "Hi! I\'m John, your Product Manager"\n') +
|
|
820
|
+
chalk.gray(' 🔊 Better Audio Balance - Background music reduced 15% for clearer TTS voice\n') +
|
|
821
|
+
chalk.gray(' 🏗️ installer.js: 84 → ~8 complexity (90% reduction)\n') +
|
|
822
|
+
chalk.gray(' 📦 dependency-checker.js: 43 → ~5, 23 → ~8 (88% & 65% reductions)\n\n') +
|
|
701
823
|
chalk.gray('📖 Full Release Notes: RELEASE_NOTES.md\n') +
|
|
702
824
|
chalk.gray('🌐 Website: https://agentvibes.org\n') +
|
|
703
825
|
chalk.gray('📦 Repository: https://github.com/paulpreibisch/AgentVibes\n\n') +
|
|
@@ -1218,6 +1340,103 @@ async function copyCommandFiles(targetDir, spinner) {
|
|
|
1218
1340
|
}
|
|
1219
1341
|
}
|
|
1220
1342
|
|
|
1343
|
+
/**
|
|
1344
|
+
* Check if a file should be included as a hook file
|
|
1345
|
+
* @param {string} file - Filename to check
|
|
1346
|
+
* @param {Object} stat - File stats object
|
|
1347
|
+
* @returns {boolean} True if file should be included
|
|
1348
|
+
*/
|
|
1349
|
+
function shouldIncludeHookFile(file, stat) {
|
|
1350
|
+
return stat.isFile() &&
|
|
1351
|
+
(file.endsWith('.sh') || file === 'hooks.json') &&
|
|
1352
|
+
!file.includes('prepare-release') &&
|
|
1353
|
+
!file.startsWith('.');
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
/**
|
|
1357
|
+
* Filter hook files from directory
|
|
1358
|
+
* @param {string} srcHooksDir - Source hooks directory
|
|
1359
|
+
* @param {Array} allFiles - All files in directory
|
|
1360
|
+
* @returns {Promise<Array>} Filtered hook files
|
|
1361
|
+
*/
|
|
1362
|
+
async function filterHookFiles(srcHooksDir, allFiles) {
|
|
1363
|
+
const hookFiles = [];
|
|
1364
|
+
|
|
1365
|
+
for (const file of allFiles) {
|
|
1366
|
+
const srcPath = path.join(srcHooksDir, file);
|
|
1367
|
+
try {
|
|
1368
|
+
const stat = await fs.stat(srcPath);
|
|
1369
|
+
if (shouldIncludeHookFile(file, stat)) {
|
|
1370
|
+
hookFiles.push(file);
|
|
1371
|
+
}
|
|
1372
|
+
} catch (err) {
|
|
1373
|
+
console.log(chalk.yellow(` ⚠ Could not check ${file}: ${err.message}`));
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
return hookFiles;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* Copy a single hook file and set permissions
|
|
1382
|
+
* @param {string} srcPath - Source file path
|
|
1383
|
+
* @param {string} destPath - Destination file path
|
|
1384
|
+
* @param {string} filename - Name of the file
|
|
1385
|
+
* @returns {Promise<Object>} Result object with success/error info
|
|
1386
|
+
*/
|
|
1387
|
+
async function copyHookFile(srcPath, destPath, filename) {
|
|
1388
|
+
try {
|
|
1389
|
+
await fs.copyFile(srcPath, destPath);
|
|
1390
|
+
|
|
1391
|
+
if (filename.endsWith('.sh')) {
|
|
1392
|
+
await fs.chmod(destPath, 0o750);
|
|
1393
|
+
return { success: true, name: filename, executable: true };
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
return { success: true, name: filename, executable: false };
|
|
1397
|
+
} catch (err) {
|
|
1398
|
+
return { success: false, name: filename, error: err.message };
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
/**
|
|
1403
|
+
* Build boxen content for hook installation results
|
|
1404
|
+
* @param {Array} installedFiles - Successfully installed files
|
|
1405
|
+
* @param {Array} failedFiles - Failed files
|
|
1406
|
+
* @returns {string} Boxen formatted content
|
|
1407
|
+
*/
|
|
1408
|
+
function buildHookInstallationBoxen(installedFiles, failedFiles) {
|
|
1409
|
+
let content = chalk.bold(`${installedFiles.length} TTS Hook Scripts Installed\n\n`);
|
|
1410
|
+
content += chalk.gray('Hook scripts automatically run at key moments during your\n');
|
|
1411
|
+
content += chalk.gray('Claude Code sessions to provide TTS feedback and manage audio.\n\n');
|
|
1412
|
+
|
|
1413
|
+
installedFiles.forEach(file => {
|
|
1414
|
+
content += chalk.green(`✓ ${file.name}`);
|
|
1415
|
+
if (file.executable) {
|
|
1416
|
+
content += chalk.gray(' (executable)');
|
|
1417
|
+
}
|
|
1418
|
+
content += '\n';
|
|
1419
|
+
});
|
|
1420
|
+
|
|
1421
|
+
if (failedFiles.length > 0) {
|
|
1422
|
+
content += '\n' + chalk.gray('─'.repeat(60)) + '\n\n';
|
|
1423
|
+
content += chalk.bold.yellow(`${failedFiles.length} Failed\n\n`);
|
|
1424
|
+
failedFiles.forEach(file => {
|
|
1425
|
+
content += chalk.yellow(`⚠ ${file.name}\n`);
|
|
1426
|
+
content += chalk.dim(` ${file.error}\n`);
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
return boxen(content.trim(), {
|
|
1431
|
+
padding: 1,
|
|
1432
|
+
margin: 1,
|
|
1433
|
+
borderStyle: 'round',
|
|
1434
|
+
borderColor: 'green',
|
|
1435
|
+
title: chalk.bold('🔧 TTS Scripts'),
|
|
1436
|
+
titleAlignment: 'center'
|
|
1437
|
+
});
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1221
1440
|
/**
|
|
1222
1441
|
* Copy hook files to target directory
|
|
1223
1442
|
* @param {string} targetDir - Target installation directory
|
|
@@ -1233,87 +1452,36 @@ async function copyHookFiles(targetDir, spinner) {
|
|
|
1233
1452
|
await fs.mkdir(hooksDir, { recursive: true });
|
|
1234
1453
|
|
|
1235
1454
|
const allHookFiles = await fs.readdir(srcHooksDir);
|
|
1236
|
-
const hookFiles =
|
|
1237
|
-
|
|
1238
|
-
for (const file of allHookFiles) {
|
|
1239
|
-
const srcPath = path.join(srcHooksDir, file);
|
|
1240
|
-
try {
|
|
1241
|
-
const stat = await fs.stat(srcPath);
|
|
1242
|
-
|
|
1243
|
-
if (stat.isFile() &&
|
|
1244
|
-
(file.endsWith('.sh') || file === 'hooks.json') &&
|
|
1245
|
-
!file.includes('prepare-release') &&
|
|
1246
|
-
!file.startsWith('.')) {
|
|
1247
|
-
hookFiles.push(file);
|
|
1248
|
-
}
|
|
1249
|
-
} catch (err) {
|
|
1250
|
-
console.log(chalk.yellow(` ⚠ Could not check ${file}: ${err.message}`));
|
|
1251
|
-
// Continue with other files
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1455
|
+
const hookFiles = await filterHookFiles(srcHooksDir, allHookFiles);
|
|
1254
1456
|
|
|
1255
1457
|
spinner.start(`Installing ${hookFiles.length} TTS scripts...`);
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1458
|
+
|
|
1459
|
+
const installedFiles = [];
|
|
1460
|
+
const failedFiles = [];
|
|
1259
1461
|
|
|
1260
1462
|
for (const file of hookFiles) {
|
|
1261
1463
|
const srcPath = path.join(srcHooksDir, file);
|
|
1262
1464
|
const destPath = path.join(hooksDir, file);
|
|
1263
|
-
|
|
1264
|
-
await fs.copyFile(srcPath, destPath);
|
|
1465
|
+
const result = await copyHookFile(srcPath, destPath, file);
|
|
1265
1466
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
} else {
|
|
1271
|
-
installedFiles.push({ name: file, executable: false });
|
|
1272
|
-
}
|
|
1273
|
-
successCount++;
|
|
1274
|
-
} catch (err) {
|
|
1275
|
-
failedFiles.push({ name: file, error: err.message });
|
|
1467
|
+
if (result.success) {
|
|
1468
|
+
installedFiles.push({ name: result.name, executable: result.executable });
|
|
1469
|
+
} else {
|
|
1470
|
+
failedFiles.push({ name: result.name, error: result.error });
|
|
1276
1471
|
}
|
|
1277
1472
|
}
|
|
1278
1473
|
|
|
1474
|
+
const successCount = installedFiles.length;
|
|
1475
|
+
|
|
1279
1476
|
if (successCount === hookFiles.length) {
|
|
1280
1477
|
spinner.succeed(chalk.green('Installed TTS scripts!\n'));
|
|
1281
1478
|
} else {
|
|
1282
1479
|
spinner.warn(chalk.yellow(`Installed ${successCount}/${hookFiles.length} scripts (some failed)\n`));
|
|
1283
1480
|
}
|
|
1284
1481
|
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
let content = chalk.bold(`${installedFiles.length} TTS Hook Scripts Installed\n\n`);
|
|
1289
|
-
content += chalk.gray('Hook scripts automatically run at key moments during your\n');
|
|
1290
|
-
content += chalk.gray('Claude Code sessions to provide TTS feedback and manage audio.\n\n');
|
|
1291
|
-
installedFiles.forEach(file => {
|
|
1292
|
-
content += chalk.green(`✓ ${file.name}`);
|
|
1293
|
-
if (file.executable) {
|
|
1294
|
-
content += chalk.gray(' (executable)');
|
|
1295
|
-
}
|
|
1296
|
-
content += '\n';
|
|
1297
|
-
});
|
|
1298
|
-
|
|
1299
|
-
if (failedFiles.length > 0) {
|
|
1300
|
-
content += '\n' + chalk.gray('─'.repeat(60)) + '\n\n';
|
|
1301
|
-
content += chalk.bold.yellow(`${failedFiles.length} Failed\n\n`);
|
|
1302
|
-
failedFiles.forEach(file => {
|
|
1303
|
-
content += chalk.yellow(`⚠ ${file.name}\n`);
|
|
1304
|
-
content += chalk.dim(` ${file.error}\n`);
|
|
1305
|
-
});
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
boxenContent = boxen(content.trim(), {
|
|
1309
|
-
padding: 1,
|
|
1310
|
-
margin: 1,
|
|
1311
|
-
borderStyle: 'round',
|
|
1312
|
-
borderColor: 'green',
|
|
1313
|
-
title: chalk.bold('🔧 TTS Scripts'),
|
|
1314
|
-
titleAlignment: 'center'
|
|
1315
|
-
});
|
|
1316
|
-
}
|
|
1482
|
+
const boxenContent = installedFiles.length > 0
|
|
1483
|
+
? buildHookInstallationBoxen(installedFiles, failedFiles)
|
|
1484
|
+
: null;
|
|
1317
1485
|
|
|
1318
1486
|
return { count: successCount, boxen: boxenContent };
|
|
1319
1487
|
} catch (err) {
|
|
@@ -1697,7 +1865,7 @@ async function checkAndInstallPiper(targetDir, options) {
|
|
|
1697
1865
|
const { execSync } = await import('node:child_process');
|
|
1698
1866
|
|
|
1699
1867
|
try {
|
|
1700
|
-
execSync('command -v piper', { stdio: 'ignore' });
|
|
1868
|
+
execSync('command -v piper', { stdio: 'ignore' }); // NOSONAR - Safe: fixed command, no user input
|
|
1701
1869
|
console.log(chalk.green('✅ Piper TTS is already installed\n'));
|
|
1702
1870
|
return;
|
|
1703
1871
|
} catch {
|
|
@@ -2108,36 +2276,31 @@ frame-expert,en_GB-alan-medium
|
|
|
2108
2276
|
* @param {Object} spinner - Ora spinner instance
|
|
2109
2277
|
* @returns {Promise<boolean>} True if migration was performed
|
|
2110
2278
|
*/
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
];
|
|
2119
|
-
|
|
2120
|
-
// Check if any old config exists
|
|
2121
|
-
let hasOldConfig = false;
|
|
2122
|
-
for (const oldPath of oldConfigPaths) {
|
|
2279
|
+
/**
|
|
2280
|
+
* Check if any old config files exist
|
|
2281
|
+
* @param {string[]} paths - Array of paths to check
|
|
2282
|
+
* @returns {Promise<boolean>} True if any old config exists
|
|
2283
|
+
*/
|
|
2284
|
+
async function hasOldConfigFiles(paths) {
|
|
2285
|
+
for (const oldPath of paths) {
|
|
2123
2286
|
try {
|
|
2124
2287
|
await fs.access(oldPath);
|
|
2125
|
-
|
|
2126
|
-
break;
|
|
2288
|
+
return true;
|
|
2127
2289
|
} catch {
|
|
2128
2290
|
// File doesn't exist, continue
|
|
2129
2291
|
}
|
|
2130
2292
|
}
|
|
2293
|
+
return false;
|
|
2294
|
+
}
|
|
2131
2295
|
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2296
|
+
/**
|
|
2297
|
+
* Execute migration script
|
|
2298
|
+
* @param {string} migrationScript - Path to migration script
|
|
2299
|
+
* @param {string} targetDir - Target directory
|
|
2300
|
+
* @param {Object} spinner - Ora spinner instance
|
|
2301
|
+
* @returns {Promise<boolean>} True if migration succeeded
|
|
2302
|
+
*/
|
|
2303
|
+
async function executeMigrationScript(migrationScript, targetDir, spinner) {
|
|
2141
2304
|
try {
|
|
2142
2305
|
await fs.access(migrationScript);
|
|
2143
2306
|
|
|
@@ -2162,6 +2325,27 @@ async function detectAndMigrateOldConfig(targetDir, spinner) {
|
|
|
2162
2325
|
}
|
|
2163
2326
|
}
|
|
2164
2327
|
|
|
2328
|
+
async function detectAndMigrateOldConfig(targetDir, spinner) {
|
|
2329
|
+
const oldConfigPaths = [
|
|
2330
|
+
path.join(targetDir, '.claude', 'config', 'agentvibes.json'),
|
|
2331
|
+
path.join(targetDir, '.claude', 'config', 'bmad-voices.md'),
|
|
2332
|
+
path.join(targetDir, '.claude', 'config', 'bmad-voices-enabled.flag'),
|
|
2333
|
+
path.join(targetDir, '.claude', 'plugins', 'bmad-voices-enabled.flag'),
|
|
2334
|
+
path.join(targetDir, '.claude', 'plugins', 'bmad-party-mode-disabled.flag'),
|
|
2335
|
+
];
|
|
2336
|
+
|
|
2337
|
+
// Check if any old config exists
|
|
2338
|
+
if (!await hasOldConfigFiles(oldConfigPaths)) {
|
|
2339
|
+
return false; // No migration needed
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
spinner.info(chalk.yellow('🔄 Old configuration detected - migrating to .agentvibes/'));
|
|
2343
|
+
|
|
2344
|
+
// Run migration script
|
|
2345
|
+
const migrationScript = path.join(targetDir, '.claude', 'hooks', 'migrate-to-agentvibes.sh');
|
|
2346
|
+
return await executeMigrationScript(migrationScript, targetDir, spinner);
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2165
2349
|
/**
|
|
2166
2350
|
* Handle BMAD integration (detection and TTS injection)
|
|
2167
2351
|
* @param {string} targetDir - Target installation directory
|
|
@@ -2218,7 +2402,7 @@ async function handleBmadIntegration(targetDir) {
|
|
|
2218
2402
|
async function showRecentChanges(sourceDir) {
|
|
2219
2403
|
try {
|
|
2220
2404
|
const { execSync } = await import('node:child_process');
|
|
2221
|
-
const gitLog = execSync(
|
|
2405
|
+
const gitLog = execSync( // NOSONAR - Safe: fixed command with controlled cwd, no user input
|
|
2222
2406
|
'git log --oneline --no-decorate -5',
|
|
2223
2407
|
{ cwd: sourceDir, encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }
|
|
2224
2408
|
).trim();
|
|
@@ -2305,84 +2489,129 @@ async function updatePersonalityFiles(targetDir, srcPersonalitiesDir) {
|
|
|
2305
2489
|
}
|
|
2306
2490
|
|
|
2307
2491
|
/**
|
|
2308
|
-
*
|
|
2492
|
+
* Create a silent spinner for update operations
|
|
2493
|
+
* @returns {Object} Mock spinner object
|
|
2494
|
+
*/
|
|
2495
|
+
function createSilentSpinner() {
|
|
2496
|
+
return { start: () => {}, succeed: () => {}, info: () => {}, fail: () => {} };
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
/**
|
|
2500
|
+
* Update command files
|
|
2309
2501
|
* @param {string} targetDir - Target installation directory
|
|
2310
|
-
* @param {Object}
|
|
2502
|
+
* @param {Object} spinner - Ora spinner instance
|
|
2503
|
+
* @returns {Promise<number>} Number of commands updated
|
|
2311
2504
|
*/
|
|
2312
|
-
async function
|
|
2313
|
-
|
|
2505
|
+
async function updateCommandFiles(targetDir, spinner) {
|
|
2506
|
+
spinner.text = 'Updating commands...';
|
|
2507
|
+
const commandsDir = path.join(targetDir, '.claude', 'commands', 'agent-vibes');
|
|
2508
|
+
const srcCommandsDir = path.join(__dirname, '..', '.claude', 'commands', 'agent-vibes');
|
|
2509
|
+
const commandFiles = await fs.readdir(srcCommandsDir);
|
|
2314
2510
|
|
|
2315
|
-
|
|
2316
|
-
const
|
|
2317
|
-
const
|
|
2511
|
+
for (const file of commandFiles) {
|
|
2512
|
+
const srcPath = path.join(srcCommandsDir, file);
|
|
2513
|
+
const destPath = path.join(commandsDir, file);
|
|
2514
|
+
await fs.copyFile(srcPath, destPath);
|
|
2515
|
+
}
|
|
2318
2516
|
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
const srcCommandsDir = path.join(__dirname, '..', '.claude', 'commands', 'agent-vibes');
|
|
2322
|
-
const commandFiles = await fs.readdir(srcCommandsDir);
|
|
2517
|
+
return commandFiles.length;
|
|
2518
|
+
}
|
|
2323
2519
|
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2520
|
+
/**
|
|
2521
|
+
* Perform all update operations
|
|
2522
|
+
* @param {string} targetDir - Target installation directory
|
|
2523
|
+
* @param {Object} spinner - Ora spinner instance
|
|
2524
|
+
* @returns {Promise<Object>} Update results
|
|
2525
|
+
*/
|
|
2526
|
+
async function performUpdateOperations(targetDir, spinner) {
|
|
2527
|
+
const silentSpinner = createSilentSpinner();
|
|
2330
2528
|
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
console.log(chalk.green(`✓ Updated ${hookResult.count} TTS scripts`));
|
|
2529
|
+
// Update commands
|
|
2530
|
+
const commandCount = await updateCommandFiles(targetDir, spinner);
|
|
2531
|
+
console.log(chalk.green(`\n✓ Updated ${commandCount} commands`));
|
|
2335
2532
|
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
console.log(chalk.green(`✓ Updated ${personalityResult.updated} personalities, added ${personalityResult.new} new`));
|
|
2533
|
+
// Update hooks
|
|
2534
|
+
spinner.text = 'Updating TTS scripts...';
|
|
2535
|
+
const hookResult = await copyHookFiles(targetDir, silentSpinner);
|
|
2536
|
+
console.log(chalk.green(`✓ Updated ${hookResult.count} TTS scripts`));
|
|
2341
2537
|
|
|
2342
|
-
|
|
2538
|
+
// Update personalities
|
|
2539
|
+
spinner.text = 'Updating personality templates...';
|
|
2540
|
+
const srcPersonalitiesDir = path.join(__dirname, '..', '.claude', 'personalities');
|
|
2541
|
+
const personalityResult = await updatePersonalityFiles(targetDir, srcPersonalitiesDir);
|
|
2542
|
+
console.log(chalk.green(`✓ Updated ${personalityResult.updated} personalities, added ${personalityResult.new} new`));
|
|
2343
2543
|
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2544
|
+
// Update plugin files
|
|
2545
|
+
const pluginFileCount = await copyPluginFiles(targetDir, silentSpinner);
|
|
2546
|
+
if (pluginFileCount > 0) {
|
|
2547
|
+
console.log(chalk.green(`✓ Updated ${pluginFileCount} BMAD plugin files`));
|
|
2548
|
+
}
|
|
2349
2549
|
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2550
|
+
// Update BMAD config files
|
|
2551
|
+
const bmadConfigFileCount = await copyBmadConfigFiles(targetDir, silentSpinner);
|
|
2552
|
+
if (bmadConfigFileCount > 0) {
|
|
2553
|
+
console.log(chalk.green(`✓ Updated ${bmadConfigFileCount} BMAD config files`));
|
|
2554
|
+
}
|
|
2355
2555
|
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2556
|
+
// Update background music files
|
|
2557
|
+
const backgroundMusicUpdateResult = await copyBackgroundMusicFiles(targetDir, silentSpinner);
|
|
2558
|
+
if (backgroundMusicUpdateResult.count > 0) {
|
|
2559
|
+
console.log(chalk.green(`✓ Installed ${backgroundMusicUpdateResult.count} background music track${backgroundMusicUpdateResult.count === 1 ? '' : 's'}`));
|
|
2560
|
+
}
|
|
2361
2561
|
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2562
|
+
// Update config files
|
|
2563
|
+
const configFileCount = await copyConfigFiles(targetDir, silentSpinner);
|
|
2564
|
+
if (configFileCount > 0) {
|
|
2565
|
+
console.log(chalk.green(`✓ Installed ${configFileCount} config file${configFileCount === 1 ? '' : 's'}`));
|
|
2566
|
+
}
|
|
2367
2567
|
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2568
|
+
// Update settings.json
|
|
2569
|
+
spinner.text = 'Updating AgentVibes hook configuration...';
|
|
2570
|
+
await configureSessionStartHook(targetDir, silentSpinner);
|
|
2371
2571
|
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2572
|
+
// Detect and migrate old configuration
|
|
2573
|
+
spinner.text = 'Checking for old configuration...';
|
|
2574
|
+
await detectAndMigrateOldConfig(targetDir, spinner);
|
|
2575
|
+
|
|
2576
|
+
return {
|
|
2577
|
+
commandCount,
|
|
2578
|
+
hookCount: hookResult.count,
|
|
2579
|
+
personalityResult,
|
|
2580
|
+
pluginFileCount
|
|
2581
|
+
};
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2584
|
+
/**
|
|
2585
|
+
* Display update summary
|
|
2586
|
+
* @param {Object} results - Update results
|
|
2587
|
+
*/
|
|
2588
|
+
function displayUpdateSummary(results) {
|
|
2589
|
+
console.log(chalk.cyan('📦 Update Summary:'));
|
|
2590
|
+
console.log(chalk.white(` • ${results.commandCount} commands updated`));
|
|
2591
|
+
console.log(chalk.white(` • ${results.hookCount} TTS scripts updated`));
|
|
2592
|
+
console.log(chalk.white(` • ${results.personalityResult.new + results.personalityResult.updated} personality templates (${results.personalityResult.new} new, ${results.personalityResult.updated} updated)`));
|
|
2593
|
+
if (results.pluginFileCount > 0) {
|
|
2594
|
+
console.log(chalk.white(` • ${results.pluginFileCount} BMAD plugin files updated`));
|
|
2595
|
+
}
|
|
2596
|
+
console.log('');
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
/**
|
|
2600
|
+
* Update AgentVibes files in target directory
|
|
2601
|
+
* @param {string} targetDir - Target installation directory
|
|
2602
|
+
* @param {Object} options - Update options
|
|
2603
|
+
*/
|
|
2604
|
+
async function updateAgentVibes(targetDir, options) {
|
|
2605
|
+
const spinner = ora('Updating AgentVibes...').start();
|
|
2606
|
+
|
|
2607
|
+
try {
|
|
2608
|
+
// Perform all update operations
|
|
2609
|
+
const updateResults = await performUpdateOperations(targetDir, spinner);
|
|
2375
2610
|
|
|
2376
2611
|
spinner.succeed(chalk.green.bold('\n✨ Update complete!\n'));
|
|
2377
2612
|
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
console.log(chalk.white(` • ${hookResult.count} TTS scripts updated`));
|
|
2381
|
-
console.log(chalk.white(` • ${personalityResult.new + personalityResult.updated} personality templates (${personalityResult.new} new, ${personalityResult.updated} updated)`));
|
|
2382
|
-
if (pluginFileCount > 0) {
|
|
2383
|
-
console.log(chalk.white(` • ${pluginFileCount} BMAD plugin files updated`));
|
|
2384
|
-
}
|
|
2385
|
-
console.log('');
|
|
2613
|
+
// Display summary
|
|
2614
|
+
displayUpdateSummary(updateResults);
|
|
2386
2615
|
|
|
2387
2616
|
// Show recent changes
|
|
2388
2617
|
await showRecentChanges(path.join(__dirname, '..'));
|
|
@@ -2644,17 +2873,21 @@ async function install(options = {}) {
|
|
|
2644
2873
|
await fs.writeFile(piperConfigPath, piperVoicesPath);
|
|
2645
2874
|
}
|
|
2646
2875
|
|
|
2647
|
-
// Set default voice based on
|
|
2876
|
+
// Set default voice based on user selection or provider defaults
|
|
2648
2877
|
const voiceConfigPath = path.join(claudeDir, 'tts-voice.txt');
|
|
2649
|
-
let defaultVoice;
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2878
|
+
let defaultVoice = userConfig.defaultVoice;
|
|
2879
|
+
|
|
2880
|
+
// Fallback to defaults if voice wasn't selected
|
|
2881
|
+
if (!defaultVoice) {
|
|
2882
|
+
switch (selectedProvider) {
|
|
2883
|
+
case 'piper':
|
|
2884
|
+
defaultVoice = 'en_US-ryan-high';
|
|
2885
|
+
break;
|
|
2886
|
+
case 'macos':
|
|
2887
|
+
default:
|
|
2888
|
+
defaultVoice = 'Samantha';
|
|
2889
|
+
break;
|
|
2890
|
+
}
|
|
2658
2891
|
}
|
|
2659
2892
|
await fs.writeFile(voiceConfigPath, defaultVoice);
|
|
2660
2893
|
|