anthropics / anthropics/claude-code

Voice mode: capture doesn't re-acquire the input device on default-device or topology changes — Bluetooth connect/disconnect silently kills dictation until restart

Abierto
#88,890 0 comentarios 0 reacciones 0 asignados Ver en GitHub
area:tui bug platform:macos
Lenguaje dominante
Python
Estrellas
145k
Forks
23.1k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

## Environment

- Claude Code 2.1.239, macOS (Darwin 25.3.0), iTerm2
- Mics: Shure MV7+ (USB), AirPods Pro (Bluetooth)
- Voice mode: tap (`/voice tap`); hold mode behaves the same

## Summary

Voice mode resolves the audio input device once (at process start, or first
capture) and never re-acquires it. Two distinct failure classes follow, both
reproduced and isolated with OS-level capture verified healthy each time:

1. **Default-input change is ignored.** Started a session while AirPods were
the system default input, then switched the default to the USB mic in
System Settings. Voice mode kept recording from the old device. Toggling
`/voice` off/on does not rebind; only restarting the CLI does.
2. **Device-topology change wedges capture entirely.** With the correct mic
already the default and working, disconnecting the AirPods (removing
them) killed voice capture — even though the *pinned default device never
changed*. The AirPods leaving reshuffles the Core Audio device graph, the
stale stream dies, and voice mode delivers silence until the CLI is
restarted. Reconnecting Bluetooth devices does the same. In practice every
AirPods connect/disconnect during a session costs a restart.

## Why it looks like a user problem (and why it isn't)

The failure is silent: no error is surfaced at tap time (eventually "Voice
input is failing repeatedly and has been paused"). During each incident we
verified the OS side independently:

- `SwitchAudioSource -t input -c` confirmed the correct default input.
- `AVCaptureDevice.authorizationStatus(for: .audio)` returned `authorized`
for the hosting terminal.
- `ffmpeg -f avfoundation -i ":" -t 4 -af volumedetect` captured
healthy live audio (mean approx. -28 dB, peaks approx. -10 dB) from the exact device
voice mode should be using — at the same moment voice mode produced
nothing.

A fresh `claude` process picked the mic up correctly every time, which
isolates the defect to the running process's device binding.

## Expected behavior

Standard macOS capture hygiene: subscribe to the default-input-device-changed
property (`kAudioHardwarePropertyDefaultInputDevice`) and to configuration-
change notifications (`AVAudioEngineConfigurationChange` or equivalent), and
rebuild/re-acquire the input on either. Most capture apps (Zoom, QuickTime)
survive AirPods churn transparently.

## Suggested behavior if a full fix is deferred

Even without live rebinding, detecting a dead/invalidated stream and surfacing
"input device changed — voice needs a restart" (or auto-rebinding on the next
tap) would convert a silent failure into an actionable one.

## Related

- #36041 (input-device selection feature request) — complementary: a device
picker doesn't help if the binding to the picked device goes stale.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Start from the /voice tap entry point and locate the voice-capture implementation that binds the input device. Reproduce a default-input switch and an AirPods connect/disconnect while checking whether the stream becomes invalid or silent. Done means capture re-acquires the current input or surfaces the documented actionable failure instead of requiring a CLI restart.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
macos, python
Área
audio-video-rtc, cli, operating-systems
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Activo
Claridad
Bastante claro
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.