agentvibes 2.0.17 → 2.0.20
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-core/agent-teams/team-all.yaml +15 -0
- package/.bmad-core/agent-teams/team-fullstack.yaml +19 -0
- package/.bmad-core/agent-teams/team-ide-minimal.yaml +11 -0
- package/.bmad-core/agent-teams/team-no-ui.yaml +14 -0
- package/.bmad-core/agents/analyst.md +84 -0
- package/.bmad-core/agents/architect.md +85 -0
- package/.bmad-core/agents/bmad-master.md +110 -0
- package/.bmad-core/agents/bmad-orchestrator.md +147 -0
- package/.bmad-core/agents/dev.md +81 -0
- package/.bmad-core/agents/pm.md +84 -0
- package/.bmad-core/agents/po.md +79 -0
- package/.bmad-core/agents/qa.md +87 -0
- package/.bmad-core/agents/sm.md +65 -0
- package/.bmad-core/agents/ux-expert.md +69 -0
- package/.bmad-core/checklists/architect-checklist.md +440 -0
- package/.bmad-core/checklists/change-checklist.md +184 -0
- package/.bmad-core/checklists/pm-checklist.md +372 -0
- package/.bmad-core/checklists/po-master-checklist.md +434 -0
- package/.bmad-core/checklists/story-dod-checklist.md +96 -0
- package/.bmad-core/checklists/story-draft-checklist.md +155 -0
- package/.bmad-core/core-config.yaml +22 -0
- package/.bmad-core/data/bmad-kb.md +809 -0
- package/.bmad-core/data/brainstorming-techniques.md +38 -0
- package/.bmad-core/data/elicitation-methods.md +156 -0
- package/.bmad-core/data/technical-preferences.md +5 -0
- package/.bmad-core/data/test-levels-framework.md +148 -0
- package/.bmad-core/data/test-priorities-matrix.md +174 -0
- package/.bmad-core/enhanced-ide-development-workflow.md +248 -0
- package/.bmad-core/install-manifest.yaml +230 -0
- package/.bmad-core/tasks/advanced-elicitation.md +119 -0
- package/.bmad-core/tasks/apply-qa-fixes.md +150 -0
- package/.bmad-core/tasks/brownfield-create-epic.md +162 -0
- package/.bmad-core/tasks/brownfield-create-story.md +149 -0
- package/.bmad-core/tasks/correct-course.md +72 -0
- package/.bmad-core/tasks/create-brownfield-story.md +314 -0
- package/.bmad-core/tasks/create-deep-research-prompt.md +280 -0
- package/.bmad-core/tasks/create-doc.md +103 -0
- package/.bmad-core/tasks/create-next-story.md +114 -0
- package/.bmad-core/tasks/document-project.md +345 -0
- package/.bmad-core/tasks/execute-checklist.md +88 -0
- package/.bmad-core/tasks/facilitate-brainstorming-session.md +138 -0
- package/.bmad-core/tasks/generate-ai-frontend-prompt.md +53 -0
- package/.bmad-core/tasks/index-docs.md +175 -0
- package/.bmad-core/tasks/kb-mode-interaction.md +77 -0
- package/.bmad-core/tasks/nfr-assess.md +345 -0
- package/.bmad-core/tasks/qa-gate.md +163 -0
- package/.bmad-core/tasks/review-story.md +316 -0
- package/.bmad-core/tasks/risk-profile.md +355 -0
- package/.bmad-core/tasks/shard-doc.md +187 -0
- package/.bmad-core/tasks/test-design.md +176 -0
- package/.bmad-core/tasks/trace-requirements.md +266 -0
- package/.bmad-core/tasks/validate-next-story.md +136 -0
- package/.bmad-core/templates/architecture-tmpl.yaml +651 -0
- package/.bmad-core/templates/brainstorming-output-tmpl.yaml +156 -0
- package/.bmad-core/templates/brownfield-architecture-tmpl.yaml +477 -0
- package/.bmad-core/templates/brownfield-prd-tmpl.yaml +281 -0
- package/.bmad-core/templates/competitor-analysis-tmpl.yaml +307 -0
- package/.bmad-core/templates/front-end-architecture-tmpl.yaml +219 -0
- package/.bmad-core/templates/front-end-spec-tmpl.yaml +350 -0
- package/.bmad-core/templates/fullstack-architecture-tmpl.yaml +824 -0
- package/.bmad-core/templates/market-research-tmpl.yaml +253 -0
- package/.bmad-core/templates/prd-tmpl.yaml +203 -0
- package/.bmad-core/templates/project-brief-tmpl.yaml +222 -0
- package/.bmad-core/templates/qa-gate-tmpl.yaml +103 -0
- package/.bmad-core/templates/story-tmpl.yaml +138 -0
- package/.bmad-core/user-guide.md +577 -0
- package/.bmad-core/utils/bmad-doc-template.md +327 -0
- package/.bmad-core/utils/workflow-management.md +71 -0
- package/.bmad-core/workflows/brownfield-fullstack.yaml +298 -0
- package/.bmad-core/workflows/brownfield-service.yaml +188 -0
- package/.bmad-core/workflows/brownfield-ui.yaml +198 -0
- package/.bmad-core/workflows/greenfield-fullstack.yaml +241 -0
- package/.bmad-core/workflows/greenfield-service.yaml +207 -0
- package/.bmad-core/workflows/greenfield-ui.yaml +236 -0
- package/.bmad-core/working-in-the-brownfield.md +606 -0
- package/.claude/activation-instructions +54 -0
- package/.claude/commands/BMad/agents/analyst.md +88 -0
- package/.claude/commands/BMad/agents/architect.md +89 -0
- package/.claude/commands/BMad/agents/bmad-master.md +114 -0
- package/.claude/commands/BMad/agents/bmad-orchestrator.md +151 -0
- package/.claude/commands/BMad/agents/dev.md +85 -0
- package/.claude/commands/BMad/agents/pm.md +88 -0
- package/.claude/commands/BMad/agents/po.md +83 -0
- package/.claude/commands/BMad/agents/qa.md +91 -0
- package/.claude/commands/BMad/agents/sm.md +69 -0
- package/.claude/commands/BMad/agents/ux-expert.md +73 -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/github-star-reminder.txt +1 -1
- package/.claude/hooks/bmad-tts-injector.sh +33 -4
- package/.claude/hooks/bmad-voice-manager.sh +146 -10
- package/.claude/hooks/check-output-style.sh +60 -8
- package/.claude/hooks/github-star-reminder.sh +67 -7
- package/.claude/hooks/language-manager.sh +34 -2
- package/.claude/hooks/learn-manager.sh +34 -2
- package/.claude/hooks/personality-manager.sh +34 -1
- package/.claude/hooks/piper-download-voices.sh +131 -9
- package/.claude/hooks/piper-installer.sh +38 -4
- package/.claude/hooks/piper-voice-manager.sh +102 -36
- package/.claude/hooks/play-tts-elevenlabs.sh +32 -6
- package/.claude/hooks/play-tts-piper.sh +79 -18
- package/.claude/hooks/play-tts.sh +34 -3
- package/.claude/hooks/provider-commands.sh +36 -1
- package/.claude/hooks/provider-manager.sh +32 -1
- package/.claude/hooks/replay-target-audio.sh +34 -3
- package/.claude/hooks/sentiment-manager.sh +39 -1
- package/.claude/hooks/speed-manager.sh +36 -2
- package/.claude/hooks/voice-manager.sh +85 -6
- package/.claude/hooks/voices-config.sh +39 -2
- package/README.md +77 -137
- package/RELEASE_NOTES.md +269 -0
- package/RELEASE_NOTES_v2.0.17_DRAFT.md +650 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760744118.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760748535.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760748676.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760750748.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760750947.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760752718.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760752907.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753017.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753045.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753241.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753315.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753382.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753408.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753426.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753446.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753541.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753553.mp3 +0 -0
- package/agentvibes.org/.claude/audio/tts-padded-1760753577.mp3 +0 -0
- package/agentvibes.org/.claude/commands/agent-vibes/add.md +21 -0
- package/agentvibes.org/.claude/commands/agent-vibes/agent-vibes.md +68 -0
- package/agentvibes.org/.claude/commands/agent-vibes/bmad.md +196 -0
- package/agentvibes.org/.claude/commands/agent-vibes/commands.json +77 -0
- package/agentvibes.org/.claude/commands/agent-vibes/get.md +9 -0
- package/agentvibes.org/.claude/commands/agent-vibes/language.md +23 -0
- package/agentvibes.org/.claude/commands/agent-vibes/learn.md +67 -0
- package/agentvibes.org/.claude/commands/agent-vibes/list.md +13 -0
- package/agentvibes.org/.claude/commands/agent-vibes/personality.md +79 -0
- package/agentvibes.org/.claude/commands/agent-vibes/preview.md +17 -0
- package/agentvibes.org/.claude/commands/agent-vibes/provider.md +54 -0
- package/agentvibes.org/.claude/commands/agent-vibes/replay-target.md +14 -0
- package/agentvibes.org/.claude/commands/agent-vibes/replay.md +19 -0
- package/agentvibes.org/.claude/commands/agent-vibes/sample.md +12 -0
- package/agentvibes.org/.claude/commands/agent-vibes/sentiment.md +52 -0
- package/agentvibes.org/.claude/commands/agent-vibes/set-language.md +47 -0
- package/agentvibes.org/.claude/commands/agent-vibes/set-pretext.md +65 -0
- package/agentvibes.org/.claude/commands/agent-vibes/set-speed.md +41 -0
- package/agentvibes.org/.claude/commands/agent-vibes/switch.md +53 -0
- package/agentvibes.org/.claude/commands/agent-vibes/target-voice.md +26 -0
- package/agentvibes.org/.claude/commands/agent-vibes/target.md +30 -0
- package/agentvibes.org/.claude/commands/agent-vibes/update.md +20 -0
- package/agentvibes.org/.claude/commands/agent-vibes/version.md +10 -0
- package/agentvibes.org/.claude/commands/agent-vibes/whoami.md +7 -0
- package/agentvibes.org/.claude/hooks/bmad-tts-injector.sh +386 -0
- package/agentvibes.org/.claude/hooks/bmad-voice-manager.sh +375 -0
- package/agentvibes.org/.claude/hooks/check-output-style.sh +60 -0
- package/agentvibes.org/.claude/hooks/github-star-reminder.sh +94 -0
- package/agentvibes.org/.claude/hooks/language-manager.sh +360 -0
- package/agentvibes.org/.claude/hooks/learn-manager.sh +443 -0
- package/agentvibes.org/.claude/hooks/personality-manager.sh +324 -0
- package/agentvibes.org/.claude/hooks/piper-download-voices.sh +133 -0
- package/agentvibes.org/.claude/hooks/piper-installer.sh +144 -0
- package/agentvibes.org/.claude/hooks/piper-voice-manager.sh +227 -0
- package/agentvibes.org/.claude/hooks/play-tts-elevenlabs.sh +376 -0
- package/agentvibes.org/.claude/hooks/play-tts-piper.sh +281 -0
- package/agentvibes.org/.claude/hooks/play-tts.sh +69 -0
- package/agentvibes.org/.claude/hooks/provider-commands.sh +505 -0
- package/agentvibes.org/.claude/hooks/provider-manager.sh +248 -0
- package/agentvibes.org/.claude/hooks/replay-target-audio.sh +64 -0
- package/agentvibes.org/.claude/hooks/sentiment-manager.sh +163 -0
- package/agentvibes.org/.claude/hooks/speed-manager.sh +259 -0
- package/agentvibes.org/.claude/hooks/voice-manager.sh +477 -0
- package/agentvibes.org/.claude/hooks/voices-config.sh +33 -0
- package/agentvibes.org/.claude/journal/2025-10-07.html +373 -0
- package/agentvibes.org/.claude/journal/index.html +91 -0
- package/agentvibes.org/.claude/output-styles/agent-vibes.md +203 -0
- package/agentvibes.org/.claude/personalities/angry.md +17 -0
- package/agentvibes.org/.claude/personalities/annoying.md +17 -0
- package/agentvibes.org/.claude/personalities/crass.md +17 -0
- package/agentvibes.org/.claude/personalities/dramatic.md +17 -0
- package/agentvibes.org/.claude/personalities/dry-humor.md +53 -0
- package/agentvibes.org/.claude/personalities/flirty.md +23 -0
- package/agentvibes.org/.claude/personalities/funny.md +17 -0
- package/agentvibes.org/.claude/personalities/grandpa.md +35 -0
- package/agentvibes.org/.claude/personalities/millennial.md +17 -0
- package/agentvibes.org/.claude/personalities/moody.md +17 -0
- package/agentvibes.org/.claude/personalities/normal.md +19 -0
- package/agentvibes.org/.claude/personalities/pirate.md +17 -0
- package/agentvibes.org/.claude/personalities/poetic.md +17 -0
- package/agentvibes.org/.claude/personalities/professional.md +17 -0
- package/agentvibes.org/.claude/personalities/robot.md +17 -0
- package/agentvibes.org/.claude/personalities/sarcastic.md +41 -0
- package/agentvibes.org/.claude/personalities/sassy.md +17 -0
- package/agentvibes.org/.claude/personalities/surfer-dude.md +17 -0
- package/agentvibes.org/.claude/personalities/zen.md +17 -0
- package/agentvibes.org/.claude/piper-voices-dir.txt +1 -0
- package/agentvibes.org/.claude/plugins/bmad-voices.md +42 -0
- package/agentvibes.org/.claude/tts-provider.txt +1 -0
- package/agentvibes.org/.mcp-minimal.json +60 -0
- package/agentvibes.org/CHANGELOG.md +56 -0
- package/agentvibes.org/README.md +93 -0
- package/agentvibes.org/app/(auth)/layout.tsx +15 -0
- package/agentvibes.org/app/(auth)/reset-password/page.tsx +45 -0
- package/agentvibes.org/app/(auth)/signin/page.tsx +82 -0
- package/agentvibes.org/app/(auth)/signup/page.tsx +104 -0
- package/agentvibes.org/app/(default)/blog/[slug]/page.tsx +128 -0
- package/agentvibes.org/app/(default)/blog/page.tsx +95 -0
- package/agentvibes.org/app/(default)/layout.tsx +31 -0
- package/agentvibes.org/app/(default)/page.tsx +20 -0
- package/agentvibes.org/app/api/hello/route.ts +3 -0
- package/agentvibes.org/app/css/additional-styles/theme.css +82 -0
- package/agentvibes.org/app/css/additional-styles/utility-patterns.css +55 -0
- package/agentvibes.org/app/css/style.css +100 -0
- package/agentvibes.org/app/layout.tsx +63 -0
- package/agentvibes.org/components/code-block.tsx +27 -0
- package/agentvibes.org/components/cta.tsx +58 -0
- package/agentvibes.org/components/features.tsx +256 -0
- package/agentvibes.org/components/hero-home.tsx +133 -0
- package/agentvibes.org/components/mdx-components.tsx +128 -0
- package/agentvibes.org/components/modal-video.tsx +137 -0
- package/agentvibes.org/components/page-illustration.tsx +55 -0
- package/agentvibes.org/components/spotlight.tsx +77 -0
- package/agentvibes.org/components/testimonials.tsx +282 -0
- package/agentvibes.org/components/ui/footer.tsx +82 -0
- package/agentvibes.org/components/ui/header.tsx +68 -0
- package/agentvibes.org/components/ui/logo.tsx +10 -0
- package/agentvibes.org/components/workflows.tsx +176 -0
- package/agentvibes.org/content/blog/discovering-new-piper-voices.mdx +253 -0
- package/agentvibes.org/content/blog/getting-started-agentvibes.mdx +228 -0
- package/agentvibes.org/content/blog/introducing-agentvibes-v2.mdx +250 -0
- package/agentvibes.org/content/blog/language-learning-with-agentvibes.mdx +142 -0
- package/agentvibes.org/content/blog/voice-personalities-guide.mdx +119 -0
- package/agentvibes.org/lib/blog.ts +73 -0
- package/agentvibes.org/next.config.js +6 -0
- package/agentvibes.org/package-lock.json +4285 -0
- package/agentvibes.org/package.json +40 -0
- package/agentvibes.org/pnpm-lock.yaml +1141 -0
- package/agentvibes.org/postcss.config.js +5 -0
- package/agentvibes.org/public/audio/02-sarcastic.mp3 +0 -0
- package/agentvibes.org/public/audio/03-angry.mp3 +0 -0
- package/agentvibes.org/public/audio/04-grandpa.mp3 +0 -0
- package/agentvibes.org/public/audio/05-sarcastic-example2.mp3 +0 -0
- package/agentvibes.org/public/audio/french-rachel.mp3 +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_0_Cori_Samuel.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_10_Steve_C.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_11_Owlivia.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_12_Paul_Hampton.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_13_Jennifer_Dorr.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_14_Emily_Cripps.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_15_Martin_Clifton.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_1_Kara_Shallenberg.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_2_Kristin_Hughes.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_3_Maria_Kasper.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_4_Mike_Pelton.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_5_Mark_Nelson.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_6_Michael_Scherer.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_7_James_K_White.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_8_Rose_Ibex.wav +0 -0
- package/agentvibes.org/public/audio/piper-voices/speaker_9_progressingamerica.wav +0 -0
- package/agentvibes.org/public/audio/spanish-antoni.mp3 +0 -0
- package/agentvibes.org/public/favicon.ico +0 -0
- package/agentvibes.org/public/fonts/nacelle-italic.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-regular.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-semibold.woff2 +0 -0
- package/agentvibes.org/public/fonts/nacelle-semibolditalic.woff2 +0 -0
- package/agentvibes.org/public/images/blurred-shape-gray.svg +1 -0
- package/agentvibes.org/public/images/blurred-shape.svg +1 -0
- package/agentvibes.org/public/images/client-logo-01.svg +1 -0
- package/agentvibes.org/public/images/client-logo-02.svg +1 -0
- package/agentvibes.org/public/images/client-logo-03.svg +1 -0
- package/agentvibes.org/public/images/client-logo-04.svg +1 -0
- package/agentvibes.org/public/images/client-logo-05.svg +1 -0
- package/agentvibes.org/public/images/client-logo-06.svg +1 -0
- package/agentvibes.org/public/images/client-logo-07.svg +1 -0
- package/agentvibes.org/public/images/client-logo-08.svg +1 -0
- package/agentvibes.org/public/images/client-logo-09.svg +1 -0
- package/agentvibes.org/public/images/features.png +0 -0
- package/agentvibes.org/public/images/footer-illustration.svg +1 -0
- package/agentvibes.org/public/images/hero-image-01.jpg +0 -0
- package/agentvibes.org/public/images/logo.svg +1 -0
- package/agentvibes.org/public/images/page-illustration.svg +1 -0
- package/agentvibes.org/public/images/secondary-illustration.svg +1 -0
- package/agentvibes.org/public/images/testimonial-01.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-02.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-03.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-04.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-05.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-06.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-07.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-08.jpg +0 -0
- package/agentvibes.org/public/images/testimonial-09.jpg +0 -0
- package/agentvibes.org/public/images/workflow-01.png +0 -0
- package/agentvibes.org/public/images/workflow-02.png +0 -0
- package/agentvibes.org/public/images/workflow-03.png +0 -0
- package/agentvibes.org/public/videos/video.mp4 +0 -0
- package/agentvibes.org/tsconfig.json +28 -0
- package/agentvibes.org/utils/useMasonry.tsx +67 -0
- package/agentvibes.org/utils/useMousePosition.tsx +27 -0
- package/docs/ai-optimized-documentation-standards.md +78 -4
- package/docs/bryce-beattie-voice-licensing.md +131 -0
- package/docs/commands.md +21 -1
- package/docs/mcp-setup.md +1 -6
- package/github-star-reminder.txt +1 -0
- package/linkedin/vibe-coding-and-pulseaudio.md +121 -0
- package/mcp-server/WINDOWS_SETUP.md +182 -199
- package/mcp-server/docs/elevenlabs-setup.md +213 -0
- package/mcp-server/docs/troubleshooting-audio.md +316 -0
- package/mcp-server/server.py +38 -4
- package/mcp-server/test_server.py +38 -3
- package/package.json +1 -1
- package/scripts/audio-tunnel.config +17 -0
- package/test/helpers/test-helper.bash +31 -4
- package/test/unit/personality-manager.bats +22 -6
- package/test/unit/play-tts.bats +21 -3
- package/test/unit/provider-manager.bats +508 -0
- package/test/unit/speed-manager.bats +436 -0
- package/test/unit/voice-manager.bats +4 -1
- package/.claude/piper-voices/en_US-lessac-medium.onnx +0 -0
- package/.claude/piper-voices/en_US-lessac-medium.onnx.json +0 -493
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export default function HeroHome() {
|
|
2
|
+
return (
|
|
3
|
+
<section>
|
|
4
|
+
<div className="mx-auto max-w-6xl px-4 sm:px-6">
|
|
5
|
+
{/* Hero content */}
|
|
6
|
+
<div className="py-12 md:py-20">
|
|
7
|
+
{/* Section header */}
|
|
8
|
+
<div className="pb-12 text-center md:pb-20">
|
|
9
|
+
<h1
|
|
10
|
+
className="animate-[gradient_6s_linear_infinite] bg-[linear-gradient(to_right,var(--color-gray-200),var(--color-indigo-200),var(--color-gray-50),var(--color-indigo-300),var(--color-gray-200))] bg-[length:200%_auto] bg-clip-text pb-5 font-nacelle text-4xl font-semibold text-transparent md:text-5xl"
|
|
11
|
+
data-aos="fade-up"
|
|
12
|
+
>
|
|
13
|
+
🎤 Bring Your Claude Code Sessions to Life
|
|
14
|
+
</h1>
|
|
15
|
+
<div className="mx-auto max-w-3xl">
|
|
16
|
+
<p
|
|
17
|
+
className="mb-8 text-xl text-[--color-agent-magenta]"
|
|
18
|
+
data-aos="fade-up"
|
|
19
|
+
data-aos-delay={200}
|
|
20
|
+
>
|
|
21
|
+
Professional text-to-speech narration for Claude Code with 150+ AI voices,
|
|
22
|
+
multiple provider options, and support for 30+ languages.
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
{/* Audio Samples */}
|
|
26
|
+
<div className="mb-8 mt-5 rounded-2xl border-2 border-purple-500 p-8" data-aos="fade-up" data-aos-delay={300}>
|
|
27
|
+
<h3 className="mb-6 text-center text-2xl font-semibold text-[--color-agent-cyan]">
|
|
28
|
+
Finally, your Agents can Talk back!
|
|
29
|
+
</h3>
|
|
30
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
31
|
+
<div className="flex flex-col items-center">
|
|
32
|
+
<span className="mb-2 text-sm text-gray-400">Sarcastic</span>
|
|
33
|
+
<audio controls className="w-48">
|
|
34
|
+
<source src="/audio/02-sarcastic.mp3" type="audio/mpeg" />
|
|
35
|
+
</audio>
|
|
36
|
+
</div>
|
|
37
|
+
<div className="flex flex-col items-center">
|
|
38
|
+
<span className="mb-2 text-sm text-gray-400">Angry</span>
|
|
39
|
+
<audio controls className="w-48">
|
|
40
|
+
<source src="/audio/03-angry.mp3" type="audio/mpeg" />
|
|
41
|
+
</audio>
|
|
42
|
+
</div>
|
|
43
|
+
<div className="flex flex-col items-center">
|
|
44
|
+
<span className="mb-2 text-sm text-gray-400">Grandpa</span>
|
|
45
|
+
<audio controls className="w-48">
|
|
46
|
+
<source src="/audio/04-grandpa.mp3" type="audio/mpeg" />
|
|
47
|
+
</audio>
|
|
48
|
+
</div>
|
|
49
|
+
<div className="flex flex-col items-center">
|
|
50
|
+
<span className="mb-2 text-sm text-gray-400">Spanish (Antoni)</span>
|
|
51
|
+
<audio controls className="w-48">
|
|
52
|
+
<source src="/audio/spanish-antoni.mp3" type="audio/mpeg" />
|
|
53
|
+
</audio>
|
|
54
|
+
</div>
|
|
55
|
+
<div className="flex flex-col items-center">
|
|
56
|
+
<span className="mb-2 text-sm text-gray-400">French (Rachel)</span>
|
|
57
|
+
<audio controls className="w-48">
|
|
58
|
+
<source src="/audio/french-rachel.mp3" type="audio/mpeg" />
|
|
59
|
+
</audio>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
{/* Badges */}
|
|
65
|
+
<div className="flex flex-wrap items-center justify-center gap-3 mb-8" data-aos="fade-up" data-aos-delay={350}>
|
|
66
|
+
<a
|
|
67
|
+
href="https://www.npmjs.com/package/agentvibes"
|
|
68
|
+
target="_blank"
|
|
69
|
+
rel="noopener noreferrer"
|
|
70
|
+
className="transition-opacity hover:opacity-80"
|
|
71
|
+
>
|
|
72
|
+
<img src="https://badge.fury.io/js/agentvibes.svg" alt="npm version" className="h-5 w-auto" />
|
|
73
|
+
</a>
|
|
74
|
+
<a
|
|
75
|
+
href="https://github.com/paulpreibisch/AgentVibes/actions/workflows/test.yml"
|
|
76
|
+
target="_blank"
|
|
77
|
+
rel="noopener noreferrer"
|
|
78
|
+
className="transition-opacity hover:opacity-80"
|
|
79
|
+
>
|
|
80
|
+
<img src="https://github.com/paulpreibisch/AgentVibes/actions/workflows/test.yml/badge.svg" alt="Test Suite" className="h-5 w-auto" />
|
|
81
|
+
</a>
|
|
82
|
+
<a
|
|
83
|
+
href="https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml"
|
|
84
|
+
target="_blank"
|
|
85
|
+
rel="noopener noreferrer"
|
|
86
|
+
className="transition-opacity hover:opacity-80"
|
|
87
|
+
>
|
|
88
|
+
<img src="https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml/badge.svg" alt="Publish" className="h-5 w-auto" />
|
|
89
|
+
</a>
|
|
90
|
+
<a
|
|
91
|
+
href="https://opensource.org/licenses/Apache-2.0"
|
|
92
|
+
target="_blank"
|
|
93
|
+
rel="noopener noreferrer"
|
|
94
|
+
className="transition-opacity hover:opacity-80"
|
|
95
|
+
>
|
|
96
|
+
<img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License" className="h-5 w-auto" />
|
|
97
|
+
</a>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div className="mx-auto max-w-xs sm:flex sm:max-w-none sm:justify-center">
|
|
101
|
+
<div data-aos="fade-up" data-aos-delay={400}>
|
|
102
|
+
<a
|
|
103
|
+
className="btn group mb-4 w-full bg-linear-to-t from-indigo-600 to-indigo-500 bg-[length:100%_100%] bg-[bottom] text-white shadow-[inset_0px_1px_0px_0px_--theme(--color-white/.16)] hover:bg-[length:100%_150%] sm:mb-0 sm:w-auto"
|
|
104
|
+
href="https://github.com/paulpreibisch/AgentVibes"
|
|
105
|
+
target="_blank"
|
|
106
|
+
rel="noopener noreferrer"
|
|
107
|
+
>
|
|
108
|
+
<span className="relative inline-flex items-center">
|
|
109
|
+
Download on GitHub
|
|
110
|
+
<span className="ml-1 tracking-normal text-white/50 transition-transform group-hover:translate-x-0.5">
|
|
111
|
+
->
|
|
112
|
+
</span>
|
|
113
|
+
</span>
|
|
114
|
+
</a>
|
|
115
|
+
</div>
|
|
116
|
+
<div data-aos="fade-up" data-aos-delay={600}>
|
|
117
|
+
<a
|
|
118
|
+
className="btn relative w-full bg-linear-to-b from-gray-800 to-gray-800/60 bg-[length:100%_100%] bg-[bottom] text-gray-300 before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:border before:border-transparent before:[background:linear-gradient(to_right,var(--color-gray-800),var(--color-gray-700),var(--color-gray-800))_border-box] before:[mask-composite:exclude_!important] before:[mask:linear-gradient(white_0_0)_padding-box,_linear-gradient(white_0_0)] hover:bg-[length:100%_150%] sm:ml-4 sm:w-auto"
|
|
119
|
+
href="https://github.com/paulpreibisch/AgentVibes/releases/tag/v2.0.0"
|
|
120
|
+
target="_blank"
|
|
121
|
+
rel="noopener noreferrer"
|
|
122
|
+
>
|
|
123
|
+
View v2.0.0 Release
|
|
124
|
+
</a>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</section>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { CodeBlock } from './code-block';
|
|
2
|
+
|
|
3
|
+
export const MDXComponents = {
|
|
4
|
+
// Custom pre block (wraps code blocks)
|
|
5
|
+
pre: ({ children, ...props }: any) => {
|
|
6
|
+
// Extract the code element from pre
|
|
7
|
+
const codeChild = children?.props ? children : children?.type === 'code' ? children : null;
|
|
8
|
+
|
|
9
|
+
if (codeChild?.props?.className) {
|
|
10
|
+
const match = /language-(\w+)/.exec(codeChild.props.className || '');
|
|
11
|
+
const language = match ? match[1] : 'text';
|
|
12
|
+
const codeContent = String(codeChild.props.children || '').replace(/\n$/, '');
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<CodeBlock language={language}>
|
|
16
|
+
{codeContent}
|
|
17
|
+
</CodeBlock>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Fallback for pre without code
|
|
22
|
+
return <pre {...props}>{children}</pre>;
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// Custom inline code component
|
|
26
|
+
code: ({ className, children, ...props }: any) => {
|
|
27
|
+
// Only render inline code (code blocks are handled by pre above)
|
|
28
|
+
if (!className) {
|
|
29
|
+
return (
|
|
30
|
+
<code
|
|
31
|
+
className="rounded bg-gray-800 px-2 py-1 text-sm text-indigo-300 before:content-none after:content-none"
|
|
32
|
+
{...props}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</code>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// This is part of a code block, just return children
|
|
40
|
+
return <code {...props}>{children}</code>;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Custom heading components with anchors
|
|
44
|
+
h1: ({ children, ...props }: any) => (
|
|
45
|
+
<h1
|
|
46
|
+
className="mb-6 mt-8 font-nacelle text-4xl font-bold text-gray-100"
|
|
47
|
+
{...props}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
</h1>
|
|
51
|
+
),
|
|
52
|
+
|
|
53
|
+
h2: ({ children, ...props }: any) => (
|
|
54
|
+
<h2
|
|
55
|
+
className="mb-4 mt-8 font-nacelle text-3xl font-semibold text-gray-100"
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
{children}
|
|
59
|
+
</h2>
|
|
60
|
+
),
|
|
61
|
+
|
|
62
|
+
h3: ({ children, ...props }: any) => (
|
|
63
|
+
<h3
|
|
64
|
+
className="mb-3 mt-6 font-nacelle text-2xl font-semibold text-gray-100"
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
</h3>
|
|
69
|
+
),
|
|
70
|
+
|
|
71
|
+
// Custom paragraph
|
|
72
|
+
p: ({ children, ...props }: any) => (
|
|
73
|
+
<p className="mb-4 leading-7 text-gray-300" {...props}>
|
|
74
|
+
{children}
|
|
75
|
+
</p>
|
|
76
|
+
),
|
|
77
|
+
|
|
78
|
+
// Custom links
|
|
79
|
+
a: ({ children, ...props }: any) => (
|
|
80
|
+
<a
|
|
81
|
+
className="text-indigo-400 no-underline transition-colors hover:text-indigo-300"
|
|
82
|
+
{...props}
|
|
83
|
+
>
|
|
84
|
+
{children}
|
|
85
|
+
</a>
|
|
86
|
+
),
|
|
87
|
+
|
|
88
|
+
// Custom lists
|
|
89
|
+
ul: ({ children, ...props }: any) => (
|
|
90
|
+
<ul className="mb-4 list-disc space-y-2 pl-6 text-gray-300" {...props}>
|
|
91
|
+
{children}
|
|
92
|
+
</ul>
|
|
93
|
+
),
|
|
94
|
+
|
|
95
|
+
ol: ({ children, ...props }: any) => (
|
|
96
|
+
<ol className="mb-4 list-decimal space-y-2 pl-6 text-gray-300" {...props}>
|
|
97
|
+
{children}
|
|
98
|
+
</ol>
|
|
99
|
+
),
|
|
100
|
+
|
|
101
|
+
li: ({ children, ...props }: any) => (
|
|
102
|
+
<li className="text-gray-300" {...props}>
|
|
103
|
+
{children}
|
|
104
|
+
</li>
|
|
105
|
+
),
|
|
106
|
+
|
|
107
|
+
// Custom blockquote
|
|
108
|
+
blockquote: ({ children, ...props }: any) => (
|
|
109
|
+
<blockquote
|
|
110
|
+
className="my-4 border-l-4 border-indigo-500 bg-gray-800/50 py-3 pl-4 pr-4 italic text-gray-300"
|
|
111
|
+
{...props}
|
|
112
|
+
>
|
|
113
|
+
{children}
|
|
114
|
+
</blockquote>
|
|
115
|
+
),
|
|
116
|
+
|
|
117
|
+
// Custom strong/bold
|
|
118
|
+
strong: ({ children, ...props }: any) => (
|
|
119
|
+
<strong className="font-semibold text-gray-200" {...props}>
|
|
120
|
+
{children}
|
|
121
|
+
</strong>
|
|
122
|
+
),
|
|
123
|
+
|
|
124
|
+
// Custom horizontal rule
|
|
125
|
+
hr: (props: any) => (
|
|
126
|
+
<hr className="my-8 border-gray-800" {...props} />
|
|
127
|
+
),
|
|
128
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState, useRef } from "react";
|
|
4
|
+
import type { StaticImageData } from "next/image";
|
|
5
|
+
import { Dialog, DialogBackdrop, DialogPanel } from "@headlessui/react";
|
|
6
|
+
import Image from "next/image";
|
|
7
|
+
import SecondaryIllustration from "@/public/images/secondary-illustration.svg";
|
|
8
|
+
|
|
9
|
+
interface ModalVideoProps {
|
|
10
|
+
thumb: StaticImageData;
|
|
11
|
+
thumbWidth: number;
|
|
12
|
+
thumbHeight: number;
|
|
13
|
+
thumbAlt: string;
|
|
14
|
+
video: string;
|
|
15
|
+
videoWidth: number;
|
|
16
|
+
videoHeight: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default function ModalVideo({
|
|
20
|
+
thumb,
|
|
21
|
+
thumbWidth,
|
|
22
|
+
thumbHeight,
|
|
23
|
+
thumbAlt,
|
|
24
|
+
video,
|
|
25
|
+
videoWidth,
|
|
26
|
+
videoHeight,
|
|
27
|
+
}: ModalVideoProps) {
|
|
28
|
+
const [modalOpen, setModalOpen] = useState<boolean>(false);
|
|
29
|
+
const videoRef = useRef<HTMLVideoElement>(null);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="relative">
|
|
33
|
+
{/* Secondary illustration */}
|
|
34
|
+
<div
|
|
35
|
+
className="pointer-events-none absolute bottom-8 left-1/2 -z-10 -ml-28 -translate-x-1/2 translate-y-1/2"
|
|
36
|
+
aria-hidden="true"
|
|
37
|
+
>
|
|
38
|
+
<Image
|
|
39
|
+
className="md:max-w-none"
|
|
40
|
+
src={SecondaryIllustration}
|
|
41
|
+
width={1165}
|
|
42
|
+
height={1012}
|
|
43
|
+
alt="Secondary illustration"
|
|
44
|
+
/>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
{/* Video thumbnail */}
|
|
48
|
+
<button
|
|
49
|
+
className="group relative flex items-center justify-center rounded-2xl focus:outline-hidden focus-visible:ring-3 focus-visible:ring-indigo-200"
|
|
50
|
+
onClick={() => {
|
|
51
|
+
setModalOpen(true);
|
|
52
|
+
}}
|
|
53
|
+
aria-label="Watch the video"
|
|
54
|
+
data-aos="fade-up"
|
|
55
|
+
data-aos-delay={200}
|
|
56
|
+
>
|
|
57
|
+
<figure className="relative overflow-hidden rounded-2xl before:absolute before:inset-0 before:-z-10 before:bg-linear-to-br before:from-gray-900 before:via-indigo-500/20 before:to-gray-900">
|
|
58
|
+
<Image
|
|
59
|
+
className="opacity-50 grayscale"
|
|
60
|
+
src={thumb}
|
|
61
|
+
width={thumbWidth}
|
|
62
|
+
height={thumbHeight}
|
|
63
|
+
priority
|
|
64
|
+
alt={thumbAlt}
|
|
65
|
+
/>
|
|
66
|
+
</figure>
|
|
67
|
+
{/* Play icon */}
|
|
68
|
+
<span className="pointer-events-none absolute p-2.5 before:absolute before:inset-0 before:rounded-full before:bg-gray-950 before:duration-300 group-hover:before:scale-110">
|
|
69
|
+
<span className="relative flex items-center gap-3">
|
|
70
|
+
<svg
|
|
71
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
72
|
+
width={20}
|
|
73
|
+
height={20}
|
|
74
|
+
fill="none"
|
|
75
|
+
>
|
|
76
|
+
<path
|
|
77
|
+
fill="url(#pla)"
|
|
78
|
+
fillRule="evenodd"
|
|
79
|
+
d="M10 20c5.523 0 10-4.477 10-10S15.523 0 10 0 0 4.477 0 10s4.477 10 10 10Zm3.5-10-5-3.5v7l5-3.5Z"
|
|
80
|
+
clipRule="evenodd"
|
|
81
|
+
/>
|
|
82
|
+
<defs>
|
|
83
|
+
<linearGradient
|
|
84
|
+
id="pla"
|
|
85
|
+
x1={10}
|
|
86
|
+
x2={10}
|
|
87
|
+
y1={0}
|
|
88
|
+
y2={20}
|
|
89
|
+
gradientUnits="userSpaceOnUse"
|
|
90
|
+
>
|
|
91
|
+
<stop stopColor="#6366F1" />
|
|
92
|
+
<stop offset={1} stopColor="#6366F1" stopOpacity=".72" />
|
|
93
|
+
</linearGradient>
|
|
94
|
+
</defs>
|
|
95
|
+
</svg>
|
|
96
|
+
<span className="text-sm font-medium leading-tight text-gray-300">
|
|
97
|
+
Watch Demo
|
|
98
|
+
<span className="text-gray-600"> - </span>
|
|
99
|
+
3:47
|
|
100
|
+
</span>
|
|
101
|
+
</span>
|
|
102
|
+
</span>
|
|
103
|
+
</button>
|
|
104
|
+
{/* End: Video thumbnail */}
|
|
105
|
+
|
|
106
|
+
<Dialog
|
|
107
|
+
initialFocus={videoRef}
|
|
108
|
+
open={modalOpen}
|
|
109
|
+
onClose={() => setModalOpen(false)}
|
|
110
|
+
>
|
|
111
|
+
<DialogBackdrop
|
|
112
|
+
transition
|
|
113
|
+
className="fixed inset-0 z-99999 bg-black/70 transition-opacity duration-300 ease-out data-closed:opacity-0"
|
|
114
|
+
/>
|
|
115
|
+
<div className="fixed inset-0 z-99999 flex px-4 py-6 sm:px-6">
|
|
116
|
+
<div className="mx-auto flex h-full max-w-6xl items-center">
|
|
117
|
+
<DialogPanel
|
|
118
|
+
transition
|
|
119
|
+
className="aspect-video max-h-full w-full overflow-hidden rounded-2xl bg-black shadow-2xl duration-300 ease-out data-closed:scale-95 data-closed:opacity-0"
|
|
120
|
+
>
|
|
121
|
+
<video
|
|
122
|
+
ref={videoRef}
|
|
123
|
+
width={videoWidth}
|
|
124
|
+
height={videoHeight}
|
|
125
|
+
loop
|
|
126
|
+
controls
|
|
127
|
+
>
|
|
128
|
+
<source src={video} type="video/mp4" />
|
|
129
|
+
Your browser does not support the video tag.
|
|
130
|
+
</video>
|
|
131
|
+
</DialogPanel>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</Dialog>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import Image from "next/image";
|
|
2
|
+
import Illustration from "@/public/images/page-illustration.svg";
|
|
3
|
+
import BlurredShapeGray from "@/public/images/blurred-shape-gray.svg";
|
|
4
|
+
import BlurredShape from "@/public/images/blurred-shape.svg";
|
|
5
|
+
|
|
6
|
+
export default function PageIllustration({
|
|
7
|
+
multiple = false,
|
|
8
|
+
}: {
|
|
9
|
+
multiple?: boolean;
|
|
10
|
+
}) {
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
<div
|
|
14
|
+
className="pointer-events-none absolute left-1/2 top-0 -z-10 -translate-x-1/4"
|
|
15
|
+
aria-hidden="true"
|
|
16
|
+
>
|
|
17
|
+
<Image
|
|
18
|
+
className="max-w-none"
|
|
19
|
+
src={Illustration}
|
|
20
|
+
width={846}
|
|
21
|
+
height={594}
|
|
22
|
+
alt="Page illustration"
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
25
|
+
{multiple && (
|
|
26
|
+
<>
|
|
27
|
+
<div
|
|
28
|
+
className="pointer-events-none absolute left-1/2 top-[400px] -z-10 -mt-20 -translate-x-full opacity-50"
|
|
29
|
+
aria-hidden="true"
|
|
30
|
+
>
|
|
31
|
+
<Image
|
|
32
|
+
className="max-w-none"
|
|
33
|
+
src={BlurredShapeGray}
|
|
34
|
+
width={760}
|
|
35
|
+
height={668}
|
|
36
|
+
alt="Blurred shape"
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
39
|
+
<div
|
|
40
|
+
className="pointer-events-none absolute left-1/2 top-[440px] -z-10 -translate-x-1/3"
|
|
41
|
+
aria-hidden="true"
|
|
42
|
+
>
|
|
43
|
+
<Image
|
|
44
|
+
className="max-w-none"
|
|
45
|
+
src={BlurredShape}
|
|
46
|
+
width={760}
|
|
47
|
+
height={668}
|
|
48
|
+
alt="Blurred shape"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
</>
|
|
52
|
+
)}
|
|
53
|
+
</>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import React, { useRef, useState, useEffect } from "react";
|
|
4
|
+
import useMousePosition from "@/utils/useMousePosition";
|
|
5
|
+
|
|
6
|
+
type SpotlightProps = {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function Spotlight({
|
|
12
|
+
children,
|
|
13
|
+
className = "",
|
|
14
|
+
}: SpotlightProps) {
|
|
15
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
16
|
+
const mousePosition = useMousePosition();
|
|
17
|
+
const mouse = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
|
|
18
|
+
const containerSize = useRef<{ w: number; h: number }>({ w: 0, h: 0 });
|
|
19
|
+
const [boxes, setBoxes] = useState<Array<HTMLElement>>([]);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
containerRef.current &&
|
|
23
|
+
setBoxes(
|
|
24
|
+
Array.from(containerRef.current.children).map(
|
|
25
|
+
(el) => el as HTMLElement,
|
|
26
|
+
),
|
|
27
|
+
);
|
|
28
|
+
}, []);
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
initContainer();
|
|
32
|
+
window.addEventListener("resize", initContainer);
|
|
33
|
+
|
|
34
|
+
return () => {
|
|
35
|
+
window.removeEventListener("resize", initContainer);
|
|
36
|
+
};
|
|
37
|
+
}, [boxes]);
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
onMouseMove();
|
|
41
|
+
}, [mousePosition]);
|
|
42
|
+
|
|
43
|
+
const initContainer = () => {
|
|
44
|
+
if (containerRef.current) {
|
|
45
|
+
containerSize.current.w = containerRef.current.offsetWidth;
|
|
46
|
+
containerSize.current.h = containerRef.current.offsetHeight;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const onMouseMove = () => {
|
|
51
|
+
if (containerRef.current) {
|
|
52
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
53
|
+
const { w, h } = containerSize.current;
|
|
54
|
+
const x = mousePosition.x - rect.left;
|
|
55
|
+
const y = mousePosition.y - rect.top;
|
|
56
|
+
const inside = x < w && x > 0 && y < h && y > 0;
|
|
57
|
+
if (inside) {
|
|
58
|
+
mouse.current.x = x;
|
|
59
|
+
mouse.current.y = y;
|
|
60
|
+
boxes.forEach((box) => {
|
|
61
|
+
const boxX =
|
|
62
|
+
-(box.getBoundingClientRect().left - rect.left) + mouse.current.x;
|
|
63
|
+
const boxY =
|
|
64
|
+
-(box.getBoundingClientRect().top - rect.top) + mouse.current.y;
|
|
65
|
+
box.style.setProperty("--mouse-x", `${boxX}px`);
|
|
66
|
+
box.style.setProperty("--mouse-y", `${boxY}px`);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div className={className} ref={containerRef}>
|
|
74
|
+
{children}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|