MCPcopy
hub / github.com/codeaashu/claude-code / checkRecordingAvailability

Function checkRecordingAvailability

src/services/voice.ts:259–328  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

257}
258
259export async function checkRecordingAvailability(): Promise<RecordingAvailability> {
260 // Remote environments have no local microphone
261 if (isRunningOnHomespace() || isEnvTruthy(process.env.CLAUDE_CODE_REMOTE)) {
262 return {
263 available: false,
264 reason:
265 'Voice mode requires microphone access, but no audio device is available in this environment.\n\nTo use voice mode, run Claude Code locally instead.',
266 }
267 }
268
269 // Native audio module (cpal) handles everything on macOS, Linux, and Windows
270 const napi = await loadAudioNapi()
271 if (napi.isNativeAudioAvailable()) {
272 return { available: true, reason: null }
273 }
274
275 // Windows has no supported fallback
276 if (process.platform === 'win32') {
277 return {
278 available: false,
279 reason:
280 'Voice recording requires the native audio module, which could not be loaded.',
281 }
282 }
283
284 const wslNoAudioReason =
285 'Voice mode could not access an audio device in WSL.\n\nWSL2 with WSLg (Windows 11) provides audio via PulseAudio — if you are on Windows 10 or WSL1, run Claude Code in native Windows instead.'
286
287 // On Linux (including WSL), probe arecord. hasCommand() is insufficient:
288 // the binary can exist while the device open() fails (WSL1, Win10-WSL2,
289 // headless Linux). WSL2+WSLg (Win11 default) works via PulseAudio RDP
290 // pipes — cpal fails (no /proc/asound/cards) but arecord succeeds.
291 if (process.platform === 'linux' && hasCommand('arecord')) {
292 const probe = await probeArecord()
293 if (probe.ok) {
294 return { available: true, reason: null }
295 }
296 if (getPlatform() === 'wsl') {
297 return { available: false, reason: wslNoAudioReason }
298 }
299 logForDebugging(`[voice] arecord probe failed: ${probe.stderr}`)
300 // fall through to SoX
301 }
302
303 // Fallback: check for SoX
304 if (!hasCommand('rec')) {
305 // WSL without arecord AND without SoX: the generic "install SoX"
306 // hint below is misleading on WSL1/Win10 (no audio devices at all),
307 // but correct on WSL2+WSLg (SoX works via PulseAudio). Since we can't
308 // distinguish WSLg-vs-not without a backend to probe, show the WSLg
309 // guidance — it points WSL1 users at native Windows AND tells WSLg
310 // users their setup should work (they can install sox or alsa-utils).
311 // Known gap: WSL with SoX but NO arecord skips both this branch and
312 // the probe above — hasCommand('rec') lies the same way. We optimistically
313 // trust it (WSLg+SoX would work) rather than probeSox() for a near-zero
314 // population (WSL1 × minimal distro × SoX-but-not-alsa-utils).
315 if (getPlatform() === 'wsl') {
316 return { available: false, reason: wslNoAudioReason }

Callers 2

callFunction · 0.85
callFunction · 0.85

Calls 8

isRunningOnHomespaceFunction · 0.85
isEnvTruthyFunction · 0.85
loadAudioNapiFunction · 0.85
probeArecordFunction · 0.85
getPlatformFunction · 0.85
logForDebuggingFunction · 0.85
detectPackageManagerFunction · 0.85
hasCommandFunction · 0.70

Tested by

no test coverage detected