voice-interface-builder
Expert in building voice interfaces, speech recognition, and text-to-speech systems
What this skill does
# Voice Interface Builder Skill
I help you build voice-enabled interfaces using the Web Speech API and modern voice technologies.
## What I Do
**Speech Recognition:**
- Voice commands and controls
- Voice-to-text input
- Continuous dictation
- Command detection
**Text-to-Speech:**
- Reading content aloud
- Voice feedback and notifications
- Multilingual speech output
- Voice selection and customization
**Voice UI:**
- Voice-first interfaces
- Accessibility features
- Hands-free controls
- Voice search
## Web Speech API Basics
### Speech Recognition
```typescript
// hooks/useSpeechRecognition.ts
'use client'
import { useState, useEffect, useRef } from 'react'
interface SpeechRecognitionOptions {
continuous?: boolean
language?: string
onResult?: (transcript: string) => void
onError?: (error: string) => void
}
export function useSpeechRecognition({
continuous = false,
language = 'en-US',
onResult,
onError
}: SpeechRecognitionOptions = {}) {
const [isListening, setIsListening] = useState(false)
const [transcript, setTranscript] = useState('')
const recognitionRef = useRef<SpeechRecognition | null>(null)
useEffect(() => {
if (typeof window === 'undefined') return
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
if (!SpeechRecognition) {
console.warn('Speech recognition not supported')
return
}
const recognition = new SpeechRecognition()
recognition.continuous = continuous
recognition.lang = language
recognition.interimResults = true
recognition.onresult = event => {
const transcript = Array.from(event.results)
.map(result => result[0].transcript)
.join('')
setTranscript(transcript)
onResult?.(transcript)
}
recognition.onerror = event => {
console.error('Speech recognition error:', event.error)
onError?.(event.error)
setIsListening(false)
}
recognition.onend = () => {
setIsListening(false)
}
recognitionRef.current = recognition
return () => {
recognition.stop()
}
}, [continuous, language, onResult, onError])
const start = () => {
if (recognitionRef.current && !isListening) {
recognitionRef.current.start()
setIsListening(true)
}
}
const stop = () => {
if (recognitionRef.current && isListening) {
recognitionRef.current.stop()
setIsListening(false)
}
}
return { isListening, transcript, start, stop }
}
```
**Usage:**
```typescript
'use client'
import { useSpeechRecognition } from '@/hooks/useSpeechRecognition'
export function VoiceInput() {
const { isListening, transcript, start, stop } = useSpeechRecognition({
onResult: (text) => console.log('Recognized:', text)
})
return (
<div>
<button onClick={isListening ? stop : start}>
{isListening ? '๐ด Stop' : '๐ค Start Listening'}
</button>
<p>{transcript}</p>
</div>
)
}
```
---
### Text-to-Speech
```typescript
// hooks/useSpeechSynthesis.ts
'use client'
import { useState, useEffect } from 'react'
export function useSpeechSynthesis() {
const [voices, setVoices] = useState<SpeechSynthesisVoice[]>([])
const [speaking, setSpeaking] = useState(false)
useEffect(() => {
if (typeof window === 'undefined') return
const loadVoices = () => {
const availableVoices = window.speechSynthesis.getVoices()
setVoices(availableVoices)
}
loadVoices()
window.speechSynthesis.onvoiceschanged = loadVoices
}, [])
const speak = (
text: string,
options?: {
voice?: SpeechSynthesisVoice
rate?: number
pitch?: number
volume?: number
}
) => {
if (typeof window === 'undefined') return
const utterance = new SpeechSynthesisUtterance(text)
if (options?.voice) utterance.voice = options.voice
if (options?.rate) utterance.rate = options.rate // 0.1 - 10
if (options?.pitch) utterance.pitch = options.pitch // 0 - 2
if (options?.volume) utterance.volume = options.volume // 0 - 1
utterance.onstart = () => setSpeaking(true)
utterance.onend = () => setSpeaking(false)
utterance.onerror = () => setSpeaking(false)
window.speechSynthesis.speak(utterance)
}
const cancel = () => {
if (typeof window !== 'undefined') {
window.speechSynthesis.cancel()
setSpeaking(false)
}
}
return { speak, cancel, speaking, voices }
}
```
**Usage:**
```typescript
'use client'
import { useSpeechSynthesis } from '@/hooks/useSpeechSynthesis'
export function TextToSpeech() {
const { speak, cancel, speaking, voices } = useSpeechSynthesis()
const [text, setText] = useState('Hello, how can I help you today?')
return (
<div>
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
rows={4}
/>
<button
onClick={() => speak(text)}
disabled={speaking}
>
{speaking ? 'Speaking...' : '๐ Speak'}
</button>
<button onClick={cancel} disabled={!speaking}>
โน๏ธ Stop
</button>
<select onChange={(e) => {
const voice = voices.find(v => v.name === e.target.value)
if (voice) speak(text, { voice })
}}>
{voices.map((voice) => (
<option key={voice.name} value={voice.name}>
{voice.name} ({voice.lang})
</option>
))}
</select>
</div>
)
}
```
---
## Voice Commands
### Command Detection
```typescript
'use client'
import { useSpeechRecognition } from '@/hooks/useSpeechRecognition'
import { useEffect } from 'react'
interface Command {
phrase: string | RegExp
action: () => void
}
export function VoiceCommands({ commands }: { commands: Command[] }) {
const { isListening, transcript, start, stop } = useSpeechRecognition({
continuous: true
})
useEffect(() => {
if (!transcript) return
const lowerTranscript = transcript.toLowerCase()
for (const command of commands) {
if (typeof command.phrase === 'string') {
if (lowerTranscript.includes(command.phrase.toLowerCase())) {
command.action()
}
} else {
if (command.phrase.test(lowerTranscript)) {
command.action()
}
}
}
}, [transcript, commands])
return (
<button onClick={isListening ? stop : start}>
{isListening ? '๐ด Stop Voice Commands' : '๐ค Start Voice Commands'}
</button>
)
}
```
**Usage:**
```typescript
export function App() {
const commands = [
{
phrase: 'go home',
action: () => router.push('/')
},
{
phrase: 'open menu',
action: () => setMenuOpen(true)
},
{
phrase: 'search for',
action: () => {
// Extract search query after "search for"
}
}
]
return <VoiceCommands commands={commands} />
}
```
---
## Voice Search
```typescript
'use client'
import { useSpeechRecognition } from '@/hooks/useSpeechRecognition'
import { useState } from 'react'
export function VoiceSearch() {
const [query, setQuery] = useState('')
const { isListening, start, stop } = useSpeechRecognition({
onResult: (transcript) => {
setQuery(transcript)
}
})
const handleSearch = () => {
if (query) {
// Perform search with query
console.log('Searching for:', query)
}
}
return (
<div className="flex gap-2">
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search or speak..."
className="flex-1 px-4 py-2 border rounded"
/>
<button
onClick={isListening ? stop : start}
className={`px-4 py-2 rounded ${
isListening ? 'bg-red-600 text-white' : 'bg-gray-200'
}`}
>
{isListening ? '๐ด' : '๐ค'}
</button>
<button
onClick={handleSearch}
className="px-4 py-2 bg-blue-600 text-white rounded"
>
Related in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.