/** * Detect ffmpeg on the user's PATH. Result is cached; call resetFfmpegCache() * if you want to re-probe (e.g. after the user installs ffmpeg mid-session). */ export declare function isFfmpegAvailable(): Promise; export declare function resetFfmpegCache(): void; export declare function setFfmpegPath(p: string): void; /** * Quick probe: try to capture 200ms of audio from the default mic. * Returns: * 'ok' — got audio bytes, mic is alive * 'no-mic' — ffmpeg started but failed to open the input device * 'no-ffmpeg' — ffmpeg isn't on PATH * 'error' — something else went wrong * * Cached for 10 seconds so repeated F5 presses don't spawn a fresh * subprocess each time. Pass `force=true` to bypass the cache (e.g. * after the user plugs in a mic mid-session). */ export type MicProbeResult = 'ok' | 'no-mic' | 'no-ffmpeg' | 'error'; export declare function probeMic(force?: boolean): Promise; /** * Friendly one-line message explaining a probe result. Caller logs + * announces via TTS. Returned phrasing is screen-reader-friendly. */ export declare function micProbeMessage(r: MicProbeResult): string; /** * Record from the default mic for up to `maxSeconds`, return WAV-encoded * bytes. ffmpeg encodes to 16kHz mono PCM-16 (Whisper's preferred format). * * Returns null on failure — including ffmpeg missing or mic unavailable. * Caller usually wraps with `dictateOnce()` which handles the UX. */ export declare function recordAudio(maxSeconds: number): Promise; /** * Pipe an audio buffer (MP3 from ElevenLabs, or WAV from us) through ffplay * if available, falling back to ffmpeg with the platform's default audio * output. Honors an AbortSignal so a Ctrl+C or new-message arrival can cut * playback immediately. * * Returns true if playback completed without error, false otherwise. */ export declare function playAudioBuffer(buf: Buffer, signal?: AbortSignal): Promise; /** * Generate + play a short tone for state transitions. Uses ffmpeg's `sine` * filter, so no asset files needed. Plays via ffplay when available so it * doesn't fight the main TTS pipeline. * * Frequencies / durations are tuned to be brief (under 250ms) and pleasant * (no harsh upper harmonics). */ export type AudioCue = 'ready' | 'recording-start' | 'recording-stop' | 'processing' | 'done' | 'error'; /** * Play a named audio cue. Best-effort; returns true on apparent success. * Failures are silent — a missing beep should never break the REPL. */ export declare function audioCue(name: AudioCue): Promise; /** * Start a recording subprocess and return a controller. The caller calls * `stop()` to finalize and receive the audio buffer (or null on error). * * Used by the F1 push-to-talk hotkey: keydown → startRecording, keyup → * controller.stop(). The maxSeconds cap is a safety net for stuck keys. */ export interface RecordController { stop: () => Promise; abort: () => void; } export declare function startRecording(maxSeconds?: number): Promise;