Muninn

Haz que tu agente inicie el dictado

Documentación

muninn

Crates.io Version CI CodSpeed Crates.io Downloads License Discord Buymecoffee

Dictado nativo de IA en la barra de menús de macOS para texto de desarrollador.

Muninn graba el habla, la transcribe, procesa la transcripción mediante un pipeline de texto configurable e inyecta el texto final en la aplicación activa. El pipeline predeterminado está diseñado para dictado cercano al código: comandos, flags, nombres de paquetes, rutas de archivos, variables de entorno, acrónimos y otros tokens que el dictado de propósito general suele modificar.

Muninn menu-bar dictation screenshot

Contenido

Qué hace Muninn

Flujo predeterminado en modo grabado:

hotkey or tray click
-> record temporary WAV
-> resolve transcription provider route
-> transcribe with the first usable provider
-> run the refine step
-> run optional external filters
-> inject final text into the active app

Muninn incluye:

  • una aplicación de barra de menús de macOS con un indicador de bandeja en vivo
  • teclas de acceso rápido globales para pulsar-para-hablar, alternar modo hecho y cancelar
  • captura de micrófono a un WAV temporal, con valor predeterminado de 16 kHz mono
  • una ruta de transcripción local-primero a través de Apple Speech, whisper.cpp, Deepgram, OpenAI, Google y SpaceXAI (xAI) para transcripción grabada
  • un modo de streaming opcional para proveedores que admiten transcripción en vivo en este código base
  • un paso refine integrado que aplica un prompt conservador de dictado para desarrolladores (OpenAI o SpaceXAI / xAI)
  • soporte de filtros Unix externos para pasos de pipeline personalizados
  • inyección de texto mediante eventos de teclado en la aplicación actual
  • control externo opcional mediante URLs muninn:// y un servidor MCP en localhost
  • artefactos de reproducción opcionales para depurar expresiones

Controles predeterminados:

AcciónPredeterminado
Pulsar-para-hablarctrl con disparador double_tap y una ventana de doble toque de 300 ms
Alternar modo hechoctrl + shift + d
Cancelar captura activactrl + shift + x
Clic izquierdo en bandejaAlternar: iniciar cuando está inactivo, detener cuando graba

Los cambios de teclas de acceso rápido se leen de la configuración, pero la recarga en vivo de la configuración no reemplaza los enlaces de teclas activos. Reinicia Muninn después de cambiar las teclas de acceso rápido.

Inicio rápido

Usa esta ruta cuando quieras ejecutar Muninn desde este repositorio.

Requisitos previos

  • macOS
  • Rust 1.88.0 o más reciente
  • Herramientas de línea de comandos de Xcode para compilaciones locales
  • Permisos de macOS para Micrófono, Accesibilidad y Monitoreo de Entrada
  • Claves opcionales de proveedores en la nube cuando uses Deepgram, OpenAI, Google, SpaceXAI (xAI) o un paso refine respaldado por la nube

1. Compilar el binario

cargo build --release --bin muninn

2. Crear un archivo de configuración

Muninn lee la configuración en este orden:

  1. MUNINN_CONFIG
  2. $XDG_CONFIG_HOME/muninn/config.toml
  3. ~/.config/muninn/config.toml

Si el archivo de configuración resuelto no existe, Muninn crea una configuración predeterminada ejecutable. Para comenzar desde la configuración de ejemplo en su lugar:

CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/muninn"
mkdir -p "$CONFIG_DIR"
cp configs/config.sample.toml "$CONFIG_DIR/config.toml"

3. Establecer credenciales cuando sea necesario

Muninn carga ./.env desde el directorio de trabajo actual de forma predeterminada. Las variables de entorno existentes del shell anulan .env y los valores de configuración.

Crea .env solo con las claves que uses:

OPENAI_API_KEY=<OPENAI_API_KEY>
DEEPGRAM_API_KEY=<DEEPGRAM_API_KEY>
GOOGLE_API_KEY=<GOOGLE_API_KEY>
GOOGLE_STT_TOKEN=<GOOGLE_STT_TOKEN>
XAI_API_KEY=<XAI_API_KEY>

Establece MUNINN_LOAD_DOTENV=0, false o no para deshabilitar la carga de .env.

4. Ejecutar la aplicación de bandeja

cargo run --release --bin muninn

Resultado esperado: Muninn aparece en la barra de menús de macOS con un indicador de bandeja M.

5. Otorgar permisos y verificar

Otorga estos permisos al propio Muninn:

PermisoPor qué Muninn lo necesitaRuta en Configuración del Sistema
MicrófonoGrabar tu hablaPrivacidad y seguridad > Micrófono
AccesibilidadInyectar el texto final en la aplicación activaPrivacidad y seguridad > Accesibilidad
Monitoreo de EntradaEscuchar teclas de acceso rápido globales mientras otra aplicación está activaPrivacidad y seguridad > Monitoreo de Entrada

Para verificar la aplicación:

  1. Enfoca un campo de texto en otra aplicación.
  2. Haz clic en el ícono de bandeja de Muninn para comenzar a grabar.
  3. Di una frase corta.
  4. Haz clic nuevamente en el ícono de bandeja para detener la grabación.

Resultado esperado: Muninn transcribe la expresión, ejecuta el pipeline y escribe el texto final en la aplicación enfocada.

Si macOS deja de mostrar el aviso de permiso, restablece el servicio TCC afectado y reinicia Muninn:

tccutil reset ListenEvent
tccutil reset Accessibility
tccutil reset Microphone

Instalación y ejecución

Instalar desde crates.io

cargo install muninn-speech-to-text
muninn

El nombre del paquete es muninn-speech-to-text; el nombre del binario es muninn.

Ejecutar desde la configuración de ejemplo

MUNINN_CONFIG="$PWD/configs/config.sample.toml" cargo run --release --bin muninn

Esto es útil para el desarrollo local porque evita cambiar tu configuración de usuario.

Instalar un binario de versión

El flujo de trabajo de versiones compila archivos tar para:

  • aarch64-apple-darwin
  • x86_64-apple-darwin

Después de extraer un archivo de versión, mantén el binario en una ruta estable antes de otorgar permisos de macOS:

mkdir -p "$HOME/.local/bin"
mv muninn "$HOME/.local/bin/muninn"
chmod +x "$HOME/.local/bin/muninn"
"$HOME/.local/bin/muninn"

Los permisos de macOS se adjuntan a la identidad exacta de la aplicación o binario. Mover o reemplazar un binario sin empaquetar puede requerir otorgar permisos nuevamente.

Compilar un paquete .app local

Usa el paquete de aplicación cuando quieras una identidad de aplicación estable, manejo de URLs muninn:// y comportamiento normal de Elementos de Inicio de Sesión.

cargo build --release --bin muninn
bash scripts/package-macos-app.sh
open dist/Muninn.app

El script de empaquetado crea dist/Muninn.app, lo firma ad hoc de forma predeterminada y crea dist/Muninn.app.zip cuando ditto está disponible. Establece CODESIGN_IDENTITY para usar un certificado de Developer ID, o establece CODESIGN_APP=0 para omitir la firma.

Configuración recomendada del paquete de aplicación:

  1. Mueve dist/Muninn.app a /Applications/Muninn.app.
  2. Ejecútalo una vez y otorga permisos a Muninn.
  3. Agrégalo en Configuración del Sistema > General > Elementos de Inicio de Sesión.
  4. Mantén [app].autostart = false cuando uses Elementos de Inicio de Sesión.

Finder y Elementos de Inicio de Sesión no heredan el entorno de tu shell. Guarda las credenciales en la configuración o asegúrate de que el directorio de trabajo de Muninn contenga el archivo .env que esperas que lea.

Habilitar inicio automático de binario sin empaquetar

Establece [app].autostart = true para permitir que Muninn escriba un LaunchAgent para la ruta del ejecutable actual.

Comportamiento:

  • Muninn escribe ~/Library/LaunchAgents/com.bnomei.muninn.plist cuando inicia o recarga la configuración.
  • Los cambios surten efecto en el próximo inicio de sesión de macOS.
  • El LaunchAgent incluye MUNINN_CONFIG.
  • El LaunchAgent no hereda las exportaciones interactivas del shell.
  • Cuando uses Muninn.app, prefiere los Elementos de Inicio de Sesión de macOS sobre esta ruta de LaunchAgent para binario sin empaquetar.

Configurar Muninn

El ejemplo canónico es configs/config.sample.toml. El esquema raíz se encuentra en src/config.rs.

Secciones importantes de configuración

SecciónPropósito
[app]Perfil predeterminado, contrato estricto de pasos, inicio automático de binario sin empaquetar
[hotkeys.*]Enlaces de pulsar-para-hablar, alternar modo hecho y cancelar
[indicator]Visibilidad y colores del indicador de bandeja
[recording]Formato de captura WAV y post-procesamiento opcional de tempo con FFmpeg; valores predeterminados: mono, 16 kHz y postprocess_speed = 1.0
[transcription]Modo grabado versus streaming y ruta ordenada de proveedores
[pipeline]Plazo del pipeline, formato de payload y pasos posteriores a la transcripción
[transcript]Prompt base y texto de anexo al prompt para el paso de refinamiento integrado
[refine]Proveedor de refinamiento (openai o xai), endpoint, modelo, temperatura y salvaguardas
[voices.*]Comportamiento de refinamiento con nombre y glifo opcional de una letra en la bandeja
[profiles.*]Anulaciones específicas de contexto para grabación, ruta, pipeline, transcripción o refinamiento
[[profile_rules]]Coincidencias ordenadas para la aplicación frontal y el título de la ventana
[external_control]Esquema de URL y ajustes de control de grabación MCP
[logging]Artefactos de reproducción, retención y detalle de depuración
[providers.*]Credenciales de proveedores, endpoints, modelos y ajustes de streaming

Post-procesamiento de tempo en WAV grabado

Establece una velocidad superior a 1.0 para post-procesar cada captura completada con FFmpeg antes de que un proveedor de grabación la lea. El filtro preserva el tono:

[recording]
postprocess_speed = 2.0

El valor predeterminado, 1.0, deja el WAV finalizado sin cambios. Se aceptan valores desde 1.0 hasta 16.0; los valores superiores a 2× se expresan como múltiples etapas atempo de FFmpeg para evitar el comportamiento de omisión de muestras del filtro con un solo factor alto. Muninn necesita ffmpeg en PATH cuando el valor configurado es superior a 1.0 (por ejemplo, brew install ffmpeg); si no está disponible, la bandeja muestra un estado de error rojo y la captura se descarta. Los proveedores de streaming aún reciben fotogramas de captura en vivo a velocidad normal; el WAV post-procesado se usa para transcripción grabada, respaldo y reproducción después de que la captura finaliza.

Ruta de proveedores

La ruta de proveedores predeterminada es local-primero:

[transcription]
providers = ["apple_speech", "whisper_cpp", "deepgram", "openai", "google", "xai"]

Los perfiles pueden anular solo la ruta:

[profiles.mail.transcription]
providers = ["deepgram", "openai", "google", "xai"]

Si aún tienes pasos stt_* explícitos en pipeline.steps, Muninn los acepta e infiere la ruta a partir de ese orden. Las configuraciones nuevas deberían preferir [transcription].providers.

Pasos del pipeline

Cada paso del pipeline tiene:

  • id
  • cmd
  • args opcional
  • io_mode opcional
  • timeout_ms
  • on_error

Valores admitidos de io_mode:

ValorComportamiento
autoLos integrados usan JSON de sobre; los comandos externos usan filtrado de texto de forma predeterminada
envelope_jsonEl paso lee y escribe el sobre JSON completo
text_filterEl paso lee el texto de la transcripción y escribe texto de reemplazo

Valores admitidos de on_error:

ValorComportamiento
continueConservar el sobre anterior y ejecutar pasos posteriores
fallback_rawSustituir transcript.raw_text y continuar
abortDetener el pipeline y mostrar el error

Ejemplo:

[transcription]
providers = ["apple_speech", "whisper_cpp", "deepgram", "openai", "google", "xai"]

[[pipeline.steps]]
id = "refine"
cmd = "refine"
timeout_ms = 2500
on_error = "continue"

[[pipeline.steps]]
id = "uppercase"
cmd = "/usr/bin/tr"
args = ["[:lower:]", "[:upper:]"]
timeout_ms = 250
on_error = "continue"

Sugerencias de prompt de refinamiento

transcript.system_prompt y transcript.system_prompt_append guían el paso refine integrado. No cambian el proveedor de voz a texto, y Muninn no analiza el JSON anexado en APIs de adaptación nativas del proveedor.

[transcript]
system_prompt = "Prefer minimal corrections. Focus on technical terms, developer tools, package names, commands, flags, file names, paths, env vars, acronyms, and obvious dictation errors. If uncertain, keep the original wording."
system_prompt_append = """
Vocabulary JSON:
{"terms":["Muninn","whisper.cpp","Deepgram","Cargo.toml"],"commands":["cargo test --all-targets","rg --files"],"paths":["src/config.rs",".env"]}
"""

Proveedores de transcripción

ProveedorModo grabadoModo streamingCredencialesNotas
Apple SpeechSíNoNingunaProveedor local de macOS 26+. Utiliza los recursos de Speech gestionados por Apple para la configuración regional seleccionada.
whisper.cppSíNoNingunaProveedor local. Por defecto usa tiny.en, almacenado en ~/.local/share/muninn/models, con device = "auto".
DeepgramSíSíDEEPGRAM_API_KEY o providers.deepgram.api_keyLas subidas grabadas usan /v1/listen; el streaming usa la API WebSocket en vivo.
OpenAISíSíOPENAI_API_KEY o providers.openai.api_keyLas subidas grabadas se verifican contra el límite de audio de 25 MB de OpenAI; el streaming usa transcripción en tiempo real.
GoogleSíNo invocable actualmenteGOOGLE_API_KEY, GOOGLE_STT_TOKEN o valores de configuraciónLa transcripción REST grabada funciona a través del endpoint configurado. El adaptador de streaming de Google construye solicitudes de Speech-to-Text v2, pero la dependencia fijada google-cloud-speech-v2 1.12.0 no expone un RPC de streaming invocable, por lo que Muninn informa google_official_client_streaming_rpc_unavailable.
SpaceXAI (xAI)SíSíXAI_API_KEY o providers.xai.api_keyId de configuración xai, paso stt_xai. Las subidas grabadas usan POST https://api.x.ai/v1/stt (multipart; sin campo STT model). El streaming usa wss://api.x.ai/v1/stt con autenticación Bearer, PCM mono de 16 kHz y un handshake transcript.created. Opcionales language, format, keyterm, diarize, filler_words y vad_threshold bajo [providers.xai]. Anulaciones de entorno: XAI_STT_ENDPOINT, XAI_STT_STREAMING_ENDPOINT, XAI_STT_LANGUAGE.

El paso refine no es un proveedor de STT. Usa la configuración [refine] y HTTP compatible con chat-completions por defecto (provider = "openai"). Establece provider = "xai" para refinar con SpaceXAI / xAI (https://api.x.ai/v1/chat/completions, modelo grok-4.5 por defecto). Establecer solo el proveedor cambia el endpoint y el modelo a los valores predeterminados de ese proveedor, de modo que una clave de xAI nunca se envía a una URL de OpenAI.

Variables de entorno

AspectoVariables
Ruta de configuraciónMUNINN_CONFIG
Carga de .envMUNINN_LOAD_DOTENV
DeepgramDEEPGRAM_API_KEY, DEEPGRAM_STT_ENDPOINT, DEEPGRAM_STT_MODEL, DEEPGRAM_STT_LANGUAGE, MUNINN_DEEPGRAM_STUB_TEXT
Transcripción y refinamiento de OpenAIOPENAI_API_KEY, MUNINN_OPENAI_STUB_TEXT, MUNINN_REFINE_STUB_TEXT
Transcripción grabada de GoogleGOOGLE_API_KEY, GOOGLE_STT_TOKEN, GOOGLE_STT_ENDPOINT, GOOGLE_STT_MODEL, MUNINN_GOOGLE_STUB_TEXT
Transcripción y refinamiento de SpaceXAI (xAI)XAI_API_KEY, XAI_STT_ENDPOINT, XAI_STT_STREAMING_ENDPOINT, XAI_STT_LANGUAGE, MUNINN_XAI_STT_STUB_TEXT, MUNINN_REFINE_STUB_TEXT

Las variables simuladas están pensadas para comprobaciones locales y pruebas. Omiten las llamadas en vivo al proveedor para el paso correspondiente.

Ciclo de vida del modelo whisper.cpp

Comportamiento predeterminado:

  • providers.whisper_cpp.model sin establecer se resuelve a tiny.en
  • tiny.en se resuelve a ggml-tiny.en.bin
  • el directorio de modelos predeterminado es ~/.local/share/muninn/models
  • Muninn descarga automáticamente modelos canónicos conocidos en el primer uso
  • las rutas de modelos personalizados explícitos deben existir previamente
  • device = "auto" usa Metal en builds compatibles de Apple Silicon y CPU en caso contrario

Precalienta la caché de modelos predeterminada:

mkdir -p "$HOME/.local/share/muninn/models"
curl -L \
  -o "$HOME/.local/share/muninn/models/ggml-tiny.en.bin" \
  "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin"

Si una ruta solo local apunta a un modelo personalizado inexistente, Muninn registra un diagnóstico missing_whisper_cpp_model y no inyecta nada a menos que otro proveedor produzca transcript.raw_text más adelante.

Modelo de pipeline

Muninn pasa un sobre a través de cada paso integrado y externo. Los pasos STT integrados completan transcript.raw_text; los pasos de transformación como refine escriben output.final_text. La inyección prefiere output.final_text y puede recurrir a transcript.raw_text.

Comandos de pasos integrados:

ComandoPropósito
stt_apple_speechTranscripción de Apple Speech para grabaciones completadas
stt_whisper_cppTranscripción local de whisper.cpp para grabaciones completadas
stt_deepgramTranscripción de Deepgram para grabaciones completadas
stt_openaiTranscripción de OpenAI para grabaciones completadas
stt_googleTranscripción REST de Google para grabaciones completadas
stt_xaiTranscripción de SpaceXAI / xAI para grabaciones completadas
refineLimpieza de dictado de desarrollador con chat-completions (openai o xai)

Ejecuta un paso integrado directamente para comprobaciones rápidas:

cargo run -q -- __internal_step <stt_apple_speech|stt_whisper_cpp|stt_deepgram|stt_openai|stt_google|stt_xai|refine>

Usa los fixtures JSON en tests/fixtures para ejemplos de sobres de entrada.

Transcripción en streaming

El modo grabado es el predeterminado. Habilita el streaming explícitamente:

[transcription]
mode = "streaming"
providers = ["deepgram", "openai", "xai"]

[transcription.streaming]
frame_ms = 100
finish_timeout_ms = 10000
fallback_to_recorded_on_error = true

Comportamiento del streaming:

  • El streaming de Deepgram envía audio LINEAR16 mono a través de WebSocket.
  • El streaming de OpenAI usa transcripción en tiempo real y fuerza captura mono de 24 kHz para esa emisión.
  • El streaming de SpaceXAI / xAI usa wss://api.x.ai/v1/stt con Bearer XAI_API_KEY, espera transcript.created, envía tramas PCM mono de 16 kHz y finaliza con audio.done. Cuando xAI es el proveedor de streaming activo, Muninn fuerza captura mono de 16 kHz para esa emisión.
  • El streaming de Google no es invocable actualmente porque la dependencia fijada google-cloud-speech-v2 1.12.0 expone tipos de solicitud y respuesta pero ningún método de streaming invocable.
  • Muninn aún escribe el WAV completado durante el streaming.
  • Cuando el streaming falla y fallback_to_recorded_on_error = true, Muninn puede ejecutar la ruta de WAV completado.
  • Una transcripción de streaming exitosa siembra transcript.raw_text; refine, la puntuación, la reproducción y la inyección usan el mismo pipeline descendente que el modo grabado.
  • Los resultados intermedios de streaming son transitorios. Muninn no muestra una interfaz de transcripción parcial ni persiste el historial de transcripción parcial.

Perfiles contextuales y voces

Muninn puede cambiar el comportamiento de refinamiento según la aplicación en primer plano. Captura el id del bundle, el nombre de la aplicación y un título de ventana de mejor esfuerzo, luego aplica la primera entrada profile_rules que coincida. Si ninguna regla coincide, el comportamiento recurre a [app].profile; el glifo de la bandeja inactiva recurre a M.

Orden de resolución:

  1. Comienza desde la configuración base.
  2. Aplica la voz coincidente, si el perfil coincidente nombra una.
  3. Aplica las anulaciones del perfil al final.

Voz significa comportamiento de modelado de texto más un glifo opcional de bandeja, no una voz de audio.

[app]
profile = "default"

[voices.codex]
indicator_glyph = "C"
system_prompt = "Prefer terse developer dictation. Keep commands, flags, file names, and code tokens intact."
system_prompt_append = """
Vocabulary JSON:
{"terms":["Codex","Muninn","Cargo.toml"],"commands":["cargo test --all-targets","cargo clippy --all-targets -- -D warnings"]}
"""

[voices.terminal]
indicator_glyph = "T"
system_prompt = "Preserve shell commands exactly. Prefer minimal punctuation changes."

[profiles.codex]
voice = "codex"

[profiles.terminal]
voice = "terminal"

[[profile_rules]]
id = "codex-app"
profile = "codex"
app_name = "Codex"

[[profile_rules]]
id = "terminal-app"
profile = "terminal"
bundle_id = "com.apple.Terminal"

Comportamiento de la bandeja:

  • la vista previa inactiva muestra el glifo de la voz coincidente, o M
  • la grabación y el procesamiento congelan el glifo resuelto para esa emisión
  • ? está reservado para comentarios de credenciales faltantes

Control externo

Muninn puede ser controlado por agentes y scripts a través de dos transportes:

  • Esquema de URL muninn://, disponible para el .app empaquetado de macOS
  • Servidor MCP HTTP streamable en localhost, deshabilitado por defecto

Ambos transportes usan el mismo vocabulario de control de grabación que los eventos de bandeja y atajos de teclado.

[external_control]
url_scheme_enabled = true
mcp_enabled = false
start_recording_enabled = false
mcp_bind_address = "127.0.0.1:2769"

Semántica de acciones:

AcciónComportamiento
startInicia la grabación solo cuando está inactivo y start_recording_enabled = true
stopDetiene una grabación activa y ejecuta el pipeline; no-op cuando está inactivo
toggleInicia cuando está inactivo y permitido; de lo contrario detiene una grabación activa
cancelDescarta una grabación activa sin transcripción ni inyección

El inicio externo está deshabilitado por defecto porque inicia la captura del micrófono. Habilitar start_recording_enabled = true es la decisión de confianza local para agentes y scripts configurados.

Esquema de URL

El .app empaquetado registra muninn:// a través de CFBundleURLTypes.

URLAcción
muninn://record, muninn://startiniciar
muninn://stop, muninn://donedetener
muninn://togglealternar
muninn://cancel, muninn://abortcancelar
open "muninn://record"

Un binario lanzado con cargo run no recibe estos enlaces de LaunchServices.

Servidor MCP

Cuando mcp_enabled = true, Muninn sirve MCP en:

http://127.0.0.1:2769/mcp

Herramientas:

  • get_status
  • start_recording
  • stop_recording
  • cancel_recording

Ejemplo de registro con un cliente compatible con MCP:

auggie mcp add muninn --transport http --url http://127.0.0.1:2769/mcp

get_status es de solo lectura y devuelve JSON como:

{
  "state": "idle",
  "recording_active": false,
  "busy": false,
  "permissions": {
    "microphone": "granted",
    "accessibility": "granted",
    "input_monitoring": "granted"
  }
}

state es uno de idle, recording_active, permission_blocked, already_running o failed.

Restricciones de seguridad:

  • El servidor MCP no tiene autenticación.
  • mcp_bind_address debe ser una dirección de socket de loopback explícita como 127.0.0.1:2769 o [::1]:2769.
  • Muninn rechaza wildcard, LAN, nombres de host y otros enlaces que no sean loopback.
  • El servidor MCP se inicia solo al lanzar la aplicación. Cambiar mcp_enabled más tarde requiere reiniciar Muninn.

Privacidad, reproducción y depuración

Los registros de trazado van a stderr y se controlan con RUST_LOG.

RUST_LOG=recording=debug cargo run --release --bin muninn

El registro de reproducción está deshabilitado por defecto. Cuando está habilitado:

  • replay_detail = "minimal" almacena solo metadatos dispersos de emisiones
  • replay_detail = "full_debug" almacena configuración redactada, contexto objetivo, sobres finales, resultado del pipeline, contexto de refinamiento y ruta de inyección
  • replay_retain_audio = true conserva audio solo cuando replay_detail = "full_debug"
  • el audio retenido usa un enlace duro cuando es posible y recurre a una copia
  • las instantáneas de depuración completa redactan secretos de proveedores y campos de prompts
  • los artefactos de reproducción son para inspección, no para re-ejecución
[logging]
replay_enabled = true
replay_detail = "minimal"
replay_retain_audio = false
replay_dir = "~/.local/state/muninn/replay"
replay_retention_days = 7
replay_max_bytes = 52428800

Comprobaciones comunes de recuperación:

SíntomaComprobación
El atajo de teclado no inicia la grabaciónOtorga Monitoreo de Entrada a Muninn y reinicia después de cambiar la configuración del atajo
El clic en la bandeja graba pero el atajo noFalta Monitoreo de Entrada o el listener del atajo necesita reinicio
El texto no se inyectaOtorga Accesibilidad a Muninn
No se inyecta texto después de una ruta solo local de WhisperVerifica missing_whisper_cpp_model y confirma la ruta del modelo configurado
El inicio MCP externo es rechazadoEstablece external_control.start_recording_enabled = true y reinicia si el servidor MCP no estaba habilitado al lanzar
El streaming de Google falla o informa no disponibleUsa transcripción grabada de Google, streaming de Deepgram, streaming de OpenAI o streaming de xAI
Faltan credenciales de SpaceXAI / xAIEstablece XAI_API_KEY o providers.xai.api_key; para refinamiento también establece [refine] provider = "xai"

Desarrollo

Ejecuta las comprobaciones principales:

cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets

El repositorio también incluye hooks prek:

prek validate-config
prek run --all-files
prek install

Ejecuta la suite de benchmarks:

cargo bench --bench runtime_bottlenecks

Filtra a un grupo de benchmarks:

cargo bench --bench runtime_bottlenecks pipeline_runner
cargo bench --bench runtime_bottlenecks replay_persist

El objetivo del benchmark se centra en rutas de latencia por emisión que no requieren llamadas de red:

  • transformación y remuestreo de salida de audio
  • viajes de ida y vuelta JSON de sobres
  • construcción del cuerpo de solicitud de Google
  • resolución de perfiles y voces
  • puntuación de reemplazo
  • sobrecarga del runner de pipeline en proceso
  • persistencia de reproducción con y sin artefactos de audio retenidos

Límites actuales

  • El runtime compatible de Muninn es macOS.
  • Apple Speech requiere macOS 26+ y recursos de Speech gestionados por Apple.
  • whisper.cpp y Apple Speech son solo proveedores de grabación completada.
  • La construcción de solicitudes de streaming de Google existe, pero el streaming en vivo de Google no es invocable hasta que el cliente oficial fijado exponga un RPC de streaming.
  • El modo streaming usa solo el texto final del proveedor. No hay interfaz de transcripción parcial.
  • Los artefactos de reproducción son para inspección, no para reproducción determinista.
  • La transcripción respaldada por proveedores necesita presupuestos de tiempo de espera realistas.
  • El servidor MCP de control externo no tiene autenticación, está deshabilitado por defecto, se enlaza solo a loopback y se inicia solo al lanzar la aplicación.
  • El flujo de trabajo de lanzamiento del repositorio empaqueta binarios crudos; usa el script de empaquetado local cuando necesites un bundle .app.

Mapa de fuentes

Usa estos archivos al verificar las afirmaciones del README contra el código fuente:

ÁreaFuente
Metadatos del paquete y MSRVCargo.toml
Configuración de ejemploconfigs/config.sample.toml
Esquema de configuración y valores predeterminadossrc/config.rs, src/config/logging.rs
Vocabulario del proveedor y ruta predeterminadasrc/transcription.rs
Ejecutor de pipeline y herramientas integradassrc/runner.rs, src/internal_tools.rs
Proveedor Apple Speechsrc/stt_apple_speech_tool.rs, src/apple_speech_transcriber.swift
Proveedor whisper.cppsrc/stt_whisper_cpp_tool.rs
Proveedor Deepgramsrc/stt_deepgram_tool.rs, src/streaming_transcription/deepgram.rs
Proveedor OpenAI y refinamientosrc/stt_openai_tool.rs, src/streaming_transcription/openai.rs, src/refine.rs
Proveedor SpaceXAI / xAI y refinamientosrc/stt_xai_tool.rs, src/streaming_transcription/xai.rs, src/refine.rs
Proveedor Googlesrc/stt_google_tool.rs, src/streaming_transcription/google.rs
Atajos de teclado, bandeja y flujo de ejecuciónsrc/hotkeys.rs, src/runtime_tray.rs, src/runtime_flow.rs
Permisos de macOSsrc/runtime_permissions.rs, src/permissions.rs
Control externosrc/external_control.rs, src/external_control/action.rs, src/external_control/mcp.rs, src/external_control/url_scheme.rs
Empaquetado y scripts de publicaciónscripts/package-macos-app.sh, scripts/package-release.sh, .github/workflows/release.yml