No description
  • Shell 85.2%
  • Python 14.8%
Find a file
2026-05-23 18:45:28 +00:00
bin Restart OSD when script changes 2026-05-23 14:14:22 -04:00
docs docs: add prospective Murmur architecture note 2026-05-23 14:40:09 -04:00
tests stabilize v1.0 and outline markdown plugin work 2026-03-07 19:01:22 -05:00
config.conf.example Animate OSD listening pulse and chunk flash 2026-05-23 13:52:37 -04:00
install-links.sh Complete Murmur Wayland rename 2026-05-20 14:40:25 -04:00
PLAN.md Complete Murmur Wayland rename 2026-05-20 14:40:25 -04:00
README.md Add optional LAN Whisper STT prompt 2026-05-23 12:47:40 -04:00

Murmur

Systeme local de dictee vocale sur Wayland, avec:

  • capture audio + overlays de statut
  • nettoyage texte via LLM
  • primitives textuelles de base
  • insertion dans l'app active (typing ou paste)

Quickstart (60 secondes)

  1. Installer/mettre a jour les liens:
bash ~/Projets/murmur-wayland/install-links.sh
  1. Verifier la config active dans ~/.config/murmur/config.conf:
  • WAYSTT_CLEANUP_MODEL=gpt-5-nano (ou gpt-5-mini si besoin de meilleure qualite)
  • WAYSTT_TYPE_MODE=paste
  • WAYSTT_PASTE_SHORTCUT=auto
  • WAYSTT_TEXT_ENGINE=python (defaut reel)
  • WAYSTT_PRIVACY_MODE=cloud-full
  • WAYSTT_CLIPBOARD_MODE=raw-and-clean
  • WAYSTT_SINK=auto
  • WAYSTT_UI=dunst
  • WAYSTT_OSD_POSITION=upper-center
  • WAYSTT_BACKEND=lanwhisper
  • WAYSTT_LANWHISPER_BASE_URL=http://192.168.100.33:18080
  • WAYSTT_LANWHISPER_MODEL=whisper-1
  • WAYSTT_LANWHISPER_LANGUAGE=fr
  • WAYSTT_LANWHISPER_FALLBACK=none

Debug runtime utile:

  • waystt-ctl status affiche aussi le backend actif
  • log de session: $(XDG_RUNTIME_DIR)/waystt-local/session.log (ou fallback /tmp)
  1. Lancer via ton bind Hyprland habituel.

Pilotage manuel disponible:

  • ~/.local/bin/waystt-ctl toggle
  • ~/.local/bin/waystt-ctl toggle --clipboard-only
  • ~/.local/bin/waystt-ctl status
  • ~/.local/bin/waystt-ctl doctor

doctor verifie maintenant aussi les valeurs d'env critiques, la presence du prompt de cleanup, l'etat du fichier d'alias et la disponibilite des credentials OpenAI si le pipeline en depend.

  1. Dicter un test rapide:
  • ouvrez les guillemets test fermez les guillemets
  • a la ligne
  • nouveau paragraphe
  1. Si une app reagit mal au collage auto:
  • forcer WAYSTT_PASTE_SHORTCUT=shift-insert ou ctrl-v
  • ou desactiver la saisie auto avec WAYDOT_TYPE=0

Vue d'ensemble

Flux haut niveau:

  1. waystt-launch lance le backend actif, gere beep/overlays et pipe la transcription.
  2. waystt-post-cleanup recoit le brut, copie au clipboard, nettoie via OpenAI.
  3. Le resultat est recopie au clipboard puis injecte dans la fenetre active.

Composants:

  • bin/waystt-launch: orchestration runtime + overlays d'enregistrement.
  • bin/waystt-ctl: controle start/stop/cancel/status/doctor avec etat runtime local.
  • bin/waystt-post-cleanup: pipeline texte (preprocess -> LLM -> postprocess).
  • bin/waystt-common.sh: fonctions partagees (env, couleurs, utilitaires).
  • bin/waystt-ui.sh: module UI semantique et backends d'affichage.
  • bin/waystt-osd.py: prototype OSD Wayland minimal base sur GTK3 + gtk-layer-shell.
  • bin/waystt-backend-waystt.sh: adaptateur backend actuel pour waystt.
  • bin/waystt-backend-lanwhisper.sh: adaptateur backend pour Whisper LAN via Speaches.
  • bin/waystt-lanwhisper-runner: capture locale PipeWire + appel API Speaches.
  • bin/waystt-text-pipeline.py: moteur texte Python (pre/post-process deterministic).
  • install-links.sh: installe/met a jour les symlinks.

Sources de verite

  • Scripts runtime: ~/Projets/murmur-wayland/bin
  • Config utilisateur: ~/dotfiles/murmur
  • Lien actif de config: ~/.config/murmur -> ~/dotfiles/murmur

Installation / mise a jour

bash ~/Projets/murmur-wayland/install-links.sh

Le script met a jour:

  • ~/.local/bin/waystt-launch
  • ~/.local/bin/waystt-post-cleanup
  • ~/.local/bin/waystt-common.sh
  • ~/.local/bin/waystt-ctl
  • ~/.config/murmur -> ~/dotfiles/murmur

Version actuelle

  • etat stable courant: v1.1.0
  • backend STT par defaut: lanwhisper via Speaches LAN
  • coeur texte minimal valide en tests et en usage desktop
  • chantier Markdown en cours sur feat/markdown-v0-fixtures, sans impact stable sur main

Pipeline texte

La base v1.0 repose sur un pipeline texte sobre:

  1. reception du brut transcrit
  2. cleanup LLM d'orthographe / ponctuation / syntaxe legere
  3. sortie vers le sink choisi

La couche de grammaire a ete reduite a un coeur texte propre et extensible.

Cleanup provider:

  • WAYSTT_CLEANUP_PROVIDER=openai (defaut)
  • WAYSTT_CLEANUP_PROVIDER=none pour bypasser le cleanup LLM

Moteur texte:

  • WAYSTT_TEXT_ENGINE=python (defaut, Python >= 3.10)

Le fallback legacy a ete retire. Une config WAYSTT_TEXT_ENGINE=legacy echoue explicitement.

Primitives textuelles fondamentales retenues comme base cible:

  • ouvre[z] les guillemets
  • ferme[z] les guillemets
  • a la ligne / à la ligne
  • nouveau paragraphe

La grammaire Markdown legacy est sortie du coeur. Toute reprise Markdown doit passer par un plugin separe.

Etat du chantier Markdown hors main:

  • branche experimentale active: feat/markdown-v0-fixtures
  • direction actuelle: proteger le lexique Markdown avant cleanup, puis utiliser une seconde passe LLM a sortie JSON structuree appliquee localement
  • etat: encore insuffisant en usage desktop reel, donc non promu vers dev ni main
  • handoff de reprise: docs/NEXT_SESSION_PROMPT.md

Point d'accroche interne deja en place:

  • le pipeline appelle deja une interface de plugin de grammaire
  • seul le plugin embarque plain existe pour l'instant
  • aucun plugin optionnel n'est encore expose en config

Option de rendu guillemets:

  • WAYSTT_ASCII_QUOTES=0 (defaut): « »
  • WAYSTT_ASCII_QUOTES=1: " "

Sortie vers l'application active

Sinks disponibles:

  • WAYSTT_SINK=auto: conserve le comportement historique
  • WAYSTT_SINK=paste: colle via le raccourci de collage
  • WAYSTT_SINK=type: envoi caractere par caractere via wtype -
  • WAYSTT_SINK=clipboard: n'injecte rien, garde la sortie dans le clipboard
  • WAYSTT_SINK=stdout: ecrit le resultat sur stdout
  • WAYSTT_SINK=file: ecrit dans WAYSTT_OUTPUT_FILE

Reglages utiles:

  • WAYSTT_CLEANUP_PROVIDER=openai|none
  • WAYSTT_CLEANUP_REASONING_EFFORT=minimal|low|medium|high|none (Responses API; defaut minimal)
  • WAYSTT_CLEANUP_TEXT_VERBOSITY=low|medium|high|none (Responses API; defaut low)
  • WAYSTT_CLEANUP_MAX_OUTPUT_TOKENS=0|N (0 omet la limite)
  • WAYSTT_CLEANUP_OPENAI_EXTRA_JSON='{...}' (merge JSON avance dans le payload Responses)
  • WAYSTT_SINK=auto|paste|type|clipboard|stdout|file
  • WAYSTT_OUTPUT_FILE=/chemin/vers/sortie.txt (si WAYSTT_SINK=file)
  • WAYSTT_UI=dunst|none|osd
  • WAYSTT_OSD_POSITION=upper-center|top-left|top-center|center
  • WAYSTT_BACKEND=lanwhisper|waystt
  • WAYSTT_LANWHISPER_BASE_URL=http://host:18080 (backend lanwhisper)
  • WAYSTT_LANWHISPER_MODEL=whisper-1 (backend lanwhisper)
  • WAYSTT_LANWHISPER_LANGUAGE=fr (backend lanwhisper)
  • WAYSTT_LANWHISPER_PROMPT_ENABLED=0|1 + WAYSTT_LANWHISPER_PROMPT_FILE=/chemin/prompt.txt (prompt STT envoye a Speaches)
  • WAYSTT_LANWHISPER_CHUNK_SECONDS=0|N (backend lanwhisper, chunking WAV post-capture via ffmpeg si N>=10)
  • WAYSTT_LANWHISPER_LIVE_CHUNK_SECONDS=0|N (experimental: segmentation pendant capture si N>=10)
  • WAYSTT_LANWHISPER_LIVE_MAX_JOBS=1|N (jobs STT live en parallele)
  • WAYSTT_LANWHISPER_FALLBACK=none|waystt|openai (backend lanwhisper)
  • WAYSTT_PASTE_SHORTCUT=auto|ctrl-shift-v|shift-insert|ctrl-v
  • WAYSTT_WTYPE_NEWLINES=send|space|marker (mode type uniquement)
  • WAYDOT_TYPE=0 pour desactiver toute saisie auto (clipboard only)

Recommendation pratique pour les TUIs: WAYSTT_SINK=auto + WAYSTT_PASTE_SHORTCUT=auto.

Fichiers de config

  • ~/dotfiles/murmur/config.conf: config versionnee, non secrete
  • ~/dotfiles/murmur/cleanup-system-prompt.md: prompt system cleanup

Secrets:

  • OPENAI_API_KEY doit venir de l'environnement ou d'un helper local
  • config.conf est maintenant obligatoire

Politique de donnees actuelle par defaut:

  • WAYSTT_PRIVACY_MODE=cloud-full: transcription et cleanup cloud autorises si le backend/fallback les utilise
  • WAYSTT_CLIPBOARD_MODE=raw-and-clean: brut puis clean vont dans le clipboard
  • WAYSTT_UI=dunst: backend UI par defaut, encapsule via le module UI
  • WAYSTT_UI=osd: prototype OSD Wayland possible en worktree de dev
  • les combinaisons invalides echouent explicitement au runtime et dans waystt-ctl doctor

Backend Whisper LAN

Le backend lanwhisper enregistre localement avec PipeWire, envoie le WAV a une API Speaches/OpenAI-compatible sur le LAN, puis transmet le texte brut au pipeline local existant. Pour les longues dictees, il peut aussi decouper le WAV local en morceaux avant transcription (WAYSTT_LANWHISPER_CHUNK_SECONDS) ou, en mode experimental, enregistrer/transcrire des segments pendant la capture (WAYSTT_LANWHISPER_LIVE_CHUNK_SECONDS).

Config minimale:

WAYSTT_BACKEND=lanwhisper
WAYSTT_LANWHISPER_BASE_URL=http://192.168.100.33:18080
WAYSTT_LANWHISPER_MODEL=whisper-1
WAYSTT_LANWHISPER_LANGUAGE=fr
WAYSTT_LANWHISPER_FALLBACK=none
WAYSTT_LANWHISPER_PROMPT_ENABLED=0
WAYSTT_LANWHISPER_CHUNK_SECONDS=0
WAYSTT_LANWHISPER_LIVE_CHUNK_SECONDS=0

Fallbacks:

  • WAYSTT_LANWHISPER_FALLBACK=none: echec explicite si Speaches est indisponible.
  • WAYSTT_LANWHISPER_FALLBACK=waystt: si Speaches est indisponible avant la capture, bascule vers l'ancien backend waystt pour cette session.
  • WAYSTT_LANWHISPER_FALLBACK=openai: si la transcription LAN echoue apres capture, tente l'API OpenAI audio. Refuse par la politique runtime si WAYSTT_PRIVACY_MODE interdit la transcription cloud.

Verification:

waystt-ctl doctor
curl -sS "$WAYSTT_LANWHISPER_BASE_URL/v1/models" | jq .

Docs de reference

  • Plan courant: PLAN.md
  • Roadmap Murmur: docs/MURMUR_ROADMAP.md
  • Interface backend capture/STT: docs/BACKEND_INTERFACE.md
  • Interface plugin grammaire: docs/GRAMMAR_PLUGIN_INTERFACE.md
  • Plan plugin Markdown: docs/MARKDOWN_PLUGIN_PLAN.md
  • Revue du chantier Markdown expérimental: docs/MARKDOWN_EXPERIMENT_REVIEW.md
  • Prompt de reprise de session: docs/NEXT_SESSION_PROMPT.md

Workflow git

  • main: branche stable, utilisable sur le desktop
  • main: ne recoit que code valide, corrections de bugs et changements deja verifies
  • dev: branche d'integration pour tester les nouvelles fonctionnalites en conditions reelles
  • nouvelles fonctionnalites: toujours sur une branche ad hoc dediee
  • flux recommande: branche ad hoc -> dev -> validation desktop -> main
  • nommage des branches: pragmatique, descriptif, sans schema impose

Tests (pipeline texte)

Lancer les non-regressions du moteur Python:

python3 tests/run-text-pipeline-tests.py

Cas couverts actuellement:

  • commandes guillemets et nettoyage de ponctuation parasite
  • variantes ASR sur a la ligne / à la ligne / nouveau paragraphe
  • mode guillemets ASCII

Verification rapide v1.0

  • bash bin/waystt-ctl doctor
  • python3 tests/run-text-pipeline-tests.py
  • test desktop nominal: dicter ouvrez les guillemets test fermez les guillemets, puis a la ligne, puis nouveau paragraphe
  • verifier que le resultat arrive correctement dans le sink actif sans commande Markdown implicite