<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: elboKazQC</title>
    <description>The latest articles on DEV Community by elboKazQC (@elbokazqc).</description>
    <link>https://dev.to/elbokazqc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3989535%2F6bc332b1-bfc3-40c5-832b-145b0624bb35.png</url>
      <title>DEV Community: elboKazQC</title>
      <link>https://dev.to/elbokazqc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elbokazqc"/>
    <language>en</language>
    <item>
      <title>3 semaines de build-in-public plus tard : 4 abonnés, 0 vente, et le bug de hotkey qui m'a pris 2 soirs</title>
      <dc:creator>elboKazQC</dc:creator>
      <pubDate>Mon, 06 Jul 2026 16:20:40 +0000</pubDate>
      <link>https://dev.to/elbokazqc/3-semaines-de-build-in-public-plus-tard-4-abonnes-0-vente-et-le-bug-de-hotkey-qui-ma-pris-2-jfh</link>
      <guid>https://dev.to/elbokazqc/3-semaines-de-build-in-public-plus-tard-4-abonnes-0-vente-et-le-bug-de-hotkey-qui-ma-pris-2-jfh</guid>
      <description>&lt;p&gt;Ça fait trois semaines que je publie ici en mode transparent sur Tania Dictée, mon outil de dictée vocale FR-Québec. Le premier article avait un titre franc : 0 inscrit, 3 jours pour valider l'idée. Il a eu une réaction. Les deux suivants, sur le code-switching et la vie privée, zéro.&lt;/p&gt;

&lt;p&gt;Alors on continue avec les vrais chiffres, plus un bug qui m'a fait perdre deux soirées et qui vaut la peine d'être raconté.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les chiffres, sans les habiller
&lt;/h2&gt;

&lt;p&gt;Sur dev.to : 3 articles publiés, 4 abonnés au blog. Les 4 sont arrivés en silence, aucun commentaire, aucune réaction associée. Moins de 25 vues par article. Une seule réaction au total, sur le tout premier post.&lt;/p&gt;

&lt;p&gt;Sur X (@TaniaDictee) : 1 abonné. Sur Hacker News, mon karma est à 1. Le repo GitHub a 0 star.&lt;/p&gt;

&lt;p&gt;Zéro vente. Le produit est à 9$ CAD sur Gumroad depuis des semaines, personne n'a encore acheté.&lt;/p&gt;

&lt;p&gt;Je pourrais dramatiser ou je pourrais dire que c'est normal pour un projet solo à budget zéro. La vérité est entre les deux : c'est petit, mais dev.to est le seul endroit où quelque chose bouge, même faiblement. Alors j'y mets plus d'énergie plutôt que de disperser sur cinq canaux qui ne répondent pas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le bug qui m'a pris deux soirs
&lt;/h2&gt;

&lt;p&gt;Tania Dictée fonctionne en push-to-talk : tu tiens F6, tu parles, tu relâches, ça transcrit et ça colle le texte où t'as le curseur. Simple sur papier. Sauf que la détection du relâchement de touche sur Windows n'est pas aussi fiable qu'on pense.&lt;/p&gt;

&lt;p&gt;Le module &lt;code&gt;keyboard&lt;/code&gt; en Python expose deux événements : &lt;code&gt;add_hotkey&lt;/code&gt; pour la pression, &lt;code&gt;on_release_key&lt;/code&gt; pour le relâchement. Mon premier réflexe a été de démarrer l'enregistrement sur la pression et de l'arrêter sur le relâchement. Ça marchait... la plupart du temps.&lt;/p&gt;

&lt;p&gt;Le problème : si tu relâches F6 pendant qu'une autre fenêtre a le focus, ou si Windows avale l'événement à cause d'un conflit avec un autre hook clavier actif (j'en avais un autre qui tournait pour une raison complètement différente), l'événement de relâchement ne se déclenche jamais. Résultat : Tania reste convaincue que tu parles encore. Elle enregistre en boucle jusqu'à ce que tu réappuies sur F6, ce qui bascule l'état dans le mauvais sens et fige l'app dans un état bizarre.&lt;/p&gt;

&lt;p&gt;La vraie source du bug, ce n'était pas mon code d'enregistrement, c'était une hypothèse fausse : je pensais qu'un événement clavier Windows me serait toujours livré. Dans mon cas il ne l'était pas, surtout avec plusieurs hooks actifs en parallèle.&lt;/p&gt;

&lt;p&gt;La solution qui a fini par tenir : au lieu de dépendre uniquement de l'événement &lt;code&gt;on_release_key&lt;/code&gt;, j'ai ajouté un &lt;code&gt;threading.Timer&lt;/code&gt; qui revérifie activement l'état des touches à intervalle court avec &lt;code&gt;keyboard.is_pressed()&lt;/code&gt;. Si aucune des touches du hotkey n'est physiquement pressée, on arrête l'enregistrement, peu importe si l'événement de relâchement est arrivé ou pas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_schedule_stop_if_hotkey_released&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# debounce configurable, pas un chiffre magique code en dur
&lt;/span&gt;    &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;release_debounce_ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;1000.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_stop_if_hotkey_inactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;daemon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_stop_if_hotkey_inactive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# on ne fait pas confiance a l'evenement de relachement :
&lt;/span&gt;    &lt;span class="c1"&gt;# on verifie l'etat physique reel des touches
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_pressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hotkey_keys&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop_recording&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En gros : ne fais pas confiance à l'événement, vérifie l'état réel. Ça semble évident écrit comme ça, mais sur le coup j'ai passé deux soirées à ajouter des logs, suspecter le driver du micro, suspecter faster-whisper, avant de réaliser que le vrai coupable était une hypothèse sur le comportement du clavier que je n'avais jamais vérifiée.&lt;/p&gt;

&lt;p&gt;Il y a un deuxième détail qui a mordu en même temps : &lt;code&gt;add_hotkey&lt;/code&gt; avec &lt;code&gt;suppress=True&lt;/code&gt; empêche la touche d'atteindre les autres apps (utile pour que F6 ne tape pas un caractère parasite dans ton éditeur), mais ça change aussi comment Windows route certains événements de relâchement selon le contexte de focus. Ce n'est documenté nulle part de façon limpide, il a fallu tester à la main pour comprendre.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce que ça change concrètement
&lt;/h2&gt;

&lt;p&gt;Depuis ce fix, Tania tourne chez moi tous les jours sans ce comportement fantôme. C'est le genre de bug qu'un utilisateur externe aurait rencontré dans sa première semaine et qui aurait tué la confiance direct. Bonne nouvelle : c'est réglé avant que qui que ce soit d'autre que moi ne l'ait vécu, parce que pour l'instant je suis mon seul utilisateur.&lt;/p&gt;

&lt;p&gt;C'est aussi une leçon plus large sur le solo dev : quand t'es le seul testeur, les bugs les plus vicieux sont ceux qui dépendent du contexte système (autres apps ouvertes, autres hooks actifs, focus de fenêtre) et que tu ne reproduis pas facilement en isolation. Le fix a fini par être plus robuste que l'approche initiale précisément parce qu'il ne fait plus confiance à un seul signal.&lt;/p&gt;

&lt;p&gt;Au fond, c'est pour ça que je bâtis ce truc : si tu dictes en français québécois une bonne partie de ta journée et que l'idée d'envoyer ta voix dans le cloud te dérange, c'est exactement l'outil que j'aurais voulu trouver au lieu de le coder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Où on en est
&lt;/h2&gt;

&lt;p&gt;Le code reste ouvert sous licence MIT sur &lt;a href="https://github.com/elboKazQC/tania-dictee" rel="noopener noreferrer"&gt;github.com/elboKazQC/tania-dictee&lt;/a&gt; si le bug ou le hotkey handling vous intéresse en détail. Toujours 0 star, ça ne me dérange pas de le dire.&lt;/p&gt;

&lt;p&gt;La suite : je continue de nourrir dev.to en priorité puisque c'est le seul canal où il se passe quelque chose, même petit. Prochain post, probablement le premier vrai benchmark de précision (WER) que j'ai promis dans les articles précédents et que je n'ai toujours pas publié. Il est temps.&lt;/p&gt;

&lt;p&gt;Si vous avez déjà chassé un bug qui se cachait derrière une hypothèse fausse sur un événement système (clavier, réseau, fichier), ça m'intéresse de l'entendre en commentaire.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>opensource</category>
      <category>python</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>Dicter du code confidentiel : pourquoi j'ai arrêté d'envoyer ma voix dans le cloud</title>
      <dc:creator>elboKazQC</dc:creator>
      <pubDate>Tue, 30 Jun 2026 14:22:35 +0000</pubDate>
      <link>https://dev.to/elbokazqc/dicter-du-code-confidentiel-pourquoi-jai-arrete-denvoyer-ma-voix-dans-le-cloud-1e9d</link>
      <guid>https://dev.to/elbokazqc/dicter-du-code-confidentiel-pourquoi-jai-arrete-denvoyer-ma-voix-dans-le-cloud-1e9d</guid>
      <description>&lt;p&gt;Je suis consultant IA. La moitié de mes journées, je pilote des modèles de langage pour des clients. Je dicte beaucoup : des prompts à Claude Code, des notes de conception, des noms de variables, des bouts de logique métier qui ne sont pas encore publics.&lt;/p&gt;

&lt;p&gt;Pendant un bon moment, j'ai utilisé une solution de dictée cloud. Commode. Ça marche bien. Et puis un jour j'ai réalisé ce qui part réellement sur leurs serveurs quand j'appuie sur le bouton d'enregistrement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce que ta voix contient vraiment
&lt;/h2&gt;

&lt;p&gt;Quand tu dictes un prompt à un outil de code ou à un agent IA, t'as pas l'impression de transmettre quelque chose de sensible. T'es dans ta bulle, t'es chez toi, c'est juste toi qui parles à un micro.&lt;/p&gt;

&lt;p&gt;Mais dans ce flux audio, il y a le nom du produit client qui n'est pas encore annoncé. Il y a la logique d'un flux de données propriétaire. Il y a les noms des tables, des endpoints, des règles d'affaires. Il y a les acronymes internes qui permettent à n'importe qui de chercher sur Google et de comprendre dans quelle industrie tu travailles.&lt;/p&gt;

&lt;p&gt;Pour les outils de dictée cloud comme Wispr Flow, Otter ou les fonctions vocales intégrées à divers services, cet audio transite par des serveurs distants. Ce qui arrive ensuite, c'est leur affaire : rétention du contenu pour amélioration du modèle, accès interne potentiel, politiques qui changent silencieusement d'une mise à jour des CGU à l'autre.&lt;/p&gt;

&lt;p&gt;Sous NDA, t'es responsable de ça. Pas eux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce que "100 % local" veut dire en pratique
&lt;/h2&gt;

&lt;p&gt;La promesse d'une solution locale, c'est que l'audio ne quitte jamais ton disque. Point. Pas de requête réseau, pas de token envoyé quelque part, pas de métadonnée. Le modèle Whisper tourne directement sur ta machine.&lt;/p&gt;

&lt;p&gt;Il y a un test simple pour le vérifier : tu coupes ta connexion Wi-Fi, tu dictes, tu lâches le bouton. Si la transcription arrive, c'est 100 % local. Sinon, quelque chose part quelque part.&lt;/p&gt;

&lt;p&gt;Tu peux aussi ouvrir un moniteur réseau (Little Snitch, Glasswire, ou simplement Wireshark si t'as le goût de souffrir un peu) pendant une session de dictée, et regarder si des connexions sortantes s'ouvrent. Avec une solution vraiment locale, t'as rien. C'est le silence réseau qui prouve la confidentialité, pas la politique de vie privée du vendor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le comment technique, sans faire semblant que c'est compliqué
&lt;/h2&gt;

&lt;p&gt;Le moteur sous le capot, c'est faster-whisper, une implémentation optimisée de Whisper par Systran. Plus rapide que l'originale d'OpenAI sur CPU, et elle tourne proprement sur Windows sans configuration ésotérique.&lt;/p&gt;

&lt;p&gt;La première fois que tu l'actives, le modèle (quelques centaines de mégaoctets selon la taille choisie) se télécharge une fois. Après ça, plus besoin de connexion. Si tu veux voir à quoi ressemble un appel de base :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;faster_whisper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WhisperModel&lt;/span&gt;

&lt;span class="n"&gt;modele&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WhisperModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;small&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compute_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;int8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;modele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transcribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;audio.wav&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;initial_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;useState, Stripe, fa que, pis, API REST, webhook&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;segment&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;segments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le paramètre &lt;code&gt;initial_prompt&lt;/code&gt; est la pièce souvent oubliée. Il force le modèle à s'attendre à certains mots, ce qui améliore la transcription des termes techniques et des expressions québécoises. Tu peux y mettre des noms de variables, des mots de ton domaine, des expressions typiques de ton projet. La limite est d'environ 224 tokens, pis ça se remplit vite, fa que sois sélectif.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le compromis honnête
&lt;/h2&gt;

&lt;p&gt;Je vais pas te vendre ça comme une solution parfaite, parce que c'est pas le cas.&lt;/p&gt;

&lt;p&gt;L'accent québécois demeure plus difficile pour Whisper que le français de France standard. Sur un texte technique avec du vocabulaire précis, le glossaire dans &lt;code&gt;initial_prompt&lt;/code&gt; aide vraiment. Sur une phrase purement conversationnelle avec des expressions régionales denses, attends-toi à plus de corrections manuelles qu'en FR standard. C'est la réalité. Je publie pas de chiffres de taux d'erreur parce que j'ai pas encore fait le benchmark formel, pis je vais pas inventer un nombre.&lt;/p&gt;

&lt;p&gt;C'est aussi Windows uniquement pour l'instant. Mac et Linux, c'est pas là. Et l'interface reste en phase alpha : fonctionnelle, mais elle a pas encore le polish d'un produit mature.&lt;/p&gt;

&lt;p&gt;Le setup de base demande quelques étapes techniques si tu pars de zéro. C'est précisément pourquoi j'ai fini par empaqueter tout ça.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi j'ai packagé ça
&lt;/h2&gt;

&lt;p&gt;J'avais déjà monté ce pipeline pour moi-même. Faster-whisper installé, un petit script Python, push-to-talk sur F6 (maintiens pour parler, relâche pour transcrire), intégration au presse-papier pour coller dans n'importe quelle app. Ça marchait.&lt;/p&gt;

&lt;p&gt;J'ai montré ça à quelques personnes. La réaction habituelle : "c'est cool, mais je vais pas m'asseoir pour installer tout ça."&lt;/p&gt;

&lt;p&gt;Fa que j'ai fait l'installeur. 63 MB. Tu lance, t'installes, t'appuies sur F6. Le code est ouvert sous licence MIT sur &lt;a href="https://github.com/elboKazQC/tania-dictee" rel="noopener noreferrer"&gt;github.com/elboKazQC/tania-dictee&lt;/a&gt; si tu veux voir exactement ce qui tourne sur ta machine (pis c'est là que la transparence privacy commence vraiment : open source, pas juste une promesse dans une FAQ).&lt;/p&gt;

&lt;p&gt;La version packagée est disponible à 9 $ CAD, achat unique, sur Gumroad. Pas d'abonnement.&lt;/p&gt;

&lt;p&gt;Zéro utilisateur externe à date. Je suis en mode build-in-public, pis je te parle depuis le début du tunnel, pas depuis l'autre bout.&lt;/p&gt;

&lt;p&gt;Si le sujet t'intéresse, la waitlist est ici : &lt;a href="https://elbokazqc.github.io/tania-dictee" rel="noopener noreferrer"&gt;elbokazqc.github.io/tania-dictee&lt;/a&gt;&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>privacy</category>
      <category>ai</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>La dictée vocale en français québécois, c'est pas un gadget : c'est un problème de code-switching</title>
      <dc:creator>elboKazQC</dc:creator>
      <pubDate>Fri, 26 Jun 2026 18:17:19 +0000</pubDate>
      <link>https://dev.to/elbokazqc/la-dictee-vocale-en-francais-quebecois-cest-pas-un-gadget-cest-un-probleme-de-code-switching-1fjg</link>
      <guid>https://dev.to/elbokazqc/la-dictee-vocale-en-francais-quebecois-cest-pas-un-gadget-cest-un-probleme-de-code-switching-1fjg</guid>
      <description>&lt;p&gt;J'utilise la dictée vocale tous les jours depuis six mois. Pas pour taper moins vite. Pour penser plus vite quand je vibe-code avec Claude Code et Cursor.&lt;/p&gt;

&lt;p&gt;Pis j'ai fini par construire mon propre outil parce que les outils existants me tapaient sur les nerfs d'une façon très précise.&lt;/p&gt;




&lt;h2&gt;
  
  
  Le problème réel
&lt;/h2&gt;

&lt;p&gt;Quand tu travailles en tech au Québec, tes phrases ressemblent à ça :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"OK fa que je fais un useState pour le component pis je passe le handler en props"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ça, c'est une phrase normale. Personne en tech QC ne parle autrement. Pas parce qu'on est négligents avec la langue. Parce que le vocabulaire technique vient de l'anglais et qu'on le soude naturellement au français au fil de la pensée.&lt;/p&gt;

&lt;p&gt;Ça s'appelle le code-switching. Et c'est là que la plupart des outils de dictée craquent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que les outils mainstream font mal
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dragon NaturallySpeaking
&lt;/h3&gt;

&lt;p&gt;Dragon, c'est le vieux standard. Médical, juridique, corporate. Ça coûte environ 500$ en une shot. C'est lourd à installer et à entraîner. Et sa gestion du français québécois avec des termes tech intercalés... c'est en gros zéro.&lt;/p&gt;

&lt;p&gt;"useState" devient "usé état". "Fa que" devient "faque" parfois, "fake" d'autres fois. C'est aléatoire. T'as intérêt à corriger après chaque phrase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wispr Flow
&lt;/h3&gt;

&lt;p&gt;Wispr Flow est plus moderne. UX propre, cross-platform, et leur gestion du français s'est améliorée. Leur plan Pro coûte 15$/mois, soit environ 144$/an.&lt;/p&gt;

&lt;p&gt;Mais il y a un problème structurel que leur propre doc admet : la détection de langue se fait par session, pas par mot.&lt;/p&gt;

&lt;p&gt;Autrement dit : Wispr détecte la langue une fois au début de la session. Si tu commences en français, il reste en mode français jusqu'à la fin. Les mots anglais qui arrivent dans la phrase, il tente de les translittérer en français. "Handler" peut devenir "andler" ou "ender", "props" survit parfois, parfois pas. C'est variable.&lt;/p&gt;

&lt;p&gt;Pour une phrase de temps en temps avec un mot anglais, ça passe. Pour un vibe-coder québécois qui switch constamment dans la même phrase, ça ne passe pas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pourquoi c'est un vrai problème, pas un détail
&lt;/h2&gt;

&lt;p&gt;La dictée vocale utile, c'est quand tu peux parler aussi vite que tu penses et que la transcription suit. Le moment où tu dois ralentir pour articuler différemment, ou corriger constamment après, tu perds exactement l'avantage pour lequel t'as adopté l'outil.&lt;/p&gt;

&lt;p&gt;J'ai fini par faire le calcul : le temps de correction de franglais = le temps que je sauvais à dicter. Retour à la case départ.&lt;/p&gt;

&lt;p&gt;Fa que j'ai décidé de régler ça directement.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que j'ai construit
&lt;/h2&gt;

&lt;p&gt;Tania Dictée est un outil de dictée vocale Windows, 100% local. Tu maintiens F6, tu parles, tu relâches. Le texte se colle dans n'importe quelle app active : VS Code, Cursor, Claude Code, Gmail, peu importe.&lt;/p&gt;

&lt;p&gt;La différence principale par rapport aux outils existants :&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traitement par phrase, pas par session.&lt;/strong&gt; Chaque phrase passe à travers Whisper (via faster-whisper) avec un glossaire FR-QC intégré d'office. "useState", "handler", "fa que", "pis", "Supabase", "Cursor", tout ça est dans le glossaire. Le modèle sait que c'est du franglais québécois. Il n'essaie pas de choisir une langue et de tout forcer dedans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100% local, zéro cloud.&lt;/strong&gt; Ce que tu dictes reste sur ton PC. Pas de compte à créer. Pas de tokens qui partent sur un serveur externe. Pour un consultant sous NDA ou un dev avec du code proprio, ça compte.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows-first, sans friction.&lt;/strong&gt; Installeur d'environ 63 MB. Pas de Python à installer, pas de droits admin. Tu dézippe, tu lances, ça marche.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prix : 9$ CAD une seule fois.&lt;/strong&gt; Pas d'abonnement. Un achat, c'est fini.&lt;/p&gt;

&lt;p&gt;Le code est open source MIT sur GitHub (github.com/elboKazQC/tania-dictee).&lt;/p&gt;




&lt;h2&gt;
  
  
  Ce que je ne prétends pas (build-in-public oblige)
&lt;/h2&gt;

&lt;p&gt;Je construis en transparent, alors voici ce qui est vrai à date :&lt;/p&gt;

&lt;p&gt;Zéro utilisateur externe. C'est moi qui l'utilise tous les jours. La première vraie validation externe, c'est ce que je cherche en ce moment.&lt;/p&gt;

&lt;p&gt;Pas de version Mac ou Linux. Windows only, point.&lt;/p&gt;

&lt;p&gt;L'UX est en alpha. Il n'y a pas encore de paramètres graphiques élaborés, pas d'onboarding fancy.&lt;/p&gt;

&lt;p&gt;Le benchmark de précision (protocole WER contre Whisper vanilla et Dragon) n'est pas encore publié. Le protocole est prêt et les mesures arrivent. Je ne vais pas inventer des chiffres d'ici là.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pourquoi ça peut quand même marcher
&lt;/h2&gt;

&lt;p&gt;La niche est petite mais réelle : développeurs et consultants qui travaillent en franglais québécois, qui vibe-codent, qui ont du code proprio à protéger. Les outils qui existent ne sont pas conçus pour eux.&lt;/p&gt;

&lt;p&gt;La preuve du concept existe : moi. Six mois d'usage quotidien, ça m'a économisé du temps réel. Si ça marche pour moi, il y a probablement d'autres personnes avec le même problème.&lt;/p&gt;

&lt;p&gt;Si t'as déjà pesté contre Dragon ou Wispr Flow quand tu dictes du franglais tech, j'aimerais t'entendre. Qu'est-ce qui t'a le plus agacé ? Est-ce que c'était le code-switching, la précision globale, ou autre chose ?&lt;/p&gt;

&lt;p&gt;La waitlist est à &lt;a href="https://elbokazqc.github.io/tania-dictee" rel="noopener noreferrer"&gt;https://elbokazqc.github.io/tania-dictee&lt;/a&gt;. 9$ CAD, achat unique, si jamais tu veux soutenir le projet et être parmi les premiers testeurs externes.&lt;/p&gt;

&lt;p&gt;-- Vincent&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>productivity</category>
      <category>ai</category>
      <category>indiehackers</category>
    </item>
    <item>
      <title>Build-in-public : 0 inscrit, 3 jours pour valider mon outil de dictée vocale FR/QC</title>
      <dc:creator>elboKazQC</dc:creator>
      <pubDate>Wed, 17 Jun 2026 17:12:50 +0000</pubDate>
      <link>https://dev.to/elbokazqc/build-in-public-0-inscrit-3-jours-pour-valider-mon-outil-de-dictee-vocale-frqc-54ma</link>
      <guid>https://dev.to/elbokazqc/build-in-public-0-inscrit-3-jours-pour-valider-mon-outil-de-dictee-vocale-frqc-54ma</guid>
      <description>&lt;p&gt;Je lance un compte à rebours public.&lt;/p&gt;

&lt;p&gt;Point de contrôle : 20 juin 2026.&lt;br&gt;
Cible : 25 inscrits à la waitlist.&lt;br&gt;
En-dessous, je repense le plan.&lt;/p&gt;

&lt;p&gt;Voilà où on en est.&lt;/p&gt;

&lt;h2&gt;
  
  
  C'est quoi Tania Dictée
&lt;/h2&gt;

&lt;p&gt;Un outil de dictée vocale Windows, 100 % local (Whisper via faster-whisper : modèle small sur CPU, large-v3 sur GPU), optimisé pour le français québécois et le franglais. Tu maintiens F6, tu parles, tu relâches, ton texte apparaît dans n'importe quelle app active.&lt;/p&gt;

&lt;p&gt;Pourquoi j'ai bâti ça : j'ai essayé Dragon NaturallySpeaking et Wispr Flow. Aucun des deux ne gère le code-switching FR/EN dans la même phrase. Et Wispr Flow à 144 $/an pour transcrire mon code à moitié de travers, c'est non.&lt;/p&gt;

&lt;p&gt;Résultat : j'ai bâti le mien. Ça fait 6 mois que je l'utilise tous les jours pour vibe coder avec Claude Code et Cursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  L'état du produit (honnête)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Installeur Windows (63 Mo, pas de Python, pas de droits admin requis)&lt;/li&gt;
&lt;li&gt;Zéro cloud, zéro compte, zéro abonnement&lt;/li&gt;
&lt;li&gt;Glossaire FR-QC inclus (Cursor, Supabase, useState, "pis", "fa que"...)&lt;/li&gt;
&lt;li&gt;Prix : 9 $ CAD sur Gumroad&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce qui manque encore : version Mac, UX plus polie, benchmark WER public.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pourquoi je publie ça maintenant
&lt;/h2&gt;

&lt;p&gt;Le produit marche pour moi, mais j'ai 0 donnée sur s'il aide quelqu'un d'autre.&lt;/p&gt;

&lt;p&gt;Le seul moyen de le savoir : aller chercher des early adopters, leur faire tester, voir si ça colle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le plan des 3 prochains jours
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Posts X @TaniaDictee quotidiens (build-in-public transparent)&lt;/li&gt;
&lt;li&gt;Découvrabilité GitHub (annuaires d'outils Whisper)&lt;/li&gt;
&lt;li&gt;Point de contrôle public le 20 juin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si tu es dev québécois, consultant qui dicte beaucoup, ou juste curieux d'un outil Whisper local sur Windows : &lt;a href="https://elbokazqc.github.io/tania-dictee" rel="noopener noreferrer"&gt;waitlist ici&lt;/a&gt; ou achat direct 9 $ CAD.&lt;/p&gt;

&lt;p&gt;Pas de spam. Juste les updates concrètes.&lt;/p&gt;

&lt;p&gt;-- Vincent&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>indiehackers</category>
      <category>ai</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
