- Shell 85.2%
- Python 14.8%
|
|
||
|---|---|---|
| bin | ||
| docs | ||
| tests | ||
| config.conf.example | ||
| install-links.sh | ||
| PLAN.md | ||
| README.md | ||
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)
- Installer/mettre a jour les liens:
bash ~/Projets/murmur-wayland/install-links.sh
- Verifier la config active dans
~/.config/murmur/config.conf:
WAYSTT_CLEANUP_MODEL=gpt-5-nano(ougpt-5-minisi besoin de meilleure qualite)WAYSTT_TYPE_MODE=pasteWAYSTT_PASTE_SHORTCUT=autoWAYSTT_TEXT_ENGINE=python(defaut reel)WAYSTT_PRIVACY_MODE=cloud-fullWAYSTT_CLIPBOARD_MODE=raw-and-cleanWAYSTT_SINK=autoWAYSTT_UI=dunstWAYSTT_OSD_POSITION=upper-centerWAYSTT_BACKEND=lanwhisperWAYSTT_LANWHISPER_BASE_URL=http://192.168.100.33:18080WAYSTT_LANWHISPER_MODEL=whisper-1WAYSTT_LANWHISPER_LANGUAGE=frWAYSTT_LANWHISPER_FALLBACK=none
Debug runtime utile:
waystt-ctl statusaffiche aussi le backend actif- log de session:
$(XDG_RUNTIME_DIR)/waystt-local/session.log(ou fallback/tmp)
- 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.
- Dicter un test rapide:
ouvrez les guillemets test fermez les guillemetsa la lignenouveau paragraphe
- Si une app reagit mal au collage auto:
- forcer
WAYSTT_PASTE_SHORTCUT=shift-insertouctrl-v - ou desactiver la saisie auto avec
WAYDOT_TYPE=0
Vue d'ensemble
Flux haut niveau:
waystt-launchlance le backend actif, gere beep/overlays et pipe la transcription.waystt-post-cleanuprecoit le brut, copie au clipboard, nettoie via OpenAI.- 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 pourwaystt.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:
lanwhispervia Speaches LAN - coeur texte minimal valide en tests et en usage desktop
- chantier Markdown en cours sur
feat/markdown-v0-fixtures, sans impact stable surmain
Pipeline texte
La base v1.0 repose sur un pipeline texte sobre:
- reception du brut transcrit
- cleanup LLM d'orthographe / ponctuation / syntaxe legere
- 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=nonepour 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 guillemetsferme[z] les guillemetsa la ligne/à la lignenouveau 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
devnimain - 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
plainexiste 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 historiqueWAYSTT_SINK=paste: colle via le raccourci de collageWAYSTT_SINK=type: envoi caractere par caractere viawtype -WAYSTT_SINK=clipboard: n'injecte rien, garde la sortie dans le clipboardWAYSTT_SINK=stdout: ecrit le resultat sur stdoutWAYSTT_SINK=file: ecrit dansWAYSTT_OUTPUT_FILE
Reglages utiles:
WAYSTT_CLEANUP_PROVIDER=openai|noneWAYSTT_CLEANUP_REASONING_EFFORT=minimal|low|medium|high|none(Responses API; defautminimal)WAYSTT_CLEANUP_TEXT_VERBOSITY=low|medium|high|none(Responses API; defautlow)WAYSTT_CLEANUP_MAX_OUTPUT_TOKENS=0|N(0omet la limite)WAYSTT_CLEANUP_OPENAI_EXTRA_JSON='{...}'(merge JSON avance dans le payload Responses)WAYSTT_SINK=auto|paste|type|clipboard|stdout|fileWAYSTT_OUTPUT_FILE=/chemin/vers/sortie.txt(siWAYSTT_SINK=file)WAYSTT_UI=dunst|none|osdWAYSTT_OSD_POSITION=upper-center|top-left|top-center|centerWAYSTT_BACKEND=lanwhisper|waysttWAYSTT_LANWHISPER_BASE_URL=http://host:18080(backendlanwhisper)WAYSTT_LANWHISPER_MODEL=whisper-1(backendlanwhisper)WAYSTT_LANWHISPER_LANGUAGE=fr(backendlanwhisper)WAYSTT_LANWHISPER_PROMPT_ENABLED=0|1+WAYSTT_LANWHISPER_PROMPT_FILE=/chemin/prompt.txt(prompt STT envoye a Speaches)WAYSTT_LANWHISPER_CHUNK_SECONDS=0|N(backendlanwhisper, chunking WAV post-capture viaffmpegsiN>=10)WAYSTT_LANWHISPER_LIVE_CHUNK_SECONDS=0|N(experimental: segmentation pendant capture siN>=10)WAYSTT_LANWHISPER_LIVE_MAX_JOBS=1|N(jobs STT live en parallele)WAYSTT_LANWHISPER_FALLBACK=none|waystt|openai(backendlanwhisper)WAYSTT_PASTE_SHORTCUT=auto|ctrl-shift-v|shift-insert|ctrl-vWAYSTT_WTYPE_NEWLINES=send|space|marker(modetypeuniquement)WAYDOT_TYPE=0pour 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_KEYdoit venir de l'environnement ou d'un helper localconfig.confest maintenant obligatoire
Politique de donnees actuelle par defaut:
WAYSTT_PRIVACY_MODE=cloud-full: transcription et cleanup cloud autorises si le backend/fallback les utiliseWAYSTT_CLIPBOARD_MODE=raw-and-clean: brut puis clean vont dans le clipboardWAYSTT_UI=dunst: backend UI par defaut, encapsule via le module UIWAYSTT_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 backendwaysttpour cette session.WAYSTT_LANWHISPER_FALLBACK=openai: si la transcription LAN echoue apres capture, tente l'API OpenAI audio. Refuse par la politique runtime siWAYSTT_PRIVACY_MODEinterdit 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 desktopmain: ne recoit que code valide, corrections de bugs et changements deja verifiesdev: 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 doctorpython3 tests/run-text-pipeline-tests.py- test desktop nominal: dicter
ouvrez les guillemets test fermez les guillemets, puisa la ligne, puisnouveau paragraphe - verifier que le resultat arrive correctement dans le sink actif sans commande Markdown implicite