Letext — un éditeur de texte type Word avec IA 100 % locale (via Ollama). Aucune donnée ne quitte votre machine.
App sœur de Letcalc (tableur) : même stack, même esthétique, même IA locale, verrou partagé pour qu'une seule génération tourne à la fois.
open ~/Documents/Letext/dist/mac-arm64/Letext.appnpm startnpm run start:webImportant : ouvrez bien http://localhost:4711 dans le navigateur (pas le fichier index.html directement), sinon Ollama sera injoignable.
- Ollama installé et lancé (ollama.com) avec au moins un modèle :
ollama pull granite4.1:8b # ou tout autre modèle
- Mise en forme complète : gras, italique, souligné, barré, exposant/indice
- Polices, tailles, couleur du texte et surligneur
- Titres (T1–T3), listes à puces/numérotées, retraits, alignements
- Tableaux (grille interactive), images, liens (Maj+Ctrl/Cmd+K), lignes horizontales
- Collage assaini : les styles de Word ou d'une page web sont retirés, seule la structure est gardée
Bouton Nettoyer (onglets Accueil et Révision) ou Maj+Ctrl/Cmd+N. Chaque option est
activable séparément et le nombre d'occurrences trouvées est affiché avant d'agir :
| Option | Ce qui est corrigé |
|---|---|
| Caractères invisibles | espaces de largeur nulle, BOM, tirets conditionnels, marques de direction |
| Espaces | insécables, multiples, tabulations, espaces en fin de ligne |
| Retours à la ligne parasites | phrases coupées et césures des copies de PDF (respon-\nsable → responsable) |
| Puces et citations | puces exotiques (Word, Wingdings), chevrons > des mails |
| Ponctuation | ... → …, !!! → !, espaces avant ; : ! ? |
| Guillemets français | "mot" → « mot », apostrophes typographiques |
| Traqueurs dans les URL | utm_*, fbclid, gclid, igshid… |
| Paragraphes vides | séries de lignes vides |
| Espaces insécables | typographie française stricte (désactivé par défaut) |
| Balisage Markdown | **gras**, ##, `code`, [lien](url) (désactivé par défaut) |
| Émojis | suppression (désactivé par défaut) |
- La mise en forme est préservée : le nettoyage travaille dans les nœuds de texte, pas sur du texte brut.
- Copier au propre (
Maj+Ctrl/Cmd+C) met le texte nettoyé dans le presse-papiers sans toucher au document. - Le sous-ensemble « artefacts » (invisibles, espaces, césures, puces) est appliqué automatiquement au collage et à toute sortie de l'IA.
- 15 actions : corriger, style, formel, simplifier, raccourcir, développer, résumer, rédiger un e-mail, continuer le texte, idées, plan, traduire FR/EN/ES/RU
- Reformulation par phrase : 3 variantes (formelle, simple, concise) cliquables
- Suggestions en direct : relecture de la phrase terminée, soulignée discrètement, bulle à la demande (Tab)
- Suivi des modifications type Word : accepter/refuser une correction à la fois
- Diff mot-à-mot avec statistiques (corrections, caractères modifiés, taux)
- Streaming en direct avec compteur de tokens et vitesse, bouton Stop
Deux blocs de consignes que l'on remplit une fois et qui s'ajoutent automatiquement à chaque action IA.
- Contexte du document : destinataire, objectif du texte, message ou document de référence (jusqu'à 4 000 caractères — le mail du client, par exemple), points à ne pas oublier, à éviter. Il est mémorisé par document : changer de document change de contexte.
- Style d'écriture : huit réglages guidés (ton, vouvoiement, registre, personne, longueur des phrases, vocabulaire, densité, entrée en matière), huit interdits à cocher (emojis, points d'exclamation, superlatifs, anglicismes, jargon, formules toutes faites, questions rhétoriques, listes à puces), mots à privilégier et à bannir, formule de clôture, et un extrait de votre écriture que le modèle imite. Le tout s'enregistre en profils réutilisables (client, interne…).
- Les quatre réglages les plus utiles sont directement dans le ruban ; le reste dans « Style détaillé… ».
- Les consignes qui raccourcissent (phrases courtes, densité, entrée directe) assouplissent les bornes de longueur du harnais. Sans cela il rejetait le résultat comme « trop court » et relançait le modèle en lui demandant d'écrire plus — l'inverse exact du réglage demandé. Mesuré sur granite4.1:8b : 8 sorties sur 8 tombaient sous la borne, jusqu'à 0,37.
- Le panneau signale les consignes que le modèle n'a pas suivies quand c'est vérifiable mécaniquement (tutoiement, vouvoiement, points d'exclamation, emojis, listes à puces, phrases courtes). Un réglage ignoré en silence passerait pour un réglage appliqué.
- Au lancement d'une action, le panneau annonce ce qui a réellement été transmis (« Transmis au modèle : 5 champs de contexte, 12 consignes de style »), et le dit aussi quand rien ne l'a été — un contexte rempli puis ignoré passerait sinon pour une panne.
- L'indicateur du ruban dit toujours ce qui part réellement : « Contexte : 5 champs · Style : 12 consignes ».
Ce qu'un petit modèle en fait, mesuré. Sur granite4.1:8b, six tirages par condition : longueur de phrase, absence de point d'exclamation, absence de liste et propreté du format sont respectées 6 fois sur 6 ; le tutoiement ne passe pas (0 sur 6, y compris sur la rédaction d'e-mail, avec ou sans exemple few-shot, et avec une formulation explicite). Le même modèle tutoie pourtant du premier coup quand c'est la seule consigne : ce n'est pas la plomberie mais l'attention du modèle sur une consigne noyée parmi d'autres. D'où l'avertissement du panneau plutôt qu'une promesse.
Ces consignes ne sont pas ajoutées partout. La correction reste hermétique — un correcteur qui reçoit un contexte se met à réécrire. Le résumé et les traductions ne reçoivent pas le document de référence (il finirait résumé ou traduit lui aussi) mais gardent le vouvoiement et le registre. Tout part dans le message système, jamais dans le texte à traiter : les contrôles de longueur comparent la sortie à l'entrée, et un contexte glissé dans l'entrée fausserait tous les ratios.
Un modèle 3-8 B répond rarement au format demandé du premier coup. Le harnais s'en charge :
- Exemple minimal (few-shot) joint à chaque action : c'est ce qui fixe le format bien mieux qu'une consigne.
- Nettoyage systématique de la réponse : blocs de raisonnement (
<think>, y compris jamais refermés), blocs```, préambules (« Voici le texte corrigé : »), notes finales, guillemets enveloppants. - Contrôle de vraisemblance avant de proposer le résultat : réponse vide, longueur hors bornes, consigne recopiée, texte transformé en liste, modèle parti en boucle.
- Une relance automatique en cas d'échec, à température nulle et avec une consigne chiffrée (« ta réponse doit faire moins de 420 caractères ») — un petit modèle n'agit pas sur « trop long ».
- Découpage des longs documents en morceaux : un morceau que le modèle rate est conservé dans sa version d'origine et signalé, au lieu de tronquer ou de résumer le document.
- Avertissement si une « correction » réécrit plus de 40 % des mots.
- Options adaptées à l'action : température,
num_ctxcalculé sur la taille réelle du texte et de la consigne (contexte et style compris — Ollama tronque le début d'une invite trop longue, donc la consigne elle-même, et répond 200 sans le moindre avertissement),num_predictborné, pénalité de répétition. - Modèle gardé en mémoire (
keep_alive) et préchargé dès qu'il est choisi : plus d'attente de chargement à la première reformulation. - Chien de garde : 3 minutes d'attente pour le premier token (chargement du modèle), puis 60 s de silence maximum en cours de réponse. Un flux coupé est refusé, jamais rendu comme une réponse complète.
- Verrou partagé avec Letcalc : « IA occupée par Letcalc » puis nouvelle tentative automatique.
- Protection anti-perte : avertissement avant d'écraser ou de fermer un document modifié
- Autosave serveur discret (2,5 s) + brouillon local restauré au démarrage
- Historique de versions : chaque enregistrement explicite crée un instantané (30 conservés)
- Fichiers récents, Enregistrer sous (Maj+Ctrl/Cmd+S)
- Import : .docx (Word), .txt, .md, .html
- Export : .docx natif (généré sans dépendance), PDF (impression), .html, .txt, .md
- Panneau plan : navigation par titres dans les documents longs
- Modèle rapide dédié aux suggestions (le gros modèle reste pour les tâches lourdes)
- Raccourcis Markdown à la frappe :
#→ titre,-→ liste,1.→ liste numérotée,>→ citation - Recherche & remplacement (Ctrl+F), palette de commandes (Ctrl+K, 28 commandes)
- Undo/redo fiable (100 niveaux), mise en page A4/Lettre/Légal, thème sombre, zoom, pleine page
- Info-bulles explicatives sur chaque icône, avec le raccourci associé
| Raccourci | Action |
|---|---|
| Ctrl/Cmd+S | Enregistrer (crée une version) |
| Maj+Ctrl/Cmd+S | Enregistrer sous |
| Ctrl/Cmd+A | Tout sélectionner (document entier) |
| Ctrl/Cmd+F | Rechercher & remplacer |
| Ctrl/Cmd+K | Palette de commandes |
| Maj+Ctrl/Cmd+K | Insérer un lien |
| Maj+Ctrl/Cmd+N | Nettoyer le texte (en mode web, Chrome capte ce raccourci : utiliser le bouton Nettoyer) |
| Maj+Ctrl/Cmd+C | Copier au propre |
| Maj+Ctrl/Cmd+V | Coller sans mise en forme |
| Tab | Voir puis accepter la suggestion en direct |
| Échap | Ignorer la suggestion / fermer une fenêtre |
| Ctrl/Cmd+Z / Maj+Z | Annuler / Rétablir |
| Ctrl/Cmd+B / I / U | Gras / Italique / Souligné |
- Le serveur intégré n'écoute que sur 127.0.0.1 : rien n'est accessible depuis le réseau local.
- Les requêtes portant une origine étrangère sont refusées (403) : une page web ouverte à côté ne peut ni lire ni écrire vos documents, ni piloter Ollama.
- Le collage est assaini dans un document inerte (
DOMParser) : aucun gestionnaire d'événement, aucun chargement de ressource distante, et les liensjavascript:/data:sont retirés. - Aucune donnée ne sort de la machine : le seul appel réseau est vers Ollama en local.
npm install
npm test # 12 suites jsdom, 379 vérificationsnode tests/live-check.js granite4.1:8b vérifie le harnais contre un vrai modèle Ollama.
├── main.js # Processus principal Electron
├── preload.js # Pont menu Electron → page
├── server.js # Serveur HTTP intégré (UI + proxy Ollama + documents + historique)
├── public/
│ ├── index.html # Interface (sprite SVG inline)
│ ├── app.js # Éditeur, harnais IA, nettoyage de texte
│ └── style.css # Styles (thème clair/sombre, impression)
├── tests/ # Suites jsdom (npm test)
├── documents/ # Documents (mode web)
└── dist/ # App compilée (Letext.app)
Dans l'app de bureau, les documents sont stockés dans ~/Library/Application Support/letext/documents
(persistant entre les mises à jour), avec l'historique dans .history/.
npm install
npx electron-builder --mac dirSans certificat Apple, signer ensuite pour un lancement local (sinon crash au démarrage) :
APP="dist/mac-arm64/Letext.app"
xattr -cr "$APP"
find "$APP/Contents/Frameworks" -type f -name "*.dylib" -exec codesign --force --sign - {} \;
find "$APP/Contents/Frameworks" -maxdepth 1 \( -name "*.app" -o -name "*.framework" -o -name "*.xpc" \) -exec codesign --force --sign - {} \;
codesign --force --sign - "$APP"
codesign --verify --deep --strict "$APP"- Zéro dépendance runtime : serveur
httpnatif, aucune bibliothèque front (le .docx est généré à la main en ZIP + OOXML) - Le proxy Ollama évite tout problème CORS ;
OLLAMA_HOSTpermet de changer d'hôte /api/warmprécharge un modèle sans rien générer (et s'abstient si l'app sœur génère)- Le verrou
/tmp/letext-ollama.lockest commun à Letext et Letcalc (PID + horodatage 120 s) - Port 4711 (Letcalc utilise 4712) ; si le port est occupé, l'app réutilise le serveur existant
Voir AGENTS.md pour les règles de développement à respecter.