MCPcopy Index your code
hub / github.com/codeaashu/claude-code / useVoice

Function useVoice

src/hooks/useVoice.ts:199–1144  ·  view source on GitHub ↗
({
  onTranscript,
  onError,
  enabled,
  focusMode,
}: UseVoiceOptions)

Source from the content-addressed store, hash-verified

197}
198
199export function useVoice({
200 onTranscript,
201 onError,
202 enabled,
203 focusMode,
204}: UseVoiceOptions): UseVoiceReturn {
205 const [state, setState] = useState<VoiceState>('idle')
206 const stateRef = useRef<VoiceState>('idle')
207 const connectionRef = useRef<VoiceStreamConnection | null>(null)
208 const accumulatedRef = useRef('')
209 const onTranscriptRef = useRef(onTranscript)
210 const onErrorRef = useRef(onError)
211 const cleanupTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
212 const releaseTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
213 // True once we've seen a second keypress (auto-repeat) while recording.
214 // The OS key repeat delay (~500ms on macOS) means the first keypress is
215 // solo — arming the release timer before auto-repeat starts would cause
216 // a false release.
217 const seenRepeatRef = useRef(false)
218 const repeatFallbackTimerRef = useRef<ReturnType<typeof setTimeout> | null>(
219 null,
220 )
221 // True when the current recording session was started by terminal focus
222 // (not by a keypress). Focus-driven sessions end on blur, not key release.
223 const focusTriggeredRef = useRef(false)
224 // Timer that tears down the session after prolonged silence in focus mode.
225 const focusSilenceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(
226 null,
227 )
228 // Set when a focus-mode session is torn down due to silence. Prevents
229 // the focus effect from immediately restarting. Cleared on blur so the
230 // next focus cycle re-arms recording.
231 const silenceTimedOutRef = useRef(false)
232 const recordingStartRef = useRef(0)
233 // Incremented on each startRecordingSession(). Callbacks capture their
234 // generation and bail if a newer session has started — prevents a zombie
235 // slow-connecting WS from an abandoned session from overwriting
236 // connectionRef mid-way through the next session.
237 const sessionGenRef = useRef(0)
238 // True if the early-error retry fired during this session.
239 // Tracked for the tengu_voice_recording_completed analytics event.
240 const retryUsedRef = useRef(false)
241 // Full audio captured this session, kept for silent-drop replay. ~1% of
242 // sessions get a sticky-broken CE pod that accepts audio but returns zero
243 // transcripts (anthropics/anthropic#287008 session-sticky variant); when
244 // finalize() resolves via no_data_timeout with hadAudioSignal=true, we
245 // replay the buffer on a fresh WS once. Bounded: 32KB/s × ~60s max ≈ 2MB.
246 const fullAudioRef = useRef<Buffer[]>([])
247 const silentDropRetriedRef = useRef(false)
248 // Bumped when the early-error retry is scheduled. Captured per
249 // attemptConnect — onError swallows stale-gen events (conn 1's
250 // trailing close-error) but surfaces current-gen ones (conn 2's
251 // genuine failure). Same shape as sessionGenRef, one level down.
252 const attemptGenRef = useRef(0)
253 // Running total of chars flushed in focus mode (each final transcript is
254 // injected immediately and accumulatedRef reset). Added to transcriptChars
255 // in the completed event so focus-mode sessions don't false-positive as
256 // silent-drops (transcriptChars=0 despite successful transcription).

Callers

nothing calls this directly

Calls 11

useTerminalFocusFunction · 0.85
useSetVoiceStateFunction · 0.85
logForDebuggingFunction · 0.85
finishRecordingFunction · 0.85
beginFocusRecordingFunction · 0.85
isVoiceStreamAvailableFunction · 0.85
startRecordingSessionFunction · 0.85
armFocusSilenceTimerFunction · 0.85
updateStateFunction · 0.85
cleanupFunction · 0.70
closeMethod · 0.45

Tested by

no test coverage detected