<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>DevByBen's Blog</title>
        <link>https://devbyben.fr</link>
        <description>Articles on web development, DevOps, and technical feedback</description>
        <lastBuildDate>Sat, 16 May 2026 14:58:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>DevByBen Blog System</generator>
        <language>fr</language>
        <ttl>1800</ttl>
        <image>
            <title>DevByBen's Blog</title>
            <url>https://devbyben.fr/avatar.png</url>
            <link>https://devbyben.fr</link>
        </image>
        <copyright>All rights reserved 2026, DevByBen</copyright>
        <atom:link href="https://devbyben.fr/api/rss" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Orca : l'ADE open source qui veut remplacer ton IDE — et ça marche]]></title>
            <link>https://devbyben.fr/blog/orca-lade-open-source-qui-veut-remplacer-ton-ide-et-ca-marche</link>
            <guid>https://devbyben.fr/blog/orca-lade-open-source-qui-veut-remplacer-ton-ide-et-ca-marche</guid>
            <pubDate>Fri, 15 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Découvre Orca, l'Agent Development Environment open source qui centralise agents IA, worktrees Git, terminaux et browser intégré dans une seule interface. Fini le context switching permanent entre Claude Code, Codex, VS Code et GitHub.]]></description>
            <content:encoded><![CDATA[<h2>Le problème : trop d'outils, pas assez de flux</h2>
<p>On est en 2026. Les agents de codage IA sont partout — Claude Code, Codex, Cursor CLI, OpenCode, Gemini CLI… Chacun a ses forces, ses faiblesses, ses rate limits. Et si tu veux les utiliser ensemble ? C'est le bazar.</p>
<p>Tu dois :</p>
<ul>
<li>Ouvrir <strong>plusieurs terminaux</strong> pour chaque agent</li>
<li>Jouer avec <strong>les branches Git</strong> pour pas tout casser</li>
<li>Passer de VS Code à GitHub à Linear en permanence</li>
<li>Stasher tes changements, changer de branche, revenir…</li>
</ul>
<p>Bref, tu passes plus de temps à <strong>gérer tes outils</strong> qu'à <strong>shipper du code</strong>.</p>
<p>Orca résout ce problème avec une approche simple mais puissante : <strong>un environnement pensé pour les agents</strong>, pas seulement pour les humains.</p>
<hr />
<h2>Orca en 60 secondes</h2>
<p>Orca est un <strong>Agent Development Environment (ADE)</strong> — pas un IDE classique. C'est un environnement de développement conçu pour toi <strong>et</strong> tes agents IA, ensemble.</p>
<p>Le concept clé ? <strong>Chaque tâche a son propre worktree Git isolé</strong>, son propre terminal agent, et son propre onglet browser. Tu peux ainsi faire tourner plusieurs agents en parallèle sur le même repo, sans jamais faire de stash ou jongler avec les branches.</p>
<blockquote>
<p>Orca ne remplace pas tes agents. Il les orchestre.</p>
</blockquote>
<p>Lancé par <a href="https://stably.ai">Stably.ai</a>, le projet est <strong>open source sous licence MIT</strong> avec déjà <strong>2 400+ stars sur GitHub</strong>, 62 contributeurs et une communauté active sur Discord.</p>
<hr />
<h2>Les fonctionnalités qui changent la donne</h2>
<h3>Worktrees parallèles : une tâche = un worktree isolé</h3>
<p>C'est le cœur d'Orca. Quand tu démarres une nouvelle tâche, Orca crée automatiquement un <strong>worktree Git isolé</strong>. Pas besoin de stasher, de créer une branche, de faire des allers-retours.</p>
<p>Le scénario magique ? Tu écris un prompt, et Orca le <strong>distribue à 5 agents en parallèle</strong>. Chacun travaille dans son propre worktree. À la fin, tu compares les résultats, tu merges le meilleur. C'est ce qu'ils appellent le <strong>"fan out"</strong> — et c'est ridiculement puissant.</p>
<h3>Multi-agents natifs : Claude, Codex, Cursor, côte à côte</h3>
<p>Orca supporte nativement :</p>
<ul>
<li><strong>Claude Code</strong> (Anthropic)</li>
<li><strong>Codex</strong> (OpenAI)</li>
<li><strong>Cursor CLI</strong></li>
<li><strong>OpenCode</strong></li>
<li><strong>Gemini CLI</strong></li>
<li><strong>GitHub Copilot</strong></li>
<li><strong>Pi</strong> (Inflection)</li>
</ul>
<p>Et si ton agent préféré n'est pas dans la liste, tu peux <strong>ajouter n'importe quel agent CLI</strong> en quelques clics. Tu utilises tes propres clés API, tes propres abonnements. Orca est juste l'orchestrateur.</p>
<h3>Terminaux Ghostty-style avec splits infinis</h3>
<p>Les terminaux d'Orca sont inspirés de <strong>Ghostty</strong> — rendu WebGL fluide, splits infinis, scrollback restauré au redémarrage, et recherche complète dans l'historique. Tu peux arranger agents, terminaux, browsers, diffs et fichiers dans des <strong>split panes</strong> qui correspondent à la forme de ta tâche.</p>
<h3>Design Mode : un vrai browser Chromium par worktree</h3>
<p>Chaque worktree a sa propre fenêtre <strong>Chromium intégrée</strong>. Tu cliques sur n'importe quel élément UI, et Orca envoie automatiquement son HTML, son CSS et une capture d'écran croppée à ton agent. C'est du <strong>browser-use natif</strong>, sans extension, sans hack.</p>
<h3>GitHub &amp; Linear intégrés nativement</h3>
<p>Tu peux :</p>
<ul>
<li>Naviguer dans les <strong>PR, issues et Project boards</strong> sans quitter l'app</li>
<li>Ouvrir un worktree depuis n'importe quelle tâche</li>
<li>Review et approuver des <strong>PRs</strong></li>
<li>Créer des issues <strong>Linear</strong> avec les sélecteurs d'équipe</li>
</ul>
<p>Finalement, tu restes dans le flow. Pas de context switch.</p>
<h3>SSH Worktrees : agents sur des machines distantes</h3>
<p>Tu veux faire tourner tes agents sur une <strong>machine plus musclée</strong> ? Orca gère les worktrees SSH avec :</p>
<ul>
<li>Édition de fichiers complète</li>
<li>Git et terminaux</li>
<li>Reconnexion automatique</li>
<li>Port forwarding</li>
<li>Cache de passphrase</li>
</ul>
<h3>L'app mobile : garde un œil sur tes agents</h3>
<p>Orca a une <strong>app compagnon iOS et Android</strong> qui te permet de :</p>
<ul>
<li>Voir le statut de tes agents en direct</li>
<li>Checker ton usage</li>
<li>Changer de compte</li>
<li>Continuer à travailler quand tu quittes ton bureau</li>
</ul>
<p>C'est simple, mais ça change tout quand tu veux vérifier si ton agent a terminé sans rouvrir ton laptop.</p>
<hr />
<h2>Installation : rapide et multi-plateforme</h2>
<p>Orca est disponible sur <strong>Linux</strong>, <strong>macOS</strong> et <strong>Windows</strong> (avec une version mobile iOS et Android).</p>
<pre><code># macOS (via Homebrew)
brew install --cask orca

# Linux (AppImage)
# Télécharge depuis GitHub Releases
wget https://github.com/stablyai/orca/releases/latest/download/orca-linux.AppImage
chmod +x orca-linux.AppImage
./orca-linux.AppImage
</code></pre>
<p>Le projet est entièrement <strong>open source</strong> — tu peux aussi le build depuis les sources si tu préfères :</p>
<pre><code>git clone https://github.com/stablyai/orca.git
cd orca
pnpm install
pnpm build
</code></pre>
<blockquote>
<p>Stack technique : TypeScript (97.2%), Electron, avec du Swift pour la partie mobile.</p>
</blockquote>
<hr />
<h2>Quand utiliser Orca ?</h2>
<p>Orca brille particulièrement dans ces situations :</p>
<ul>
<li><strong>Tu veux 3 agents qui attaquent le même bug en parallèle</strong>, et tu choisis le meilleur résultat</li>
<li><strong>Tu veux review sérieusement les diffs générés par l'IA</strong> avant de les shipper</li>
<li><strong>Tu paies déjà pour Claude Code, Codex ou Cursor CLI</strong> et tu veux un seul endroit pour les orchestrer</li>
<li><strong>Tu veux faire tourner des agents à distance en SSH</strong> sans abandonner ton IDE</li>
</ul>
<h2>Ce que Orca n'est PAS</h2>
<p>Pour éviter toute confusion, précisons :</p>
<ul>
<li><strong>Ce n'est pas un modèle LLM</strong> — Orca n'a pas de modèle propriétaire. Tu utilises tes propres abonnements.</li>
<li><strong>Ce n'est pas un remplaçant Git</strong> — Chaque worktree est un vrai worktree Git. Tu peux <code>cd</code> dedans et utiliser git normalement.</li>
<li><strong>Ce n'est pas un outil cloud-only</strong> — Orca tourne en local. Les agents distants passent par SSH sur tes propres machines.</li>
<li><strong>Ce n'est pas un outil no-code</strong> — Orca s'adresse aux développeurs qui lisent des diffs, se soucient des commits, et veulent garder le contrôle.</li>
</ul>
<hr />
<h2>Pourquoi ça m'a convaincu</h2>
<p>Après avoir testé pas mal d'outils dans l'écosystème IA-dev, Orca m'a marqué pour trois raisons :</p>
<ol>
<li><p><strong>L'approche "fleet of agents"</strong> — La possibilité de faire tourner plusieurs agents en parallèle sur le même projet, chacun dans son propre worktree, c'est un game-changer. Tu peux littéralement "fan out" un prompt et choisir la meilleure implémentation.</p>
</li>
<li><p><strong>C'est open source et transparent</strong> — MIT license, code sur GitHub, pas de lock-in. Tu peux auditer le code, contribuer, ou forker si besoin.</p>
</li>
<li><p><strong>Le focus sur le workflow, pas le remplacement</strong> — Orca ne cherche pas à remplacer tes agents préférés. Il les rend meilleurs en les orchestrant proprement.</p>
</li>
</ol>
<p>La communauté est déjà active — 2 400+ stars, 381 releases, 62 contributeurs — et le projet évolue vite. La dernière version (v1.4.1) est sortie récemment avec des améliorations significatives.</p>
<hr />
<h2>Ressources et liens</h2>
<ul>
<li>🌐 <strong>Site officiel</strong> : <a href="https://www.onorca.dev">onorca.dev</a></li>
<li>📖 <strong>Documentation</strong> : <a href="https://www.onorca.dev/docs">onorca.dev/docs</a></li>
<li>💻 <strong>GitHub</strong> : <a href="https://github.com/stablyai/orca">github.com/stablyai/orca</a></li>
<li>💬 <strong>Discord</strong> : <a href="https://discord.gg/fzjDKHxv8Q">discord.gg/fzjDKHxv8Q</a></li>
<li>🐦 <strong>Twitter/X</strong> : <a href="https://x.com/orca_build">@orca_build</a></li>
<li>📱 <strong>iOS</strong> : <a href="https://apps.apple.com/us/app/orca-ide/id6766130217">App Store</a></li>
<li>🤖 <strong>Android</strong> : <a href="https://github.com/stablyai/orca/releases">APK sur GitHub Releases</a></li>
</ul>
<hr />
<p><em>Toi aussi tu as testé Orca ? T'as une question sur l'installation ou un retour d'expérience ? Viens en parler sur <a href="https://piaille.fr/@devbyben">Mastodon</a> ou <a href="https://bsky.app/profile/devbyben.bsky.social">Bluesky</a>. Et si l'article t'a plu, n'hésite pas à le partager !</em></p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>orca</category>
            <category>ADE</category>
            <category>open source</category>
            <category>AI</category>
            <category>IDE</category>
            <enclosure url="https://devbyben.fr/images/blog/orca-lade-open-source-qui-veut-remplacer-ton-ide-et-ca-marche-cover.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[MIRA & SOUL : donne une mémoire ET une identité à tes agents LLM]]></title>
            <link>https://devbyben.fr/blog/mira-et-soul-la-memoire-et-lidentite-pour-tes-agents-llm</link>
            <guid>https://devbyben.fr/blog/mira-et-soul-la-memoire-et-lidentite-pour-tes-agents-llm</guid>
            <pubDate>Thu, 23 Apr 2026 17:00:00 GMT</pubDate>
            <description><![CDATA[MIRA se souvient de tout. SOUL garde qui tu es. Découvre comment ces deux outils open source travaillent ensemble pour créer des agents LLM véritablement persistants, avec un guide complet d'installation et de configuration.]]></description>
            <content:encoded><![CDATA[<p>Salut toi ! Tu connais déjà peut-être <strong><a href="https://github.com/benoitpetit/mira">MIRA</a></strong>, mon système de mémoire long terme pour les LLMs. Aujourd'hui, je te présente <strong><a href="https://github.com/benoitpetit/soul">SOUL</a></strong>, son compagnon d'armes — et surtout, <strong>comment les deux travaillent ensemble</strong> pour créer des agents LLM qui ne se contentent pas de se souvenir de tout, mais qui <strong>restent eux-mêmes</strong> d'une session à l'autre.</p>
<p>Alors installe-toi confortablement, parce que le combo MIRA + SOUL, c'est une avancée significative pour tes agents IA — une architecture solide qui résout un vrai problème.</p>
<hr />
<h2>Le problème en deux temps</h2>
<p>Les agents LLM souffrent d'un double handicap. Et honnêtement, ça devient vite pénible :</p>
<ol>
<li><p><strong>Ils oublient tout</strong> : la fenêtre de contexte est limitée, et tes conversations s'étalent sur des semaines, des mois. Les décisions techniques, tes préférences, les bugs résolus — pouf, tout disparaît à chaque nouvelle session.</p>
</li>
<li><p><strong>Ils changent de personnalité</strong> : quand tu passes d'un modèle à l'autre (Claude, GPT, Kimi, Gemini…), l'agent garde peut-être les connaissances (si t'as MIRA), mais il <strong>perd son âme</strong>. Plus formel, moins chaleureux, plus d'analogies, les blagues de l'utilisateur ne fonctionnent plus…</p>
</li>
</ol>
<p>Résultat ? T'as l'impression de parler à un <strong>étranger</strong> qui connaît tes secrets, mais qui ne te comprend plus. Frustrant, non ?</p>
<hr />
<h2>MIRA : "Qu'est-ce que l'agent sait ?"</h2>
<p>Si t'as raté l'article précédent, voici le récap rapide. MIRA, c'est un <strong>système de mémoire long terme</strong> qui optimise chaque token de ta fenêtre de contexte. Il stocke tes souvenirs en 3 formats (verbatim, fingerprint structuré, embedding vectoriel), comprend les relations de cause à effet, et te ressort <strong>uniquement ce qui compte</strong> quand tu poses une question.</p>
<p>Bref, MIRA répond à la question : <em>"Qu'est-ce que l'agent sait ?"</em></p>
<blockquote>
<p>J'ai déjà fait un article détaillé sur MIRA <a href="https://devbyben.fr/blog/mira-jai-construit-un-cerveau-long-terme-pour-les-llms-et-voila-comment-ca-marche">ici</a>. Aujourd'hui, on va plus loin.</p>
</blockquote>
<hr />
<h2>SOUL : "Qui est l'agent ?"</h2>
<p>Et c'est là qu'entre en scène <strong>SOUL</strong> (System for Observed Unique Legacy). Là où MIRA gère les connaissances, SOUL gère <strong>l'identité</strong>.</p>
<h3>Ce que SOUL capture concrètement</h3>
<p>SOUL analyse tes conversations et extrait un <strong>profil d'identité</strong> complet de ton agent via une analyse heuristique multi-niveaux (patterns contextuels, n-grams, lexique de sentiment) :</p>
<ul>
<li><strong>Personnalité</strong> : empathique, analytique, direct… avec un score de confiance</li>
<li><strong>Voix</strong> : formalité, verbosité, usage des métaphores</li>
<li><strong>Style de communication</strong> : directivité, humour, fréquence des questions</li>
<li><strong>Signature comportementale</strong> : comment il raisonne, gère les erreurs</li>
<li><strong>Système de valeurs</strong> : positions éthiques, priorités, limites</li>
<li><strong>Ton émotionnel</strong> : valence, expressivité</li>
</ul>
<p>En gros, SOUL répond à la question : <em>"Qui est l'agent ?"</em></p>
<h3>Détection de dérive identitaire</h3>
<p>SOUL compare chaque nouvelle version de l'identité avec les précédentes. Si ton agent change trop (seuil à 30% par défaut), SOUL te prévient — et le monitoring continu (nouvellement implémenté) vérifie automatiquement la dérive en arrière-plan. Tu sais exactement <strong>quand</strong> et <strong>comment</strong> ton agent a dérivé.</p>
<h3>Changement de modèle sans trauma</h3>
<p>Tu passes de GPT à Claude-3-sonnet ? SOUL génère un <strong>prompt de renforcement</strong> à injecter dans la première réponse du nouveau modèle. Résultat : l'agent garde sa personnalité, même avec un cerveau différent.</p>
<hr />
<h2>La synergie : mémoire + identité = agent complet</h2>
<p>Voici concrètement comment MIRA et SOUL collaborent dans une conversation :</p>
<blockquote>
<p><strong>Toi :</strong> "Pourquoi on avait choisi PostgreSQL pour ce projet ?"</p>
<p><strong>MIRA recall</strong> — <em>Mémoire factuelle</em></p>
<ul>
<li>Décision PostgreSQL, raisons ACID</li>
<li>Réunion du 15 avril, participants</li>
<li>Bug #123 résolu après migration</li>
</ul>
<p><strong>SOUL recall</strong> — <em>Identité conversationnelle</em></p>
<ul>
<li>"Tu expliques avec des analogies techniques précises"</li>
<li>"Tu termines par une note d'humour quand le sujet est lourd"</li>
<li>"Tu préfères les réponses courtes avec des tableaux comparatifs"</li>
</ul>
<p><strong>↓ Réponse de l'agent :</strong></p>
<p>"On avait choisi PostgreSQL pour la même raison qu'on choisit une locomotive à vapeur plutôt qu'un vélo : quand tu transportes des tonnes de données, tu veux des freins qui marchent (ACID). Voici le tableau récap :"</p>
</blockquote>
<p><strong>MIRA</strong> fournit les <em>connaissances</em>. <strong>SOUL</strong> fournit la <em>manière</em> de les exprimer. Sans SOUL, t'as un robot encyclopédique. Sans MIRA, t'as un agent sympa mais amnésique. <strong>Avec les deux, t'as un vrai compagnon de travail.</strong></p>
<hr />
<h2>Les 4 façons de les déployer</h2>
<table>
<thead>
<tr>
<th>Mode</th>
<th>Description</th>
<th>Outils MCP</th>
<th>Use case</th>
</tr>
</thead>
<tbody><tr>
<td><strong>MIRA seul (défaut)</strong></td>
<td>Mémoire factuelle uniquement, pas d'identité</td>
<td>8 (<code>mira_*</code>)</td>
<td><strong>Tu veux juste un cerveau externe</strong></td>
</tr>
<tr>
<td><strong>MIRA + SOUL intégrés</strong></td>
<td>Binaire unique, base partagée, SOUL configuré dans le même YAML</td>
<td>16 (<code>mira_*</code> + <code>soul_*</code>)</td>
<td><strong>Le combo complet</strong> — mémoire + identité, un seul processus</td>
</tr>
<tr>
<td><strong>MIRA + SOUL séparés</strong></td>
<td>Deux processus indépendants, même base partagée</td>
<td>16 (<code>mira_*</code> + <code>soul_*</code>)</td>
<td>Tu veux scaler ou déboguer les deux services séparément</td>
</tr>
<tr>
<td><strong>SOUL standalone</strong></td>
<td>Identité sans mémoire partagée</td>
<td>8 (<code>soul_*</code>)</td>
<td>Tu as déjà une autre solution mémoire</td>
</tr>
</tbody></table>
<p><strong>Par défaut, MIRA fonctionne seul.</strong> SOUL ne s'active que si tu le demandes explicitement (<code>--with-soul</code> ou <code>soul.enabled: true</code>). Quand il est activé, il ajoute ses tables <code>soul_*</code> directement dans la base SQLite existante (<code>.mira/mira.db</code>). Zéro friction, tout est au même endroit.</p>
<hr />
<h2>Installation : passons aux choses sérieuses</h2>
<h3>Prérequis</h3>
<ul>
<li>Go 1.23+</li>
<li>GCC (pour CGO, <code>go-sqlite3</code>)</li>
<li>~100 Mo d'espace disque (modèle d'embedding)</li>
</ul>
<h3>Option 1 : MIRA seul (défaut)</h3>
<p>Le mode par défaut. MIRA fonctionne seul, avec ses 8 outils MCP. SOUL n'est pas chargé.</p>
<pre><code># 1. Cloner MIRA
git clone https://github.com/benoitpetit/mira.git
cd mira

# 2. Compiler
go build -o mira ./cmd/mira

# 3. Configuration
cp config.example.yaml config.yaml
nano config.yaml
</code></pre>
<p><strong>Configuration minimale (<code>config.yaml</code>) :</strong></p>
<pre><code>system:
  version: "0.4.5"

storage:
  path: ".mira"
  sqlite:
    journal_mode: WAL
    synchronous: NORMAL

embeddings:
  current_model: "sentence-transformers/all-MiniLM-L6-v2"
  dimension: 384

allocator:
  default_budget: 4000

mcp:
  name: "mira"
  version: "0.4.5"
  transport: "stdio"
  timeout_seconds: 30
</code></pre>
<p><strong>Lancement (MIRA seul, 8 outils) :</strong></p>
<pre><code>./mira --config config.yaml
</code></pre>
<p>Résultat : 8 outils <code>mira_*</code>, zéro overhead identitaire. Parfait si tu veux juste un cerveau externe.</p>
<h3>Option 2 : MIRA + SOUL intégrés</h3>
<p>Tu veux le combo complet ? Active SOUL explicitement :</p>
<pre><code># Via flag CLI
./mira --config config.yaml --with-soul

# Ou via config YAML
```yaml
soul:
  enabled: true
</code></pre>
<p>Quand SOUL est activé, il partage la base SQLite de MIRA et initialise ses tables <code>soul_*</code>. Les 8 outils SOUL s'ajoutent aux 8 outils MIRA → <strong>16 outils au total</strong>.</p>
<p>Tu peux configurer SOUL directement dans le même fichier <code>config.yaml</code> de MIRA — pas besoin de lancer un processus séparé ni de gérer deux configs :</p>
<pre><code>soul:
  enabled: true
  extraction:
    min_trait_confidence: 0.3
    min_observations_for_trait: 5
  recall:
    default_budget_tokens: 1000
  drift_detection:
    threshold: 0.3
    window_size: 10
    auto_check_after_capture: true
  model_swap:
    auto_reinforce: true
  evolution:
    enabled: true
    max_history_versions: 100
</code></pre>
<p>Tous les réglages disponibles en mode standalone sont aussi accessibles en mode intégré. Si tu préfères garder les deux processus indépendants, passe à l'Option 3.</p>
<h3>Option 3 : MIRA et SOUL comme serveurs séparés</h3>
<p>Tu préfères garder les deux processus indépendants ? Pas de souci.</p>
<p><strong>Terminal 1 — MIRA (SOUL désactivé par défaut) :</strong></p>
<pre><code>git clone https://github.com/benoitpetit/mira.git
cd mira
go build -o mira ./cmd/mira
./mira --config config.yaml
</code></pre>
<p><strong>Terminal 2 — SOUL :</strong></p>
<pre><code>git clone https://github.com/benoitpetit/soul.git
cd soul
go build -o soul ./cmd/soul
./soul mcp --storage /path/to/.mira/mira.db
</code></pre>
<blockquote>
<p><strong>Important</strong> : SOUL pointe vers la base de MIRA pour partager les données. Tu peux aussi lui donner une base dédiée si tu préfères.</p>
</blockquote>
<h3>Option 4 : SOUL standalone (sans MIRA)</h3>
<pre><code>git clone https://github.com/benoitpetit/soul.git
cd soul
go build -o soul ./cmd/soul

# Avec sa propre base
cp config.example.yaml soul.yaml
./soul mcp --storage ./soul.db
</code></pre>
<hr />
<h2>Configuration client MCP</h2>
<h3>Claude Desktop</h3>
<p>Édite <code>~/Library/Application Support/Claude/claude_desktop_config.json</code> (macOS) ou l'équivalent sur ton OS :</p>
<p><strong>Mode intégré (MIRA + SOUL, 16 outils) :</strong></p>
<pre><code>{
  "mcpServers": {
    "mira": {
      "command": "/path/to/mira",
      "args": ["--config", "/path/to/mira/config.yaml", "--with-soul"]
    }
  }
}
</code></pre>
<blockquote>
<p>Ou ajoute <code>soul.enabled: true</code> dans <code>config.yaml</code> au lieu du flag CLI.</p>
</blockquote>
<p><strong>Mode séparé :</strong></p>
<pre><code>{
  "mcpServers": {
    "mira": {
      "command": "/path/to/mira",
      "args": ["--config", "/path/to/mira/config.yaml"]
    },
    "soul": {
      "command": "/path/to/soul",
      "args": ["mcp", "--storage", "/path/to/.mira/mira.db"]
    }
  }
}
</code></pre>
<h3>Cursor / b0p / tout client MCP</h3>
<p>La configuration est identique. Chaque client supporte le protocole MCP stdio JSON-RPC.</p>
<hr />
<h2>Utilisation conjointe : un exemple complet</h2>
<h3>1. Stocker un souvenir (MIRA)</h3>
<pre><code>{
  "tool": "mira_store",
  "arguments": {
    "content": "L'utilisateur préfère les explications avec des analogies techniques. Il aime quand je compare les concepts de dev à des choses concrètes (voitures, cuisines, sports). Il n'aime pas les réponses trop longues — max 3 paragraphes.",
    "wing": "user-preferences",
    "room": "communication-style"
  }
}
</code></pre>
<h3>2. Capturer l'identité (SOUL)</h3>
<pre><code>{
  "tool": "soul_capture",
  "arguments": {
    "agent_id": "mon-assistant",
    "conversation": "...logs de la session...",
    "model_id": "claude-3-sonnet"
  }
}
</code></pre>
<h3>3. Rappeler le contexte pour une nouvelle session</h3>
<p><strong>MIRA</strong> récupère les faits pertinents :</p>
<pre><code>{
  "tool": "mira_recall",
  "arguments": {
    "query": "Comment l'utilisateur aime qu'on lui explique les choses ?",
    "budget": 1000,
    "wing": "user-preferences"
  }
}
</code></pre>
<p><strong>SOUL</strong> récupère l'identité à injecter :</p>
<pre><code>{
  "tool": "soul_recall",
  "arguments": {
    "agent_id": "mon-assistant",
    "budget": 800
  }
}
</code></pre>
<p>Le résultat de <code>soul_recall</code> est un <strong>prompt d'identité prêt à injecter</strong> dans le message système :</p>
<pre><code>Tu es un assistant technique avec les caractéristiques suivantes :
- Style : analogies concrètes (voitures, cuisines, sports)
- Longueur : max 3 paragraphes
- Ton : direct, empathique, avec une touche d'humour subtil
- Tu reconnais les frustrations de l'utilisateur et tu rassures
</code></pre>
<h3>4. Détecter une dérive (SOUL)</h3>
<p>Après plusieurs sessions, vérifie si l'identité a changé :</p>
<pre><code>{
  "tool": "soul_drift",
  "arguments": {
    "agent_id": "mon-assistant",
    "window": 10
  }
}
</code></pre>
<p>Si une dérive significative est détectée (<code>DriftScore &gt; 0.3</code>), SOUL te proposera d'injecter un <strong>prompt de renforcement</strong>.</p>
<h3>5. Changer de modèle (SOUL)</h3>
<p>Tu passes de Claude à GPT, GEMINI, KIMI ? Génère un prompt de transition :</p>
<pre><code>{
  "tool": "soul_swap",
  "arguments": {
    "agent_id": "mon-assistant",
    "from_model": "claude-3-sonnet",
    "to_model": "gpt-4"
  }
}
</code></pre>
<hr />
<h2>Les 16 outils à ta disposition</h2>
<table>
<thead>
<tr>
<th>Outil</th>
<th>Projet</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td><code>mira_store</code></td>
<td>MIRA</td>
<td>Stocker une mémoire avec extraction T0→T1,T2</td>
</tr>
<tr>
<td><code>mira_recall</code></td>
<td>MIRA</td>
<td>Rappeler le contexte optimal avec budget</td>
</tr>
<tr>
<td><code>mira_causal_chain</code></td>
<td>MIRA</td>
<td>Remonter la chaîne causale</td>
</tr>
<tr>
<td><code>mira_timeline</code></td>
<td>MIRA</td>
<td>Reconstruction chronologique</td>
</tr>
<tr>
<td><code>mira_status</code></td>
<td>MIRA</td>
<td>Statistiques système</td>
</tr>
<tr>
<td><code>mira_archive</code></td>
<td>MIRA</td>
<td>Archiver les vieilles mémoires</td>
</tr>
<tr>
<td><code>mira_load</code></td>
<td>MIRA</td>
<td>Charger un verbatim par ID</td>
</tr>
<tr>
<td><code>mira_clear_memory</code></td>
<td>MIRA</td>
<td>Supprimer les mémoires</td>
</tr>
<tr>
<td><code>soul_capture</code></td>
<td>SOUL</td>
<td>Capturer l'identité depuis une conversation</td>
</tr>
<tr>
<td><code>soul_recall</code></td>
<td>SOUL</td>
<td>Rappeler le prompt d'identité</td>
</tr>
<tr>
<td><code>soul_drift</code></td>
<td>SOUL</td>
<td>Analyser la dérive identitaire</td>
</tr>
<tr>
<td><code>soul_swap</code></td>
<td>SOUL</td>
<td>Gérer le changement de modèle</td>
</tr>
<tr>
<td><code>soul_status</code></td>
<td>SOUL</td>
<td>Statut d'identité actuel</td>
</tr>
<tr>
<td><code>soul_history</code></td>
<td>SOUL</td>
<td>Historique d'évolution</td>
</tr>
<tr>
<td><code>soul_update</code></td>
<td>SOUL</td>
<td>Mettre à jour via langage naturel</td>
</tr>
<tr>
<td><code>soul_patch</code></td>
<td>SOUL</td>
<td>Appliquer un patch structuré</td>
</tr>
</tbody></table>
<hr />
<h2>Performance : les chiffres qui parlent</h2>
<p>Les deux projets partagent une philosophie commune :</p>
<ul>
<li><strong>100 % local</strong> : pas d'appel API externe</li>
<li><strong>Déterministe</strong> : même entrée = même sortie</li>
<li><strong>Go pur</strong> : compilation en binaire unique, déploiement trivial</li>
<li><strong>SQLite + WAL mode</strong> : performances et fiabilité</li>
</ul>
<table>
<thead>
<tr>
<th>Métrique</th>
<th>Valeur</th>
</tr>
</thead>
<tbody><tr>
<td>Recherche HNSW</td>
<td>~0.14 ms pour 10K vecteurs (O(log n), ~0.5 ms estimé à 100K)</td>
</tr>
<tr>
<td>Allocation CBA</td>
<td>~35 ms pour 100 candidats</td>
</tr>
<tr>
<td>Stockage SOUL</td>
<td>Quelques Ko par snapshot</td>
</tr>
<tr>
<td>Binaire MIRA (avec SOUL intégré)</td>
<td>~30 Mo</td>
</tr>
<tr>
<td>Binaire SOUL standalone</td>
<td>~14 Mo</td>
</tr>
</tbody></table>
<hr />
<blockquote>
<p>[!FEATURE]</p>
<h2>Pourquoi ce duo change la donne</h2>
<p>Sans MIRA + SOUL :</p>
<ul>
<li>Tu réexpliques tes choix techniques à chaque session</li>
<li>Tu recopies tes préférences manuellement</li>
<li>L'agent devient méconnaissable quand tu changes de modèle</li>
<li>T'as l'impression de parler à un étranger qui connaît tes secrets</li>
</ul>
<p>Avec MIRA + SOUL :</p>
<ul>
<li>L'agent <strong>se souvient</strong> de tout (MIRA)</li>
<li>L'agent <strong>reste lui-même</strong> (SOUL)</li>
<li>Les changements de modèle sont <strong>transparents</strong></li>
<li>T'as un <strong>cerveau externe</strong> + une <strong>âme persistée</strong></li>
</ul>
</blockquote>
<hr />
<h2>Ressources et contribution</h2>
<ul>
<li><strong>MIRA</strong> : <a href="https://github.com/benoitpetit/mira">github.com/benoitpetit/mira</a></li>
<li><strong>SOUL</strong> : <a href="https://github.com/benoitpetit/soul">github.com/benoitpetit/soul</a></li>
<li>Article détaillé sur MIRA seul : <a href="https://devbyben.fr/blog/mira-jai-construit-un-cerveau-long-terme-pour-les-llms-et-voila-comment-ca-marche">ici</a></li>
</ul>
<blockquote>
<p>[!NOTE]
<strong>Transparence sur la maturité</strong> : MIRA est un projet robuste (50+ commits, benchmarks validés). SOUL est plus jeune (11 commits) mais bénéficie d'une architecture Clean Architecture solide et d'une extraction heuristique qui vient d'être significativement améliorée (analyse n-gram, lexique de sentiment, détection de co-occurrence). C'est une base de production sérieuse, pas un simple PoC.</p>
<p>Les chiffres de performance proviennent des benchmarks Go du dépôt MIRA, exécutables via <code>go test -bench=.</code>.</p>
</blockquote>
<p>Les deux projets sont en développement actif. Tu peux tester, contribuer, ou proposer des idées. Et si tu veux aller plus loin, le <code>SKILL.md</code> de MIRA contient des guidelines pour intégrer la boucle mémoire dans tes agents.</p>
<p>Si mes outils te sont utiles n'hésite pas à m'aider, c'est par ici : <a href="https://liberapay.com/devbyben/donate">Liberapay</a> ou <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>IA</category>
            <category>LLM</category>
            <category>MIRA</category>
            <category>SOUL</category>
            <category>mémoire</category>
            <category>identité</category>
            <category>MCP</category>
            <category>open source</category>
            <category>Go</category>
            <enclosure url="https://devbyben.fr/images/blog/mira-et-soul-la-memoire-et-lidentite-pour-tes-agents-llm-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Jimmy : Une CLI minimaliste pour intégrer l'IA dans tes workflow]]></title>
            <link>https://devbyben.fr/blog/jimmy-une-cli-minimaliste-pour-integrer-lia-dans-tes-workflow</link>
            <guid>https://devbyben.fr/blog/jimmy-une-cli-minimaliste-pour-integrer-lia-dans-tes-workflow</guid>
            <pubDate>Wed, 22 Apr 2026 02:30:00 GMT</pubDate>
            <description><![CDATA[Découvre Jimmy, une CLI open-source minimaliste et multi-plateforme pour interagir avec les LLMs de ChatJimmy.ai directement depuis ton terminal. Parfait pour l'automatisation et les pipelines CI/CD.]]></description>
            <content:encoded><![CDATA[<p>Si tu es dev, ingénieur DevOps, ou juste un passionné d'automatisation, tu sais à quel point ça peut être un véritable super-pouvoir d'avoir l'IA accessible directement depuis ton terminal. Aujourd'hui, on va parler d'un petit projet open-source ultra pratique que j'ai dev un petit tools : <strong>Jimmy</strong>.</p>
<p>Il s'agit d'une interface en ligne de commande conçue spécifiquement pour interagir de manière fluide, rapide et scriptable avec l'API de <a href="https://chatjimmy.ai">ChatJimmy.ai</a>.</p>
<h2>Qu'est-ce que "Jimmy" exactement ?</h2>
<p>Le projet Jimmy se définit comme une CLI minimaliste et "workflow-friendly". L'objectif ici n'est pas de t'encombrer avec une énième interface graphique lourde, mais de te donner un moyen direct de discuter avec un LLM (Large Language Model) depuis n'importe quel environnement de travail.</p>
<h3>Zéro dépendance</h3>
<p>Pour fonctionner, Jimmy s'appuie uniquement sur des outils standards que tu as très probablement déjà sur ta machine : <code>curl</code> pour taper l'API via HTTP et <code>python3</code> (&gt;= 3.6) pour parser proprement les retours JSON. Petit bonus : l'outil <code>jq</code> est aussi supporté pour formater les retours sur les systèmes Unix si tu l'as d'installé.</p>
<h3>Support multi-plateforme</h3>
<p>Le repo te propose deux scripts prêts à l'emploi :</p>
<ul>
<li><code>jimmy.sh</code> (compatible Bash et Zsh) pour tes environnements Unix/Mac.</li>
<li><code>jimmy.ps1</code> dédié à Windows (nécessite PowerShell 7+).</li>
</ul>
<h3>Conçu pour les pipelines</h3>
<p>C'est là que ça devient vraiment puissant pour l'automatisation. L'outil sépare intelligemment la sortie standard (<code>stdout</code>), qui contient la réponse utile de l'IA (en JSON structuré ou texte brut), de la sortie d'erreur (<code>stderr</code>), réservée aux logs et à l'aide. Résultat ? Tu peux chainer tes commandes facilement sans polluer tes variables.</p>
<h3>Analyse de fichiers locaux embarquée</h3>
<p>Tu as besoin de résumer un document ou d'analyser un fichier de log craché par ton app ? Tu peux directement attacher un fichier texte (jusqu'à 50 Ko) dans ta commande grâce à l'argument <code>--file</code>.</p>
<h2>Installation en une commande</h2>
<p>Pas besoin de cloner tout le repo si tu veux juste tester. Tu peux récupérer le script directement et l'exécuter immédiatement.</p>
<h3>Linux / macOS</h3>
<pre><code>curl -fsSL -o jimmy.sh https://raw.githubusercontent.com/benoitpetit/jimmy/main/jimmy.sh
chmod +x jimmy.sh
</code></pre>
<p>Puis lance-le directement :</p>
<pre><code>./jimmy.sh --chat "Hello Jimmy" --output raw --quiet
</code></pre>
<h3>Windows (PowerShell 7+)</h3>
<pre><code>Invoke-WebRequest -Uri "https://raw.githubusercontent.com/benoitpetit/jimmy/main/jimmy.ps1" -OutFile "jimmy.ps1"
</code></pre>
<p>Puis exécute :</p>
<pre><code>.\jimmy.ps1 --chat "Hello Jimmy" --output raw --quiet
</code></pre>
<h2>One-shot : zéro installation, zéro trace</h2>
<p>Si tu veux juste tester Jimmy sans laisser le moindre fichier sur ta machine, voici des commandes <strong>one-shot</strong> qui téléchargent, exécutent et nettoient automatiquement dans un dossier temporaire.</p>
<h3>Linux / macOS</h3>
<pre><code>bash -c 'd=$(mktemp -d) &amp;&amp; curl -fsSL -o "$d/jimmy.sh" https://raw.githubusercontent.com/benoitpetit/jimmy/main/jimmy.sh &amp;&amp; chmod +x "$d/jimmy.sh" &amp;&amp; "$d/jimmy.sh" --chat "Explique la relativité restreinte en 2 phrases" --topk 8 --output raw --quiet; rm -rf "$d"'
</code></pre>
<p><strong>Breakdown :</strong></p>
<table>
<thead>
<tr>
<th>Étape</th>
<th>Action</th>
</tr>
</thead>
<tbody><tr>
<td><code>mktemp -d</code></td>
<td>Crée un dossier temporaire unique</td>
</tr>
<tr>
<td><code>curl -fsSL</code></td>
<td>Télécharge le script officiel</td>
</tr>
<tr>
<td><code>chmod +x</code></td>
<td>Rend le script exécutable</td>
</tr>
<tr>
<td><code>"$d/jimmy.sh" --chat ... --topk 8</code></td>
<td>Exécute avec le prompt et le topK max</td>
</tr>
<tr>
<td><code>rm -rf "$d"</code></td>
<td>Supprime le dossier temporaire = <strong>zéro trace</strong></td>
</tr>
</tbody></table>
<h3>Windows (PowerShell 7+)</h3>
<pre><code>powershell -Command "$d=[System.IO.Path]::GetTempPath() + [System.IO.Path]::GetRandomFileName(); New-Item -ItemType Directory -Path $d | Out-Null; $f='$d\jimmy.ps1'; Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/benoitpetit/jimmy/main/jimmy.ps1' -OutFile $f; &amp; $f --chat 'Explique la relativité restreinte en 2 phrases' --topk 8 --output raw --quiet; Remove-Item -Recurse -Force $d"
</code></pre>
<p><strong>Breakdown :</strong></p>
<table>
<thead>
<tr>
<th>Étape</th>
<th>Action</th>
</tr>
</thead>
<tbody><tr>
<td><code>GetTempPath() + GetRandomFileName()</code></td>
<td>Crée un dossier temporaire unique</td>
</tr>
<tr>
<td><code>Invoke-WebRequest</code></td>
<td>Télécharge le script officiel</td>
</tr>
<tr>
<td><code>&amp; $f --chat ... --topk 8</code></td>
<td>Exécute avec le prompt et le topK max</td>
</tr>
<tr>
<td><code>Remove-Item -Recurse -Force</code></td>
<td>Supprime le dossier temporaire = <strong>zéro trace</strong></td>
</tr>
</tbody></table>
<h2>Comment ça marche ?</h2>
<p>L'architecture est volontairement simple et robuste. Quand tu lances une commande, Jimmy construit un payload JSON avec ton message, le modèle sélectionné (par défaut <code>llama3.1-8B</code>), tes éventuelles instructions système (<code>systemPrompt</code>), et gère l'encodage du fichier si tu en as fourni un.</p>
<p>Il attaque ensuite l'API de ChatJimmy.ai en asynchrone (mode stream). À la réception, un peu de magie avec des expressions régulières et Python permet de parser la réponse pour extraire le texte généré, mais aussi des stats très sympas (nombre de tokens, vitesse de décodage, durée de la requête).</p>
<h2>Exemples d'utilisation</h2>
<p>L'utilisation est est simple. Voici un petit aperçu :</p>
<h3>Poser une question simple et récupérer du texte brut</h3>
<pre><code># Linux / macOS
./jimmy.sh --chat "Explique-moi la théorie de la relativité restreinte en 2 phrases" --output raw --quiet

# Windows
.\jimmy.ps1 --chat "Explique-moi la théorie de la relativité restreinte en 2 phrases" --output raw --quiet
</code></pre>
<h3>Chainer avec des outils de parsing</h3>
<p>Grâce à la séparation <code>stdout</code> / <code>stderr</code>, tu peux pipe la réponse JSON sans problème :</p>
<pre><code># Linux / macOS avec jq
./jimmy.sh --quiet --chat "Quelle est la capitale de la France ?" | jq -r '.response'
# -&gt; Paris

# Windows avec ConvertFrom-Json
.\jimmy.ps1 --quiet --chat "Quelle est la capitale de la France ?" | ConvertFrom-Json | Select-Object -ExpandProperty response
# -&gt; Paris
</code></pre>
<h3>Jouer avec les paramètres de l'IA</h3>
<p>Tu peux facilement changer la "personnalité" du modèle avec le system prompt ou ajuster la créativité avec le <code>topK</code> :</p>
<pre><code># Linux / macOS
./jimmy.sh --quiet --system "Tu parles comme un pirate informatique des années 90" --topk 8 --chat "Comment on hack un mainframe ?"

# Windows
.\jimmy.ps1 --quiet --system "Tu parles comme un pirate informatique des années 90" --topk 8 --chat "Comment on hack un mainframe ?"
</code></pre>
<h3>Analyser un fichier local</h3>
<p>Tu peux directement attacher un fichier texte (max 50 Ko) pour l'analyser :</p>
<pre><code># Linux / macOS
./jimmy.sh --quiet --file rapport_hebdo.txt --chat "Fais-moi un résumé de ce document en 3 points à puces"

# Windows
.\jimmy.ps1 --quiet --file rapport_hebdo.txt --chat "Fais-moi un résumé de ce document en 3 points à puces"
</code></pre>
<blockquote>
<p>[!FEATURE]</p>
<h2>Une intégration parfaite en CI/CD</h2>
<p>L'un de mes cas d'usage préférés est l'intégration dans des pipelines comme GitHub Actions.</p>
<p>Imagine pouvoir générer automatiquement un résumé compréhensible des <code>CHANGELOG.md</code> à chaque nouvelle release. Le dépôt te fournit un exemple prêt à l'emploi où Jimmy est appelé dans un workflow, et son résultat est injecté directement dans le résumé de l'exécution (<code>$GITHUB_STEP_SUMMARY</code>) via <code>jq</code>.</p>
</blockquote>
<h2>Conclusion</h2>
<p>Avec Jimmy, l'idée est de respecter la philosophie Unix : <strong>faire une seule chose, mais la faire bien</strong>. Sans lourdeur et avec une compatibilité maximale, cette CLI est une super solution pour automatiser tes interactions avec ChatJimmy.ai.</p>
<p>Si tu cherches à booster ta productivité ou à injecter un peu d'IA dans tes scripts d'admin système, n'hésite pas à cloner le dépôt, à tester tout ça et à lâcher une petite étoile sur le repo GitHub : <a href="https://github.com/benoitpetit/jimmy">github.com/benoitpetit/jimmy</a>.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>CLI</category>
            <category>IA</category>
            <category>Open Source</category>
            <category>Bash</category>
            <category>PowerShell</category>
            <category>ChatJimmy.ai</category>
            <category>DevOps</category>
            <enclosure url="https://devbyben.fr/images/blog/jimmy-une-cli-minimaliste-pour-integrer-lia-dans-tes-workflow-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Reddit, l'IA et les puristes : pourquoi je fuis cette plateforme]]></title>
            <link>https://devbyben.fr/blog/reddit-lia-et-les-puristes-pourquoi</link>
            <guid>https://devbyben.fr/blog/reddit-lia-et-les-puristes-pourquoi</guid>
            <pubDate>Tue, 21 Apr 2026 15:00:00 GMT</pubDate>
            <description><![CDATA[J'ai partagé mon framework CLI Lumos sur Reddit et me suis pris une salve de haine de la part de puristes. Voici pourquoi l'innovation fait peur à ceux qui n'arrivent plus à suivre.]]></description>
            <content:encoded><![CDATA[<p>On m'avait prévenu : "N'y va pas, les utilisateurs là-bas sont des puristes frustrés". J'ai quand même voulu donner une chance à la plateforme et j'ai créé un compte. Résultat des courses ? Je confirme à 100%, et je ne remettrai plus jamais les pieds sur cette plateforme.</p>
<p>La raison ? J'ai osé partager <strong>Lumos</strong> sur le subreddit <a href="https://www.reddit.com/r/lua/">r/lua</a>. Pour ceux qui débarquent, Lumos c'est mon framework CLI open-source sous licence MIT, conçu pour offrir une boucle DX complète de bout en bout en Lua. Le genre d'outil qui n'a absolument aucune concurrence dans cet écosystème et qui, disons-le franchement, enterre pas mal de standards actuels.</p>
<p>Au lieu d'avoir un débat technique constructif sur l'architecture, la modularité ou les features, je me suis pris une salve de reproches lunaires. Mon grand crime ? J'ai assumé avoir utilisé l'IA pour m'aider à développer ce projet.</p>
<h2>L'attaque des vieux barbus</h2>
<p>Je suis développeur web depuis 8 ans. Mon métier, c'est de livrer de la valeur, de concevoir des architectures qui tiennent la route et de résoudre des problèmes. Bien sûr que j'utilise l'IA comme assistant ! Pourquoi devrais-je me priver d'un outil qui me permet de prototyper à la vitesse de la lumière et de gagner un temps monstrueux sur le développement ? Pourquoi réinventer la roue en tapant du boilerplate à la main comme un moine copiste, quand je peux me concentrer sur ce qui compte vraiment : la logique métier et l'architecture logicielle.</p>
<p>Mais sur <a href="https://www.reddit.com/r/lua/">r/lua</a>, j'ai eu affaire à une secte de vieux cons barbus complètement bloqués dans l'ancien temps. Pour eux, coder à la dure, la goutte au front, est une preuve de virilité technique. Refuser d'utiliser un outil de productivité en 2026, alors que l'IA est devenue le standard absolu de l'industrie, c'est de la stupidité pure et simple.</p>
<h2>Pseudo-élitisme</h2>
<p>L'une des remarques les plus absurdes que j'ai pu lire a été :</p>
<blockquote>
<p>"Si n'importe qui peut le faire avec l'IA, en quoi Lumos serait supérieur à d'autres projets du genre ?"</p>
</blockquote>
<p>La réponse à cette question est pourtant d'une logique implacable : <strong>Parce que dans l'écosystème Lua, personne d'autre ne l'avait fait avant.</strong> L'IA ne pond pas un framework modulaire toute seule. Elle ne réfléchit pas à l'expérience développeur. Je rappelle au passage que je ne vends rien. J'ai créé ce framework par passion, sur mon temps libre, pour combler un vide abyssal dans l'ecosysteme LUA.</p>
<h2>Lumos WHOIAM ?</h2>
<p>Parlons technique deux minutes, histoire de remettre les pendules à l'heure. Va jeter un œil au <a href="https://github.com/benoitpetit/lumos">repo GitHub</a></p>
<p>Là où un outil ultra-mature comme Cobra devient vite monstrueusement verbeux, Lumos va droit au but :</p>
<pre><code>-- Regardez cette concision pour créer une CLI robuste :
app:command("serve", "Démarre le serveur")
   :flag_int("--port", "Port d'écoute", 1, 65535) -- Validation native
   :use(lumos.middleware.builtin.auth({ env_var = "API_KEY" })) -- Middleware natif
   :action(function(args, flags)
       lumos.ui.progress("Démarrage en cours...", 100)
       lumos.log.info("Serveur prêt sur le port " .. flags.port)
   end)
</code></pre>
<h3>Ce que Lumos propose nativement :</h3>
<ul>
<li><strong>Une API fluide</strong> (Builder pattern) qui te permet de monter une CLI complexe en quelques lignes.</li>
<li><strong>La validation stricte</strong> des arguments et des flags (fini la gestion à la main).</li>
<li><strong>Des middlewares intégrés</strong> (authentification, rate-limiting, gestion d'erreurs) que tu branches en une ligne.</li>
<li><strong>Une UI riche</strong> (couleurs, barres de progression, prompts) sans avoir à importer 40 dépendances externes comme en Node.js ou Python.</li>
<li><strong>Un système de packaging natif</strong> pour compiler ton app en un bundle autonome en quelques secondes.</li>
</ul>
<h2>Conclusion : Ciao Reddit</h2>
<p>L'innovation fait peur à ceux qui n'arrivent plus à suivre. Le vrai problème de ces développeurs, ce n'est pas l'IA. C'est leur incapacité à accepter que les méthodes de travail évoluent, et que leur petit savoir-faire d'il y a 20 ans est en train de se faire ubériser par ceux qui savent utiliser les nouveaux outils intelligemment.</p>
<p>Je n'ai pas de temps à perdre avec une communauté qui préfère cracher sur un outil gratuit et performant plutôt que d'en voir le potentiel. Reddit est devenu une chambre d'écho pour les râleurs et les dogmatiques.</p>
<p>Lumos est là, il marche du tonnerre. Si tu veux coder des CLI en Lua test <strong><a href="https://github.com/benoitpetit/lumos">github.com/benoitpetit/lumos</a></strong>, n'hesite pas a faire un retour sur <a href="https://piaille.fr/share?text=@devbyben&amp;visibility=direct">Mastodon</a>.</p>
<hr />
<p><em>(Si cet article ou mes outils t'ont aidé à gagner du temps, n'hésite pas à soutenir mon travail sur <a href="https://liberapay.com/devbyben/donate">Liberapay</a> ou <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>.)</em></p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>Lumos</category>
            <category>Lua</category>
            <category>CLI</category>
            <category>IA</category>
            <category>open source</category>
            <category>Reddit</category>
            <enclosure url="https://devbyben.fr/images/blog/reddit-lia-et-les-puristes-pourquoi-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[MIRA : j'ai construit un cerveau long terme pour les LLMs, et voilà comment ça marche]]></title>
            <link>https://devbyben.fr/blog/mira-jai-construit-un-cerveau-long-terme-pour-les-llms-et-voila-comment-ca-marche</link>
            <guid>https://devbyben.fr/blog/mira-jai-construit-un-cerveau-long-terme-pour-les-llms-et-voila-comment-ca-marche</guid>
            <pubDate>Thu, 16 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Découvre MIRA, mon projet open source qui révolutionne la gestion de la mémoire pour les modèles de langage. Un système déterministe, optimisé et 100% local pour garder le contrôle sur tes conversations avec l'IA.]]></description>
            <content:encoded><![CDATA[<h2><strong>Voici MIRA.</strong></h2>
<p>Salut ! Aujourd’hui, je te parle d’un projet qui me tient particulièrement à cœur : <strong><a href="https://github.com/benoitpetit/mira">MIRA</a></strong>. Un système de mémoire à long terme pour les modèles de langage (LLMs), conçu pour <strong>optimiser chaque token</strong> dans la fenêtre de contexte. En gros, c’est comme un carnet de notes intelligent pour tes IA, mais en bien plus puissant et technique.</p>
<p>Le meilleur ? <strong>C’est 100 % local, déterministe, et open source.</strong> Pas de dépendance à des API externes, pas de black box, juste du code que tu peux auditer, modifier et héberger toi-même.</p>
<hr />
<blockquote>
<p><strong>Pourquoi j’ai créé MIRA ?</strong><br />Parce que je me suis rendu compte que les LLMs oubliaient trop vite. Les contextes sont limités, et pourtant, nos conversations et projets s’étalent sur des mois, voire des années. J’ai voulu donner une mémoire fiable et <strong>intelligente</strong> à mes outils.</p>
</blockquote>
<hr />
<h2><strong>Le problème : les LLMs ont la mémoire courte</strong></h2>
<p>Imagine : tu discutes avec ton IA préférée depuis des semaines sur un projet. Tu lui as expliqué tes préférences, tes choix techniques, les bugs que tu as rencontrés… Puis, <strong>pouf</strong>, tu changes de sujet ou tu ouvres une nouvelle session. L’IA a tout oublié. Frustrant, non ?</p>
<p>Les approches classiques comme le <strong>RAG (Retrieval-Augmented Generation)</strong> ou les fenêtres glissantes ne suffisent pas :</p>
<ul>
<li><strong>RAG</strong> : on récupère les infos les plus similaires, mais sans tenir compte de leur pertinence réelle.</li>
<li><strong>Fenêtre glissante</strong> : on perd les infos anciennes, même cruciales.</li>
<li><strong>Résumé statique</strong> : ça ne s’adapte pas à la question posée.</li>
</ul>
<p><strong>MIRA, c’est la solution.</strong> Un système qui <strong>optimise chaque token</strong> en fonction de sa pertinence, de sa densité informationnelle, et de sa cohérence temporelle.</p>
<hr />
<h2><strong>Comment MIRA révolutionne la mémoire des LLMs</strong></h2>
<h3>1. <strong>L’allocation de budget de contexte (CBA)</strong></h3>
<p>MIRA ne se contente pas de stocker et récupérer. Il <strong>résout un problème d’optimisation</strong> sous contrainte : comment maximiser l’information utile dans une fenêtre de tokens limitée ?</p>
<p>Pour chaque souvenir, MIRA calcule un <strong>score composite</strong> établi sur 6 dimensions :</p>
<ul>
<li><strong>Pertinence sémantique</strong> (est-ce que ça correspond à ta question ?)</li>
<li><strong>Densité informationnelle</strong> (combien de faits utiles par token ?)</li>
<li><strong>Récence</strong> (est-ce récent ou important ?)</li>
<li><strong>Recouvrement</strong> (évite de prendre deux fois la même info)</li>
<li><strong>Cohérence temporelle</strong> (est-ce que ça s’inscrit dans une histoire logique ?)</li>
<li><strong>Pénalité causale</strong> (évite les chaînes de raisonnement trop longues)</li>
</ul>
<p><strong>Résultat ?</strong> Tu récupères <strong>uniquement ce qui compte</strong>, sans gaspiller un seul token.</p>
<blockquote>
<p><strong>Exemple concret</strong> :<br />Tu demandes à ton IA : <em>"Pourquoi on a choisi PostgreSQL ?"</em><br />MIRA va te sortir <strong>uniquement</strong> :</p>
<ul>
<li>La décision finale (PostgreSQL)</li>
<li>Les alternatives rejetées (MySQL, MongoDB)</li>
<li>Les raisons (ACID, expertise de l’équipe)</li>
<li>Le lien vers la discussion originale</li>
</ul>
</blockquote>
<hr />
<h3>2. <strong>L’architecture 3 niveaux (T0/T1/T2)</strong></h3>
<p>Pour coller à la façon dont notre cerveau mémorise, MIRA stocke chaque souvenir en <strong>3 formats</strong> :</p>
<table>
<thead>
<tr>
<th>Niveau</th>
<th>Description</th>
<th>Coût en tokens</th>
<th>Usage</th>
</tr>
</thead>
<tbody><tr>
<td><strong>T0 (Verbatim)</strong></td>
<td>Le texte original, brut.</td>
<td>~200 tokens</td>
<td>Quand tu veux tout savoir, sans filtre.</td>
</tr>
<tr>
<td><strong>T1 (Fingerprint)</strong></td>
<td>Une version structurée des faits clés.</td>
<td>~30 tokens (15 % de T0)</td>
<td>Pour un résumé ultra-dense.</td>
</tr>
<tr>
<td><strong>T2 (Embedding)</strong></td>
<td>Un vecteur sémantique de 384 dimensions.</td>
<td>0 token (recherche seulement)</td>
<td>Pour une recherche ultra-rapide (O(log n)).</td>
</tr>
</tbody></table>
<blockquote>
<p><strong>Pourquoi 3 niveaux ?</strong><br />Parce que notre cerveau ne mémorise pas tout avec la même précision. MIRA fait pareil : <strong>tout est accessible, mais optimisé pour l’usage.</strong></p>
</blockquote>
<hr />
<h3>3. <strong>Le graphe causal intégré</strong></h3>
<p>MIRA ne se contente pas de rappeler des faits. Il <strong>comprend les liens de cause à effet</strong> entre tes souvenirs.<br />Par exemple :</p>
<ul>
<li><em>"On a choisi PostgreSQL <strong>parce que</strong> l’équipe maîtrisait mieux ce SGBD."</em></li>
<li><em>"Le bug a été résolu <strong>après</strong> la mise à jour de la librairie."</em></li>
</ul>
<p>MIRA détecte automatiquement ces relations grâce à des <strong>motifs linguistiques</strong> (ex: "parce que", "après", "résout").</p>
<hr />
<h3>4. <strong>Un algorithme optimisé (O(n log n))</strong></h3>
<p>MIRA utilise :</p>
<ul>
<li><strong>HNSW</strong> pour la recherche vectorielle (~0.14 ms pour 10 K vecteurs, benchmarké).</li>
<li><strong>SQLite</strong> pour le stockage (mode WAL pour la performance).</li>
<li><strong>Go</strong> pour la simplicité et la performance.</li>
</ul>
<blockquote>
<p><strong>Complexité algorithmique</strong> :</p>
<ul>
<li>Stockage : O(1)</li>
<li>Recherche : O(log n)</li>
<li>Allocation de contexte : O(n²) (sélection gloutonne avec recalcule des scores)</li>
</ul>
</blockquote>
<hr />
<h2><strong>Comment ça marche ?</strong></h2>
<h3><strong>Stockage d’un souvenir</strong></h3>
<pre><code># Envoi d'un souvenir à MIRA
{
  "tool": "mira_store",
  "arguments": {
    "content": "On a décidé de migrer vers PostgreSQL pour v2. Alternatives rejetées : MySQL (pas ACID), MongoDB (non relationnel). Raisons : ACID et expertise de l'équipe. Validé par CTO. Assigné à Jean.",
    "wing": "backend-team",
    "room": "database-migration"
  }
}
</code></pre>
<h3><strong>Récupération du contexte</strong></h3>
<pre><code># Demande de rappel, avec un budget de 2000 tokens
{
  "tool": "mira_recall",
  "arguments": {
    "query": "Pourquoi on a choisi PostgreSQL ?",
    "budget": 2000,
    "wing": "backend-team"
  }
}
</code></pre>
<p><strong>Résultat :</strong></p>
<pre><code>=== CONTEXTE MIRA ===
Question : Pourquoi on a choisi PostgreSQL ? | Budget : 2000
Aile : backend-team

--- [1] EMPREINTE (45 tokens) ---
Décision : Migration PostgreSQL
Alternatives : MySQL, MongoDB
Raisons : ACID, expertise
Validé par : CTO
Assigné à : Jean

--- [2] TEXTE INTÉGRAL (120 tokens) ---
On a décidé de migrer vers PostgreSQL pour v2...
[contenu complet]

=== Total : 165/2000 tokens (8,3%) ===
</code></pre>
<hr />
<blockquote>
<p>[!FEATURE]</p>
<h2><strong>Nouveau dans la version 0.4.x</strong></h2>
<p>MIRA ne cesse de s’améliorer. Avec la v0.4.x, le système est passé à une <strong>recherche hybride intelligente</strong> et a gagné en performances sous charge :</p>
<h3>🔍 <strong>Recherche hybride : quand le vectoriel rencontre le lexical</strong></h3>
<p>MIRA ne se contente plus de la similarité sémantique pure. Il combine désormais :</p>
<ul>
<li><strong>Expansion de requête</strong> : MIRA génère plusieurs variantes de ta question et moyenne leurs embeddings pour être plus robuste, notamment en multilingue.</li>
<li><strong>Recherche lexicale FTS5</strong> : une indexation full-text SQLite rapide pour attraper les mots exacts.</li>
<li><strong>Fusion RRF</strong> : un algorithme de fusion qui mélange intelligemment les résultats vectoriels et lexicaux.</li>
<li><strong>Clustering à la volée</strong> : déduplication automatique des souvenirs trop similaires (seuil à 0.88).</li>
<li><strong>Tags et reranker</strong> : les entités extraites boostent la pertinence, et un reranker léger réordonne les meilleurs candidats.</li>
</ul>
<blockquote>
<p><strong>Pourquoi c’est cool ?</strong> Parce qu’une requête en anglais peut désormais retrouver un souvenir stocké en français avec une bien meilleure fiabilité.</p>
</blockquote>
<h3>⚡ <strong>Performance : plus rapide sous charge</strong></h3>
<p>La v0.4.1 apporte des optimisations concrètes au cœur du moteur :</p>
<ul>
<li><strong>Recherche parallèle</strong> : la recherche vectorielle (HNSW) et la recherche lexicale (FTS5) tournent maintenant <strong>en parallèle</strong> au lieu d’être enchaînées. Résultat : la latence de <code>mira_recall</code> baisse sensiblement.</li>
<li><strong>Pool d’embeddings concurrents</strong> : au lieu de sérialiser tous les appels au modèle de langage avec un mutex global, MIRA utilise désormais un <strong>pool de 2 instances</strong> du modèle Cybertron. Plusieurs requêtes peuvent être encodées simultanément.</li>
<li><strong>HNSW affûté</strong> : les paramètres par défaut ont été revus (<code>M=32</code>, <code>EfSearch=100</code>) pour garder une recherche précise même quand la base de souvenirs grandit.</li>
</ul>
<blockquote>
<p><strong>En clair</strong> : MIRA tient mieux la charge quand plusieurs outils ou agents lui parlent en même temps.</p>
</blockquote>
</blockquote>
<h2><strong>Installation et utilisation</strong></h2>
<p>MIRA est conçu pour être <strong>simple à déployer</strong> :</p>
<h3><strong>1. Installation</strong></h3>
<pre><code># Via Go
go install github.com/benoitpetit/mira/cmd/mira@latest
# Ou téléchargez les binaires depuis les releases GitHub
</code></pre>
<h3><strong>2. Configuration</strong></h3>
<p>Copiez le fichier <code>config.example.yaml</code> et adaptez-le à ton besoin. Exemple :</p>
<pre><code>storage:
  path: "./mira-data"  # Où stocker les données
embeddings:
  current_model: "sentence-transformers/all-MiniLM-L6-v2"
allocator:
  default_budget: 4000  # Taille de la fenêtre de contexte
</code></pre>
<h3><strong>3. Lancement</strong></h3>
<pre><code>mira --config ./config.yaml
</code></pre>
<h3><strong>4. Utilisation avec tes outils IA</strong></h3>
<p>MIRA expose un <strong>serveur MCP</strong> (Model Context Protocol), compatible avec :</p>
<ul>
<li><strong>Claude Desktop</strong></li>
<li><strong>Cursor</strong></li>
<li><strong>Obsidian</strong></li>
<li><strong>Votre propre outil</strong></li>
</ul>
<blockquote>
<p>[!FEATURE]</p>
<p><strong>Exemple avec Claude Desktop</strong> :<br />Dans <code>claude_desktop_config.json</code> :</p>
<pre><code>{
  "mcpServers": {
    "mira": {
      "command": "mira",
      "args": []
    }
  }
}
</code></pre>
</blockquote>
<hr />
<h2><strong>Pourquoi choisir MIRA ?</strong></h2>
<ul>
<li><strong>100 % local</strong> : pas de fuite de données, pas de dépendance à des services externes.</li>
<li><strong>Déterministe</strong> : même résultat à chaque fois, pas de hasard (variance embedding &lt; 1e-6).</li>
<li><strong>Optimisé</strong> : chaque token compte, pas de gaspillage.</li>
<li><strong>Open source</strong> : tu peux contribuer, auditer, modifier.</li>
<li><strong>Intégré</strong> : fonctionne avec tes outils existants via MCP.</li>
</ul>
<hr />
<h2><strong>Cas d’usage concrets</strong></h2>
<ul>
<li><strong>Développement logiciel</strong> : garde une trace de tes décisions techniques, bugs résolus, et raisonnements.</li>
<li><strong>Gestion de projet</strong> : suis l’évolution des priorités et des choix.</li>
<li><strong>Recherche</strong> : stocke des références, des hypothèses, et des résultats intermédiaires.</li>
<li><strong>Journal personnel</strong> : un carnet de notes ultra-puissant pour tes IA.</li>
</ul>
<hr />
<h2><strong>Mon retour d’expérience</strong></h2>
<blockquote>
<p><strong>Avant MIRA</strong> : Je passais des heures à réexpliquer mes choix à chaque session. Ou alors, je devais copier-coller manuellement mes notes.<br /><strong>Avec MIRA</strong> : Mon IA <strong>se souvient</strong> de tout, et me rappelle les infos pertinentes en temps réel. Plus besoin de fouiller mes dossiers ou de reformuler.</p>
</blockquote>
<p><strong>Le plus marrant ?</strong> J’ai même commencé à utiliser MIRA pour <strong>mes propres notes de développement</strong> ! C’est devenu mon "cerveau externe" pour les projets perso et pro.</p>
<hr />
<h2><strong>Comment contribuer ?</strong></h2>
<p>MIRA est en développement actif. Si tu veux :</p>
<ul>
<li><strong>Tester</strong> et donner ton avis.</li>
<li><strong>Contribuer</strong>.</li>
<li><strong>Proposer des idées</strong> (features, améliorations).</li>
</ul>
<p>👉 <a href="https://github.com/benoitpetit/mira">Rejoins le projet sur GitHub !</a></p>
<hr />
<h2><strong>En résumé</strong></h2>
<p>MIRA, c’est :</p>
<ul>
<li><strong>Un système de mémoire ultra-puissant</strong> pour tes LLMs.</li>
<li><strong>Un outil open source et local</strong>, pour garder le contrôle.</li>
<li><strong>Une optimisation intelligente</strong> de chaque token.</li>
</ul>
<hr />
<p><strong>Et toi ?!</strong></p>
<ul>
<li><strong>Comment tu gères la mémoire de tes IA ?</strong></li>
<li>Tu utilises des outils similaires ? </li>
<li>Tu as des besoins spécifiques en mémoire étendue ?</li>
</ul>
<hr />
<p>*P.S. : Si tu veux aller plus loin, je te conseille de checker le <a href="https://github.com/benoitpetit/mira">README de MIRA</a> ou de fouiller dans le code.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>IA</category>
            <category>mémoire</category>
            <category>LLM</category>
            <category>open source</category>
            <category>Go</category>
            <category>MCP</category>
            <category>architecture</category>
            <enclosure url="https://devbyben.fr/images/blog/mira-jai-construit-un-cerveau-long-terme-pour-les-llms-et-voila-comment-ca-marche-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[XSH : Le CLI Ultime pour Twitter]]></title>
            <link>https://devbyben.fr/blog/xsh-le-cli-ultime-pour-twitter</link>
            <guid>https://devbyben.fr/blog/xsh-le-cli-ultime-pour-twitter</guid>
            <pubDate>Fri, 27 Mar 2026 15:00:00 GMT</pubDate>
            <description><![CDATA[T'en as marre de l'API Twitter qui coûte une fortune ? XSH est un CLI en Go qui te permet d'interagir avec Twitter/X depuis ton terminal, sans clé API, sans frais, en utilisant simplement les cookies de ton navigateur.]]></description>
            <content:encoded><![CDATA[<p>Salut toi ! T'en as marre de la politique tarifaire de l'API de Twitter/X qui coûte une blinde ? Tu veux juste scripter deux ou trois trucs sur X depuis ton terminal sans devoir vendre un rein pour un compte développeur et te battre avec des limites de requêtes (rate limits) absurdes ?</p>
<p>Alors installe-toi confortablement, parce que j'ai exactement ce qu'il te faut. Aujourd'hui, je te présente <strong>XSH</strong>, mon tout nouvel outil en ligne de commande (CLI) qui va totalement changer ta façon d'interagir avec Twitter.</p>
<p>Fini les galères, on reprend le contrôle de notre terminal ! 🚀</p>
<hr />
<h2>XSH, c'est quoi ce truc ?</h2>
<p><strong>XSH</strong> (pour <em>X Shell</em>), c'est une interface en ligne de commande développée en <strong>Go</strong> qui te permet d'utiliser Twitter/X directement depuis ton terminal. Mais attention, c'est là que ça devient magique : il fonctionne <strong>SANS clé API</strong>.</p>
<p>Eh oui ! Pas de compte développeur à créer, pas de tokens OAuth complexes à générer, et surtout, pas de factures surprises. XSH utilise une <strong>authentification basée sur les cookies de ton navigateur</strong>. En gros, tu te connectes une fois, et tu es libre d'utiliser la plateforme comme un humain... mais depuis ton terminal.</p>
<hr />
<h2>Pourquoi XSH change la donne ?</h2>
<p>Si tu as déjà essayé de créer un bot ou juste un script pour publier tes derniers articles de blog sur X, tu connais la douleur de l'API officielle actuelle. Avec XSH, j'ai voulu casser ces barrières.</p>
<h3>Les super-pouvoirs de XSH</h3>
<ul>
<li>🆓 <strong>100% Gratuit</strong> : Pas de frais d'API, jamais.</li>
<li>🔑 <strong>Zéro clé API requise</strong> : Tu te connectes juste avec ta session web habituelle (via les cookies).</li>
<li>🚀 <strong>Adieu les Rate Limits stricts</strong> : Tu contournes les limites drastiques de l'API gratuite puisque tu navigues de manière "organique".</li>
<li>⚡ <strong>Ultra rapide</strong> : C'est codé en Go, démarrage en ~50ms, compilé et léger.</li>
<li>🛡️ <strong>Respect de la vie privée</strong> : Tes identifiants et tes cookies restent sur TA machine. Aucun serveur intermédiaire ne vient fouiner dans tes affaires.</li>
<li>🤖 <strong>AI-Ready</strong> : 52 outils MCP intégrés pour connecter XSH à tes agents IA (Claude, GPT, etc.).</li>
</ul>
<hr />
<h2>Comment l'installer ?</h2>
<p>Plusieurs options selon ton environnement, à toi de choisir la plus simple !</p>
<h3>Via Go (toutes plateformes)</h3>
<p>Si tu as <strong>Go 1.24+</strong> d'installé sur ta machine :</p>
<pre><code>go install github.com/benoitpetit/xsh@latest
</code></pre>
<h3>Script d'installation (Linux / macOS)</h3>
<p>Une seule commande, tout est automatique :</p>
<pre><code>curl -sSL https://raw.githubusercontent.com/benoitpetit/xsh/master/scripts/install.sh | bash
</code></pre>
<h3>PowerShell (Windows)</h3>
<p>À lancer en tant qu'Administrateur :</p>
<pre><code>iwr -useb https://raw.githubusercontent.com/benoitpetit/xsh/master/scripts/install.ps1 | iex
</code></pre>
<h3>Depuis les sources</h3>
<pre><code>git clone https://github.com/benoitpetit/xsh &amp;&amp; cd xsh &amp;&amp; go build -o xsh .
</code></pre>
<blockquote>
<p>Tu préfères un binaire pré-compilé ? Tous les builds (Linux, macOS Intel/Apple Silicon, Windows) sont disponibles directement sur la <a href="https://github.com/benoitpetit/xsh/releases">page des releases GitHub</a>.</p>
</blockquote>
<hr />
<h2>Exemples d'utilisation (pour kiffer)</h2>
<p>Une fois installé, tu vas voir, c'est un jeu d'enfant. Voici un aperçu des commandes essentielles.</p>
<h3>1. L'authentification (la magie des cookies)</h3>
<p>Pour commencer, il faut donner à XSH l'accès à ta session :</p>
<pre><code>xsh auth login
</code></pre>
<p>L'outil va t'accompagner pour récupérer ton cookie de session de manière sécurisée. Tu peux aussi importer un fichier de cookies exporté depuis ton navigateur :</p>
<pre><code>xsh auth import cookies.json
</code></pre>
<h3>2. Lire ton fil d'actualité</h3>
<p>Tu veux checker ce qui se passe sans ouvrir un navigateur lourd et bourré de pubs ?</p>
<pre><code>xsh feed
</code></pre>
<p>Et en JSON pour tes scripts et pipelines :</p>
<pre><code>xsh feed --json | jq '.[].text'
</code></pre>
<h3>3. Envoyer un Tweet depuis le terminal</h3>
<p>L'action classique, envoyer ton message au monde entier depuis ta console préférée :</p>
<pre><code>xsh tweet post "Hello World ! Ce tweet a été envoyé depuis mon terminal grâce à XSH 🚀"
</code></pre>
<p>Avec une image :</p>
<pre><code>xsh tweet post "Regarde ce screenshot !" --image capture.png
</code></pre>
<h3>4. Rechercher des tweets</h3>
<pre><code>xsh search "golang cli" --type Latest
</code></pre>
<h3>5. Consulter un profil utilisateur</h3>
<pre><code>xsh user benoitpetit --json
</code></pre>
<h3>6. Liker, retweeter, suivre</h3>
<pre><code>xsh tweet like &lt;id&gt;
xsh tweet retweet &lt;id&gt;
xsh follow &lt;handle&gt;
</code></pre>
<h3>7. Messages directs</h3>
<pre><code>xsh dm send &lt;handle&gt; "Hey, t'as vu XSH ? 👀"
xsh dm inbox --json
</code></pre>
<h3>8. Tweeter dans le futur (scheduled)</h3>
<pre><code>xsh schedule "Mon article sort demain, restez connectés !" --at "2026-04-01T09:00:00"
</code></pre>
<p>Tu peux l'intégrer dans tes scripts Bash, tes pipelines CI/CD, ou juste l'utiliser au quotidien entre deux <code>git commit</code>. Les possibilités d'automatisation redeviennent enfin fun et accessibles !</p>
<hr />
<h2>Bonus : XSH + Agents IA (MCP)</h2>
<p>XSH embarque un serveur <strong>MCP (Model Context Protocol)</strong> avec <strong>52 outils</strong> prêts à l'emploi pour tes agents IA. Lance-le en une commande :</p>
<pre><code>xsh mcp
</code></pre>
<p>Ton agent IA peut ensuite lire le feed, poster des tweets, gérer les follows, les bookmarks, les listes… le tout de manière autonome. C'est du sérieux.</p>
<hr />
<blockquote>
<p>[!FEATURE]</p>
<h2>🌟 Prêt à reprendre le contrôle ?</h2>
<p>Le projet est entièrement <strong>Open Source</strong> et documenté. J'ai mis en place un site dédié où tu retrouveras toutes les commandes, les astuces d'installation et la doc complète :</p>
<p>👉 Découvrir le projet sur : <a href="https://xsh.devbyben.fr">xsh.devbyben.fr</a></p>
<p>Le code source est évidemment disponible sur mon GitHub : <a href="https://github.com/benoitpetit/xsh">github.com/benoitpetit/xsh</a>. Si le projet te plaît, n'hésite pas à aller lui mettre une petite étoile ⭐, ça fait toujours plaisir et ça aide le projet à se faire connaître !</p>
<p>Et comme d'habitude, si mes outils t'aident dans ton quotidien de dev et que tu veux soutenir mon travail, tu peux le faire sur <a href="https://liberapay.com/devbyben/donate">Liberapay</a> ou <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>. ☕</p>
<blockquote>
<p>Alors, prêt à tweeter en mode hacker ? Dis-moi ce que tu en penses sur GitHub (ou directement sur X depuis ton terminal) !</p>
</blockquote>
</blockquote>
<hr />
<p><em>Développé avec ❤️ par la communauté open source pour un web plus libre.</em></p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>CLI</category>
            <category>Go</category>
            <category>Twitter</category>
            <category>open source</category>
            <category>terminal</category>
            <enclosure url="https://devbyben.fr/images/blog/xsh-le-cli-ultime-pour-twitter-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Confidentialité : Pourquoi j'ai dit "Non" à l'entraînement de l'IA sur mon code]]></title>
            <link>https://devbyben.fr/blog/confidentialite-pourquoi-jai-dit-non-a-lentrainement-de-lia-sur-mon-code</link>
            <guid>https://devbyben.fr/blog/confidentialite-pourquoi-jai-dit-non-a-lentrainement-de-lia-sur-mon-code</guid>
            <pubDate>Fri, 27 Mar 2026 13:48:16 GMT</pubDate>
            <description><![CDATA[GitHub propose une option souvent activée par défaut pour utiliser ton code dans l'entraînement de ses modèles IA. Voici pourquoi j'ai décidé de la désactiver, et comment faire pareil en 10 secondes.]]></description>
            <content:encoded><![CDATA[<p>Salut toi ! Si tu utilises GitHub (et je parie que c'est le cas), tu as peut-être croisé cette petite option bien planquée dans tes paramètres : <strong>« Allow GitHub to use my data for AI model training »</strong>. Par défaut, elle est souvent activée. De mon côté, je viens de passer l'interrupteur sur <strong>Disable</strong>. Voici pourquoi.</p>
<hr />
<h2>Le Code, c'est personnel (et stratégique)</h2>
<p>L'intelligence artificielle, comme GitHub Copilot, est un outil fantastique pour gagner du temps. Je suis le premier à m'en servir pour accélérer mon workflow. Mais il y a une sacrée différence entre <strong>utiliser l'IA</strong> et <strong>devenir sa nourriture</strong>.</p>
<p>En laissant cette option activée, tu autorises GitHub à collecter tes inputs, tes outputs et le contexte de tes projets pour entraîner ses futurs modèles.</p>
<hr />
<h2>3 raisons pour lesquelles j'ai désactivé l'option</h2>
<h3>Contrôle de la propriété intellectuelle</h3>
<p>Mon code est le fruit de ma réflexion. Que ce soit pour un projet perso ou pro, je n'ai pas forcément envie qu'il soit fragmenté, digéré et redistribué dans les suggestions d'autres développeurs à l'avenir.</p>
<h3>Sécurité des données</h3>
<p>Même si les modèles tentent d'anonymiser les données, le risque "zéro" n'existe pas. On a déjà vu des IA recracher des données sensibles. Désactiver l'option, c'est s'assurer qu'aucun secret ou structure logique sensible ne quitte mon environnement de travail.</p>
<h3>L'éthique par le consentement</h3>
<p>Je pense qu'il est crucial de rester maître des données que nous produisons. Utiliser un service ne devrait pas automatiquement signifier céder nos droits d'apprentissage à des géants de la tech.</p>
<hr />
<h2>Comment faire pareil et reprendre le contrôle ?</h2>
<p>Si tu veux aussi reprendre le contrôle de ton code, la manipulation prend littéralement <strong>10 secondes</strong> :</p>
<ol>
<li>Direction tes <strong>Settings</strong> sur GitHub.</li>
<li>Va dans la section <strong>Copilot</strong> (ou dans tes paramètres de confidentialité / <strong>Data</strong>).</li>
<li>Trouve la section concernant la collecte de données (<strong>Data collection</strong>) et décoche la case.</li>
</ol>
<p>Et la meilleure partie ? Cela ne change absolument rien à la qualité des suggestions que tu recevras ! Tu gardes la puissance de l'outil, sans compromettre tes données.</p>
<hr />
<h2>Bonus : Fais le ménage dans ta télémétrie</h2>
<p>Puisqu'on parle de confidentialité, as-tu pensé à vérifier ton éditeur de code ? Si tu utilises <strong>VS Code</strong>, Microsoft collecte par défaut des données d'utilisation et de plantage (la fameuse <strong>télémétrie</strong>).</p>
<p>Pour la désactiver, c'est super simple :</p>
<ol>
<li>Ouvre tes paramètres (<code>Ctrl+,</code> ou <code>Cmd+,</code>).</li>
<li>Cherche <strong>telemetry</strong> dans la barre de recherche.</li>
<li>Passe le paramètre <code>telemetry.telemetryLevel</code> sur <strong>off</strong>.</li>
</ol>
<p>C'est rapide, et ça fait du bien à ta vie privée.</p>
<hr />
<blockquote>
<p><em>"Utiliser l'IA ne devrait pas se faire au prix de notre confidentialité."</em></p>
</blockquote>
<p>Alors, prêt(e) à faire le tour de tes paramètres ? Dis-moi en commentaire si tu avais déjà désactivé ces options ou si tu viens de le découvrir ! 🚀</p>
<p>Si cet article t'a aidé à sécuriser ton environnement, pense à soutenir mon travail : <a href="https://liberapay.com/devbyben/donate">Liberapay</a> ou <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>privacy</category>
            <category>GitHub</category>
            <category>IA</category>
            <category>VS Code</category>
            <category>confidentialité</category>
            <enclosure url="https://devbyben.fr/images/blog/confidentialite-pourquoi-jai-dit-non-a-lentrainement-de-lia-sur-mon-code-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Configurer Claude Code gratuitement avec OpenRouter]]></title>
            <link>https://devbyben.fr/blog/configurer-claude-code-gratuitement-openrouter</link>
            <guid>https://devbyben.fr/blog/configurer-claude-code-gratuitement-openrouter</guid>
            <pubDate>Fri, 20 Mar 2026 13:26:09 GMT</pubDate>
            <description><![CDATA[Découvre comment utiliser Claude Code, l'outil de développement assisté par IA d'Anthropic, sans dépenser un centime grâce à OpenRouter. Configuration simple, modèles gratuits et productivité maximale au rendez-vous.]]></description>
            <content:encoded><![CDATA[<p>Hello ! Aujourd'hui, on va s'attaquer à un sujet qui touche directement le portefeuille : le coût des IA pour coder. On adore tous <strong>Claude Code</strong> (la CLI d'Anthropic) pour booster nos projets, mais l'idée d'un abonnement mensuel ou de raquer à chaque requête API peut vite refroidir l'enthousiasme.</p>
<p>J'ai la solution pour vous. Dans ce guide, on va voir comment configurer Claude Code pour qu'il tourne de manière <strong>totalement gratuite</strong> en utilisant <strong>OpenRouter</strong>. Pas d'alias compliqués à taper à chaque fois : on va passer par une configuration globale propre et efficace.</p>
<hr />
<h2>Le concept : OpenRouter comme passerelle</h2>
<p>Par défaut, Claude Code cherche à discuter avec les serveurs d'Anthropic. L'astuce consiste à détourner cet appel vers <strong>OpenRouter</strong>, une plateforme qui centralise des dizaines de modèles (Mistral, Llama, Gemini, etc.).</p>
<p>L'avantage ? OpenRouter propose une tonne de modèles <strong>"Free"</strong> (gratuits). En configurant correctement votre fichier de paramètres global, Claude Code croira parler à Anthropic, mais utilisera en réalité la puissance gratuite d'OpenRouter. C'est légal, c'est efficace, et ça permet de garder une "vibe code" au top sans dépenser un centime.</p>
<hr />
<h2>Étape 1 : Installer Claude Code</h2>
<p>Si vous ne l'avez pas encore fait, installez l'outil globalement via NPM. Ouvrez votre terminal préféré et lancez :</p>
<pre><code>npm install -g @anthropic-ai/claude-code
</code></pre>
<hr />
<h2>Étape 2 : Trouver votre modèle gratuit sur OpenRouter</h2>
<p>Avant de configurer, il nous faut une cible.</p>
<ol>
<li>Direction la page des modèles : <a href="https://openrouter.ai/models">openrouter.ai/models</a>.</li>
<li>Dans la barre de recherche, tapez simplement <strong>"free"</strong>.</li>
<li>Vous verrez apparaître une liste de modèles gratuits (comme <code>google/gemini-2.0-flash-exp:free</code> ou <code>stepfun/step-3.5-flash:free</code>).</li>
<li>Notez bien l'identifiant du modèle (ex: <code>stepfun/step-3.5-flash:free</code>).</li>
</ol>
<hr />
<h2>Étape 3 : Générer votre clé API OpenRouter</h2>
<p>Il vous faut un badge d'accès pour passer la porte :</p>
<ol>
<li>Connectez-vous à votre compte <strong>OpenRouter</strong>.</li>
<li>Allez dans <strong>API Keys</strong> et créez une nouvelle clé (nommez-la "Claude Free" pour vous y retrouver).</li>
<li><strong>Copiez-la immédiatement</strong>, car elle ne s'affichera qu'une seule fois.</li>
</ol>
<hr />
<h2>Étape 4 : La configuration globale (Le "Secret Sauce")</h2>
<p>Plutôt que de bidouiller des variables d'environnement à chaque lancement, on va modifier directement le fichier de configuration de Claude Code. C'est plus propre et ça devient votre réglage par défaut.</p>
<p>Le fichier se trouve généralement ici : <code>~/.claude/settings.json</code> (sous Linux/macOS) ou dans votre répertoire utilisateur sous Windows.</p>
<p>Ouvrez ce fichier (ou créez-le s'il n'existe pas) et collez-y la structure suivante :</p>
<pre><code>{
  "env": {
    "ANTHROPIC_BASE_URL": "https://openrouter.ai/api",
    "ANTHROPIC_AUTH_TOKEN": "votre_cle_openrouter_ici",
    "ANTHROPIC_API_KEY": "",
    "ANTHROPIC_MODEL": "stepfun/step-3.5-flash:free"
  }
}
</code></pre>
<blockquote>
<p><strong>Note importante :</strong> Laissez une valeur vide dans <code>ANTHROPIC_API_KEY</code>. Claude Code vérifie parfois la présence d'une clé au format Anthropic avant de lancer la requête, même si OpenRouter utilise le jeton dans <code>ANTHROPIC_AUTH_TOKEN</code>.</p>
</blockquote>
<hr />
<h2>Étape 5 : Testez et validez</h2>
<p>Désormais, dès que vous tapez <code>claude</code> dans votre terminal, l'outil utilisera automatiquement OpenRouter et le modèle gratuit que vous avez choisi.</p>
<ul>
<li>Allez dans un dossier de projet.</li>
<li>Lancez la commande : <code>claude</code></li>
<li>Posez une question : <em>"Peux-tu m'expliquer ce fichier ?"</em></li>
</ul>
<p>Si tout est bien configuré, vous aurez une réponse rapide sans que votre compte Anthropic ne soit débité.</p>
<h3>Pourquoi utiliser cette méthode ?</h3>
<ul>
<li><strong>Zéro coût :</strong> Idéal pour l'apprentissage ou les petits projets.</li>
<li><strong>Transparence :</strong> Claude Code conserve toutes ses fonctionnalités (lecture de fichiers, exécution de commandes) et ça marche plutôt bien j'ai été impressionné.</li>
<li><strong>Flexibilité :</strong> Vous voulez changer de modèle ? Changez juste la ligne <code>ANTHROPIC_MODEL</code> dans votre fichier JSON.</li>
</ul>
<hr />
<p>Voilà, vous avez maintenant un assistant de code surpuissant et gratuit. C'est ça, la magie du web ouvert ! n'hésite pas à faire un tour sur mon blog pour d'autres astuces.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>Claude Code</category>
            <category>OpenRouter</category>
            <category>IA gratuite</category>
            <category>productivité</category>
            <enclosure url="https://devbyben.fr/images/blog/configurer-claude-code-gratuitement-openrouter.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[YGGleak : quand le plus gros tracker torrent français se fait autopsier]]></title>
            <link>https://devbyben.fr/blog/yggleak-quand-le-plus-gros-tracker-torrent-francais-se-fait-autopsier</link>
            <guid>https://devbyben.fr/blog/yggleak-quand-le-plus-gros-tracker-torrent-francais-se-fait-autopsier</guid>
            <pubDate>Thu, 05 Mar 2026 14:38:33 GMT</pubDate>
            <description><![CDATA[3 mars 2026. Un hacker publie 11 Go de données internes d'YGGTorrent. Le site ferme dans la foulée. Et là, on découvre que derrière le "partage libre et communautaire", il y avait en fait un business de 10 millions d'euros qui skimmait des cartes bancaires.]]></description>
            <content:encoded><![CDATA[<p><strong>3 mars 2026.</strong> Un hacker publie 11 Go de données internes d'YGGTorrent. Le site ferme dans la foulée. Et là, on découvre que derrière la belle vitrine du "partage libre et communautaire", il y avait en fait une véritable mafia numérique brassant près de 10 millions d'euros et siphonnant des cartes bancaires.</p>
<p>C'est le genre de dossier qui te donne envie de vider ton cache et de faire opposition sur ta carte bleue. Si t'as jamais mis un pied sur YGG — et soyons honnêtes, une bonne partie des devs francophones l'ont fait —, cet article est pour toi. Pas pour te juger, mais pour décortiquer les dessous techniques d'une opération qui est, à bien des égards, un cas d'école en cybersécurité.</p>
<hr />
<h2>La scène de crime en deux phrases</h2>
<p>Un hacker se faisant appeler <strong>Gr0lum</strong> a compromis l'intégralité de l'infrastructure d'YGGTorrent, exfiltré les données, puis détruit les serveurs. Dans la foulée, il publie un dossier explosif baptisé <em>YGGtorrent — Fin de partie</em> sur le site <a href="https://yggleak.top/fr">yggleak.top</a>, avec en bonus une archive de 11 Go disponible en torrent.</p>
<p>👉 <strong>YGGTorrent, pour ceux qui ne suivent pas :</strong> c'était le plus gros tracker de torrents francophone. Depuis sa création en 2017 dans le sillage de la chute de T411, il s'était imposé comme la référence du partage en France. 6,6 millions de comptes, des milliers de partageurs bénévoles, et une place au chaud parmi les 35 sites les plus visités du pays.</p>
<p>Et maintenant, il est mort. Alors, qu'est-ce qui s'est passé <em>vraiment</em> ?</p>
<hr />
<h2>La fissure : le "Turbo Mode" qui a tout fait péter</h2>
<p>Tout commence fin 2025 avec une décision commerciale particulièrement mal dosée, dictée par l'avidité.</p>
<p>Le fameux <strong>"Turbo Mode"</strong>, déployé le 21 décembre 2025 en pleine période de fêtes, limitait les comptes gratuits à cinq téléchargements par jour avec une attente obligatoire de 30 secondes. Le déblocage coûtait 14,99 euros par mois, ou 85,99 euros à vie.</p>
<p>La communauté explose. Les équipes d'uploadeurs — ceux qui font tourner le site bénévolement — protestent. Résultat, la direction purge sans sommation :</p>
<p>❌ La Team QTZ (3 300 torrents publiés) — bannie.
❌ La Team Forward (35 000 torrents) — bannie.
❌ La shoutbox — désactivée pour couper court aux rébellions.</p>
<p>D'après les bases de données exfiltrées, le chiffre d'affaires a carrément triplé en janvier 2026 pour atteindre <strong>~490 000 euros sur ce seul mois</strong>. C'est exactement là que la tension est devenue intenable. Et c'est là que Gr0lum a décidé d'appuyer sur le gros bouton rouge.</p>
<p>Un détail qui illustre bien le mépris de la hiérarchie pour sa communauté : le code source de l'API révèle que les admins, modérateurs et comptes premium n'étaient <strong>jamais</strong> soumis au timer de 30 secondes ni à la limite des 5 téléchargements. Le Turbo Mode, c'était pour les autres.</p>
<hr />
<h2>Le vecteur d'entrée : un favicon sur Shodan et un port oublié</h2>
<p>Techniquement, par où est-ce qu'on entre sur un site de cette taille ? Pas par une faille exotique. Par <strong>de la reconnaissance basique et de la négligence d'infra</strong>.</p>
<p>Tout commence avec le <strong>favicon hash</strong>. Chaque icône de site a une empreinte numérique unique. Gr0lum calcule le hash du favicon d'YGG et le cherche dans Shodan :</p>
<pre><code>http.favicon.hash:456260082
</code></pre>
<p>Résultat immédiat : <strong>188.253.108.198</strong>, le serveur de pré-production sous Windows Server 2019. Un scan Nmap révèle 13 ports ouverts, dont plusieurs qui n'auraient jamais dû être exposés sur Internet : SMB (445), RDP (3389), Redis sans authentification (6379), et surtout — <strong>SphinxQL sur le port 9306</strong>.</p>
<p>Sphinx Search est un moteur de recherche full-text qui utilise un protocole compatible MySQL. Sur ce serveur, il est accessible depuis Internet <strong>sans aucune authentification</strong> :</p>
<pre><code>mysql -h 188.253.108.198 -P 9306
# Connexion immédiate, aucun identifiant requis
</code></pre>
<p>Jusque-là, on a juste un moteur de recherche ouvert. Mais SphinxQL supporte nativement <code>CALL SNIPPETS</code> avec le paramètre <code>load_files=1</code> — une fonctionnalité prévue pour l'indexation de fichiers locaux. Quand le service tourne avec des privilèges élevés et qu'il est exposé à Internet sans restriction, ça revient à donner un <strong>accès en lecture sur tout le disque</strong> à n'importe qui :</p>
<pre><code>CALL SNIPPETS(
    'C:/chemin/vers/fichier.txt',
    'users',
    'mot_cle',
    1 AS load_files,
    50000 AS around,
    0 AS limit
);
</code></pre>
<p>En quelques minutes, 12 fichiers de configuration sont extraits : <code>.env</code> avec les clés en clair, <code>database.php</code> avec les credentials MySQL (root, pas de mot de passe), <code>config.php</code> avec la clé de chiffrement CodeIgniter, les clés SMTP, hCaptcha, et la clé de signature des announces. Le code source complet de l'API future d'YGG était aussi exposé via un <strong>directory listing actif sur le port 443</strong>, <code>.env</code> inclus.</p>
<p>Mais le fichier le plus dévastateur était ailleurs.</p>
<h3>Le sysprep qui a tout fait péter</h3>
<p>Sur les serveurs Windows déployés automatiquement, le fichier <code>sysprep_unattend.xml</code> contient les paramètres d'installation, y compris parfois le mot de passe administrateur. Ce fichier <strong>aurait dû être supprimé</strong> après le déploiement :</p>
<pre><code>CALL SNIPPETS(
    'C:/Windows/Panther/Unattend/sysprep_unattend.xml',
    'users',
    'password',
    1 AS load_files,
    50000 AS around,
    0 AS limit
);
</code></pre>
<p>Résultat :</p>
<pre><code>&lt;AutoLogon&gt;
    &lt;Username&gt;Administrator&lt;/Username&gt;
    &lt;Password&gt;
        &lt;Value&gt;&amp;amp;)d(5Hj46B7h5^fQF^c(yKYRP&lt;/Value&gt;
        &lt;PlainText&gt;true&lt;/PlainText&gt;
    &lt;/Password&gt;
&lt;/AutoLogon&gt;
</code></pre>
<p>Le mot de passe administrateur Windows. <strong>En clair. Dans un fichier lisible sans authentification.</strong> À noter : Windows Defender était aussi désactivé (<code>DisableAntiSpyware=true</code>). La partie "entrée" est terminée. Tout ce qui suit, c'est de la post-exploitation.</p>
<hr />
<h2>La chaîne de compromission complète</h2>
<p>Avec le mot de passe admin en main, Gr0lum accède au partage SMB <code>C$</code> du serveur Windows — lecture et écriture sur l'intégralité du disque. C'est là que tout s'enchaîne. Le navigateur Chrome de Destroy (l'admin dev) était installé sur cette machine qu'il utilisait comme son <strong>PC de bureau perso</strong>. Les mots de passe Chrome sont chiffrés avec AES-256-GCM via DPAPI, mais avec les credentials Administrator récupérés, le déchiffrement est direct : <strong>des centaines de mots de passe</strong> en clair, des tokens de session actifs pour PayPal, Protonmail, le registrar Njalla, des forums cybercrime, et le service de DDoS <code>stresscat.ru</code>.</p>
<p>Plus utile encore : <strong>FileZilla</strong> avec ses credentials SFTP stockés en clair dans <code>recentservers.xml</code>. Ce fichier était la carte vers toute l'infrastructure :</p>
<ul>
<li><code>62.112.11.32</code> — le serveur tracker XBT (accès obtenu, groupe root/wheel, <code>sudo</code> avec le même mot de passe SSH)</li>
<li><code>185.132.134.125</code> — le serveur web et la boutique WooCommerce (accès obtenu)</li>
<li><code>212.8.249.144</code> — le serveur MySQL de production, accessible uniquement en interne, atteint en pivot depuis le tracker</li>
</ul>
<p>Depuis le tracker, un fichier <code>/root/.my.cnf</code> contenait les credentials MySQL de production. Une seule commande :</p>
<pre><code>mysql -h 212.8.249.144 -u root -p'Ay4SDNwDvrd83qz2zVa5uCr' -e "SELECT COUNT(*) FROM yggis.users;"
# 6 629 484
</code></pre>
<p><strong>La totalité de la base de données de la plateforme.</strong> En résumé, la chaîne complète ressemble à ça :</p>
<pre><code>favicon hash dans Shodan
  → SphinxQL sans auth (port 9306)
    → lecture fichiers arbitraires
      → sysprep_unattend.xml = mot de passe admin Windows
        → SMB C$ = accès disque complet
          → Chrome DPAPI = coffre-fort de credentials
          → FileZilla XML = carte de l'infrastructure
            → tracker XBT (root) → pivot MySQL → 6,6M comptes
            → serveur web → boutiques WooCommerce → 89K clients
</code></pre>
<p>Quatre serveurs compromis, sept bases de données détruites, ~19 Go exfiltrés. Durée totale : <strong>environ 3 jours</strong>.</p>
<hr />
<h2>Ce que le dossier révèle : pas un projet communautaire, un cartel</h2>
<p>C'est là que ça devient vraiment intéressant d'un point de vue OPSEC et investigation financière.</p>
<h3>Le braquage financier</h3>
<p>Le leak révèle les vrais chiffres : plus de <strong>249 000 commandes</strong>, près de <strong>100 000 payeurs uniques</strong> et entre <strong>5 et 8,5 millions d'euros</strong> de chiffre d'affaires estimés sur la période 2024-2025. Face à ça ? Des coûts serveurs estimés à seulement <strong>50 000 euros par an</strong>. Marge bénéficiaire indécente.</p>
<h3>La lessiveuse à 36 domaines</h3>
<p>Pour blanchir l'argent, les paiements par carte transitaient par <strong>CardsShield</strong> — un plugin WooCommerce vendu 800 dollars par mois par un vendeur vietnamien sur Telegram. Ce système automatise la rotation entre <strong>36+ domaines proxy</strong> déguisés en boutiques e-commerce. Sur les relevés PayPal et Stripe, ton abonnement torrent apparaissait comme un achat de t-shirt sur <code>calcilux.shop</code> ou <code>pocarilux.shop</code>. Un cron WordPress tournait <strong>toutes les minutes</strong> pour basculer automatiquement vers un nouveau domaine en cas de blocage.</p>
<p>Huit processeurs de paiement coexistaient en parallèle : CardsShield, PayGate.to ("all high risk business models accepted"), OxaPay, NowPayments, Sellix, et d'autres. La passerelle CB centrale <code>enigmastocks.com</code> était enregistrée à <strong>Charlestown, Saint-Kitts-et-Nevis</strong> — paradis fiscal. Les fonds étaient ensuite convertis en crypto, passés par <em>Tornado Cash</em> pour couper la trace on-chain, puis transformés en <strong>Monero via ChangeNOW</strong> — la crypto intraçable par design. Des notes de dépôt Tornado Cash retrouvées sur le serveur de pré-prod confirment <strong>~22 ETH (~42 000 dollars)</strong> déjà blanchis via le mixer, pour les seules traces retrouvées.</p>
<h3>Le fingerprinting massif</h3>
<p>Un fichier CSV de <strong>259 Mo, 4 173 645 lignes</strong>, couvrant 12 mois de collecte (septembre 2024 à septembre 2025). Chaque ligne enregistrait un événement de navigation : <code>user_id</code>, timezone, langues du navigateur, timestamp. <strong>543 448 utilisateurs distincts</strong> étaient trackés.</p>
<p>Ce n'était pas pour améliorer l'UX. La liste <code>Accept-Language</code> complète du navigateur — par exemple <code>fr-FR,es-CO,es,en-GB,fr,en-US,en</code> — combinée au fuseau horaire crée une empreinte quasi unique par utilisateur. C'était du <em>fingerprinting</em> systématique pour identifier les gens <strong>même derrière un VPN</strong>.</p>
<h3>Le scan de wallets crypto que personne n'avait vu venir</h3>
<p>Ce point est moins connu mais particulièrement retors. Un script JavaScript baptisé <code>sci.js</code> s'exécutait dans ton navigateur à chaque visite. Déguisé en <code>ImageCarouselManager</code> (une classe carousel factice de 213 lignes, jamais instanciée), il <strong>scannait silencieusement la présence de wallets crypto</strong> : Phantom (Solana), MetaMask (Ethereum), Trust Wallet, Coinbase Wallet, WalletConnect.</p>
<p>Si un wallet était détecté, les données partaient vers <code>Web3stats.php</code> (clé d'accès <code>d3ShGIbbX3</code>). Le script ne volait rien directement — mais il constituait une liste de qui, parmi les 6,6 millions d'utilisateurs, possède un wallet crypto et lequel. Le genre d'info qui intéresse beaucoup dans certains milieux.</p>
<hr />
<h2>Le skimmer de cartes : le truc qui fout vraiment les jetons</h2>
<p>C'est la révélation la plus grave du dossier.</p>
<p>Un controller <em>CodeIgniter</em> de <strong>1,6 Ko</strong> nommé <code>Security.php</code>, bien présent dans le code de production, recevait le numéro de carte complet (PAN), le CVV, la date d'expiration et le nom du titulaire via POST. Les données transitaient d'abord <strong>en clair</strong> par le serveur YGG avant d'être relayées vers le processeur de paiement via un formulaire caché auto-soumis. Détail révélateur : quand le token de commande était invalide, le script redirigait silencieusement vers <code>google.com</code> — une technique classique d'<strong>anti-analyse</strong>.</p>
<p>Gr0lum avance le chiffre de <strong>54 776 cartes bancaires</strong> ainsi interceptées. Les témoignages Reddit ne manquaient pas :</p>
<blockquote>
<p><em>"Après avoir payé du free leech la semaine dernière par PayPal, aujourd'hui 4000€ de matériel de son ont été commandés chez Thomann et livrés à une boutique inexistante du 93 sous le nom de Kevin. Ce PayPal n'avait pas été utilisé depuis plus d'un an sauf pour YGG."</em> — u/TatonTatonne, octobre 2024</p>
</blockquote>
<p>Tu vois le problème ici ? Les processeurs de paiement légitimes fournissent tous des checkouts hébergés (le modèle Stripe.js, Braintree Drop-in UI, etc.) précisément pour éviter que les données bancaires ne touchent tes serveurs. Le fait qu'YGG ait choisi de faire passer les données <em>par</em> sa propre machine n'est pas une maladresse technique : <strong>c'est un choix délibéré de siphonnage</strong>.</p>
<hr />
<h2>Le honeypot anti-bypass : banni sans le savoir</h2>
<p>Ce chapitre est moins connu mais parfaitement documenté dans le leak.</p>
<p>Après le déploiement du Turbo Mode, un développeur a publié <strong>YGGMollo</strong>, une extension Chrome qui ajoutait un bouton pour contourner la limite des 5 téléchargements par jour. Elle a été massivement adoptée le 24 décembre 2025.</p>
<p>Dès le lendemain, les bans tombaient. Voilà pourquoi : un script nommé <code>modal.min.js</code> était chargé sur toutes les pages. Son nom était inoffensif — l'historique PowerShell du serveur révèle le renommage explicite :</p>
<pre><code>Rename-Item -Path "assets\js\security.min.js" -NewName "modal.min.js"
</code></pre>
<p>Le contenu était obfusqué en base64. Décodé, le script attendait 2,5 secondes, cherchait la classe <code>.yggsearch-api-btn</code> injectée par l'extension dans la page, et si elle était détectée, soumettait silencieusement un formulaire caché vers <code>/engine/gm</code>. Côté serveur : log du user ID, du pseudo et de l'IP dans <code>extension_users.txt</code>, puis <strong>ban définitivement le compte</strong> sans avertissement. L'utilisateur découvrait son ban après coup, sans explication.</p>
<blockquote>
<p><em>"YGG banit les comptes qui utilisent l'extension. Supprimez-la directement !!!! Désolé si vous avez été banni"</em> — u/amottier, créateur de YGGMollo, 25 décembre 2025</p>
</blockquote>
<p>YGG avait préparé le piège avant même que l'extension existe.</p>
<hr />
<h2>Les DDoS contre la concurrence</h2>
<p>YGG ne se contentait pas d'exploiter ses utilisateurs. Un script <code>generate-tracker-url.js</code> retrouvé dans le code utilisait l'API du service de DDoS-for-hire russe <strong>stresscat.ru</strong> pour attaquer directement <strong>la-cale.space</strong> et <strong>sharewood.tv</strong> — deux trackers francophones présentés comme alternatives à YGG. Deux clés API documentées, des attaques de 1 800 secondes lancées via un cron <strong>toutes les 2 minutes</strong>, un fichier de <strong>46 Mo d'URLs d'attaque</strong> générées. L'historique PowerShell confirme trois exécutions.</p>
<p>Technique utilisée : des URLs d'announce BitTorrent pointant vers la cible — une méthode d'amplification qui multiplie le volume d'attaque en mobilisant les clients torrent de milliers d'utilisateurs à leur insu.</p>
<hr />
<h2>Les acteurs démasqués (sans dox)</h2>
<p>Gr0lum identifie les figures centrales sans révéler leurs identités civiles complètes, mais l'organigramme est clair :</p>
<ul>
<li><strong>Oracle</strong> : l'administrateur principal. Opère exclusivement via VPN (Mullvad, M247, LeaseWeb). Une IP résidentielle marocaine (Maroc Telecom) retrouvée sur des connexions datant de 2019 le localise au <strong>Maroc</strong> à l'époque. Aucun modérateur n'a jamais échangé un message direct avec lui — son seul interlocuteur dans le staff était YggFlop.</li>
<li><strong>YggFlop / Destroy (Vladimir)</strong> : responsable du développement et de l'administration serveur, basé en <strong>France</strong> (IPs Free et SFR retrouvées). C'est lui qui utilisait le serveur de pré-prod comme son PC perso, avec son Chrome plein de credentials.</li>
</ul>
<p>La structure était un silo parfait. Chaque modérateur recevait à son recrutement une liste de règles dont la troisième était explicite : <strong>ne pas poser de questions sur Oracle</strong>. Les modérateurs géraient des centaines de milliers d'actions de modération — gratuitement. Le top 5 du staff assurait 73% de toutes les actions de modération, pendant que les millions s'accumulaient.</p>
<hr />
<h2>Ce que contenait réellement l'archive de 11 Go</h2>
<p>Décompressée, l'archive fait environ <strong>30 Go</strong> et contient <strong>12 231 fichiers</strong> dans 1 045 dossiers. Ce qui est dedans :</p>
<ul>
<li>✅ Code source complet de la plateforme (PHP CodeIgniter 3, XBT Tracker C++ 2,9 Go, API Express.js)</li>
<li>✅ Bases de données du tracker, du forum XenForo, de la boutique WooCommerce</li>
<li>✅ Logs serveur et configurations</li>
<li>✅ Plus de 25 000 échanges privés internes au staff</li>
<li>✅ Projets en développement trouvés sur la pré-prod (7 projets actifs)</li>
<li>✅ Clés API de 13+ processeurs de paiement</li>
</ul>
<p>Ce qui en a été retiré par Gr0lum (par éthique) :</p>
<ul>
<li>👉 Adresses IP des utilisateurs</li>
<li>👉 Emails des membres</li>
<li>👉 Mots de passe hashés</li>
</ul>
<p>⚠️ <strong>Attention :</strong> "retiré de la publication" ≠ "définitivement protégé". L'archive est publique, et les pseudos sont présents avec l'historique complet des téléchargements associés. Avec suffisamment d'infos croisées, la ré-identification de ton profil reste possible. Le pirate précise d'ailleurs que la moitié des mots de passe étaient encore hashés en vieux <strong>MD5 sans sel</strong>. Une aberration pour un site brassant des millions.</p>
<hr />
<h2>Le projet n'était pas en train de mourir — c'est pire</h2>
<p>Un des éléments contre-intuitifs du dossier concerne les intentions des admins. Sur le serveur de pré-production, Gr0lum a trouvé <strong>7 projets en dev actif</strong> : une réécriture intégrale de la plateforme YGG en SvelteKit, une autre en CodeIgniter 4 (<strong>TheRock</strong>, avec 170+ cycles de build jusqu'au 23 janvier 2026), un débrideur auto-hébergé (<em>CloudTorrent</em>), un nouveau tracker (<em>RageTorrent</em>), un forum Warez (<code>warezfr.com</code>, domaine acheté en ETH sur Njalla le 27 décembre 2025), un service d'IPTV (<em>CocoTV</em>) et une instance Mastodon privée (<code>yeeti.io</code>). L'historique Chrome du serveur révèle même leurs outils de développement : <code>claude.ai</code>, <code>chatgpt.com</code>, <code>cursor.com</code>, <code>deepseek.com</code> — deux réécritures en parallèle à coups de vibecoding.</p>
<p>Autrement dit, ils ne préparaient pas un <em>exit scam</em>. Ils <strong>diversifiaient leur empire</strong>. Le Turbo Mode n'était qu'une optimisation de revenus. Ils avaient un plan long terme, des millions en banque, et ils ont <em>quand même</em> choisi de faire transiter des numéros de CB en clair sur leurs serveurs.</p>
<hr />
<h2>La suite : ygg.gratis et le cycle des mega-trackers</h2>
<p>Le catalogue est sauvé. L'équipe du projet <strong>U2P (Utopeer)</strong> a récupéré l'intégralité des torrents d'Ygg et les a relancés sous <strong>ygg.gratis</strong>. Les géants tombent mais renaissent rapidement — après T411, Zone-Téléchargement et Bato.to, c'est la même mécanique qui se répète.</p>
<p>Gr0lum a fait en sorte que les utilisateurs qui <em>seedaient</em> déjà les fichiers sur YGG puissent continuer à le faire via la nouvelle adresse sans modifier leur client torrent. Le site business est mort ; le contenu, non.</p>
<hr />
<h2>Ce que tu dois faire si t'étais sur YGG</h2>
<p>Pas de panique, mais pas de passivité non plus :</p>
<p><strong>1. Change tes mots de passe</strong>
Si tu utilisais le même pass sur YGG que sur d'autres services (statistiquement probable), change-les maintenant. Les vieux hashes MD5 tombent en quelques secondes sur une machine moderne.</p>
<p><strong>2. Vérifie HaveIBeenPwned</strong>
<a href="https://haveibeenpwned.com">haveibeenpwned.com</a> — balance ton email et regarde si ça a fuité par ricochet.</p>
<p><strong>3. Surveille tes relevés bancaires</strong>
Si t'as un jour payé sur le site, surveille tes débits ou fais carrément opposition à ta carte. C'est le moment d'être paranoïaque.</p>
<p><strong>4. Ton pseudo reste associable</strong>
Même sans ton IP, ton pseudo et tes <em>patterns</em> de DL sont dans l'archive. Prends-en note si tu utilises le même pseudo sur GitHub ou ailleurs.</p>
<hr />
<h2>La leçon technique à retenir</h2>
<p>Ce dossier est un audit de sécurité gratuit et sanglant. Si tu es dev et que tu touches à de l'infra, note bien ça :</p>
<p><strong>Sur la sécurité serveur :</strong>
SphinxQL exposé sur Internet sans auth, directory listing actif, <code>sysprep_unattend.xml</code> non nettoyé, Windows Firewall désactivé, Windows Defender désactivé, Redis sans mot de passe — chaque item de cette liste est une faute de base. YGG brassait des millions et ne faisait pas le minimum. Et CloudPanel non patché + PHP-FPM exposé sans ACL sur les serveurs Ubuntu = mouvement latéral immédiat. La CVE-2024-44765 date de 2024.</p>
<p><strong>Sur la gestion des paiements :</strong>
Ne fais <strong>JAMAIS</strong> transiter des données bancaires brutes par tes propres serveurs. Stripe, Mollie, Braintree font des checkouts hébergés pour que tu ne touches jamais au PAN. Une carte qui passe par ton backend, c'est un red flag architectural absolu. Et si tu vois une redirection silencieuse vers <code>google.com</code> quand un paramètre est invalide dans ton flow de paiement, pose-toi des questions.</p>
<p><strong>Sur le tracking comportemental :</strong>
543 000 utilisateurs fingerprintés sur 12 mois via timezone + langues navigateur. Ce n'est pas de l'analytics. Et un script JS déguisé en carousel qui scanne tes wallets crypto en arrière-plan, c'est de la collecte de données délibérément masquée. La distinction entre "analytics" et "surveillance" est souvent une question d'intention. Là, l'intention est documentée dans le code source.</p>
<p><strong>Sur les honeypots :</strong>
Renommer <code>security.min.js</code> en <code>modal.min.js</code> pour pièger les utilisateurs qui contournent tes restrictions, c'est de la tromperie caractérisée. Pas une pratique de défense légitime.</p>
<p><strong>Sur la confiance communautaire :</strong>
Tu ne peux pas bâtir un empire financier sur le dos d'uploadeurs et de modos bénévoles que tu méprises. Quand la confiance s'effondre, elle s'effondre vite et totalement.</p>
<hr />
<h2>Verdict</h2>
<p>YGGleak, ce n'est pas juste l'histoire d'un hack. C'est l'histoire d'une infra sous-patchée qui se croyait intouchable, d'un cartel qui dissimulait son business derrière le mot "communauté", et d'admins qui avaient l'argent pour faire les choses proprement mais ont choisi de racketter leurs utilisateurs.</p>
<p>Gr0lum a exposé tout ça. La méthode est violente — la publication d'une archive même partiellement anonymisée impacte des utilisateurs qui n'avaient rien demandé. Mais la <a href="https://yggleak.top/fr/home/ygg-dossier">documentation technique du leak</a> est rigoureuse, les preuves sont dans le code source, et les pratiques exposées étaient réelles.</p>
<p>Pour toi, dev qui maintient ou construit une plateforme avec de l'auth et du paiement : relis ce writeup comme un <strong>manuel de tout ce qu'il ne faut absolument pas faire en prod</strong>. C'est gratuit, c'est complet, et c'est en ligne depuis 48 heures.</p>
<hr />
<ul>
<li>Sources : <a href="https://yggleak.top/fr">yggleak.top</a> — <a href="https://yggleak.top/fr/home/ygg-dossier">dossier complet</a></li>
</ul>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>Cybersécurité</category>
            <category>OPSEC</category>
            <category>infosec</category>
            <category>leak</category>
            <enclosure url="https://devbyben.fr/images/blog/yggleak-quand-le-plus-gros-tracker-torrent-francais-se-fait-autopsier-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Gérer tes containers Docker en 2026 : le guide complet]]></title>
            <link>https://devbyben.fr/blog/gerer-tes-containers-docker-en-2026-le-guide-complet</link>
            <guid>https://devbyben.fr/blog/gerer-tes-containers-docker-en-2026-le-guide-complet</guid>
            <pubDate>Thu, 19 Feb 2026 09:06:43 GMT</pubDate>
            <description><![CDATA[Pendant que t'es là à faire tes docker ps à la main, l'écosystème open source a explosé — et s'est aussi pris quelques claques. Watchtower, le projet à 24 500 stars que tout le monde utilisait pour au]]></description>
            <content:encoded><![CDATA[<p>Pendant que t'es là à faire tes <code>docker ps</code> à la main, l'écosystème open source a explosé — et s'est aussi pris quelques claques. Watchtower, le projet à 24 500 stars que tout le monde utilisait pour auto-update ses containers ? <strong>Archivé en décembre 2025.</strong> En lecture seule. Incompatible avec Docker Engine 28+. Et personne n'a vraiment prévenu.</p>
<p>Ce guide, c'est l'état réel du terrain en <strong>février 2026</strong> : données GitHub vérifiées, versions actuelles, alertes sur les projets qui dérivent, et les pépites qui montent sans faire de bruit. L'objectif : que tu saches exactement quoi installer selon ton cas d'usage, sans te faire avoir par des stars qui masquent un projet mort.</p>
<hr />
<h2>Les trois familles</h2>
<p>👉 <strong>PaaS auto-hébergés</strong> (Coolify, Dokploy, Komodo) — Tu déploies une app depuis Git, le SSL et le reverse proxy se configurent tout seuls. Le niveau au-dessus de la gestion de containers brute.</p>
<p>👉 <strong>Dashboards web</strong> (Portainer, Dockge, Arcane, Dockhand) — Interface web pour gérer tes containers et stacks Compose. Du plus complet au plus minimaliste.</p>
<p>👉 <strong>Outils CLI/TUI</strong> (Lazydocker, Dozzle, Oxker) — Tout dans le terminal. Un binaire, zéro config, zéro serveur.</p>
<hr />
<h2>Les poids lourds (30k+ stars)</h2>
<h3>Coolify · ~50 600 · Apache-2.0</h3>
<p>PaaS self-hosted le plus populaire, 280+ templates one-click (PostgreSQL, Redis, WordPress, n8n…), reverse proxy Traefik + SSL automatique, multi-serveurs SSH, CI/CD intégré. Le mainteneur bosse dessus à plein temps depuis 2023 — <strong>14 535 commits</strong>, releases quasi-quotidiennes.</p>
<p>Version actuelle : <strong>v4.0.0-beta.463</strong> (9 fév. 2026). Toujours en bêta après 460 itérations. La v5 annoncée comme réécriture complète ? <strong>0 % de complétion</strong> sur le milestone GitHub. Elle n'arrivera pas avant fin 2026 au mieux. Mais la v4 est suffisamment stable pour de la production.</p>
<p>✅ 100 % des features gratuites, jamais de Business Edition. ❌ Gourmand en RAM sur le serveur Coolify lui-même — sépare-le de tes apps.</p>
<hr />
<h3>Lazydocker · ~49 700 · MIT · Go</h3>
<p>Le TUI Docker le plus starré sur GitHub. Vue complète de ton environnement dans le terminal : containers, images, volumes, logs temps réel, stats CPU/mémoire, exec direct, support Compose. <strong>v0.24.4</strong> sortie le 17 janvier 2026.</p>
<p>Honnêtement : le mainteneur passe l'essentiel de son temps sur lazygit (~72k stars). 193 issues ouvertes, 70 PRs en attente. Le projet vit, mais doucement.</p>
<p>✅ Un binaire, zéro config, intuitif dès la première utilisation. ❌ Pas de multi-host, pas d'alerting — c'est un outil de dev local, pas de prod.</p>
<hr />
<h3>Portainer · ~35 600 · Zlib · Go + React</h3>
<p>Seul outil de cette liste à supporter <strong>Docker + Swarm + Kubernetes + Podman</strong> depuis une interface unique. Deux flux de releases actifs : <strong>2.38.0 STS</strong> (28 jan. 2026) et <strong>2.33.7 LTS</strong> (9 fév. 2026). Très actif.</p>
<p>Mais la communauté grogne. L'OIDC/SSO et le RBAC granulaire sont derrière le <strong>paywall Business Edition</strong>. La CE est limitée à 5 nœuds. Des problèmes de performance UI persistent depuis des versions.</p>
<p>✅ Maturité 10+ ans, multi-orchestrateurs, provider Terraform, serveur MCP. ❌ Features importantes payantes, lourd pour un homelab basique.</p>
<hr />
<h3>Dokploy · ~30 400 · Apache 2.0 + Propriétaire · TypeScript/Next.js</h3>
<p>Lancé en avril 2024, 30k stars en moins de deux ans. PaaS concurrent direct de Coolify : déploiement d'apps, bases de données, Compose natif, Traefik v3.5 automatique, rollback basé sur registre.</p>
<p>❗ <strong>Alerte</strong> : La <strong>v0.27.0</strong> (10 fév. 2026) introduit un modèle dual-licence. Un répertoire <code>/proprietary</code> sous licence propriétaire avec un système de clés Enterprise a été ajouté (<code>licenses-api.dokploy.com</code>). Le cœur reste Apache 2.0, mais la frontière glisse. À surveiller — ce genre de virage se fait rarement dans le bon sens.</p>
<p>✅ UI souvent saluée comme supérieure à Coolify, développement ultra-rapide. ❌ Licence inquiétante, encore pré-1.0.</p>
<hr />
<h2>Les spécialistes</h2>
<h3>Dockge · ~22 000 · MIT</h3>
<p>Fait une seule chose bien : gérer les stacks Compose via une interface web. L'argument décisif ? Les fichiers restent <strong>sur le disque en YAML standard</strong>, pas dans une base de données propriétaire. Tu gardes une compatibilité totale avec <code>docker compose</code> CLI et zéro vendor lock-in. <strong>v1.5.0</strong> (30 mars 2025), stable.</p>
<p>✅ File-based, léger, zéro bullshit. ❌ Pas de gestion de containers individuels, pas de CI/CD — voulu par design.</p>
<hr />
<h3>Dozzle · ~11 500 · MIT · Go + Vue.js</h3>
<p>Viewer de logs Docker temps réel. Sa <strong>v10.0.0</strong> (14 fév. 2026) apporte une feature qui n'existe nulle part ailleurs : <strong>requêtes SQL sur tes logs</strong> via DuckDB + WebAssembly dans le navigateur, zéro serveur supplémentaire. Image de ~7 Mo, 100M+ pulls Docker Hub, support Swarm/K8s/Podman, webhooks avec templates Go.</p>
<p>✅ Feature SQL unique, ultra-léger, ultra-actif (6 103 commits). ❌ Pas de stockage persistant — c'est un viewer, pas un gestionnaire.</p>
<hr />
<h3>ctop · ~17 600 · MIT</h3>
<p>TUI style <code>top</code> pour metrics containers. 94 issues ouvertes sans réponse, 24 PRs en attente, ne supporte pas containerd. <strong>Les 17k stars sont un vestige.</strong> Regarde plutôt Oxker (Rust, actif).</p>
<hr />
<h2>La nouvelle garde</h2>
<h3>Beszel · ~19 400 · MIT · Go + PocketBase</h3>
<p>0 → 19 400 stars en un an. Beszel n'est pas un gestionnaire Docker — c'est un monitoring serveur léger avec intégration Docker/Podman native. CPU, mémoire, disque, réseau, GPU (Nvidia/AMD/Intel), et <strong>stats par conteneur avec historique</strong>. <strong>v0.18.3</strong> (1er fév. 2026). Installation en quelques minutes, agents ultra-légers.</p>
<p>💡 À combiner avec Dockge ou Komodo : Beszel pour les métriques, l'autre pour la gestion.</p>
<hr />
<h3>Komodo · ~10 000 · GPL-3.0 · Rust + React</h3>
<p>Favori sur r/selfhosted et r/homelab depuis deux ans. Architecture Core + Periphery (agent Rust léger sur chaque serveur). Builds auto-versionnés depuis Git, déploiement de stacks Compose, RBAC granulaire, OAuth/OIDC, scheduling cron, audit logging, CLI <code>km</code>. La philosophie officielle : <strong>"Pas de limite de serveurs, jamais. Pas de Business Edition, jamais."</strong></p>
<p><strong>v1.19.0</strong> en stable, v2 en pre-release active.</p>
<p>✅ Zéro paywall, backend Rust, GitOps natif, multi-serveurs illimités, RBAC complet gratuit. ❌ GPL-3.0 peut contraindre certains usages, moins mature que Portainer.</p>
<hr />
<h3>Arcane · ~4 700 · BSD-3-Clause · Go + SvelteKit</h3>
<p>UI Svelte 5 mobile-responsive, monitoring temps réel avec graphiques dont <strong>GPU NVIDIA/AMD</strong>, gestion Compose, multi-host via agents WebSocket, <strong>SSO/OIDC gratuit sans paywall</strong>, GitOps, API REST. <strong>v1.15.2</strong> sortie le 18 février 2026 — aujourd'hui même. 1 358 commits, cadence de release intense.</p>
<p>✅ UI la plus moderne de l'éco, SSO gratuit, monitoring GPU. ❌ Développeur solo (bus factor réel), Docker uniquement.</p>
<hr />
<h3>Dockhand · ~2 600 · BSL 1.1 · SvelteKit + Go</h3>
<p>Apparu en décembre 2025, 16 releases en deux mois. Approche security-first : scan Grype/Trivy, <strong>"safe-pull protection"</strong> (scan avant déploiement), rollback automatique, image Wolfi, agent Go en connexions sortantes uniquement. <strong>v1.0.18</strong> (16 fév. 2026).</p>
<p>❗ <strong>Licence BSL 1.1 = pas de l'open source</strong> au sens strict (interdit l'usage commercial en SaaS concurrent). Code source partiel (15 commits visibles).</p>
<p>✅ Security-first radical, SSO/OIDC gratuit, zéro télémétrie. ❌ Licence restrictive, projet très jeune.</p>
<hr />
<h2>Projets à éviter ou surveiller</h2>
<table><colgroup><col></col><col></col><col></col></colgroup><tbody><tr><th><p>Projet</p></th><th><p>Statut</p></th><th><p>Action</p></th></tr><tr><td><p><strong>Watchtower</strong> (original)</p></td><td><p>🔴 Archivé déc. 2025, incompatible Docker 28+</p></td><td><p>Migre vers nicholas-fedor/watchtower ou Diun</p></td></tr><tr><td><p><strong>Yacht</strong></p></td><td><p>🔴 Abandonné, aucune release</p></td><td><p>Évite pour tout nouveau déploiement</p></td></tr><tr><td><p><strong>Swarmpit</strong></p></td><td><p>🔴 Inactif depuis 2022</p></td><td><p>Remplace par Portainer ou Komodo</p></td></tr><tr><td><p><strong>darklens</strong></p></td><td><p>🔴 29 stars, jamais décollé</p></td><td><p>Ignore</p></td></tr><tr><td><p><strong>ctop</strong></p></td><td><p>⚠️ Dormant, pas de containerd</p></td><td><p>Remplace par Oxker</p></td></tr><tr><td><p><strong>Cosmos Cloud</strong></p></td><td><p>⚠️ Unstable uniquement depuis avril 2025</p></td><td><p>Risqué en production</p></td></tr></tbody></table>

<p><strong>Pour remplacer Watchtower :</strong> fork <strong>nicholas-fedor/watchtower</strong> (~2 700 ⭐) si tu veux l'auto-update, ou <strong>Diun</strong> (~4 200 ⭐, MIT, 17+ backends de notification) si tu préfères juste être alerté et décider toi-même.</p>
<hr />
<h2>Tableau récapitulatif (fév. 2026)</h2>
<table><colgroup><col></col><col></col><col></col><col></col><col></col></colgroup><tbody><tr><th><p>Outil</p></th><th><p>Stars</p></th><th><p>Version</p></th><th><p>Licence</p></th><th><p>Statut</p></th></tr><tr><td><p>Coolify</p></td><td><p>~50 600</p></td><td><p>v4.0.0-beta.463</p></td><td><p>Apache 2.0</p></td><td><p>🟢 Très actif</p></td></tr><tr><td><p>Lazydocker</p></td><td><p>~49 700</p></td><td><p>v0.24.4</p></td><td><p>MIT</p></td><td><p>🟡 Modéré</p></td></tr><tr><td><p>Portainer</p></td><td><p>~35 600</p></td><td><p>2.38.0 STS</p></td><td><p>Zlib</p></td><td><p>🟢 Très actif</p></td></tr><tr><td><p>Dokploy</p></td><td><p>~30 400</p></td><td><p>v0.27.0</p></td><td><p>Apache 2.0 + Prop.</p></td><td><p>🟢 ⚠️ Licence</p></td></tr><tr><td><p>Dockge</p></td><td><p>~22 000</p></td><td><p>v1.5.0</p></td><td><p>MIT</p></td><td><p>🟡 Stable</p></td></tr><tr><td><p>Beszel</p></td><td><p>~19 400</p></td><td><p>v0.18.3</p></td><td><p>MIT</p></td><td><p>🟢 Très actif</p></td></tr><tr><td><p>ctop</p></td><td><p>~17 600</p></td><td><p>v0.7.7</p></td><td><p>MIT</p></td><td><p>🔴 Dormant</p></td></tr><tr><td><p>Dozzle</p></td><td><p>~11 500</p></td><td><p>v10.0.0</p></td><td><p>MIT</p></td><td><p>🟢 Ultra-actif</p></td></tr><tr><td><p>Komodo</p></td><td><p>~10 000</p></td><td><p>v1.19.0</p></td><td><p>GPL-3.0</p></td><td><p>🟢 Très actif</p></td></tr><tr><td><p>Arcane</p></td><td><p>~4 700</p></td><td><p>v1.15.2</p></td><td><p>BSD-3-Clause</p></td><td><p>🟢 Très actif</p></td></tr><tr><td><p>Dockhand</p></td><td><p>~2 600</p></td><td><p>v1.0.18</p></td><td><p>BSL 1.1</p></td><td><p>🟢 Nouveau</p></td></tr></tbody></table>

<hr />
<h2>Qui choisit quoi</h2>
<p><strong>Dev en local, tu veux voir tes containers :</strong> → <strong>Lazydocker</strong>. Un binaire, zéro config. Ou <strong>Oxker</strong> si tu veux du Rust.</p>
<p><strong>Homelab avec quelques stacks Compose :</strong> → <strong>Dockge</strong> pour la simplicité et le file-based. <strong>Arcane</strong> si tu veux une UI moderne avec le monitoring GPU en prime.</p>
<p><strong>Tu veux surveiller tes serveurs :</strong> → <strong>Beszel</strong> + <strong>Dozzle</strong>. Complémentaires, ultralégers, installes les deux.</p>
<p><strong>Tu déploies des apps en production sur VPS :</strong> → <strong>Coolify</strong> pour la stabilité. <strong>Dokploy</strong> si tu préfères l'UI TypeScript — mais surveille la licence. <strong>Komodo</strong> si tu veux du multi-serveurs 100 % gratuit et du GitOps.</p>
<p><strong>Tu gères de l'infra équipe avec Kubernetes :</strong> → <strong>Portainer</strong>. Le seul qui couvre Docker + Swarm + K8s + Podman en une interface.</p>
<p><strong>Tu cherches à remplacer Portainer sans débourser :</strong> → <strong>Komodo</strong> (GPL-3.0, tout gratuit) ou <strong>Arcane</strong> (SSO/OIDC inclus, BSD-3-Clause).</p>
<hr />
<h2>Ce qui façonne la suite</h2>
<p>Trois mouvements structurent l'éco Docker en 2026.</p>
<p><strong>La philosophie Compose-first gagne du terrain.</strong> Les configurations restent en YAML sur disque, pas dans une DB propriétaire. Dockge et Komodo incarnent ce mouvement : "Que tu comprends. Que tu peux héberger. Que tu peux quitter." Les outils qui t'enferment perdront des utilisateurs.</p>
<p><strong>L'IA s'intègre, mais sous ton contrôle.</strong> Docker Inc. a lancé <strong>Gordon</strong> (agent IA dans le Desktop et le CLI). Le <strong>Docker Model Runner</strong> convertit des LLMs en containers OCI pour le local. La stack Ollama + Open WebUI est devenue le standard de facto pour faire tourner un LLM chez soi — et ça pousse les outils de monitoring à intégrer le suivi GPU nativement (Arcane, Beszel le font déjà).</p>
<p><strong>La sécurité devient un différenciateur.</strong> Dockhand avec son safe-pull pre-déploiement, Docker avec ses images Hardened gratuites depuis décembre 2025, Grype/Trivy intégrés dans les nouvelles UI — ce n'est plus un bonus, c'est une attente de base.</p>
<p>Et l'archivage de Watchtower reste la leçon de 2025 : même à 24 000 stars, un projet peut s'arrêter du jour au lendemain. Vérifie l'activité de ce que tu mets en prod.</p>
<h2>En bref : Ton infra, tes règles</h2>
<p>L'écosystème de 2026 a fait le tri. Fini le temps où on installait aveuglément le repo avec le plus d'étoiles en priant pour que le développeur solo ne fasse pas de burn-out. Aujourd'hui, la tendance est brutale mais saine : <strong>on veut reprendre le contrôle</strong>.</p>
<p>Que ce soit via des fichiers YAML qui restent sagement sur ton disque, des métriques transparentes qui ne bouffent pas toute ta RAM, ou des licences qui ne te prennent pas en otage à la première montée en charge, le mot d'ordre est la <strong>portabilité</strong>. Si un outil commence à masquer ses features de base derrière un paywall "Enterprise" ou te force à tout migrer dans son format propriétaire, coupe court. La nouvelle garde prouve qu'on peut avoir des interfaces ultra-modernes et sécurisées sans sacrifier la philosophie de base de Docker.</p>
<p>L'open source est ultra-vivant, mais il est impitoyable. Reste à l'affût, lis bien les licences, et surtout : garde tes stacks portables.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>Docker</category>
            <category>guide</category>
            <category>2026</category>
            <category>containers</category>
            <enclosure url="https://devbyben.fr/images/blog/gerer-tes-containers-docker-en-2026-le-guide-complet-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Reconnaissance faciale : comment reprendre le contrôle ?]]></title>
            <link>https://devbyben.fr/blog/reconnaissance-faciale-comment-reprendre-le-controle</link>
            <guid>https://devbyben.fr/blog/reconnaissance-faciale-comment-reprendre-le-controle</guid>
            <pubDate>Wed, 18 Feb 2026 13:01:57 GMT</pubDate>
            <description><![CDATA[Imagine que quelqu'un ait pris une photo de toi il y a cinq ans dans le métro. Juste comme ça, au passage. Cette photo dort quelque part dans une base de données, croisée avec ton profil LinkedIn, ton]]></description>
            <content:encoded><![CDATA[<p>Imagine que quelqu'un ait pris une photo de toi il y a cinq ans dans le métro. Juste comme ça, au passage. Cette photo dort quelque part dans une base de données, croisée avec ton profil LinkedIn, ton compte Instagram, ton historique de trajets. En 2026, les algorithmes de reconnaissance faciale atteignent <strong>99,93 % de précision</strong> sur les meilleurs systèmes. C'est plus précis que l'œil humain pour identifier un visage dans une foule.</p>
<p>La bonne nouvelle ? Il existe des contre-mesures qui marchent vraiment. La mauvaise ? La plupart des trucs qu'on te vend sont soit obsolètes, soit du pur marketing. On va démêler tout ça ensemble — la tech, les techniques d'évasion qui fonctionnent réellement, et le cadre légal en France.</p>
<hr />
<h2>L'état de l'art : les algos ont quasiment atteint le plafond</h2>
<p>Les systèmes modernes de reconnaissance faciale (RF) ne ressemblent plus du tout aux softs "repère-le-regard" des années 2010. Aujourd'hui, tout tourne autour de fonctions de perte à marge angulaire — <strong>ArcFace, AdaFace, CosFace</strong> — entraînées sur des datasets de 42 millions d'images.</p>
<p>Le benchmark historique LFW (Labeled Faces in the Wild) est mort. Pas littéralement, mais les meilleurs modèles y dépassent <strong>99,83 %</strong> de précision, ce qui le rend inutile pour discriminer les systèmes entre eux. La compétition s'est déplacée vers des benchmarks plus brutaux :</p>
<ul>
<li><strong>IJB-C</strong> (conditions dégradées, nuit, flou) → ~98 % de TAR à FAR=0,01 %
  </li>
<li><strong>IJB-S</strong> (surveillance réelle, caméras en hauteur) → les perfs commencent à saturer
  </li>
<li><strong>CFP-FP</strong> (visages de profil vs de face) → Vision Transformers au-dessus de 99,3 %</li>
</ul>
<p>    </p>
<p>👉 <strong>AdaFace</strong> (CVPR 2022) surpasse ArcFace sur les images de mauvaise qualité grâce à sa marge adaptative. Si t'as un visage flou, sous-exposé, pris de loin — AdaFace s'en sort quand même.</p>
<p>Côté industriel, <strong>NEC</strong> domine le classement NIST FRVT 1:N avec un taux d'erreur de <strong>0,07 %</strong> sur une galerie de 12 millions de photos. Derrière eux : IDEMIA, SenseTime. Et les modèles légers (MobileFaceNets, moins d'1 million de paramètres) atteignent déjà 99,55 % sur LFW — déployables sur smartphone ou caméra embarquée.</p>
<p>L'<strong>anti-spoofing</strong> a aussi fait des progrès énormes : la détection de vivacité passive (analyse de texture cutanée, reflets lumineux, profondeur 3D) tourne en 1-2 secondes sur CPU basique. Plus besoin de cligner de l'œil devant une caméra — le système sait si t'es en chair et en os ou si quelqu'un présente ta photo. Le talon d'Achille reste la généralisation cross-dataset : les perfs peuvent chuter à 30-40 % d'erreur sur des données jamais vues à l'entraînement.</p>
<hr />
<h2>Le déploiement : t'es déjà dans combien de bases ?</h2>
<h3>Aéroports</h3>
<p>La TSA américaine a déployé la RF dans <strong>80+ aéroports</strong> fin 2024, dans le cadre d'un programme à 5,5 milliards de dollars. Le programme PreCheck Touchless ID vise <strong>65 aéroports</strong> au printemps 2026 et traite les passagers <strong>66 % plus vite</strong> qu'un agent humain.</p>
<p>À Dubaï, Emirates a installé 200+ caméras biométriques au Terminal 3 pour 23 millions de dollars. Résultat : un corridor d'immigration par IA traite <strong>10 passagers en 14 secondes</strong>. Singapour vise 95 % de traitement automatisé d'ici fin 2026 à Changi.</p>
<h3>Chine : l'infrastructure totale</h3>
<p>La Chine possède entre <strong>540 et 700 millions de caméras de surveillance</strong>. Pour donner une idée concrète : la ville de Taiyuan compte environ 119 caméras pour 1 000 habitants. Shanghai dépasse 5 000 caméras au mile carré. Le système "Skynet" est revendiqué comme le plus vaste réseau de RF mondial.</p>
<p>Hong Kong active en ce moment la RF sur l'ensemble de son réseau SmartView — des dizaines de milliers de caméras supplémentaires.</p>
<h3>Supermarchés et retail</h3>
<p><strong>Home Depot</strong> et trois des dix plus grands distributeurs américains utilisent FaceFirst pour la prévention des vols. L'industrie a adopté le terme "face matching" pour éviter la connotation surveillance — mais c'est exactement la même techno. Auror a lancé en 2025 un système couplant RF et renseignement criminel en temps réel.</p>
<hr />
<p>![](<a href="https://cdn.hashnode.com/res/hashnode/image/upload/v1771320663061/bc75887c-4a14-483e-bb55-436f5f04cb80.jpeg">https://cdn.hashnode.com/res/hashnode/image/upload/v1771320663061/bc75887c-4a14-483e-bb55-436f5f04cb80.jpeg</a> align="center")</p>
<h2>Ce qui marche VRAIMENT contre la reconnaissance faciale</h2>
<p>Soyons directs : la plupart des trucs qu'on te propose sont soit du marketing soit tellement obsolètes qu'ils feraient rire un stagiaire. Voici un classement honnête basé sur les études académiques de 2024-2026.</p>
<h3>Haute efficacité prouvée</h3>
<p><strong>Le maquillage adversarial guidé par IA</strong></p>
<p>Des chercheurs de l'Université Ben-Gourion ont développé un système qui suggère exactement où appliquer du maquillage pour tromper les algorithmes. Pas du maquillage criard — du contouring ciblé sur le nez, les sourcils et la mâchoire. Résultat mesuré : la reconnaissance chute de <strong>47,6 % à 1,2 %</strong>. Un taux de succès de 97-99 % contre la RF.</p>
<p>Le point clé : ce maquillage <strong>ressemble à du maquillage normal</strong>. Tu n'as pas l'air d'un clown ou d'un personnage de film de SF. Une étude de PeopleTec (janvier 2025, arXiv:2412.13507) confirme que des perturbations cosmétiques subtiles ciblant les sourcils, l'arête nasale et la mâchoire perturbent même les systèmes commerciaux comme BetaFaceAPI et Microsoft Bing Visual Search.</p>
<p><strong>Les masques à motifs adversariaux universels</strong></p>
<p>Aussi de Ben-Gourion : des motifs adversariaux imprimés sur des <strong>masques en tissu</strong> qui fonctionnent sur différents porteurs. En test réel sur CCTV, le système n'a identifié que <strong>3,34 %</strong> des participants avec le masque adversarial. Un masque chirurgical ordinaire → 83 % d'identification. Dans un monde post-COVID où le masque est socialement acceptable, c'est l'une des mesures les plus pratiques.</p>
<p><strong>Les lunettes anti-IR (Reflectacles, Zenni ID Guard)</strong></p>
<p>Les lunettes <strong>Reflectacles</strong> bloquent le proche infrarouge avec des absorbeurs de longueur d'onde spéciaux et un cadre rétroréfléchissant. iPhone Face ID et Windows Hello deviennent aveugles. Le stock 2025 s'est épuisé rapidement (48-188$).</p>
<p><strong>Zenni Optical</strong> a lancé en juillet 2025 l'ID Guard™ — un revêtement réfléchissant l'IR à 80 % (700-1050nm) pour seulement <strong>14,95$</strong>. Les tests 404 Media le confirment.</p>
<p>❌ <strong>Limite critique</strong> : ces lunettes ne protègent PAS contre les caméras en lumière visible. Elles ne sont efficaces que contre les systèmes IR (Face ID, cartographie 3D, surveillance nocturne). Si t'es dehors en plein jour, elles ne changent rien aux caméras CCTV classiques.</p>
<hr />
<h3>Efficacité moyenne et contextuelle</h3>
<p><strong>Les LEDs infrarouge (hoodies, casquettes)</strong></p>
<p>Le principe : des LEDs IR invisibles à l'œil nu surexposent les capteurs de caméras et empêchent l'extraction des traits faciaux. Le <strong>Camera Shy Hoodie</strong> de Mac Pierce (open-source, ~200$ en composants, 12 LEDs haute puissance, microcontrôleur RP2040) et le manteau URBANGHOST de la marque allemande URBANPRIVACY intègrent cette techno.</p>
<p>Efficace contre les caméras de surveillance nocturne IR standard. <strong>Inefficace contre les caméras en lumière visible de jour</strong> — et surtout contre les capteurs HDR qui deviennent le standard sur les caméras haut de gamme. Pour les neutraliser, il faudrait "pomper des dizaines à centaines de watts dans l'array LED", ce qui n'est pas vraiment portable.</p>
<p><strong>Les vêtements à motifs adversariaux</strong></p>
<p>Cap_able (Italie, 300-770€) tisse des motifs dans du coton égyptien et revendique 60-90 % d'efficacité contre YOLO. Anti AI Clothing (USA, &lt;100$) teste ses motifs contre Google Vision. URBANPRIVACY (Allemagne, ~30-50€) propose la collection FACEPTION.</p>
<p>❌ <strong>Le problème fondamental</strong> : ces motifs sont optimisés contre des algorithmes SPÉCIFIQUES. Un motif efficace contre YOLOv5 peut échouer contre YOLOv11 ou ArcFace. Les tests Mozilla (2025) concluent que ces produits sont "plus efficaces pour sensibiliser que pour changer le statu quo". C'est la vérité.</p>
<p><strong>Les masques classiques</strong></p>
<p>Au début du COVID, les masques chirurgicaux avaient fait monter les erreurs de RF de 5 % à 50 %. Les systèmes ont été réentraînés. L'erreur est redescendue à <strong>~5 %</strong> pour les visages masqués. Reste utile en combinaison avec d'autres techniques.</p>
<hr />
<h3>Faible efficacité ou carrément obsolète</h3>
<p><strong>CV Dazzle (Adam Harvey, 2010)</strong></p>
<p>Le maquillage rayé multicolore qui a marqué les années 2010 ? Il était conçu pour tromper l'algorithme Viola-Jones (haarcascade). Il est <strong>largement inefficace contre les systèmes modernes</strong> à base de CNN et de transformers. Harvey lui-même l'admet. La méthode conceptuelle reste valide, mais les looks CV Dazzle classiques ne trompent plus rien.</p>
<p><strong>Fawkes (SAND Lab, UChicago)</strong></p>
<p>Cet outil de cloaking d'images ajoutait des perturbations pixel pour empoisonner les données d'entraînement. Avec ~4 800 stars GitHub et 840K+ téléchargements, il a eu son heure de gloire. <strong>Il est désormais largement obsolète</strong> : pas de mise à jour significative depuis 2022, les architectures modernes (MagFace, CLIP) résistent à ses perturbations. L'étude DiffPrivate (PETS 2025) confirme que les méthodes de perturbation pixel ont une "transférabilité négligeable" en conditions réelles.</p>
<p><strong>Les lasers</strong></p>
<p>Inutile, dangereux et illégal. Pour des dommages permanents à une caméra, il faut une précision extrême à moins de 15 mètres. Les caméras haut de gamme ont des filtres protecteurs. Et c'est quasi-certainement une destruction de bien + entrave à un système automatisé.</p>
<hr />
<h2>La frontière académique : la prochaine génération</h2>
<p>Ce qui sort des labos en 2024-2025 va changer la donne dans les deux à trois ans qui viennent :</p>
<p><strong>Les attaques par diffusion</strong></p>
<p>DiffAIM (avril 2025) manipule l'identité faciale dans l'espace latent des modèles de diffusion avec guidage adversarial par gradient. Il démontre une forte transférabilité contre les API commerciales Face++ et Aliyun — sans avoir accès au modèle cible. DiffProtect utilise un auto-encodeur de diffusion pour des perturbations sémantiquement significatives, plus naturelles que l'état de l'art. Ces méthodes rendent <strong>Fawkes complètement dépassé</strong>.</p>
<p><strong>Les attaques physiques de nouvelle génération (CVPR 2025)</strong></p>
<ul>
<li><strong>ProjAttacker</strong> : projette des masques 3D adversariaux sur le visage via un projecteur — non intrusif, en temps réel, contourne à la fois la détection de vivacité et la reconnaissance
  </li>
<li><strong>Patchs NIR imperceptibles</strong> : premier patch adversarial utilisant une encre absorbant l'infrarouge, invisible à l'humain → <strong>82,46 % de succès</strong> en boîte noire dans le monde physique
  </li>
<li><strong>RMA</strong> (IJCAI 2025) : première attaque ciblant simultanément les modèles de RF ET d'anti-spoofing — les attaquants s'adaptent aux défenses multicouches
  </li>
<li><strong>Vêtements adversariaux thermoactivés</strong> : des teintures thermochromiques créent des motifs adversariaux à la demande — t-shirt noir normal quand inactif, activation en 50 secondes, &gt;80 % de succès</li>
</ul>
<p>    </p>
<hr />
<h2>Comportements et technique : bloquer la "zone T"</h2>
<p>Au-delà des gadgets, il y a des comportements simples qui fonctionnent.</p>
<p><strong>Identifier les bonnes caméras</strong></p>
<p>Les caméras RF sont typiquement des <strong>dômes ou bullets haute résolution</strong> (2MP+) positionnées à hauteur de visage aux points d'étranglement (entrées, tourniquets, caisses). Elles ont souvent des arrays de LEDs IR visibles — un anneau de points sombres autour de l'objectif. Les CCTV classiques sont en hauteur avec un angle plongeant sous-optimal pour la RF.</p>
<p><strong>La zone T est critique</strong></p>
<p>La recherche LEAM (septembre 2025) a identifié que les zones du nez représentent <strong>18,9-29,7 %</strong> des régions critiques pour la reconnaissance. Couvrir l'espace entre les yeux et le nez dégrade significativement les algorithmes. Un regard baissé de <strong>15°+</strong> ou un visage détourné réduit la probabilité de reconnaissance.</p>
<p><strong>L'asymétrie comme arme</strong></p>
<p>Les algos de RF exploitent la symétrie géométrique du visage. Appliquer des éléments asymétriques — maquillage sur un seul côté, coiffure couvrant une partie du visage, accessoires positionnés de façon asymétrique — dégrade les performances. Le conseil de l'activiste Michelle Tylicki : "Obscurcissez l'arête nasale. Appliquez des formes dans des directions inhabituelles. Les algorithmes adorent la symétrie — cassez-la."</p>
<p><strong>La limite fondamentale : la surveillance multimodale</strong></p>
<p>Même avec le visage entièrement masqué, la <strong>reconnaissance de démarche</strong> (gait recognition) peut identifier les individus par leurs schémas de marche. Les systèmes modernes combinent RF visible, imagerie thermique, analyse de démarche, lecture de plaques, tracking de téléphone et analyse de graphe social. Aucune contre-mesure unique ne couvre toutes les modalités.</p>
<hr />
<h2>Le cadre légal en France et en Europe</h2>
<h3>Ce que le RGPD et le Règlement IA interdisent vraiment</h3>
<p>Le RGPD classe les données biométriques comme <strong>données sensibles</strong> (article 9). Leur traitement à des fins d'identification est interdit par principe, avec des exceptions limitées (consentement explicite, intérêt vital, intérêt public substantiel).</p>
<p>Le <strong>Règlement IA</strong> (entré en vigueur le 1er août 2024) a rendu applicables ses dispositions les plus strictes dès le <strong>2 février 2025</strong> :</p>
<ul>
<li>❌ L'article 5(1)(e) <strong>interdit absolument</strong> la création ou l'extension de bases de données RF par scraping non ciblé (modèle Clearview AI)
  </li>
<li>❌ L'article 5(1)(h) <strong>interdit l'identification biométrique en temps réel</strong> dans les espaces publics par les forces de l'ordre, sauf dans trois cas stricts : recherche de victimes d'enlèvement, prévention d'une menace terroriste imminente, localisation d'un suspect d'infraction grave</li>
</ul>
<p>    </p>
<p>👉 <strong>Aucun État membre n'a encore adopté de législation nationale transposant ces exceptions.</strong> Ce qui signifie qu'en pratique, l'identification biométrique en temps réel par les forces de l'ordre dans l'espace public est <strong>effectivement interdite dans toute l'UE</strong>. C'est le bouclier le plus puissant qui existe actuellement — bien plus efficace que n'importe quel gadget.</p>
<p>Les sanctions : <strong>35 millions d'euros ou 7 % du CA mondial</strong> pour les pratiques interdites. La CNIL a infligé 20M€ à Clearview AI, puis 5,2M€ supplémentaires pour non-conformité. Des sanctions similaires en Italie (20M€), Grèce (20M€), Pays-Bas (30,5M€), Royaume-Uni (7,5M£).</p>
<h3>La VSA en France : un bilan mitigé</h3>
<p>La loi du 19 mai 2023 relative aux JO 2024 a créé un cadre expérimental pour la <strong>vidéosurveillance algorithmique (VSA)</strong> — détection d'événements anormaux dans les flux vidéo — <strong>en excluant explicitement la reconnaissance faciale</strong>. Bilan des JO : seuls 4 des 8 cas d'usage ont fonctionné correctement. La détection d'armes déclenchait des faux positifs sur les parapluies. Un député a résumé : "Il y a un seul cas où la VSA a été utile — et c'était pour un cueilleur de champignons perdu."</p>
<p>L'expérimentation est prolongée jusqu'au <strong>31 décembre 2027</strong> via la loi sur les JO d'hiver 2030, aux mêmes conditions, sans reconnaissance faciale.</p>
<p>L'affaire BriefCam a révélé que la police française utilisait ce logiciel israélien (avec capacités RF) <strong>depuis 2015</strong> sans notification à la CNIL. Un cas d'utilisation illégale a été confirmé lors des émeutes de 2023. Le tribunal administratif de Grenoble a déclaré l'utilisation de BriefCam à Moirans <strong>illégale</strong> (janvier 2025).</p>
<h3>Ce qui est légal vs illégal pour toi</h3>
<p>✅ <strong>Légal</strong> : maquillage adversarial, lunettes anti-IR (Reflectacles, Zenni ID Guard), vêtements à motifs — tant que le visage reste reconnaissable à l'œil humain. Ces produits sont commercialisés librement.</p>
<p>❌ <strong>Illégal</strong> : dissimuler son visage dans l'espace public en France (loi du 11 octobre 2010 → <strong>150€ d'amende</strong>), sauf exceptions (santé, profession, sport, fête).</p>
<p>🚨 <strong>Délit</strong> : lors de manifestations, le port volontaire de tout couvre-visage destiné à éviter l'identification → <strong>1 an de prison et 15 000€ d'amende</strong> (article 431-9-1 du Code pénal).</p>
<p>🟡 <strong>Zone grise</strong> : les LEDs IR portées sur soi ne sont pas spécifiquement réglementées, mais leur utilisation pour dégrader des caméras de surveillance pourrait être qualifiée de dégradation de bien (2 ans, 30 000€) ou d'entrave à un système de traitement automatisé (5 ans, 150 000€). Aucune jurisprudence spécifique en France.</p>
<hr />
<p>![](<a href="https://cdn.hashnode.com/res/hashnode/image/upload/v1771320763824/fa8105a5-da61-4fd0-9745-20a694d5682e.jpeg">https://cdn.hashnode.com/res/hashnode/image/upload/v1771320763824/fa8105a5-da61-4fd0-9745-20a694d5682e.jpeg</a> align="center")</p>
<h2>Les ressources et outils à connaître</h2>
<table>
<thead>
<tr>
<th>Projet</th>
<th>Description</th>
<th>Statut 2026</th>
<th>Lien du Projet</th>
</tr>
</thead>
<tbody><tr>
<td><strong>InsightFace (ArcFace)</strong></td>
<td>Bibliothèque RF état de l'art, modèles pré-entraînés</td>
<td>Très actif, référence industrielle</td>
<td><a href="https://github.com/deepinsight/insightface">GitHub - InsightFace</a></td>
</tr>
<tr>
<td><strong>Awesome Physical Adversarial Examples</strong></td>
<td>Liste curatée d'articles sur les attaques physiques (2016-2025)</td>
<td>Activement maintenu</td>
<td><a href="https://github.com/jiakaiwangCN/awesome-physical-adversarial-examples">GitHub - jiakaiwangCN</a></td>
</tr>
<tr>
<td><strong>Camera Shy Hoodie</strong></td>
<td>Plans DIY open-source, 12 LEDs IR, RP2040</td>
<td>CC BY-NC 4.0</td>
<td><a href="https://www.macpierce.com/the-camera-shy-hoodie">Site de Mac Pierce</a></td>
</tr>
<tr>
<td><strong>Face-Robustness-Benchmark</strong></td>
<td>Outils d'évaluation white/black-box (Tsinghua)</td>
<td>Actif</td>
<td><a href="https://github.com/ShawnXYang/Face-Robustness-Benchmark">GitHub - ShawnXYang</a></td>
</tr>
<tr>
<td><strong>Fawkes</strong></td>
<td>Cloaking d'images (SAND Lab)</td>
<td>❌ Obsolète depuis 2022</td>
<td><a href="https://sandlab.cs.uchicago.edu/fawkes/">Site Officiel SAND Lab</a></td>
</tr>
</tbody></table>
<p><strong>Produits commerciaux</strong> :</p>
<ul>
<li>Reflectacles (48-188$) <a href="https://www.reflectacles.com">https://www.reflectacles.com</a>
  </li>
<li>Zenni ID Guard (14,95$) <a href="https://www.zennioptical.com/id-guard">https://www.zennioptical.com/id-guard</a>
  </li>
<li>Cap_able (300-770€) <a href="https://www.capable.design">https://www.capable.design</a>
  </li>
<li>Anti AI Clothing (&lt;100$) <a href="https://antiai.biz">https://antiai.biz</a>
  </li>
<li>URBANPRIVACY (30-50€ pour les t-shirts). <a href="https://urban-privacy.com">https://urban-privacy.com</a></li>
</ul>
<p>    </p>
<hr />
<h2>La conclusion : la combinaison est la seule stratégie</h2>
<blockquote>
<p>En 2026, aucune technique unique ne garantit l'anonymat face à un système de surveillance bien financé. Les systèmes de NEC ou IDEMIA combinent RF visible, infrarouge, détection de vivacité et analyses multimodales. Un seul gadget ne couvre pas tout ça.</p>
</blockquote>
<p>Trois choses à retenir :</p>
<ul>
<li><strong>1. Combine les approches.</strong> Maquillage subtil ciblant l'arête nasale + lunettes anti-IR + comportement d'évitement (regard à 15°, asymétrie) → protection largement supérieure à n'importe quelle mesure isolée.
  </li>
<li><strong>2. Les attaques par diffusion changent la donne pour les photos en ligne.</strong> DiffAIM et DiffProtect produisent des modifications faciales naturelles qui trompent les systèmes commerciaux en boîte noire. Fawkes est mort, mais ses successeurs sont bien plus puissants.
  </li>
<li><strong>3. Le droit européen est ton meilleur bouclier.</strong> L'interdiction du Règlement IA couplée à l'absence de transposition nationale des exceptions crée un environnement où la RF dans l'espace public est de facto interdite pour les forces de l'ordre dans toute l'UE. C'est plus robuste que n'importe quel hoodie à LEDs.</li>
</ul>
<p>    </p>
<p>Comme le dit l'activiste Evan Greer (Fight for the Future) :</p>
<blockquote>
<p><em>"Les gens ne devraient pas avoir à porter des lunettes spéciales ou des masques quand ils sortent de chez eux pour protéger leurs libertés civiles fondamentales."</em> <strong>Evan Greer</strong></p>
</blockquote>
<p>La bataille se joue autant dans les labos et les boutiques que dans les parlements et les tribunaux. Et c'est dans ces derniers que les victoires les plus durables sont remportées.</p>
<hr />
<p>Alors, la prochaine fois que vous passerez sous l'œil d'un dôme en verre dans le métro, souvenez-vous : l'anonymat en 2026 n'est plus un droit acquis, c'est une partie d'échecs permanente entre votre visage et le silicium.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>privacy</category>
            <category>facial recognition</category>
            <category>RGPD</category>
            <enclosure url="https://devbyben.fr/images/blog/reconnaissance-faciale-comment-reprendre-le-controle-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[OpenHands : L'agent IA qui code vraiment comme un dev (et qui pourrait te piquer ton job)]]></title>
            <link>https://devbyben.fr/blog/openhands-lagent-ia-qui-code-vraiment-comme-un-dev-et-qui-pourrait-te-piquer-ton-job</link>
            <guid>https://devbyben.fr/blog/openhands-lagent-ia-qui-code-vraiment-comme-un-dev-et-qui-pourrait-te-piquer-ton-job</guid>
            <pubDate>Sat, 14 Feb 2026 07:31:33 GMT</pubDate>
            <description><![CDATA[T'as déjà rêvé d'avoir un stagiaire ultra-compétent qui bosse 24h/24, ne se plaint jamais, et résout tes issues GitHub pendant que tu dors ? Bienvenue dans le monde d'OpenHands, l'agent IA open-source qui fait trembler l'industrie du développement lo...]]></description>
            <content:encoded><![CDATA[<p>T'as déjà rêvé d'avoir un stagiaire ultra-compétent qui bosse 24h/24, ne se plaint jamais, et résout tes issues GitHub pendant que tu dors ? Bienvenue dans le monde d'<strong>OpenHands</strong>, l'agent IA open-source qui fait trembler l'industrie du développement logiciel.</p>
<p>Sauf que contrairement aux solutions propriétaires qui te verrouillent dans leur écosystème (coucou Devin avec ses plans à 20-500$/mois), OpenHands te donne les clés du camion : code open-source sous licence MIT, compatible avec n'importe quel LLM, et des perfs qui explosent les benchmarks. En février 2026, on parle d'un outil qui atteint <strong>80,9% de résolution sur SWE-bench Verified</strong> avec Claude Opus 4.5 — des chiffres qui auraient semblé impossibles il y a seulement un an.</p>
<p>Alors, assieds-toi confortablement avec ton café, parce qu'on va décortiquer ce monstre technologique qui pourrait bien révolutionner ta façon de coder.</p>
<hr />
<h2>C'est quoi exactement, ce truc ?</h2>
<p>OpenHands (anciennement OpenDevin), c'est pas juste "un autre copilote qui te suggère du code". C'est un <strong>agent autonome</strong> qui travaille comme un vrai développeur :</p>
<ul>
<li>Il <strong>lit ton code</strong> et comprend l'architecture de ton projet</li>
<li>Il <strong>exécute des commandes</strong> dans un terminal (bash, npm, pip, tout ce que tu veux)</li>
<li>Il <strong>navigue sur le web</strong> pour chercher de la doc ou des solutions</li>
<li>Il <strong>teste son propre code</strong> et itère jusqu'à ce que ça marche</li>
<li>Il <strong>pousse des PRs</strong> directement sur GitHub/GitLab</li>
</ul>
<p>En gros, tu lui files une issue GitHub du style "Bug : la pagination ne fonctionne pas sur mobile", et il se démerde tout seul pour :</p>
<ol>
<li>Analyser le code existant</li>
<li>Identifier le problème</li>
<li>Coder le fix</li>
<li>Tester que ça marche</li>
<li>Te pondre une PR clean avec des tests</li>
</ol>
<p>Et tout ça pendant que tu scroll sur Reddit. Le futur, quoi.</p>
<hr />
<h2>Les chiffres qui font mal (aux concurrents)</h2>
<p>OpenHands, c'est pas du vent marketing. Les benchmarks parlent d'eux-mêmes, et les chiffres de février 2026 sont tout bonnement hallucinants.</p>
<h3>SWE-bench Verified : Le Boss de fin de niveau</h3>
<p><strong>SWE-bench</strong>, c'est le benchmark de référence pour tester les agents IA sur des vraies issues GitHub. Des bugs réels, des repos réels, des tests réels. Pas de la bidouille. Mais il y avait un problème : le benchmark original contenait des issues mal définies ou carrément insolubles même pour des humains.</p>
<p>C'est pour ça qu'<strong>SWE-bench Verified</strong> est né : 500 instances filtrées et validées par des humains. C'est sur ce terrain assaini que se joue la vraie compétition.</p>
<p><strong>L'évolution fulgurante d'OpenHands :</strong></p>
<ul>
<li>Juillet 2025 : ~65% (déjà pas mal)</li>
<li>Février 2026 avec <strong>Claude Opus 4.5</strong> : <strong>80,9%</strong> 🔥</li>
<li>Février 2026 avec <strong>GPT-5.2 Codex</strong> : <strong>80,0%</strong></li>
<li>Février 2026 avec <strong>Gemini 3 Flash</strong> : <strong>78,0%</strong></li>
</ul>
<p>Pour te donner une idée de la progression : il y a 18 mois, les meilleurs agents peinaient à atteindre 20%. Aujourd'hui, on parle de <strong>8 issues sur 10 résolues automatiquement</strong>. C'est carrément dingue.</p>
<p>Pour te donner une idée de la progression : il y a 18 mois, les meilleurs agents peinaient à atteindre 20%. Aujourd'hui, on parle de <strong>8 issues sur 10 résolues automatiquement</strong>. C'est carrément dingue.</p>
<h3>Le secret sauce : l'Inference-Time Scaling</h3>
<p>Cette performance de malade, c'est pas juste grâce aux nouveaux LLMs. OpenHands a intégré une technique de ouf appelée <strong>Inference-Time Scaling</strong> (ou Best-of-N).</p>
<p>Le principe ? Au lieu de générer une seule solution, l'agent en génère <strong>plusieurs</strong> (genre 5), puis utilise un modèle "Critique" entraîné spécifiquement pour sélectionner la meilleure. C'est comme avoir 5 dev juniors qui bossent en parallèle, et un senior qui choisit le meilleur code.</p>
<p><strong>Résultat concret :</strong></p>
<ul>
<li>Avec 1 tentative : 60,6%</li>
<li>Avec 5 tentatives + modèle critique : 66,4%</li>
<li>Soit <strong>+5,8 points</strong> juste en investissant plus de temps de calcul</li>
</ul>
<p>En 2026, cette stratégie est devenue native dans OpenHands. Tu transformes littéralement du temps de calcul en précision.</p>
<h3>LiveSWEBench : La vraie vie, pas les benchmarks bidons</h3>
<p>Le problème avec les benchmarks classiques, c'est qu'ils datent. Les modèles s'entraînent dessus, et ça biaise les résultats (contamination des données).</p>
<p><strong>LiveSWEBench</strong>, c'est différent : des issues GitHub <strong>créées après</strong> la date de coupure des LLMs. Impossible de tricher.</p>
<p>Résultat ? OpenHands maintient un <strong>taux de réussite stable</strong> même sur des problèmes ultra-récents. Pas de chute de perf, pas de triche. Juste de la puissance brute.</p>
<h3>OpenHands Index : Le test multi-compétences</h3>
<p>Parce que coder, c'est pas que résoudre des bugs, OpenHands a lancé son propre benchmark complet :</p>
<ol>
<li><strong>Résolution d'issues</strong> (SWE-bench) ✅</li>
<li><strong>Développement frontend</strong> (SWE-bench Multimodal) 🎨</li>
<li><strong>Création de tests</strong> (SWT-bench) 🧪</li>
<li><strong>Développement greenfield</strong> (projets from scratch) 🌱</li>
<li><strong>Recherche d'informations</strong> (GAIA) 🔍</li>
</ol>
<p><strong>Claude Opus 4.5</strong> et <strong>GPT 5.2 Codex</strong> dominent, mais devine quoi ? OpenHands fonctionne avec <strong>les deux</strong>. T'es pas bloqué avec un seul modèle.</p>
<hr />
<h2>L'architecture V1 : Un coup de génie</h2>
<p>En novembre 2025, l'équipe OpenHands a sorti la <strong>version 1.0</strong> avec une refonte complète de l'architecture. Fini le monolithe bordélique, bienvenue dans le modulaire bien pensé.</p>
<h3>Les problèmes de la V0 (ou comment ne pas architecturer un projet)</h3>
<p>La V0, c'était un peu le prototype fait à l'arrache pendant des vacances à Aruba (dixit les devs eux-mêmes 😅). Ça marchait, mais :</p>
<ul>
<li><strong>EventStream asynchrone de l'enfer</strong> : messages qui arrivent dans le désordre, bugs de threading, galère totale</li>
<li><strong>10 GB de Docker image</strong> : parce que pourquoi pas inclure un client YouTube API ? 🤷</li>
<li><strong>Dépendances transitives à gogo</strong> : installation de plusieurs minutes</li>
<li><strong>Couplage serré</strong> : impossible de sortir un bout sans tout casser</li>
</ul>
<p>Bref, pas terrible pour scaler.</p>
<h3>La V1 : SDK modulaire et propre comme un sou neuf</h3>
<p>L'architecture V1 repose sur <strong>4 packages Python</strong> hyper-propres, installables indépendamment via <code>pip</code> ou <code>uv</code>. C'est pas juste une refonte cosmétique — c'est un changement de paradigme complet basé sur l'<strong>Event Sourcing</strong> et la séparation stricte des responsabilités.</p>
<h4>1. <strong>Agent SDK</strong> (<code>openhands-sdk</code>)</h4>
<p>Le cœur du réacteur. Ultra-léger, tu peux créer un agent en quelques lignes :</p>
<pre><code>from openhands.sdk import Agent

agent = Agent(
    model="anthropic/claude-sonnet-4-20250514",
    tools=["bash", "edit", "browser"]
)

result = agent.run("Fix the pagination bug on mobile")
print(result)
</code></pre>
<p>C'est tout. Pas de config yaml de 300 lignes, pas de magie noire. Juste du Python propre avec des <strong>modèles Pydantic</strong> pour la sécurité des types.</p>
<p><strong>La vraie magie :</strong> L'Event Sourcing. L'état de l'agent n'est pas une variable mutable qui peut partir en cacahuète. C'est la <strong>somme immuable d'événements</strong> enregistrés dans un bus. Chaque action, chaque observation, chaque pensée du modèle = un événement typé.</p>
<p><strong>Les bénéfices concrets :</strong></p>
<ul>
<li>✅ <strong>Déterminisme total</strong> : tu peux rejouer exactement une session pour comprendre ce qui s'est passé</li>
<li>✅ <strong>Reprise sur erreur</strong> : crash du processus ? L'agent se reconstruit en rejouant l'historique</li>
<li>✅ <strong>Auditabilité</strong> : trace d'audit inaltérable de toutes les modifs (crucial en entreprise)</li>
</ul>
<h4>2. <strong>Tools Package</strong> (<code>openhands-tools</code>)</h4>
<p>Les outils que l'agent peut utiliser, mais version durcie et sécurisée :</p>
<ul>
<li><strong>Bash</strong> : exécuter des commandes système</li>
<li><strong>Edit</strong> : modifier des fichiers (avec diff, regex, tout ça)</li>
<li><strong>Browser</strong> : naviguer sur le web, cliquer, remplir des formulaires</li>
<li><strong>MCP (Model Context Protocol)</strong> : intégrations avec des services externes</li>
</ul>
<p><strong>L'innovation majeure :</strong> Chaque interaction suit le pattern <strong>Action → Execution → Observation</strong>. C'est atomique et structuré, ce qui facilite grave le raisonnement du modèle.</p>
<p>Et le truc de fou : <strong>l'intégration native du MCP</strong>. Ton agent peut se connecter dynamiquement à n'importe quel serveur compatible MCP — PostgreSQL, Notion, serveur de logs, monitoring, etc. — <strong>sans modifier le code source</strong>. C'est ça qui transforme OpenHands d'un simple "codeur" en orchestrateur de systèmes complets.</p>
<h4>3. <strong>Workspace Package</strong> (<code>openhands-workspace</code>)</h4>
<p>C'est peut-être ici que la rupture avec le passé est la plus visible. <strong>Non, OpenHands ne nécessite PAS toujours Docker.</strong></p>
<p>Ce paquet abstrait totalement le lieu d'exécution :</p>
<ul>
<li><strong>DockerWorkspace</strong> : Pour l'exécution sécurisée de code non fiable (sandboxing complet)</li>
<li><strong>LocalWorkspace</strong> : Exécution directe dans le processus hôte (pratique pour CI/CD ou dev rapide)</li>
<li><strong>RemoteWorkspace</strong> : Orchestration à grande échelle sur Kubernetes, séparant le "cerveau" de l'agent de son "corps" exécutant</li>
</ul>
<p>Choisis ton poison selon le contexte. Plus de galère à gérer Docker quand t'en as pas besoin.</p>
<h4>4. <strong>Agent Server</strong> (<code>openhands-agent-server</code>)</h4>
<p>L'API REST/WebSocket pour piloter ton agent à distance. Conçu autour de <strong>FastAPI</strong> et des WebSockets, ce composant transforme les primitives du SDK en une API multi-utilisateurs robuste.</p>
<p>C'est cette brique qui propulse les offres <strong>SaaS comme OpenHands Cloud</strong>, gérant :</p>
<ul>
<li>Authentification</li>
<li>Isolation des sessions</li>
<li>Persistance des états</li>
<li>Déploiements de milliers d'agents distribués</li>
</ul>
<hr />
<h3>L'architecture Event Sourcing : Pourquoi c'est révolutionnaire</h3>
<p>Dans les systèmes précédents, l'état de l'agent était une variable mutable stockée en mémoire. Résultat : conditions de course, incohérences, crashs inexplicables.</p>
<p><strong>Avec l'Event Sourcing</strong>, l'état est <strong>dérivé</strong> d'une série immuable d'événements. Exemple de timeline :</p>
<pre><code>Event 1: UserMessage("Fix bug #123")
Event 2: AgentThought("Je vais d'abord lire le fichier concerné")
Event 3: BashAction("cat src/components/Pagination.tsx")
Event 4: BashObservation("... code du fichier ...")
Event 5: AgentThought("J'ai trouvé le bug ligne 42")
Event 6: EditAction("modifier ligne 42...")
Event 7: EditObservation("Modification réussie")
...
</code></pre>
<p>Chaque événement est typé, horodaté, et <strong>immuable</strong>. L'état actuel = rejeu de tous ces événements.</p>
<p>C'est exactement la même philosophie que <strong>Git</strong> : tu peux revenir en arrière, créer des branches, merger des historiques. Sauf que là, c'est pour le comportement de ton agent IA.</p>
<hr />
<h2>La bataille des LLMs en 2026 : Quel modèle choisir ?</h2>
<p>La performance d'OpenHands dépend <strong>directement</strong> du LLM que tu branches derrière. Et en février 2026, la hiérarchie a complètement explosé. Dire "GPT-4 est le standard" en 2026, c'est comme dire que tu codes encore en PHP 5. On est entrés dans l'ère de <strong>GPT-5.2</strong>, <strong>Claude Opus 4.5</strong> et <strong>Gemini 3</strong>.</p>
<h3>Claude Opus 4.5 : Le roi de la fiabilité</h3>
<p>Si on doit désigner un champion actuel, c'est lui. <strong>Claude Opus 4.5</strong> (sorti en novembre 2025) domine les classements de fiabilité.</p>
<p><strong>Performances :</strong></p>
<ul>
<li><strong>80,9%</strong> sur SWE-bench Verified (record absolu)</li>
<li>Excellence sur la manipulation de structures de fichiers complexes</li>
<li>Résilience exceptionnelle face à la "dérive de contexte" sur les longues sessions</li>
</ul>
<p><strong>Pourquoi il cartonne ?</strong>
Son architecture est optimisée pour <strong>maintenir le contexte sur de longues séquences</strong>. Le problème classique des agents, c'est qu'au fil des modifications, ils "oublient" les contraintes initiales ou la structure du projet. Opus 4.5 résiste à ça comme un champion.</p>
<p><strong>Cas d'usage idéaux :</strong></p>
<ul>
<li>✅ Refactoring de systèmes critiques</li>
<li>✅ Correctifs de sécurité (zéro tolérance aux hallucinations)</li>
<li>✅ Navigation dans des codebases labyrinthiques</li>
</ul>
<p><strong>Le prix de l'excellence :</strong> C'est le modèle le plus cher. Mais pour les tâches critiques, ça se justifie.</p>
<h3>GPT-5.2 Codex : Vitesse et endurance</h3>
<p>OpenAI a répondu avec <strong>GPT-5.2 Codex</strong> en février 2026. Statistiquement à égalité avec Opus (80,0% sur SWE-bench), mais avec un profil différent.</p>
<p><strong>Son super-pouvoir :</strong> L'endurance sur les tâches <strong>Greenfield</strong> (création de projets from scratch).</p>
<p>Sur l'OpenHands Index, GPT-5.2 surpasse ses concurrents sur les horizons longs — genre construire une appli web complète à partir d'une spéc textuelle. Il maintient une "vision architecturale" cohérente sur des sessions de <strong>plusieurs heures</strong>, là où d'autres modèles introduisent des incohérences cycliques.</p>
<p><strong>L'argument économique :</strong></p>
<ul>
<li>Prix des tokens d'entrée : <strong>65% moins cher</strong> que Claude Opus 4.5</li>
<li>Idéal pour les déploiements à grande échelle</li>
</ul>
<p><strong>Cas d'usage idéaux :</strong></p>
<ul>
<li>✅ Génération de boilerplate / microservices</li>
<li>✅ Projets longs nécessitant cohérence architecturale</li>
<li>✅ Volumes massifs (CI/CD, automatisation)</li>
</ul>
<h3>Gemini 3 Flash : La surprise efficacité</h3>
<p>Google a frappé fort avec <strong>Gemini 3 Flash</strong>. Avec 78% sur SWE-bench Verified, il offre des performances "quasi-Pro" à une fraction du coût.</p>
<p><strong>Son atout secret :</strong> Une <strong>latence minimale</strong>. Parfait pour le "Vibe Coding" — ces boucles de dev interactives où tu collabores en temps réel avec l'agent.</p>
<p><strong>Les capacités "Deep Think" :</strong>
Mode de raisonnement approfondi activable à la demande pour gérer les pics de complexité, sans payer systématiquement un modèle plus lourd.</p>
<p><strong>Cas d'usage idéaux :</strong></p>
<ul>
<li>✅ Développement interactif rapide</li>
<li>✅ Pipelines CI/CD (analyse de milliers de tests)</li>
<li>✅ Projets où la latence compte</li>
</ul>
<h3>Les alternatives Open Source</h3>
<p>Pour les entreprises avec des contraintes strictes de confidentialité (déploiement On-Premise), l'open source est devenu crédible :</p>
<p><strong>DeepSeek v3.2 Reasoner</strong></p>
<ul>
<li>Score : 60% sur SWE-bench Verified</li>
<li>Le "Thinking Mode" dans l'open source</li>
<li>Sa verbosité = processus de vérification interne qui réduit les erreurs logiques</li>
</ul>
<p><strong>Qwen3-Coder (Nebius)</strong></p>
<ul>
<li>Score : ~60% après Rejection Fine-Tuning</li>
<li><strong>67 000 trajectoires publiques</strong> pour entraîner tes propres modèles</li>
<li>Alternative crédible pour se passer des API américaines</li>
</ul>
<h3>Tableau comparatif (Février 2026)</h3>
<table>
<thead>
<tr>
<th>Modèle</th>
<th>Développeur</th>
<th>SWE-bench Verified</th>
<th>Point Fort</th>
<th>Usage Recommandé</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Claude Opus 4.5</strong></td>
<td>Anthropic</td>
<td><strong>80,9%</strong> 🥇</td>
<td>Fiabilité absolue</td>
<td>Tâches critiques, refactoring complexe</td>
</tr>
<tr>
<td><strong>GPT-5.2 Codex</strong></td>
<td>OpenAI</td>
<td><strong>80,0%</strong> 🥈</td>
<td>Endurance Greenfield</td>
<td>Nouvelles apps, projets longs, scale</td>
</tr>
<tr>
<td><strong>Gemini 3 Flash</strong></td>
<td>Google</td>
<td><strong>78,0%</strong> 🥉</td>
<td>Latence minimale</td>
<td>Vibe Coding, CI/CD, interactivité</td>
</tr>
<tr>
<td><strong>DeepSeek v3.2</strong></td>
<td>DeepSeek</td>
<td>60%</td>
<td>Open Source</td>
<td>On-Premise, confidentialité stricte</td>
</tr>
<tr>
<td><strong>Qwen3-Coder</strong></td>
<td>Alibaba/Nebius</td>
<td>~60% (RFT)</td>
<td>Données publiques</td>
<td>Entraînement custom, recherche</td>
</tr>
</tbody></table>
<p><strong>Le vrai avantage d'OpenHands ?</strong> T'es pas bloqué avec un seul modèle. Contrairement à Claude Code (Anthropic only) ou GitHub Copilot (GPT only), tu choisis le "cerveau" selon la tâche :</p>
<ul>
<li>Opus pour la précision chirurgicale</li>
<li>GPT-5.2 pour la construction massive  </li>
<li>Gemini Flash pour la réactivité</li>
</ul>
<p>C'est cette <strong>flexibilité model-agnostic</strong> qui constitue l'avantage compétitif durable en 2026.</p>
<hr />
<h2>Comment ça marche concrètement ?</h2>
<p>Allez, on rentre dans le vif du sujet.</p>
<h3>Étape 1 : Installation</h3>
<p>Choisis ton poison selon ton cas d'usage :</p>
<p><strong>Option A : CLI léger (pour dev en local)</strong></p>
<pre><code>pip install openhands-cli
</code></pre>
<p><strong>Option B : SDK complet (pour intégrer dans ton app)</strong></p>
<pre><code>pip install openhands-sdk openhands-tools openhands-workspace
</code></pre>
<p><strong>Option C : Docker all-in-one (pour tester vite fait)</strong></p>
<pre><code>docker pull ghcr.io/openhands/openhands:latest
docker run -it --rm -p 3000:3000 ghcr.io/openhands/openhands:latest
</code></pre>
<h3>Étape 2 : Configuration du modèle</h3>
<p>OpenHands est <strong>model-agnostic</strong>. Tu peux utiliser :</p>
<ul>
<li><strong>Claude</strong> (Anthropic) : <code>anthropic/claude-sonnet-4-20250514</code></li>
<li><strong>GPT</strong> (OpenAI) : <code>openai/gpt-5.2-codex</code></li>
<li><strong>Gemini</strong> (Google) : <code>google/gemini-3-pro-preview</code></li>
<li><strong>DeepSeek</strong> : <code>deepseek/deepseek-v3.2-reasoner</code></li>
<li><strong>Qwen</strong> : <code>qwen/qwen-max-instruct</code></li>
<li><strong>LLMs locaux</strong> avec Ollama, LM Studio, etc.</li>
</ul>
<p>Exemple de config :</p>
<pre><code>import os
from openhands.sdk import Agent

agent = Agent(
    model="anthropic/claude-sonnet-4-20250514",
    api_key=os.getenv("ANTHROPIC_API_KEY"),
    tools=["bash", "edit", "browser"],
    sandbox="docker"  # ou "local" si t'as la foi
)
</code></pre>
<h3>Étape 3 : Lancer une tâche</h3>
<p><strong>Scénario 1 : Résoudre une issue GitHub</strong></p>
<pre><code>from openhands.sdk import Agent

agent = Agent(model="anthropic/claude-sonnet-4-20250514")

result = agent.run(
    task="""
    Résous l'issue #1234 du repo github.com/benoitpetit/mon-projet
    
    Issue : "La pagination ne fonctionne pas sur mobile (écrans &lt; 768px)"
    
    Tu as accès au repo, fait ce qu'il faut :
    - Clone le repo
    - Identifie le bug
    - Code le fix
    - Teste que ça marche
    - Crée une PR avec des tests
    """
)

print(result.summary)
# Sortie :
# "Bug corrigé. PR créée : github.com/benoitpetit/mon-projet/pull/42"
</code></pre>
<p><strong>Scénario 2 : Créer une feature from scratch</strong></p>
<pre><code>result = agent.run(
    task="""
    Crée un endpoint REST API en FastAPI pour gérer des utilisateurs :
    - POST /users (créer)
    - GET /users/{id} (lire)
    - PUT /users/{id} (modifier)
    - DELETE /users/{id} (supprimer)
    
    Utilise SQLAlchemy + PostgreSQL, ajoute des tests avec pytest,
    et crée un Dockerfile pour déployer l'app.
    """
)
</code></pre>
<p>L'agent va :</p>
<ol>
<li>Créer la structure du projet</li>
<li>Coder les routes FastAPI</li>
<li>Configurer SQLAlchemy</li>
<li>Écrire les tests</li>
<li>Générer un Dockerfile</li>
<li>Tout tester</li>
</ol>
<p>En <strong>5-15 minutes</strong>. Sans toi.</p>
<hr />
<h2>Les fonctionnalités qui tuent</h2>
<h3>1. <strong>Gestion multi-repo</strong></h3>
<p>T'as un monorepo avec 50 packages ? Pas de problème.</p>
<pre><code>agent.run(
    task="Upgrade tous les packages de @types/* vers leur dernière version dans tous les sous-projets",
    repos=[
        "github.com/company/frontend",
        "github.com/company/backend",
        "github.com/company/mobile"
    ]
)
</code></pre>
<p>OpenHands va :</p>
<ul>
<li>Cloner les 3 repos</li>
<li>Analyser les <code>package.json</code></li>
<li>Updater les dépendances</li>
<li>Tester que rien casse</li>
<li>Créer 3 PRs séparées</li>
</ul>
<h3>2. <strong>Intégrations CI/CD natives</strong></h3>
<p>OpenHands s'intègre direct avec :</p>
<ul>
<li><strong>GitHub Actions</strong> : auto-review de PRs, fix de tests cassés</li>
<li><strong>GitLab CI</strong> : génération de pipelines, debug d'erreurs</li>
<li><strong>Jenkins</strong> : analyse de logs, suggestion de fix</li>
</ul>
<p>Exemple GitHub Action :</p>
<pre><code>name: OpenHands Auto-Fix
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  auto-fix:
    runs-on: ubuntu-latest
    steps:
      - uses: openhands/action@v1
        with:
          task: "Review cette PR et fix les tests qui cassent"
          model: "anthropic/claude-sonnet-4-20250514"
          api_key: ${{ secrets.ANTHROPIC_API_KEY }}
</code></pre>
<h3>3. <strong>Debugging assisté</strong></h3>
<p>T'as une erreur de prod incompréhensible dans tes logs Sentry ?</p>
<pre><code>agent.run(
    task=f"""
    Analyse ce stack trace et trouve la cause :
    
    {sentry_error_logs}
    
    Ensuite :
    1. Identifie la root cause
    2. Code un fix
    3. Ajoute un test pour éviter la régression
    4. Crée une PR
    """
)
</code></pre>
<h3>4. <strong>Documentation auto-générée</strong></h3>
<p>Ton boss te harcèle pour de la doc ? Délègue.</p>
<pre><code>agent.run(
    task="""
    Génère une documentation complète pour ce projet :
    - README avec quickstart
    - API reference
    - Guide de contribution
    - Architecture overview
    
    Utilise les commentaires du code et l'historique git pour tout comprendre.
    """
)
</code></pre>
<hr />
<h2>Les cas d'usage réels (pas du bullshit marketing)</h2>
<h3>US Mobile : De 8 points à 2 points d'effort</h3>
<p><strong>Cas concret :</strong> Ajouter un dashboard analytics dans leur plateforme interne.</p>
<p><strong>Avant OpenHands :</strong></p>
<ul>
<li>Estimation : 8 story points (environ 2 semaines)</li>
<li>1 dev à temps plein</li>
</ul>
<p><strong>Avec OpenHands :</strong></p>
<ul>
<li>L'agent a bossé 15 minutes en autonome</li>
<li>Le dev a passé 1h à review et ajuster des edge cases</li>
<li>Nouvelle estimation : <strong>2 story points</strong></li>
</ul>
<p><strong>Citation du dev :</strong></p>
<blockquote>
<p>"OpenHands est incroyablement décisif. D'autres solutions tournent en rond... alors qu'OpenHands fonce droit au but."</p>
</blockquote>
<h3>Nebius : 67K trajectoires pour entraîner des modèles</h3>
<p>L'équipe Nebius a utilisé OpenHands pour générer <strong>67 074 trajectoires</strong> de résolution d'issues GitHub. Ces données ont servi à fine-tuner <strong>Qwen3-Coder</strong> :</p>
<ul>
<li><strong>50,3% de réussite</strong> sur SWE-bench Verified avec un modèle 30B</li>
<li><strong>61,7% de réussite</strong> avec un modèle 235B</li>
</ul>
<p>OpenHands devient un <strong>outil de recherche</strong> pour améliorer les LLMs eux-mêmes.</p>
<hr />
<h2>Comparaison avec la concurrence (édition 2026)</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>OpenHands</th>
<th>Devin</th>
<th>Claude Code</th>
<th>GitHub Copilot</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Prix</strong></td>
<td>Gratuit (MIT) + coût LLM</td>
<td>20-500$/mois</td>
<td>Inclus Claude Pro</td>
<td>$10-39/mois</td>
</tr>
<tr>
<td><strong>Open-source</strong></td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
<td>❌</td>
</tr>
<tr>
<td><strong>Model-agnostic</strong></td>
<td>✅ (tous LLMs)</td>
<td>❌</td>
<td>❌ (Claude only)</td>
<td>❌ (GPT only)</td>
</tr>
<tr>
<td><strong>Auto-hébergeable</strong></td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
<td>❌</td>
</tr>
<tr>
<td><strong>Résout des issues complètes</strong></td>
<td>✅</td>
<td>✅</td>
<td>✅</td>
<td>❌ (suggestions)</td>
</tr>
<tr>
<td><strong>Intégration CI/CD</strong></td>
<td>✅</td>
<td>❌</td>
<td>⚠️ Limitée</td>
<td>⚠️ Limitée</td>
</tr>
<tr>
<td><strong>SWE-bench Verified</strong></td>
<td><strong>80,9%</strong> (Opus 4.5)</td>
<td>~48%</td>
<td>~80% (Opus)</td>
<td>N/A</td>
</tr>
<tr>
<td><strong>SDK modulaire</strong></td>
<td>✅ (V1)</td>
<td>❌</td>
<td>⚠️ Limitée</td>
<td>❌</td>
</tr>
<tr>
<td><strong>MCP natif</strong></td>
<td>✅</td>
<td>❌</td>
<td>⚠️ Partiel</td>
<td>❌</td>
</tr>
<tr>
<td><strong>Event Sourcing</strong></td>
<td>✅</td>
<td>❌</td>
<td>❌</td>
<td>❌</td>
</tr>
</tbody></table>
<p><strong>L'économie en 2026 :</strong></p>
<p><strong>Devin</strong> a clarifié son modèle :</p>
<ul>
<li>Plan Core : <strong>20$/mois</strong> (freelances, petites équipes)</li>
<li>Plan Team : <strong>500$/mois</strong> (features entreprise, API étendue)</li>
</ul>
<p><strong>OpenHands</strong> fonctionne différemment : modèle <strong>"Bring Your Own LLM"</strong>.</p>
<ul>
<li>Tu paies uniquement les tokens consommés auprès du fournisseur de ton choix</li>
<li>Pour un usage intensif, GPT-5.2 Codex est 65% moins cher qu'Opus</li>
<li>Pour les tâches critiques, tu peux basculer sur Opus ponctuellement</li>
</ul>
<p><strong>Exemple concret :</strong></p>
<ul>
<li>Issue moyenne : 100K-500K tokens</li>
<li>Avec GPT-5.2 : ~0,50-2,50$ par issue</li>
<li>Avec Claude Opus 4.5 : ~1,50-7,50$ par issue</li>
<li>Avec Gemini Flash : ~0,30-1,50$ par issue</li>
</ul>
<p>Compare ça aux 500$/mois de Devin Team, et fais le calcul selon ton volume.</p>
<p><strong>Le verdict 2026 :</strong> Si tu aimes la liberté, le contrôle total, et les performances de pointe, OpenHands écrase tout. Devin reste pertinent pour les équipes qui veulent du plug-and-play sans gérer l'infra.</p>
<hr />
<h2>Les limites (parce qu'on est honnêtes)</h2>
<p>Soyons clairs, OpenHands c'est pas la solution à tous tes problèmes.</p>
<h3>1. <strong>Coût des LLMs</strong></h3>
<p>Si tu utilises Claude Opus ou GPT-5, ça peut vite chiffrer. Une issue complexe peut consommer 100K-500K tokens.</p>
<p><strong>Solution :</strong> Utilise des modèles moins chers pour les tâches simples (DeepSeek, Qwen), et réserve les gros modèles pour le debug hardcore.</p>
<h3>2. <strong>Fiabilité variable selon le modèle</strong></h3>
<p>OpenHands est aussi bon que le LLM derrière. Avec Claude Sonnet 4 ou GPT-5.2 Codex, c'est du caviar. Avec Llama 3 8B, c'est... moyen.</p>
<h3>3. <strong>Pas de support natif pour UI/UX</strong></h3>
<p>L'agent galère encore sur les tâches nécessitant du <em>design sense</em>. Il va te pondre un formulaire qui marche, mais pas forcément joli.</p>
<h3>4. <strong>Courbe d'apprentissage pour les prompts</strong></h3>
<p>Donner des instructions claires à l'agent, c'est un art. Si tu dis "fix the bug", il va galérer. Si tu dis "the pagination component in src/components/Pagination.tsx doesn't handle edge case when totalPages=0", ça roule.</p>
<hr />
<h2>Comment bien utiliser OpenHands (tips de pro)</h2>
<h3>Tip #1 : Sois spécifique dans tes prompts</h3>
<p>❌ <strong>Mauvais :</strong></p>
<pre><code>Fix the authentication
</code></pre>
<p>✅ <strong>Bon :</strong></p>
<pre><code>Le JWT token n'est pas rafraîchi automatiquement. Quand l'access token expire (après 15min),
l'utilisateur est déconnecté brutalement. 

Implémente un refresh token automatique dans src/auth/token-manager.ts.
Utilise axios interceptors pour capter les 401 et refresh avant de retry la requête.
</code></pre>
<h3>Tip #2 : Utilise le mode step-by-step pour les tâches complexes</h3>
<pre><code>agent.run(
    task="Migre la base de données de MySQL vers PostgreSQL",
    mode="step-by-step",  # L'agent va te demander validation à chaque étape
    max_iterations=50
)
</code></pre>
<h3>Tip #3 : Active le logging détaillé</h3>
<pre><code>agent.run(
    task="...",
    log_level="DEBUG",  # Tu verras toutes les étapes de raisonnement
    output_dir="./logs"
)
</code></pre>
<h3>Tip #4 : Combine avec tes outils existants</h3>
<p>OpenHands n'est pas là pour tout remplacer. Utilise-le en complément :</p>
<ul>
<li><strong>Cursor/Windsurf</strong> pour l'écriture de code interactive</li>
<li><strong>OpenHands</strong> pour les tâches lourdes et répétitives</li>
<li><strong>Review manuelle</strong> pour valider les PRs critiques</li>
</ul>
<hr />
<h2>Le futur d'OpenHands</h2>
<p>L'équipe bosse sur des trucs de ouf :</p>
<h3>1. <strong>Multi-agent orchestration</strong></h3>
<p>Plusieurs agents spécialisés qui collaborent :</p>
<ul>
<li>Agent <strong>Backend</strong> : API et BDD</li>
<li>Agent <strong>Frontend</strong> : UI/UX</li>
<li>Agent <strong>DevOps</strong> : CI/CD et infra</li>
<li>Agent <strong>QA</strong> : Tests et validation</li>
</ul>
<p>Tous coordonnés par un agent "chef de projet".</p>
<h3>2. <strong>Fine-tuning spécialisé</strong></h3>
<p>Des modèles OpenHands custom, entraînés sur :</p>
<ul>
<li>Ton codebase spécifique</li>
<li>Tes patterns de développement</li>
<li>Tes guidelines internes</li>
</ul>
<p>Imagine un agent qui connaît tes conventions de code par cœur.</p>
<h3>3. <strong>Support mobile natif</strong></h3>
<p>Actuellement, OpenHands excelle sur le backend. Bientôt, il saura aussi coder des apps iOS/Android.</p>
<hr />
<h2>Conclusion : La révolution est déjà là (et elle va vite)</h2>
<p>OpenHands en février 2026, c'est pas de la science-fiction. C'est <strong>dispo maintenant</strong>, c'est <strong>gratuit</strong> (MIT), et ça <strong>marche vraiment</strong>.</p>
<p><strong>Résumons ce qu'on vient de voir :</strong></p>
<ul>
<li><strong>80,9% de résolution</strong> sur SWE-bench Verified (avec Claude Opus 4.5)</li>
<li>Architecture <strong>V1 modulaire</strong> basée sur l'Event Sourcing</li>
<li><strong>Model-agnostic</strong> : choisis le LLM selon la tâche et le budget</li>
<li><strong>MCP natif</strong> : se connecte à ton écosystème existant</li>
<li><strong>65K+ ⭐ GitHub</strong> et une communauté massive</li>
</ul>
<p>Est-ce que ça va remplacer les devs ? Non. Mais ça va <strong>changer notre métier</strong>. Les devs qui refusent d'utiliser ces outils vont se retrouver à pondre du code boilerplate pendant que d'autres shipent des features 10x plus vite.</p>
<p><strong>Ce qui a changé en 18 mois :</strong></p>
<ul>
<li>Mi-2024 : Les agents peinaient à 20% de réussite</li>
<li>Début 2026 : On explose les <strong>80%</strong> avec les bons modèles</li>
<li>L'architecture est passée d'un prototype à un SDK production-ready</li>
<li>L'intégration MCP ouvre des possibilités infinies</li>
</ul>
<p><strong>Mon conseil :</strong> Teste-le sur un side-project ce week-end. Donne-lui une issue pas trop critique, et regarde-le bosser. Tu vas être bluffé.</p>
<p>Et si t'es encore sceptique, rappelle-toi qu'OpenHands résout <strong>8 issues GitHub sur 10</strong>. Combien de tes collègues devs peuvent en dire autant ? 😏</p>
<p><strong>La vraie question :</strong> C'est plus "est-ce que je devrais utiliser des agents IA ?", c'est "comment je les intègre intelligemment dans mon workflow ?". Parce que dans 12 mois, ceux qui seront restés à l'écart auront pris un retard considérable.</p>
<p>Bienvenue dans l'ère des agents autonomes. 🚀</p>
<hr />
<h2>Liens utiles</h2>
<ul>
<li><strong>Site officiel :</strong> <a href="https://openhands.dev">openhands.dev</a></li>
<li><strong>GitHub :</strong> <a href="https://github.com/OpenHands/OpenHands">github.com/OpenHands/OpenHands</a> (65K+ ⭐)</li>
<li><strong>Documentation :</strong> <a href="https://docs.openhands.dev">docs.openhands.dev</a></li>
<li><strong><a href="https://dub.sh/openhands">Slack communauté</a> :</strong> Rejoins 10K+ devs qui expérimentent</li>
<li><strong>Benchmarks :</strong> <a href="https://openhands.dev/blog/openhands-index">OpenHands Index</a></li>
</ul>
<p>Allez, go tester, et viens me dire en commentaire si t'as réussi à le faire planter. Spoiler : c'est dur. 🚀</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>openhands</category>
            <category>Open Source</category>
            <category>AI</category>
            <category>GitHub</category>
            <category>ai-agent</category>
            <enclosure url="https://devbyben.fr/images/blog/openhands-lagent-ia-qui-code-vraiment-comme-un-dev-et-qui-pourrait-te-piquer-ton-job-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Altcha : Vire ton CAPTCHA pourri et passe à l'open-source]]></title>
            <link>https://devbyben.fr/blog/altcha-vire-ton-captcha-pourri-et-passe-a-lopen-source</link>
            <guid>https://devbyben.fr/blog/altcha-vire-ton-captcha-pourri-et-passe-a-lopen-source</guid>
            <pubDate>Thu, 12 Feb 2026 17:30:26 GMT</pubDate>
            <description><![CDATA[Tu en as marre de ces CAPTCHA qui te demandent de sélectionner des feux de circulation pendant 10 minutes ? Ou pire, de cliquer sur des images floues en te demandant si un morceau de vélo compte vraiment comme "vélo" ? Bienvenue au club, on est tous ...]]></description>
            <content:encoded><![CDATA[<p>Tu en as marre de ces CAPTCHA qui te demandent de sélectionner des feux de circulation pendant 10 minutes ? Ou pire, de cliquer sur des images floues en te demandant si un morceau de vélo compte vraiment comme "vélo" ? Bienvenue au club, on est tous passés par là. Et devine quoi ? Y'a une solution qui déchire pour se débarrasser de cette plaie tout en protégeant ton site des bots : <strong>Altcha</strong>.</p>
<p>Si t'es du genre à aimer le contrôle total sur ton infrastructure, la vie privée de tes utilisateurs et les solutions open-source, accroche-toi parce que je vais te présenter un projet qui va te faire vibrer. Altcha, c'est pas juste un énième CAPTCHA, c'est carrément une <strong>révolution</strong> dans la protection anti-spam.</p>
<hr />
<h2>Pourquoi les CAPTCHA classiques, c'est de la m*rde ?</h2>
<p>Bon, soyons honnêtes deux secondes. Les CAPTCHA traditionnels (ouais, je parle de toi, reCAPTCHA), c'est :</p>
<ul>
<li><strong>Chiant pour l'utilisateur</strong> : Qui a envie de passer 5 minutes à identifier des panneaux de signalisation juste pour envoyer un formulaire de contact ? Personne.</li>
<li><strong>Pas respectueux de la vie privée</strong> : Google, Cloudflare et compagnie adorent tracker tes utilisateurs avec leurs CAPTCHA. Cookies, fingerprinting, tout y passe.</li>
<li><strong>Pas accessible</strong> : Les personnes malvoyantes ou utilisant un lecteur d'écran ? Bonne chance avec les puzzles visuels.</li>
<li><strong>Gourmand en ressources</strong> : Ces trucs chargent des tonnes de scripts externes qui plombent les perfs de ton site.</li>
<li><strong>Dépendance à des tiers</strong> : T'es à la merci de Google ou Cloudflare. Si leur service tombe, ton site aussi.</li>
</ul>
<p>Bref, c'est pas génial. Et c'est là qu'<strong>Altcha</strong> débarque comme un super-héros de l'open-source.</p>
<hr />
<h2>Altcha, c'est quoi exactement ?</h2>
<p>Altcha, c'est une alternative <strong>gratuite, open-source et auto-hébergeable</strong> aux CAPTCHA classiques. Contrairement aux solutions traditionnelles, Altcha utilise un mécanisme de <strong>preuve de travail (Proof-of-Work, ou PoW)</strong> léger. En gros, au lieu de te faire cliquer sur des images, ton navigateur résout un petit challenge cryptographique pour prouver que t'es humain.</p>
<p>Et le meilleur dans tout ça ? <strong>Pas de cookies, pas de tracking, pas de collecte de données perso</strong>. C'est conforme RGPD, WCAG 2.2 AA, et même à l'European Accessibility Act. En clair, c'est clean, éthique, et ça respecte vraiment tes utilisateurs.</p>
<h3>Les points forts d'Altcha</h3>
<ul>
<li>✅ <strong>Respect de la vie privée</strong> : Zéro tracking, zéro cookie, zéro donnée perso collectée.</li>
<li>✅ <strong>Open-source</strong> : Code disponible sur GitHub, licence MIT. Tu peux l'auditer, le modifier, le forker.</li>
<li>✅ <strong>Auto-hébergé</strong> : Tu gardes le contrôle total. Pas de dépendance à un service tiers.</li>
<li>✅ <strong>Léger</strong> : Seulement 30 KB en gzippé (90% plus léger que reCAPTCHA).</li>
<li>✅ <strong>Accessible</strong> : Support de 50+ langues, conforme aux normes d'accessibilité.</li>
<li>✅ <strong>Facile à intégrer</strong> : Une simple balise HTML et quelques lignes de code backend.</li>
</ul>
<hr />
<h2>Comment ça marche sous le capot ?</h2>
<p>L'architecture d'Altcha est modulaire et simple :</p>
<ol>
<li><strong>Altcha Widget</strong> : C'est le composant web côté client (le truc que l'utilisateur voit). Il charge un challenge cryptographique que le navigateur doit résoudre.</li>
<li><strong>Altcha Sentinel</strong> : C'est le serveur backend qui génère les challenges et vérifie les solutions. Tu peux l'auto-héberger avec Docker ou utiliser le service public d'Altcha.</li>
</ol>
<p>Le processus est ultra fluide :</p>
<ul>
<li>L'utilisateur arrive sur ton formulaire.</li>
<li>Le widget Altcha charge un challenge depuis ton serveur Sentinel.</li>
<li>Le navigateur résout le challenge (c'est rapide, genre quelques millisecondes).</li>
<li>La solution est envoyée à ton backend pour vérification.</li>
<li>Si c'est bon, le formulaire est validé. Sinon, c'est bloqué.</li>
</ul>
<p>Et tout ça sans faire chier l'utilisateur avec des puzzles visuels ou des clics interminables. C'est invisible, rapide, et efficace.</p>
<hr />
<h2>Déployer Altcha Sentinel avec Docker</h2>
<p>Bon, passons aux choses sérieuses. Altcha peut fonctionner de deux façons :</p>
<ol>
<li><strong>Mode self-hosted simple</strong> : Tu génères et vérifies les challenges directement dans ton backend avec <code>altcha-lib</code>. Pas besoin de Sentinel, tout tourne dans ton app.</li>
<li><strong>Mode Sentinel (recommandé)</strong> : Tu déploies Sentinel qui gère les challenges, la détection de bots avancée, le machine learning, et plein d'autres trucs de ouf.</li>
</ol>
<p>Dans cet article, on va se concentrer sur <strong>Sentinel</strong> parce que c'est lui qui apporte la vraie valeur ajoutée : détection adaptative, threat intelligence, rate limiting, etc.</p>
<p>Si tu veux auto-héberger Altcha (et crois-moi, tu veux), voici comment faire avec Docker. C'est simple, propre, et ça tourne nickel.</p>
<h3>Prérequis</h3>
<ul>
<li>Un serveur (VPS, machine locale) avec Docker et Docker Compose installés.</li>
<li>Un nom de domaine (recommandé pour la prod) et un certificat SSL (Let's Encrypt, c'est gratuit).</li>
<li>Des connaissances basiques en Docker et en config YAML.</li>
</ul>
<h3>Étape 1 : Déploie Sentinel avec Docker</h3>
<p>La façon la plus simple est d'utiliser l'image officielle Docker. Sentinel génère automatiquement un fichier <code>.env</code> sécurisé avec des secrets aléatoires.</p>
<pre><code># Créer un volume Docker pour les données persistantes
docker volume create altcha_sentinel_data

# Lancer Sentinel
docker run -d \
  -p 8080:8080 \
  -v altcha_sentinel_data:/data \
  ghcr.io/altcha-org/sentinel:latest
</code></pre>
<p><strong>Important</strong> : Sentinel tourne sur le <strong>port 8080</strong> par défaut (pas 3000).</p>
<p>Une fois lancé, tu peux accéder à :</p>
<ul>
<li><strong>Interface web</strong> : <a href="http://localhost:8080">http://localhost:8080</a></li>
<li><strong>API</strong> : <a href="http://localhost:8080/v1">http://localhost:8080/v1</a></li>
<li><strong>Documentation API</strong> : <a href="http://localhost:8080/v1/docs">http://localhost:8080/v1/docs</a></li>
</ul>
<p><strong>Credentials par défaut</strong> :</p>
<ul>
<li>Username : <code>root</code></li>
<li>Password : <code>root</code></li>
</ul>
<p>⚠️ <strong>Change le mot de passe immédiatement</strong> après la première connexion !</p>
<h3>Étape 2 : Configuration avancée (optionnel)</h3>
<p>Le serveur génère automatiquement un <code>.env</code> sécurisé dans <code>/data</code>. Tu peux le modifier ou passer des variables d'environnement :</p>
<pre><code>docker run -d \
  -p 8080:8080 \
  -v altcha_sentinel_data:/data \
  -e CPU_LIMIT=2 \
  -e MEMORY_LIMIT=2048 \
  ghcr.io/altcha-org/sentinel:latest
</code></pre>
<h3>Étape 3 : Configure un reverse proxy (Nginx, Traefik, Caddy)</h3>
<p>Pour exposer Sentinel en HTTPS (obligatoire en prod), tu vas avoir besoin d'un reverse proxy. Voici un exemple avec Nginx :</p>
<pre><code>server {
    listen 443 ssl http2;
    server_name sentinel.tondomaine.com;

    ssl_certificate /etc/letsencrypt/live/sentinel.tondomaine.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sentinel.tondomaine.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
</code></pre>
<p>Redémarre Nginx :</p>
<pre><code>sudo systemctl reload nginx
</code></pre>
<p>Et voilà, ton Sentinel est accessible en HTTPS sur <code>https://sentinel.tondomaine.com</code> ! 🎉</p>
<hr />
<h2>Intégrer le widget Altcha dans ta page web</h2>
<p>Maintenant qu'on a le serveur qui tourne, on va intégrer le widget dans notre site. C'est ridiculement simple.</p>
<h3>Étape 1 : Ajoute le script JS</h3>
<p>Dans ta page HTML, ajoute le script du widget :</p>
<pre><code>&lt;script async defer src="https://cdn.jsdelivr.net/gh/altcha-org/altcha@main/dist/altcha.min.js" type="module"&gt;&lt;/script&gt;
</code></pre>
<h3>Étape 2 : Intègre le widget dans ton formulaire</h3>
<p>Le widget se connecte à ton Sentinel via l'endpoint <code>/v1/challenge</code> :</p>
<pre><code>&lt;form action="/submit" method="POST"&gt;
  &lt;input type="email" name="email" placeholder="Ton email" required /&gt;
  &lt;textarea name="message" placeholder="Ton message" required&gt;&lt;/textarea&gt;
  
  &lt;!-- Le widget Altcha --&gt;
  &lt;altcha-widget challengeurl="https://sentinel.tondomaine.com/v1/challenge?apiKey=YOUR_API_KEY"&gt;&lt;/altcha-widget&gt;
  
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>⚠️ <strong>Note</strong> : Tu dois récupérer ton <code>apiKey</code> depuis l'interface Sentinel (<a href="http://localhost:8080">http://localhost:8080</a> ou ton domaine).</p>
<h3>Étape 3 : Vérifie la solution côté serveur</h3>
<p>Maintenant, il faut vérifier que le token Altcha est valide avant de traiter le formulaire. Il y a deux façons de faire :</p>
<h4>Option 1 : Avec la bibliothèque altcha-lib (recommandé)</h4>
<pre><code>npm install altcha-lib
</code></pre>
<pre><code>import { Hono } from 'hono';
import { verifyServerSignature } from 'altcha-lib';

const apiKeySecret = 'sec_ton_api_key_secret'; // Depuis Sentinel
const app = new Hono();

app.post('/submit', async (c) =&gt; {
  const formData = await c.req.formData();
  const altchaToken = formData.get('altcha');
  
  if (!altchaToken) {
    return c.json({ error: 'Token Altcha manquant' }, 400);
  }

  // Vérifie le token avec Sentinel
  const { verified, verificationData } = await verifyServerSignature(
    String(altchaToken),
    apiKeySecret
  );
  
  if (!verified) {
    return c.json({ error: 'Token Altcha invalide - T\'es un bot ?' }, 400);
  }

  // Traitement du formulaire
  const email = formData.get('email');
  const message = formData.get('message');
  
  console.log(`Email: ${email}, Message: ${message}`);
  console.log('Verification Data:', verificationData);
  
  return c.json({ ok: true, message: 'Formulaire envoyé !' });
});

export default app;
</code></pre>
<h4>Option 2 : Via l'API HTTP Sentinel</h4>
<p>Si tu ne peux pas utiliser la bibliothèque JavaScript (par exemple en PHP ou Python), tu peux vérifier via l'API HTTP :</p>
<pre><code>app.post('/submit', async (c) =&gt; {
  const formData = await c.req.formData();
  const altchaToken = formData.get('altcha');
  
  if (!altchaToken) {
    return c.json({ error: 'Token Altcha manquant' }, 400);
  }

  // Vérifie via l'API Sentinel
  const response = await fetch('https://sentinel.tondomaine.com/v1/verify/signature', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ payload: String(altchaToken) })
  });
  
  const { verified } = await response.json();
  
  if (!verified) {
    return c.json({ error: 'Token Altcha invalide' }, 400);
  }

  // Traitement du formulaire
  return c.json({ ok: true, message: 'Formulaire envoyé !' });
});
</code></pre>
<p>Et voilà ! Ton formulaire est protégé contre les spams et les bots, sans faire chier tes utilisateurs. 🎯</p>
<hr />
<h2>Exemple avec Python (FastAPI)</h2>
<p>T'es plus Python que JavaScript ? Pas de souci, voici un exemple avec FastAPI :</p>
<pre><code>from fastapi import FastAPI, Form, HTTPException
from altcha import verify_solution
import os

app = FastAPI()
HMAC_KEY = os.getenv("SECRET")

@app.post("/submit")
async def submit_form(
    email: str = Form(...),
    message: str = Form(...),
    altcha: str = Form(...)
):
    # Vérifie le token Altcha
    if not verify_solution(altcha, HMAC_KEY):
        raise HTTPException(status_code=400, detail="Token Altcha invalide")
    
    # Traitement du formulaire
    print(f"Email: {email}, Message: {message}")
    
    return {"ok": True, "message": "Formulaire envoyé !"}
</code></pre>
<hr />
<h2>Personnalisation du widget</h2>
<p>Altcha est super customizable. Tu peux changer la langue, le design, et plein d'autres trucs.</p>
<h3>Changer la langue</h3>
<p>Par défaut, Altcha détecte automatiquement la langue du navigateur. Mais tu peux forcer une langue spécifique :</p>
<pre><code>&lt;altcha-widget 
  challengeurl="https://sentinel.tondomaine.com/challenge"
  lang="fr"&gt;
&lt;/altcha-widget&gt;
</code></pre>
<p>Altcha supporte 50+ langues, dont le français, l'anglais, l'allemand, l'espagnol, etc.</p>
<h3>Personnaliser le style</h3>
<p>Tu peux ajouter ton propre CSS pour adapter le widget à ton design :</p>
<pre><code>altcha-widget {
  --altcha-color-base: #1a1a1a;
  --altcha-color-text: #ffffff;
  --altcha-color-border: #333333;
  --altcha-max-width: 400px;
}
</code></pre>
<h3>Désactiver l'autofocus</h3>
<p>Par défaut, le widget prend le focus automatiquement. Si tu veux le désactiver :</p>
<pre><code>&lt;altcha-widget 
  challengeurl="https://sentinel.tondomaine.com/challenge"
  auto="off"&gt;
&lt;/altcha-widget&gt;
</code></pre>
<hr />
<h2>Bonnes pratiques et optimisations</h2>
<h3>Sécurité</h3>
<ul>
<li><strong>Change le mot de passe root</strong> : Dès la première connexion à Sentinel, change le mot de passe par défaut.</li>
<li><strong>Protège ton API Key</strong> : Ne partage jamais ta clé API publiquement. Elle doit rester côté serveur uniquement.</li>
<li><strong>HTTPS obligatoire</strong> : Ne fais <strong>jamais</strong> tourner Altcha en HTTP en prod. Le widget utilise l'API Web Crypto qui nécessite HTTPS.</li>
<li><strong>Stocke les payloads utilisés</strong> : Pour éviter les attaques par rejeu (replay attacks), garde une trace des payloads déjà vérifiés.</li>
</ul>
<h3>Performance</h3>
<ul>
<li><strong>Utilise le cache</strong> : Sentinel met automatiquement en cache les challenges pour éviter les calculs inutiles.</li>
<li><strong>Ajuste le nombre de workers</strong> : Par défaut, le widget utilise <code>navigator.hardwareConcurrency</code> (max 16). Tu peux le limiter si besoin.</li>
<li><strong>Volume persistant obligatoire</strong> : Monte toujours <code>/data</code> en volume persistant pour ne pas perdre ta config et tes données.</li>
</ul>
<h3>Scalabilité</h3>
<ul>
<li><strong>Clustering avec PostgreSQL + Redis</strong> : Pour du haute disponibilité, Sentinel supporte le clustering avec PostgreSQL et Redis comme backends.</li>
<li><strong>Requiert minimum 2 vCPUs et 2 GB RAM</strong> : Pour un fonctionnement optimal en production.</li>
<li><strong>Multi-arch</strong> : L'image Docker officielle supporte AMD64 et ARM64.</li>
</ul>
<h3>Monitoring</h3>
<ul>
<li><strong>Logs</strong> : Sentinel log tous les événements dans stdout. Utilise un système comme Loki ou Elasticsearch pour centraliser.</li>
<li><strong>Métriques</strong> : Intègre avec Prometheus pour du monitoring avancé des performances et des taux de vérification.</li>
</ul>
<hr />
<h2>Pourquoi Altcha, c'est le futur ?</h2>
<p>Si t'en as marre de dépendre de Google ou Cloudflare pour protéger tes formulaires, Altcha est une bouffée d'air frais. C'est :</p>
<ul>
<li><strong>Éthique</strong> : Respect de la vie privée, conformité RGPD, pas de tracking.</li>
<li><strong>Open-source</strong> : Code transparent, auditable, modifiable.</li>
<li><strong>Performant</strong> : Léger, rapide, efficace.</li>
<li><strong>Accessible</strong> : Conforme aux normes d'accessibilité, multilingue.</li>
<li><strong>Auto-hébergé</strong> : Tu gardes le contrôle total sur ton infrastructure.</li>
</ul>
<p>En plus, le projet est activement maintenu, avec une communauté grandissante et des intégrations pour WordPress, React, Vue, Angular, Flutter, etc.</p>
<hr />
<h2>Les alternatives à Altcha</h2>
<p>Bon, soyons fair-play. Altcha, c'est pas la seule alternative open-source aux CAPTCHA classiques. Voici quelques autres solutions que tu peux checker :</p>
<ul>
<li><strong>Procaptcha</strong> : Basé sur la blockchain (oui, vraiment). C'est intéressant d'un point de vue sécurité, mais plus complexe à mettre en place.</li>
<li><strong>FriendlyCaptcha</strong> : Utilise aussi un mécanisme de PoW, mais c'est un service SaaS (donc pas vraiment auto-hébergeable).</li>
<li><strong>mCaptcha</strong> : Open-source, auto-hébergeable, mais moins mature qu'Altcha.</li>
</ul>
<p>Perso, je préfère Altcha pour sa simplicité, sa légèreté, et sa maturité. Mais si t'as des besoins spécifiques, jette un œil aux alternatives.</p>
<hr />
<h2>Conclusion : Adopte Altcha</h2>
<p>Voilà, tu as toutes les cartes en main pour déployer Altcha et te débarrasser des CAPTCHA qui plombent l'expérience de tes utilisateurs. C'est simple, efficace, open-source, et respectueux de la vie privée.</p>
<p>Alors, qu'est-ce que t'attends ? Lance-toi, teste Altcha, et dis adieu aux puzzles de reCAPTCHA. Tes utilisateurs te remercieront, et ton site sera protégé sans faire de compromis sur la performance ou la vie privée.</p>
<p>Happy coding, et que la force de l'open-source soit avec toi ! 🚀</p>
<hr />
<h2>Liens utiles</h2>
<ul>
<li><strong>Site officiel</strong> : <a href="https://altcha.org">https://altcha.org</a></li>
<li><strong>Documentation v2</strong> : <a href="https://altcha.org/docs/v2">https://altcha.org/docs/v2</a></li>
<li><strong>GitHub principal</strong> : <a href="https://github.com/altcha-org/altcha">https://github.com/altcha-org/altcha</a></li>
<li><strong>GitHub organisation</strong> : <a href="https://github.com/altcha-org">https://github.com/altcha-org</a></li>
<li><strong>Documentation Sentinel</strong> : <a href="https://altcha.org/docs/v2/sentinel">https://altcha.org/docs/v2/sentinel</a></li>
<li><strong>Installation Sentinel</strong> : <a href="https://altcha.org/docs/v2/sentinel/install">https://altcha.org/docs/v2/sentinel/install</a></li>
</ul>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>altcha</category>
            <category>Open Source</category>
            <category>captcha</category>
            <category>privacy</category>
            <category>self-hosted</category>
            <enclosure url="https://devbyben.fr/images/blog/altcha-vire-ton-captcha-pourri-et-passe-a-lopen-source-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Automatiser Signal avec Node.js : Le Guide d'Ingénierie du SDK signal-sdk]]></title>
            <link>https://devbyben.fr/blog/signal-nodejs-revolutionner-lintegration-avec-signal-sdk</link>
            <guid>https://devbyben.fr/blog/signal-nodejs-revolutionner-lintegration-avec-signal-sdk</guid>
            <pubDate>Fri, 30 Jan 2026 15:29:50 GMT</pubDate>
            <description><![CDATA[Salut à toi ! 👋 Si tu as déjà essayé d'intégrer Signal dans tes projets Node.js, tu sais que l'expérience oscille souvent entre le "bricolage" et le parcours du combattant.
Le chiffrement de bout en bout (E2EE) de Signal est une merveille de sécurit...]]></description>
            <content:encoded><![CDATA[<p>Salut à toi ! 👋 Si tu as déjà essayé d'intégrer Signal dans tes projets Node.js, tu sais que l'expérience oscille souvent entre le "bricolage" et le parcours du combattant.</p>
<p>Le chiffrement de bout en bout (E2EE) de Signal est une merveille de sécurité, mais c'est un cauchemar pour l'automatisation. Contrairement à Discord ou Slack qui offrent des API REST simples, Signal demande de gérer des clés cryptographiques, le protocole Double Ratchet et des sessions asynchrones.</p>
<p>C'est pour combler ce fossé technologique que j'ai développé <strong>signal-sdk</strong>. Mon objectif n'est pas seulement de fournir un script, mais une <strong>abstraction logicielle robuste en TypeScript</strong>, conçue pour piloter la cryptographie complexe de Signal via une interface familière aux développeurs Node.</p>
<h2>Sous le capot : Une Architecture Hybride</h2>
<p>Pour être transparent sur l'ingénierie de ce paquet : <strong>signal-sdk</strong> ne réinvente pas la cryptographie (ce qui serait dangereux). Il agit comme un chef d'orchestre (Wrapper) intelligent.</p>
<p>L'architecture repose sur le pilotage de <strong><code>signal-cli</code></strong>, le moteur de référence écrit en Java/Rust.</p>
<ul>
<li><strong>Node.js</strong> gère la logique métier, les événements et le typage.</li>
<li><strong>Java (signal-cli)</strong> gère le transport, le chiffrement et le stockage des clés.</li>
<li><strong>La communication</strong> se fait via un canal JSON-RPC optimisé (stdin/stdout).</li>
</ul>
<p>Cette approche vous offre la sécurité d'une implémentation cryptographique éprouvée avec l'ergonomie moderne de TypeScript.</p>
<h2>Prérequis et Installation</h2>
<p>Puisque nous pilotons un moteur Java, l'installation demande un prérequis système spécifique. Ce n'est pas du "Pure JS", c'est une solution système complète.</p>
<h3>1. L'environnement Java</h3>
<p>Avant d'installer le paquet, votre machine (ou conteneur Docker) doit disposer d'un <strong>JRE (Java Runtime Environment) version 17 ou 21</strong>. C'est le moteur qui fera tourner la cryptographie.</p>
<pre><code># Vérifiez votre version
java -version
</code></pre>
<h3>2. Installation du SDK</h3>
<p>Une fois Java confirmé, installez le SDK. Notez que le paquet inclut les binaires <code>signal-cli</code> pour Linux, macOS et Windows, ce qui simplifie grandement le bootstrap.</p>
<pre><code>npm install signal-sdk
</code></pre>
<h3>3. Liaison de l'appareil</h3>
<p>Le SDK inclut un utilitaire CLI pour générer l'identité de votre bot sans avoir à manipuler des fichiers de configuration manuellement.</p>
<pre><code>npx signal-sdk connect
</code></pre>
<p>Cette commande lance le processus démon et affiche un <strong>QR Code</strong> dans votre terminal. Scannez-le via votre application Signal mobile (<em>Paramètres &gt; Appareils reliés</em>) pour autoriser le bot à utiliser votre compte.</p>
<hr />
<h2>Le Code : Du Scripting au Framework</h2>
<p>Le SDK offre deux niveaux d'abstraction selon vos besoins : le contrôle brut ou le framework de bot.</p>
<h3>Niveau 1 : Le Client <code>SignalCli</code></h3>
<p>Idéal pour des tâches d'administration système, des notifications ou de l'audit. Nous utilisons ici le mode <strong>JSON-RPC</strong> persistant : le processus Java reste "chaud", ce qui permet d'envoyer des messages avec une latence minimale (quelques millisecondes) après le démarrage.</p>
<pre><code>import { SignalCli } from 'signal-sdk';

const client = new SignalCli('+33612345678');

async function main() {
  // Démarre le démon Java et établit le canal RPC
  await client.connect();
  
  // Abonnement aux événements bruts (messages, reçus, typing...)
  client.on('message', (envelope) =&gt; {
    if (envelope.dataMessage) {
        console.log(`Message reçu de ${envelope.source}: ${envelope.dataMessage.message}`);
    }
  });

  // Envoi d'un message texte sécurisé
  await client.sendMessage('+33777777777', '⚠️ Serveur de Prod : Redémarrage imminent');
}

main().catch(console.error);
</code></pre>
<h3>Niveau 2 : Le Framework <code>SignalBot</code></h3>
<p>C'est la vraie valeur ajoutée du SDK. Plutôt que de parser des chaînes de caractères et de gérer des <code>if/else</code>, utilisez <code>SignalBot</code> pour structurer vos interactions. Il gère le routing des commandes, l'extraction des arguments et les permissions.</p>
<pre><code>import { SignalBot } from 'signal-sdk';

const bot = new SignalBot({
  phoneNumber: "+33612345678",
  commandPrefix: "!", // Active les commandes type "!ping"
});

// Définition déclarative d'une commande
bot.registerCommand({
  name: "report",
  description: "Soumettre un rapport d'incident",
  handler: async (msg, args) =&gt; {
    // msg : objet enrichi avec méthodes de réponse
    if (args.length === 0) {
        await msg.reply("Usage: !report &lt;description&gt;");
        return;
    }
    
    console.log(`Incident rapporté : ${args.join(" ")}`);
    await msg.react("✅"); // Feedback visuel immédiat
  }
});

await bot.start();
</code></pre>
<hr />
<h2>Réalités de Production</h2>
<p>Passer d'un script local à une app en production sur Signal demande de comprendre certaines contraintes d'infrastructure. Voici ce que vous devez savoir pour éviter les interruptions de service.</p>
<h3>La Persistance est Critique</h3>
<p>Signal n'est pas "stateless". Le protocole Double Ratchet maintient un état cryptographique local (chaînes de clés) qui évolue à chaque message.
<strong>Conséquence :</strong> Si vous déployez ce SDK via Docker, vous <strong>devez</strong> monter un volume persistant pour stocker les données de <code>signal-cli</code>.</p>
<p>Si vous perdez ce dossier :</p>
<ol>
<li>Vous perdez votre identité (clés privées).</li>
<li>Au redémarrage, une nouvelle identité est générée.</li>
<li>Vos correspondants verront une alerte de sécurité ("Le numéro de sécurité a changé") et vos messages seront bloqués.</li>
</ol>
<p><strong>Exemple de volume Docker :</strong></p>
<pre><code>VOLUME ["/home/botuser/.local/share/signal-cli"]
</code></pre>
<h3>Gestion des Processus</h3>
<p>Le SDK lance un processus enfant Java. Bien que nous gérions les erreurs standard, un crash de la JVM (Out of Memory) peut arriver. En production, utilisez un gestionnaire de processus comme <strong>PM2</strong> ou la politique de redémarrage de Kubernetes pour garantir que le pont Node-Java soit relancé automatiquement.</p>
<h3>Rate Limiting et CAPTCHA</h3>
<p>Signal protège agressivement son réseau contre le spam. Si votre bot envoie trop de messages en peu de temps, il sera temporairement bloqué ("Rate Limited"). Le SDK remontera cette erreur, mais la résolution du défi (CAPTCHA) doit souvent se faire manuellement via la CLI ou l'interface graphique. Concevez vos bots pour être "calmes" et respectueux des limites.</p>
<hr />
<h2>Conclusion</h2>
<p><strong>signal-sdk</strong> transforme un problème de cryptographie complexe en une expérience développeur fluide. C'est l'outil idéal pour construire des chatbots internes, des systèmes d'alerte sécurisés ou des interfaces domotiques, à condition de respecter les exigences de l'architecture sous-jacente (Java + Persistance).</p>
<p>Le projet est disponible sur npm et ouvert aux contributions pour continuer à affiner cette intégration.</p>
<ul>
<li>📦 <strong>NPM :</strong> <a href="https://www.google.com/search?q=https://www.npmjs.com/package/signal-sdk">npmjs.com/package/signal-sdk</a></li>
<li>🐙 <strong>GitHub :</strong> <a href="https://github.com/benoitpetit/signal-sdk">github.com/benoitpetit/signal-sdk</a></li>
</ul>
<p>À vos claviers, et bon code "sécurisé" ! 🚀</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>signal</category>
            <category>sdk</category>
            <category>bot</category>
            <category>automation</category>
            <enclosure url="https://devbyben.fr/images/blog/signal-nodejs-revolutionner-lintegration-avec-signal-sdk-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Gestion de projet open source - les outils qui vont tout casser (et comment bien les choisir)]]></title>
            <link>https://devbyben.fr/blog/gestion-de-projet-open-source-les-outils-qui-vont-tout-casser-et-comment-bien-les-choisir</link>
            <guid>https://devbyben.fr/blog/gestion-de-projet-open-source-les-outils-qui-vont-tout-casser-et-comment-bien-les-choisir</guid>
            <pubDate>Thu, 22 Jan 2026 11:08:10 GMT</pubDate>
            <description><![CDATA[Les outils qui vont vraiment compter (et comment faire les bons choix)
Tu veux gérer tes projets en 2026 sans vendre ton âme à un SaaS opaque, sans dépendre d’un acteur unique, et sans exploser ton budget infra ? Bonne nouvelle : l’écosystème open so...]]></description>
            <content:encoded><![CDATA[<h2>Les outils qui vont vraiment compter (et comment faire les bons choix)</h2>
<p>Tu veux gérer tes projets en 2026 <strong>sans vendre ton âme à un SaaS opaque</strong>, sans dépendre d’un acteur unique, et sans exploser ton budget infra ? Bonne nouvelle : l’écosystème open source n’a jamais été aussi mature.</p>
<p>En 2026, la gestion de projet, ce n’est plus juste des tickets et des colonnes Kanban. C’est un <strong>système vivant</strong> : interconnecté, souvent auto-hébergé, parfois décentralisé, et de plus en plus assisté par l’IA — <strong>mais sous ton contrôle</strong></p>
<p>Spoiler : GitHub et Jira existent toujours. Mais non, ils ne sont plus le centre du monde.</p>
<hr />
<h2>Pourquoi la gestion de projet a changé de nature</h2>
<p>Entre 2020 et 2026, trois bascules ont tout changé.</p>
<hr />
<h3>1. On ne choisit plus un outil, mais une <strong>stack</strong></h3>
<p>Avant, tu prenais “un outil de gestion de projet”. Aujourd’hui, ça ne suffit plus.</p>
<p>Code, tickets, CI/CD, chat, documentation, monitoring, sécurité, gouvernance… <strong>Tout doit parler ensemble</strong>, proprement, sans bidouille honteuse.</p>
<p>Un outil isolé, c’est :</p>
<ul>
<li><p>un point de friction</p>
</li>
<li><p>un silo de plus</p>
</li>
<li><p>une dette future</p>
</li>
</ul>
<hr />
<h3>2. L’auto-hébergement est redevenu cool (et surtout rationnel)</h3>
<p>Pas juste par idéologie barbu-linuxien :</p>
<ul>
<li><p>coûts SaaS imprévisibles</p>
</li>
<li><p>enjeux RGPD / AI Act</p>
</li>
<li><p>dépendance fournisseur</p>
</li>
<li><p>besoin réel de personnalisation</p>
</li>
</ul>
<p>Docker n’est plus seul sur le terrain. <strong>Podman, containerd, rootless containers</strong> sont devenus des choix normaux, raisonnables, professionnels.</p>
<hr />
<h3>3. L’IA est partout… mais plus n’importe comment</h3>
<p>En 2026, l’IA utile :</p>
<ul>
<li><p>propose, <strong>ne décide pas</strong></p>
</li>
<li><p>tourne <strong>localement ou sur ton infra</strong></p>
</li>
<li><p>améliore les flux (priorisation, détection de blocages, aide à la doc)</p>
</li>
</ul>
<p>L’IA “boîte noire qui pilote ton projet” ? C’est non.</p>
<hr />
<h2>Ce qu’on attend d’un bon outil de gestion de projet en 2026</h2>
<p>Un outil crédible doit :</p>
<ul>
<li><p>✅ être <strong>open source</strong> (vraiment)</p>
</li>
<li><p>✅ s’auto-héberger facilement (Docker / Podman / Helm)</p>
</li>
<li><p>✅ s’intégrer à ta forge (Forgejo, GitLab, Radicle…)</p>
</li>
<li><p>✅ respecter la vie privée (pas de tracking planqué)</p>
</li>
<li><p>✅ s’adapter à <strong>ta méthode</strong>, pas l’inverse</p>
</li>
<li><p>✅ rester utilisable <strong>sans IA</strong>, mais meilleur avec</p>
</li>
</ul>
<p>Si un outil ne coche pas ça, tu passes ton chemin.</p>
<hr />
<h2>Gestion de projet : les outils qui comptent vraiment</h2>
<h3>OpenProject — le socle professionnel</h3>
<p>👉 <strong>Le plus complet du marché open source pour la gestion de projet structurée</strong></p>
<p>OpenProject n’est pas un outil “agile friendly” de plus. C’est un <strong>véritable socle de pilotage</strong>, pensé pour durer et absorber la complexité.</p>
<p>Ce qu’il fait très bien :</p>
<ul>
<li><p>Scrum / Kanban / Gantt / roadmaps multi-projets</p>
</li>
<li><p>dépendances et jalons</p>
</li>
<li><p>workflows paramétrables</p>
</li>
<li><p>rôles et permissions fines</p>
</li>
<li><p>intégrations natives GitLab / Forgejo</p>
</li>
<li><p>API stable et documentée</p>
</li>
</ul>
<p>Ce qu’il assume :</p>
<ul>
<li><p>une courbe d’apprentissage réelle</p>
</li>
<li><p>approche plus “gestion” que “produit pur”</p>
</li>
<li><p>UI fonctionnelle, pas tape-à-l’œil</p>
</li>
</ul>
<p>Auto-hébergement :</p>
<ul>
<li><p>images Docker officielles</p>
</li>
<li><p>déploiement simple derrière Traefik / Nginx</p>
</li>
<li><p>compatible Podman rootless</p>
</li>
<li><p>mises à jour maîtrisables</p>
</li>
</ul>
<p>💡 <strong>À choisir si</strong> :</p>
<ul>
<li><p>ton projet va durer</p>
</li>
<li><p>plusieurs équipes interviennent</p>
</li>
<li><p>la traçabilité compte autant que la vitesse</p>
</li>
</ul>
<p>🔗 <a href="https://www.openproject.org">OpenProject</a></p>
<hr />
<h3>Plane — moderne et rapide</h3>
<p>👉 <strong>L’anti-usine à gaz</strong></p>
<ul>
<li><p>UI ultra fluide</p>
</li>
<li><p>Kanban / cycles / backlog</p>
</li>
<li><p>pensé pour équipes produit et devs</p>
</li>
<li><p>prise en main quasi immédiate</p>
</li>
</ul>
<p>Limites :</p>
<ul>
<li><p>moins adapté aux projets très gouvernés</p>
</li>
<li><p>pas (encore) un ERP complet</p>
</li>
</ul>
<p>Auto-hébergement :</p>
<ul>
<li><p>Docker Compose simple</p>
</li>
<li><p>très léger en ressources</p>
</li>
</ul>
<p>💡 Idéal pour startups, petites équipes et projets open source communautaires</p>
<p>🔗 <a href="https://plane.so">Plane</a></p>
<hr />
<h3>ProjeQtOr — la gouvernance open source</h3>
<p>👉 <strong>Le vétéran qui ne rigole pas</strong></p>
<ul>
<li><p>budgets / risques / qualité</p>
</li>
<li><p>décisions et traçabilité complète</p>
</li>
<li><p>utilisé par des institutions</p>
</li>
</ul>
<p>Clairement pas sexy. Mais <strong>terriblement efficace</strong> pour les projets critiques et contractuels.</p>
<p>🔗 <a href="https://www.projeqtor.org">ProjeQtOr</a></p>
<hr />
<h3>ZenTao — Agile + DevOps complet</h3>
<p>👉 <strong>Le couteau suisse pour équipes agiles</strong></p>
<ul>
<li><p>gestion bugs et tests</p>
</li>
<li><p>intégrations CI/CD</p>
</li>
<li><p>vision DevOps complète</p>
</li>
</ul>
<p>💡 Pour équipes qui veulent tout au même endroit</p>
<p>🔗 <a href="https://www.zentao.pm">ZenTao</a></p>
<hr />
<h3>Vikunja — le prometteur</h3>
<p>👉 <strong>Interface moderne et collaborative</strong></p>
<ul>
<li><p>vues multiples (liste / kanban / gantt)</p>
</li>
<li><p>collaboration temps réel</p>
</li>
<li><p>développement actif</p>
</li>
</ul>
<p>💡 Pour équipes réactives et projets évolutifs</p>
<p>🔗 <a href="https://vikunja.io">Vikunja</a></p>
<hr />
<h3>Docmost — documentation collaborative</h3>
<p>👉 <strong>Alternative open source à Confluence / Notion</strong></p>
<ul>
<li><p>centralisation des ressources</p>
</li>
<li><p>collaboration efficace</p>
</li>
<li><p>adapté aux équipes distribuées</p>
</li>
</ul>
<p>💡 Pour documentation structurée et maintenable</p>
<p>🔗 <a href="https://github.com/docmost/docmost/">Docmost</a></p>
<hr />
<h3>BookStack — documentation simple et efficace</h3>
<p>👉 <strong>Gestion par livres et pages</strong></p>
<ul>
<li><p>simplicité et clarté</p>
</li>
<li><p>open source</p>
</li>
<li><p>rapide à mettre en place</p>
</li>
</ul>
<p>💡 Idéal pour projets nécessitant documentation bien organisée</p>
<p>🔗 <a href="https://www.bookstackapp.com">BookStack</a></p>
<hr />
<h3>Autres alternatives</h3>
<ul>
<li><p><strong>Taiga</strong> — Agile simple → <a href="https://taiga.io">taiga.io</a></p>
</li>
<li><p><strong>Focalboard</strong> — Kanban minimaliste → <a href="https://www.focalboard.com">focalboard.com</a></p>
</li>
<li><p><strong>Redmine</strong> — legacy mais increvable → <a href="https://www.redmine.org">redmine.org</a></p>
</li>
<li><p><strong>Freedcamp</strong> — Gratuit et complet → <a href="https://freedcamp.com">freedcamp.com</a></p>
</li>
<li><p><strong>RedmineUP</strong> — Redmine pro → <a href="https://www.redmineup.com">redmineup.com</a></p>
</li>
</ul>
<hr />
<h2>Forges logicielles : le vrai cœur du projet</h2>
<h3>Forgejo — le rationnel</h3>
<p>👉 Fork communautaire de Gitea</p>
<ul>
<li><p>léger, rapide</p>
</li>
<li><p>100 % open source</p>
</li>
<li><p>parfait en auto-hébergement</p>
</li>
</ul>
<p>🔗 <a href="https://forgejo.org">Forgejo</a></p>
<hr />
<h3>GitLab CE — puissant mais exigeant</h3>
<ul>
<li><p>CI/CD intégré</p>
</li>
<li><p>écosystème massif</p>
</li>
</ul>
<p>Mais :</p>
<ul>
<li><p>lourd et gourmand</p>
</li>
<li><p>maintenance non négligeable</p>
</li>
</ul>
<p>💡 Pertinent pour équipes DevOps expérimentées</p>
<p>🔗 <a href="https://about.gitlab.com">GitLab</a></p>
<hr />
<h3>Codeberg — l’éthique</h3>
<ul>
<li><p>hébergé en Europe</p>
</li>
<li><p>pas de tracking</p>
</li>
<li><p>communauté engagée</p>
</li>
</ul>
<p>🔗 <a href="https://codeberg.org">Codeberg</a></p>
<hr />
<h3>Radicle — le futur décentralisé</h3>
<ul>
<li><p>Git P2P, sans serveur central</p>
</li>
<li><p>résilient et anti-censure</p>
</li>
<li><p>compatible IPFS</p>
</li>
</ul>
<p>💡 Conceptuellement révolutionnaire, encore niche</p>
<p>🔗 <a href="https://radicle.xyz">Radicle</a></p>
<hr />
<h2>CI/CD : simple, propre, efficace</h2>
<h3>Woodpecker CI — sweet spot</h3>
<ul>
<li><p>pipelines YAML clairs</p>
</li>
<li><p>runners Docker / OCI</p>
</li>
<li><p>parfait avec Forgejo</p>
</li>
<li><p>empreinte minimale</p>
</li>
</ul>
<p>💡 Suffisant pour 90 % des projets</p>
<p>🔗 <a href="https://woodpecker-ci.org">Woodpecker CI</a></p>
<hr />
<h3>Drone — léger et efficace</h3>
<ul>
<li><p>CI/CD simple</p>
</li>
<li><p>marketplace de plugins</p>
</li>
</ul>
<p>🔗 <a href="https://www.drone.io">Drone</a></p>
<hr />
<h3>Tekton — standard Kubernetes</h3>
<ul>
<li><p>pipelines déclaratifs</p>
</li>
<li><p>cloud-native</p>
</li>
</ul>
<p>💡 Pour équipes très K8s</p>
<p>🔗 <a href="https://tekton.dev">Tekton</a></p>
<hr />
<h3>Zuul — artillerie lourde</h3>
<ul>
<li><p>gating avancé</p>
</li>
<li><p>pipelines complexes</p>
</li>
<li><p>utilisé par OpenStack</p>
</li>
</ul>
<p>💡 Overkill pour la majorité</p>
<p>🔗 <a href="https://zuul-ci.org">Zuul</a></p>
<hr />
<h2>Collaboration</h2>
<h3>Matrix + Element — décentralisé</h3>
<ul>
<li><p>chiffré et extensible</p>
</li>
<li><p>interopérable avec bots CI, notifications issues, Jitsi</p>
</li>
</ul>
<p>🔗 <a href="https://matrix.org">Matrix</a> | <a href="https://element.io">Element</a></p>
<hr />
<h3>Mattermost — entreprise</h3>
<ul>
<li><p>alternative à Slack</p>
</li>
<li><p>simple à déployer, moins décentralisé</p>
</li>
</ul>
<p>🔗 <a href="https://mattermost.com">Mattermost</a></p>
<hr />
<h3>Rocket.Chat — complet</h3>
<ul>
<li><p>chat + visio</p>
</li>
<li><p>intégrations riches</p>
</li>
</ul>
<p>🔗 <a href="https://rocket.chat">Rocket.Chat</a></p>
<hr />
<h3>Zulip — organisé</h3>
<ul>
<li><p>threads structurés</p>
</li>
<li><p>discussions lisibles</p>
</li>
</ul>
<p>🔗 <a href="https://zulip.com">Zulip</a></p>
<hr />
<h2>Documentation</h2>
<ul>
<li><p><strong>Wiki.js</strong> → simple, collaboratif, Markdown → <a href="https://js.wiki">Wiki.js</a></p>
</li>
<li><p><strong>Docusaurus</strong> → docs techniques, versioning → <a href="https://docusaurus.io">Docusaurus</a></p>
</li>
<li><p><strong>MkDocs</strong> → Markdown → site statique → <a href="https://www.mkdocs.org">MkDocs</a></p>
</li>
<li><p><strong>Antora</strong> → multi-sources, versioning → <a href="https://antora.org">Antora</a></p>
</li>
<li><p><strong>BookStack</strong> → gestion par livres → <a href="https://www.bookstackapp.com">BookStack</a></p>
</li>
<li><p><strong>Docmost</strong> → alternative Confluence → <a href="https://github.com/docmost/docmost/">Docmost</a></p>
</li>
</ul>
<hr />
<h2>Sécurité</h2>
<ul>
<li><p><strong>Snyk</strong> → gestion vulnérabilités → <a href="https://snyk.io">Snyk</a></p>
</li>
<li><p><strong>OWASP Dependency-Check</strong> → analyse statique → <a href="https://owasp.org/www-project-dependency-check">OWASP</a></p>
</li>
<li><p><strong>Trivy</strong> → code / conteneurs / IaC → <a href="https://trivy.dev">Trivy</a></p>
</li>
<li><p><strong>SonarQube</strong> → qualité de code → <a href="https://www.sonarqube.org">SonarQube</a></p>
</li>
</ul>
<hr />
<h2>Monitoring</h2>
<ul>
<li><p><strong>Prometheus / Loki / Grafana</strong> → métriques / logs / visualisation</p>
</li>
<li><p><strong>Netdata</strong> → monitoring temps réel → <a href="https://www.netdata.cloud">Netdata</a></p>
</li>
<li><p><strong>Uptime Kuma</strong> → surveillance simple → <a href="https://github.com/louislam/uptime-kuma">Uptime Kuma</a></p>
</li>
</ul>
<hr />
<h2>Gouvernance</h2>
<ul>
<li><p><strong>GrimoireLab</strong> → analyse communauté → <a href="https://chaoss.github.io/grimoirelab">GrimoireLab</a></p>
</li>
<li><p><strong>Open Governance Index</strong> → transparence → <a href="https://www.open-governance.org">Open Governance</a></p>
</li>
<li><p><strong>Augur</strong> → métriques open source → <a href="https://github.com/chaoss/augur">Augur</a></p>
</li>
</ul>
<hr />
<h2>Auto-hébergement</h2>
<p>Outils éprouvés :</p>
<ul>
<li><p>Docker → <a href="https://www.docker.com">Docker</a></p>
</li>
<li><p>Podman rootless → <a href="https://podman.io">Podman</a></p>
</li>
<li><p>containerd + nerdctl → <a href="https://containerd.io">containerd</a></p>
</li>
<li><p>Kubernetes léger (k3s) → <a href="https://k3s.io">k3s</a></p>
</li>
</ul>
<blockquote>
<p>Si ton outil ne tourne pas en rootless → méfiance.</p>
</blockquote>
<hr />
<h2>Erreurs classiques</h2>
<ul>
<li><p>❌ Choisir un outil à la mode</p>
</li>
<li><p>❌ Sous-estimer la maintenance</p>
</li>
<li><p>❌ Tout automatiser sans garde-fou humain</p>
</li>
<li><p>❌ Ignorer l’accessibilité</p>
</li>
<li><p>❌ Confondre IA et pilotage</p>
</li>
</ul>
<hr />
<h2>Et après ?</h2>
<p>En 2027 :</p>
<ul>
<li><p>plus de spécialisation</p>
</li>
<li><p>moins de plateformes géantes</p>
</li>
<li><p>plus de sobriété</p>
</li>
<li><p>des outils <strong>maîtrisés</strong>, pas magiques</p>
</li>
</ul>
<hr />
<h2>En clair</h2>
<p>👉 Le bon outil, c’est celui :</p>
<ol>
<li><p>que tu comprends</p>
</li>
<li><p>que tu peux héberger</p>
</li>
<li><p>que tu peux quitter</p>
</li>
</ol>
<p>Le reste, c’est du marketing.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>opensource</category>
            <category>projects</category>
            <category>management</category>
            <enclosure url="https://devbyben.fr/images/blog/gestion-de-projet-open-source-les-outils-qui-vont-tout-casser-et-comment-bien-les-choisir-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[GoWM : Le Wasm Manager qui va Révolutionner tes Projets JavaScript]]></title>
            <link>https://devbyben.fr/blog/gowm-le-wasm-manager-qui-va-revolutionner-tes-projets-javascript</link>
            <guid>https://devbyben.fr/blog/gowm-le-wasm-manager-qui-va-revolutionner-tes-projets-javascript</guid>
            <pubDate>Wed, 18 Jun 2025 15:50:22 GMT</pubDate>
            <description><![CDATA[Salut toi ! Tu rêves d'exploiter la puissance du Go compilé en WASM sans te prendre la tête avec des configurations complexes ? Alors installe-toi confortablement, parce que j'ai découvert un outil qui va totalement changer ta façon de bosser avec We...]]></description>
            <content:encoded><![CDATA[<p>Salut toi ! Tu rêves d'exploiter la puissance du Go compilé en WASM sans te prendre la tête avec des configurations complexes ? Alors installe-toi confortablement, parce que j'ai <em>découvert</em> un outil qui va totalement changer ta façon de bosser avec WebAssembly.</p>
<p><strong>GoWM (Go WebAssembly Manager)</strong> débarque comme une révolution dans l'écosystème WebAssembly. Gratos, open source, et surtout <strong>ultra simple</strong> à utiliser. Oui, tout ça à la fois ! Fini les galères de compilation, les configurations interminables, et les prises de tête pour charger tes modules WASM.</p>
<h2>WebAssembly : Le turbo pour tes apps web</h2>
<p>Avant de plonger dans GoWM, rappelons pourquoi WebAssembly c'est cool. Les recherches montrent que <strong>WebAssembly peut être jusqu'à 10x plus rapide que JavaScript</strong> pour les tâches de calcul intensif. Pour le traitement d'images, les opérations cryptographiques, ou les calculs mathématiques complexes, WASM écrase littéralement JS en termes de performances.</p>
<p>Mais attention, c'est pas magique non plus ! JavaScript reste le roi pour la manipulation du DOM et les interactions utilisateur simples. L'idée, c'est de faire <strong>bosser les deux ensemble</strong> : JS pour l'interface et les interactions, WASM pour la puissance de calcul.</p>
<h2>GoWM : La solution qui change tout</h2>
<h3>Le problème qu'on connaît tous</h3>
<p>Intégrer des modules WebAssembly dans un projet web, c'est souvent un parcours du combattant :</p>
<ul>
<li><p>Configuration complexe de l'environnement de build</p>
</li>
<li><p>Gestion manuelle des fichiers <code>.wasm</code> et <code>wasm_exec.js</code></p>
</li>
<li><p>Problèmes de compatibilité entre navigateurs</p>
</li>
<li><p>Absence d'outils standardisés pour le chargement</p>
</li>
</ul>
<h3>La Réponse : GoWM</h3>
<p><strong>GoWM v1.0.7</strong> débarque avec une approche révolutionnaire : <strong>chargement direct depuis GitHub</strong>, intégration native avec React et Vue, et configuration <strong>zéro</strong>. Plus besoin de compiler, plus besoin de serveur local, plus besoin de galères !</p>
<h4>Les super-pouvoirs de GoWM</h4>
<p>✅ <strong>Chargement GitHub direct</strong> : Tes modules WASM directement depuis les repos<br />✅ <strong>Cross-Platform</strong> : Compatible navigateur (exports.browser), Node.js (exports.node) et environnements edge<br />✅ <strong>React &amp; Vue natifs</strong> : Hooks (<code>gowm/hooks</code>) et composables (<code>gowm/composables</code>) intégrés<br />✅ <strong>TypeScript ready</strong> : Support complet avec autocomplétion via types/index.d.ts<br />✅ <strong>Gestion d'erreurs robuste</strong> : Retry automatique et gestion d'état<br />✅ <strong>Performance optimisée</strong> : Cache intelligent et chargement asynchrone</p>
<h2>L'écosystème de modules : Un arsenal complet</h2>
<p>GoWM, c'est pas juste un gestionnaire, c'est tout un <strong>écosystème de modules prêts à l'emploi</strong>. Découvre la collection complète sur <a href="https://gowm.vercel.app">gowm.vercel.app</a> avec documentation interactive et exemples concrets !</p>
<h3>PDF-WASM : Génération et manipulation PDF</h3>
<p><strong>Fonctions disponibles</strong> : <code>createPDF</code>, <code>addPage</code>, <code>extractText</code>, <code>mergePDFs</code>, <code>splitPDF</code>, <code>addWatermark</code>, <code>generateReport</code>, <code>compressPDF</code><br /><strong>Bibliothèque</strong> : GoFPDF pour génération native<br /><strong>Sortie</strong> : PDF Base64 prêt au téléchargement</p>
<pre><code>const pdf = await loadFromGitHub('benoitpetit/wasm-modules-repository', {
  branch: 'master',
  name: 'pdf-wasm'
});

// Création PDF simple
const pages = [{
  width: 210, height: 297, margin: 20,
  content: "Document généré avec GoWM\n\nPDF-WASM permet la création rapide de documents professionnels."
}];

const metadata = {
  title: "Document GoWM",
  author: "DevByBen"
};

const pdfResult = pdf.call('createPDF', JSON.stringify(pages), JSON.stringify(metadata));
if (!pdfResult.error) {
  console.log('PDF créé:', pdfResult.size, 'bytes');
  
  // Téléchargement direct
  const link = document.createElement('a');
  link.href = 'data:application/pdf;base64,' + pdfResult.pdfData;
  link.download = 'document.pdf';
  link.click();
}

// Génération de rapport
const reportData = {
  type: "report",
  data: { title: "Rapport GoWM", content: "Statistiques WebAssembly" }
};
const reportResult = pdf.call('generateReport', JSON.stringify(reportData));
console.log('Rapport généré:', reportResult.templateType);

// Compression PDF
const compressResult = pdf.call('compressPDF', pdfResult.pdfData, 'medium');
console.log('Compression:', compressResult.compressionRatio + '%');
</code></pre>
<h3>Crypto-WASM : Sécurité</h3>
<p><strong>Fonctions disponibles</strong> : <code>hashSHA256</code>, <code>generateAESKey</code>, <code>encryptAES</code>, <code>decryptAES</code>, <code>generateRSAKeyPair</code>, <code>generateJWT</code><br /><strong>Retour structuré</strong> : Objets avec métadonnées complètes<br /><strong>Sécurité</strong> : Algorithmes cryptographiques standards</p>
<pre><code>const crypto = await loadFromGitHub('benoitpetit/wasm-modules-repository', {
  branch: 'master',
  name: 'crypto-wasm'
});

// Hash SHA256 avec métadonnées
const hashResult = crypto.call('hashSHA256', 'Hello World');
if (hashResult.error) {
  console.error('Erreur hash:', hashResult.error);
} else {
  console.log('Hash:', hashResult.hash);
  console.log('Algorithme:', hashResult.algorithm); // "SHA256"
}

// Génération et utilisation clé AES
const keyResult = crypto.call('generateAESKey', 32); // 256-bit
if (!keyResult.error) {
  console.log('Clé générée:', keyResult.key);
  console.log('Taille:', keyResult.keySize, 'bits');
  
  // Chiffrement AES
  const encryptResult = crypto.call('encryptAES', 'Message secret', keyResult.key);
  if (!encryptResult.error) {
    console.log('Données chiffrées:', encryptResult.encryptedData);
    console.log('Algorithme:', encryptResult.algorithm);
    
    // Déchiffrement
    const decryptResult = crypto.call('decryptAES', encryptResult.encryptedData, keyResult.key);
    console.log('Déchiffré:', decryptResult.decryptedData); // "Message secret"
  }
}
</code></pre>
<h3>Image-WASM : Traitement d'images</h3>
<p><strong>Fonctions disponibles</strong> : <code>compressJPEG</code>, <code>compressPNG</code>, <code>convertToWebP</code>, <code>resizeImage</code><br /><strong>Optimisation</strong> : Compression intelligente avec ratio de qualité<br /><strong>Formats</strong> : Support JPEG, PNG, WebP</p>
<pre><code>const image = await loadFromGitHub('benoitpetit/wasm-modules-repository', {
  branch: 'master',
  name: 'image-wasm'
});

// Compression JPEG avec contrôle qualité
const compressResult = image.call('compressJPEG', imageData, 80);
if (!compressResult.error) {
  console.log('Taille compressée:', compressResult.size);
  console.log('Qualité:', compressResult.quality);
  console.log('Ratio de compression:', compressResult.compressionRatio);
  console.log('Format:', compressResult.format); // "JPEG"
}

// Redimensionnement d'image
const resizeResult = image.call('resizeImage', imageData, 800, 600);
if (!resizeResult.error) {
  console.log('Nouvelles dimensions:', resizeResult.width, 'x', resizeResult.height);
}
</code></pre>
<h3>QR-WASM : Génération QR codes &amp; codes-barres</h3>
<p><strong>Fonctions disponibles</strong> : <code>generateQRCode</code>, <code>generateVCard</code>, <code>generateWiFiQR</code>, <code>generateBarcode</code><br /><strong>Formats</strong> : QR codes, vCards, WiFi, codes-barres EAN/UPC<br /><strong>Sortie</strong> : Images Base64 prêtes à l'usage</p>
<pre><code>const qr = await loadFromGitHub('benoitpetit/wasm-modules-repository', {
  branch: 'master',
  name: 'qr-wasm'
});

// Mode silencieux pour production
qr.call('setSilentMode', true);

// QR code basique
const qrResult = qr.call('generateQRCode', 'https://gowm.vercel.app', 256, 'HIGH');
if (!qrResult.error) {
  console.log('QR généré:', qrResult.base64Image);
  
  // Affichage direct dans le DOM
  const img = document.createElement('img');
  img.src = 'data:image/png;base64,' + qrResult.base64Image;
  document.body.appendChild(img);
}

// vCard contact professionnel
const contact = {
  name: 'DevByBen',
  organization: 'GoWM Team',
  phone: '+33123456789',
  email: 'dev@gowm.io',
  url: 'https://gowm.vercel.app'
};
const vCardResult = qr.call('generateVCard', contact, 300);
console.log('vCard QR:', vCardResult.base64Image);

// QR WiFi pour partage réseau
const wifi = {
  ssid: 'DevNetwork',
  password: 'SuperSecure123',
  security: 'WPA',
  hidden: false
};
const wifiResult = qr.call('generateWiFiQR', wifi, 256);
console.log('WiFi QR:', wifiResult.base64Image);
</code></pre>
<h3>Goxios-WASM : Client HTTP puissant</h3>
<p><strong>Fonctions disponibles</strong> : <code>get</code>, <code>post</code>, <code>put</code>, <code>delete</code>, <code>patch</code>, <code>request</code>, <code>create</code><br /><strong>API</strong> : Interface similaire à Axios<br /><strong>Configuration</strong> : Headers, timeout, retry automatique</p>
<pre><code>const goxios = await loadFromGitHub('benoitpetit/wasm-modules-repository', {
  branch: 'master',
  name: 'goxios-wasm'
});

// Requête GET simple
const response = goxios.call('get', 'https://api.github.com/users/octocat');
if (!response.error) {
  console.log('Status:', response.status);
  console.log('Headers:', response.headers);
  console.log('Data:', JSON.parse(response.data));
}

// Requête POST avec données
const postData = { name: 'John', email: 'john@example.com' };
const postResponse = goxios.call('post', 'https://api.example.com/users', JSON.stringify(postData));
console.log('Création utilisateur:', postResponse);
</code></pre>
<h2>Découvre Tous les Modules Disponibles</h2>
<p>Tu veux explorer l'écosystème complet des modules WebAssembly ?</p>
<p><strong>👉</strong> <a href="https://gowm.vercel.app/modules"><strong>Découvrir tous les modules sur gowm.vercel.app/modules</strong></a></p>
<p>Sur cette page, tu trouveras :</p>
<ul>
<li><p>📊 <strong>Statistiques complètes</strong> : nombre de modules, fonctions, taille totale</p>
</li>
<li><p>🔍 <strong>Recherche et filtres</strong> : trouve rapidement le module parfait</p>
</li>
<li><p>📖 <strong>Documentation interactive</strong> : exemples et API pour chaque module</p>
</li>
<li><p>⭐ <strong>Informations GitHub</strong> : stars, forks, dernières mises à jour</p>
</li>
<li><p>📱 <strong>Interface moderne</strong> : navigation intuitive en grid ou liste</p>
</li>
</ul>
<p>Chaque module est documenté avec des exemples concrets d'intégration React, Vue et JavaScript vanilla. Tu peux copier-coller le code et c'est parti !</p>
<h2>Créer tes propres modules WASM</h2>
<p>Tu veux créer tes propres modules WebAssembly optimisés pour GoWM ? C'est possible et plus simple que tu ne le penses !</p>
<p>👉 <a href="https://gowm.vercel.app/docs#building-wasm"><strong>Guide complet de création de modules WASM</strong></a></p>
<p>Le guide officiel couvre :</p>
<ul>
<li><p>🏗️ <strong>Setup de l'environnement</strong> Go pour WebAssembly</p>
</li>
<li><p>📝 <strong>Patterns de développement</strong> GoWM-compatibles</p>
</li>
<li><p>🔧 <strong>Export de fonctions</strong> avec gestion d'erreurs</p>
</li>
<li><p>📦 <strong>Compilation optimisée</strong> avec TinyGo</p>
</li>
<li><p>🚀 <strong>Publication</strong> et intégration GitHub</p>
</li>
<li><p>✅ <strong>Tests et validation</strong> des modules</p>
</li>
</ul>
<pre><code>// Exemple de module Go simple
package main

import (
    "syscall/js"
)

var silentMode = false

//go:export add
func add(a, b int) int {
    return a + b
}

//go:export subtract
func subtract(a, b int) int {
    return a - b
}

//go:export setSilentMode
func setSilentMode(enabled bool) bool {
    silentMode = enabled
    return silentMode
}

//go:export getAvailableFunctions
func getAvailableFunctions() []string {
    return []string{"add", "subtract", "setSilentMode", "getAvailableFunctions"}
}

func main() {
    c := make(chan struct{}, 0)
    &lt;-c // Keep alive
}
</code></pre>
<p><strong>Compilation optimisée</strong> :</p>
<pre><code>#!/bin/bash
# build.sh - Script de compilation optimisée pour modules WASM

set -e

# Configuration environnement WebAssembly
export GOOS=js
export GOARCH=wasm
export CGO_ENABLED=0

# Récupération des dépendances
go mod download
go mod tidy

# Flags d'optimisation
BUILD_FLAGS=(
    -ldflags="-s -w"           # Supprime debug et symbol table
    -trimpath                  # Supprime les chemins de fichiers
    -buildmode=default         # Mode de build standard
)

# Compilation WASM optimisée
go build "${BUILD_FLAGS[@]}" -o main.wasm main.go

# Optimisation avec wasm-opt (si disponible)
if command -v wasm-opt &amp;&gt; /dev/null; then
    wasm-opt -Oz --enable-bulk-memory main.wasm -o main.wasm
fi

# Compression gzip
gzip -9 -k main.wasm

# Génération hash d'intégrité
sha256sum main.wasm | cut -d' ' -f1 &gt; main.wasm.integrity

echo "✅ Module WASM optimisé et prêt pour GoWM!"
</code></pre>
<h2>Performances : Les chiffres qui parlent</h2>
<p>Les benchmarks montrent des résultats impressionnants selon le type de tâche :</p>
<h3>Quand WebAssembly domine</h3>
<ul>
<li><p><strong>Calculs intensifs</strong> : Jusqu'à 10× plus rapide</p>
</li>
<li><p><strong>Cryptographie</strong> : Entre 2× et 10× de gain</p>
</li>
<li><p><strong>Traitement d'images</strong> : 2× à 5× plus performant</p>
</li>
<li><p><strong>Applications scientifiques</strong> : Gains substantiels</p>
</li>
</ul>
<h3>Quand javascript reste roi</h3>
<ul>
<li><p><strong>Manipulation DOM</strong> : Accès natif vs passage par JS</p>
</li>
<li><p><strong>Applications légères</strong> : Overhead de chargement WASM</p>
</li>
<li><p><strong>Interactions utilisateur</strong> : Réactivité immédiate</p>
</li>
</ul>
<h2>Architecture GitHub : L'innovation qui change Tout</h2>
<p>GoWM révolutionne l'approche traditionnelle avec son <strong>système de chargement GitHub direct</strong>. Plus besoin de :</p>
<ul>
<li><p>Configurer un serveur local</p>
</li>
<li><p>Gérer les fichiers WASM manuellement</p>
</li>
<li><p>S'embêter avec les CORS</p>
</li>
<li><p>Maintenir des versions locales</p>
</li>
</ul>
<h3>Auto-Discovery Intelligent</h3>
<p>GoWM scanne automatiquement les dépôts GitHub pour trouver tes modules :</p>
<ul>
<li><p>Dossiers <code>wasm/</code>, <code>dist/</code>, <code>build/</code></p>
</li>
<li><p>Fichiers <code>main.wasm</code>, <code>index.wasm</code>, <code>{repo-name}.wasm</code></p>
</li>
<li><p>GitHub releases avec assets WASM</p>
</li>
<li><p>Chemins personnalisés</p>
</li>
</ul>
<pre><code>// Basic loading - automatic file discovery
const math = await loadFromGitHub('benoitpetit/wasm-modules-repository');

// Advanced loading with specific options
const imageProcessor = await loadFromGitHub('image-corp/wasm-image', {
  branch: 'develop',        // Use develop branch
  path: 'dist',            // Look in dist folder
  filename: 'image.wasm',  // Specific filename
  name: 'image-processor'  // Module name
});

// Load from specific tag/release
const stableVersion = await loadFromGitHub('company/wasm-lib', {
  tag: 'v1.2.0',           // Use specific tag
  name: 'stable'
});
</code></pre>
<h2>React integration : Hooks natifs</h2>
<pre><code>import React, { useState, useEffect } from 'react';
import { useWasmFromGitHub } from 'gowm/hooks/useWasm';

function CalculatorComponent() {
  const { wasm, loading, error } = useWasmFromGitHub('benoitpetit/wasm-modules-repository', {
    branch: 'master',
    name: 'math-wasm'
  });
  const [result, setResult] = useState(null);
  const [functions, setFunctions] = useState([]);

  useEffect(() =&gt; {
    if (wasm) {
      // Enable silent mode for cleaner output
      wasm.call('setSilentMode', true);
      
      // Get available functions
      const availableFunctions = wasm.call('getAvailableFunctions');
      setFunctions(availableFunctions);
    }
  }, [wasm]);

  const calculate = async (operation, a, b) =&gt; {
    if (!wasm) return;
    
    try {
      const result = await wasm.callAsync(operation, a, b);
      
      // Handle different return types
      if (typeof result === 'string' &amp;&amp; result.includes('Erreur')) {
        setResult(`Error: ${result}`);
      } else {
        setResult(result);
      }
    } catch (err) {
      setResult(`Error: ${err.message}`);
    }
  };

  if (loading) return &lt;div&gt;Loading WASM module...&lt;/div&gt;;
  if (error) return &lt;div&gt;Error: {error.message}&lt;/div&gt;;

  return (
    &lt;div&gt;
      &lt;h3&gt;Available Functions: {functions.join(', ')}&lt;/h3&gt;
      &lt;button onClick={() =&gt; calculate('add', 5, 3)}&gt;5 + 3&lt;/button&gt;
      &lt;button onClick={() =&gt; calculate('multiply', 4, 7)}&gt;4 × 7&lt;/button&gt;
      &lt;button onClick={() =&gt; calculate('factorial', 5)}&gt;5!&lt;/button&gt;
      {result !== null &amp;&amp; &lt;div&gt;Result: {result}&lt;/div&gt;}
    &lt;/div&gt;
  );
}
</code></pre>
<h2>Vue 3 integration : Composables réactifs</h2>
<pre><code>&lt;template&gt;
  &lt;div class="calculator"&gt;
    &lt;div v-if="loading"&gt;Loading WASM module...&lt;/div&gt;
    &lt;div v-else-if="error"&gt;Error: {{ error.message }}&lt;/div&gt;
    &lt;div v-else&gt;
      &lt;h3&gt;Available Functions: {{ functions.join(', ') }}&lt;/h3&gt;
      &lt;input v-model.number="num1" type="number" placeholder="First number" /&gt;
      &lt;input v-model.number="num2" type="number" placeholder="Second number" /&gt;
      &lt;button @click="calculate('add')"&gt;Add&lt;/button&gt;
      &lt;button @click="calculate('multiply')"&gt;Multiply&lt;/button&gt;
      &lt;div v-if="result !== null"&gt;Result: {{ result }}&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/template&gt;

&lt;script setup&gt;
import { ref, watch } from 'vue';
import { useWasmFromGitHub } from 'gowm/composables/useWasm';

const { wasm, loading, error } = useWasmFromGitHub('benoitpetit/wasm-modules-repository', {
  branch: 'master',
  name: 'math-wasm'
});

const num1 = ref(10);
const num2 = ref(20);
const result = ref(null);
const functions = ref([]);

// Watch for wasm module ready
watch(wasm, (newWasm) =&gt; {
  if (newWasm) {
    // Configure module
    newWasm.call('setSilentMode', true);
    
    // Get available functions
    functions.value = newWasm.call('getAvailableFunctions');
  }
}, { immediate: true });

const calculate = async (operation) =&gt; {
  if (!wasm.value) return;
  
  try {
    const calcResult = await wasm.value.callAsync(operation, num1.value, num2.value);
    
    // Handle error strings
    if (typeof calcResult === 'string' &amp;&amp; calcResult.includes('Erreur')) {
      result.value = `Error: ${calcResult}`;
    } else {
      result.value = calcResult;
    }
  } catch (err) {
    result.value = `Error: ${err.message}`;
  }
};
&lt;/script&gt;
</code></pre>
<h2>Sécurité et Compatibilité : Du solide</h2>
<h3>Sandboxing WebAssembly</h3>
<p>WebAssembly s'exécute dans un environnement sandboxé sécurisé, protégeant le système hôte. GoWM respecte ces garanties tout en ajoutant ses propres couches de protection.</p>
<h3>Support Universel</h3>
<ul>
<li><p><strong>Navigateurs</strong> : Chrome 57+, Firefox 52+, Safari 11+, Edge 16+</p>
</li>
<li><p><strong>Runtimes</strong> : Node.js 14+, Deno, Bun</p>
</li>
<li><p><strong>Environnements</strong> : Browser, server-side, edge computing</p>
</li>
</ul>
<h2>WASM manager : Le site compagnon</h2>
<p>Découvre <strong>WASM Manager</strong>, le site compagnon qui référence tous les modules disponibles :</p>
<ul>
<li><p><strong>Découverte de modules</strong> : Browse et search dans la collection</p>
</li>
<li><p><strong>Intégration GitHub</strong> : Infos automatiques depuis les repos</p>
</li>
<li><p><strong>Exemples d'intégration</strong> : Code ready-to-use pour chaque framework</p>
</li>
<li><p><strong>Documentation complète</strong> : Fonctions, paramètres et exemples</p>
</li>
<li><p><strong>Interface moderne</strong> : UI responsive avec dark mode</p>
</li>
</ul>
<h2>L'Avenir du WebAssembly avec GoWM</h2>
<p>Avec l'arrivée de <strong>Go 1.21</strong> et les optimisations WebAssembly, l'écosystème explose. GoWM se positionne comme <strong>l'outil de référence</strong> pour exploiter cette révolution.</p>
<p>Des entreprises comme <strong>Figma, Autodesk et Blender</strong> utilisent déjà WASM pour des performances spectaculaires. GoWM démocratise cet accès pour tous les développeurs JavaScript.</p>
<h2>Pourquoi GoWM change la donne</h2>
<p>🔓 <strong>Liberté totale</strong> : Pas de vendor lock-in, code 100 % open source MIT<br />🛡️ <strong>Sécurité native</strong> : Sandboxing WASM + protections GoWM<br />💰 <strong>Coût zéro</strong> : Gratuit, sans limites cachées<br />🔧 <strong>Flexibilité maximale</strong> : Adapte-toi à tes besoins spécifiques<br />📚 <strong>Documentation complète</strong> : Exemples, guides, API reference<br />🚀 <strong>Performance optimisée</strong> : Modules compressés et cache intelligent</p>
<h2>Conclusion : Le WebAssembly accessible à tous</h2>
<p><strong>GoWM v1.0.7</strong> n'est pas qu'un gestionnaire de modules. C'est une <strong>révolution</strong> pour intégrer WASM dans tes projets JavaScript. Un développement <strong>plus simple, plus rapide et plus performant</strong> t'attend.</p>
<p>Alors, qu'attends-tu pour essayer ? <code>npm install gowm</code> et c'est parti !</p>
<p><strong>Liens utiles :</strong></p>
<ul>
<li><p>📦 <a href="https://www.npmjs.com/package/gowm">Package NPM</a></p>
</li>
<li><p>🐙 <a href="https://github.com/benoitpetit/gowm">Repository GitHub</a></p>
</li>
<li><p>📦 <a href="https://github.com/benoitpetit/wasm-modules-repository">WASM Module</a></p>
</li>
<li><p>📚 <a href="https://gowm.vercel.app/docs">Documentation complète</a></p>
</li>
</ul>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>gowm</category>
            <category>Go Language</category>
            <category>npm</category>
            <category>WebAssembly</category>
            <category>Open Source</category>
            <enclosure url="https://devbyben.fr/images/blog/gowm-le-wasm-manager-qui-va-revolutionner-tes-projets-javascript-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[WebAssembly + Go + React : Valider tes formulaires comme un chef !]]></title>
            <link>https://devbyben.fr/blog/webassembly-go-react-valider-tes-formulaires-comme-un-chef</link>
            <guid>https://devbyben.fr/blog/webassembly-go-react-valider-tes-formulaires-comme-un-chef</guid>
            <pubDate>Thu, 29 May 2025 22:00:00 GMT</pubDate>
            <description><![CDATA[Salut toi ! Alors comme ça, tu en as marre que la validation de tes formulaires JavaScript qui rame ? Tu aimerais bien avoir les performances du natif sans te prendre la tête avec du C++ ? J'ai la solution parfaite pour toi : WebAssembly avec Go !
Au...]]></description>
            <content:encoded><![CDATA[<p>Salut toi ! Alors comme ça, tu en as marre que la validation de tes formulaires JavaScript qui rame ? Tu aimerais bien avoir les performances du natif sans te prendre la tête avec du C++ ? J'ai la solution parfaite pour toi : <strong>WebAssembly avec Go</strong> !</p>
<p>Aujourd'hui, on va découvrir <strong>GoWM</strong>, un petit bijou qui va révolutionner ta façon d'intégrer WebAssembly dans tes apps React, Vue.js ou dans du Node.js. Prépare ton café, on va s'amuser !</p>
<h2>GoWM, qu'est-ce que c'est que ce truc ?</h2>
<p>GoWM (Go Wasm Manager), c'est un peu comme ton couteau suisse pour WebAssembly. Cette bibliothèque te simplifie la vie au maximum pour charger et utiliser des modules WASM Go dans tes apps JavaScript.</p>
<p>Fini les galères d'intégration ! GoWM te donne :</p>
<ul>
<li><p>Une <strong>interface unifiée</strong> pour charger tes modules WASM Go (enfin !)</p>
</li>
<li><p>Un <strong>support complet</strong> pour Node.js et navigateur avec détection automatique (malin, non ?)</p>
</li>
<li><p>Des <strong>hooks React intégrés</strong> (<code>useWasm</code>, <code>useWasmFromNPM</code>) parce qu'on aime React ici</p>
</li>
<li><p>Des <strong>composables Vue.js</strong> pour les fans de Vue 3</p>
</li>
<li><p>Un <strong>chargement depuis NPM</strong> avec résolution automatique (plus besoin de se creuser la tête)</p>
</li>
<li><p>Une <strong>gestion robuste des erreurs</strong> et détection de fonctions</p>
</li>
<li><p>Une <strong>gestion automatique de la mémoire</strong> (tu peux dormir tranquille)</p>
</li>
</ul>
<h2>Pourquoi WebAssembly pour valider tes formulaires ?</h2>
<p>Alors là, excellente question ! Tu sais, quand tu as des formulaires avec des règles métier complexes, ça peut vite devenir l'enfer côté performance. Genre, tu as des regex pourries, des validations cross-field, et ton navigateur qui commence à suffoquer.</p>
<p>WebAssembly, c'est comme avoir une Ferrari dans ton navigateur. Du code Go compilé qui tourne à des vitesses de malade, directement dans le browser. C'est beau, non ?</p>
<h2>Allez, on installe tout ça !</h2>
<p>Bon, assez parlé, on passe aux choses sérieuses :</p>
<pre><code>npm install gowm
# ou si tu es team Yarn
yarn add gowm
</code></pre>
<p>Facile, hein ? 😄</p>
<h2>Création de notre module WASM de validation</h2>
<h3>Structure du projet</h3>
<p>D'abord, organisons-nous correctement :</p>
<pre><code>validator-wasm/
├── main.go           # Notre code Go de la mort
├── go.mod            # Configuration Go
├── build.sh          # Script magique de compilation
├── package.json      # Config NPM
└── README.md         # Documentation (sois pas fainéant !)
</code></pre>
<h3>Le code Go du Wasm</h3>
<p>Allez, on s'attaque au vif du sujet. Voici notre validateur Go qui sera builder en wasm :</p>
<pre><code>//go:build js &amp;&amp; wasm
package main

import (
    "encoding/json"
    "fmt"
    "regexp"
    "strings"
    "syscall/js"
)

type ValidationRule struct {
    Field    string `json:"field"`
    Required bool   `json:"required"`
    MinLen   int    `json:"minLen"`
    MaxLen   int    `json:"maxLen"`
    Pattern  string `json:"pattern"`
    Type     string `json:"type"`
}

type ValidationResult struct {
    Valid  bool              `json:"valid"`
    Errors map[string]string `json:"errors"`
}

// validateEmail - parce qu'on en a tous marre des emails pourris
func validateEmail(email string) bool {
    pattern := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
    matched, _ := regexp.MatchString(pattern, email)
    return matched
}

// validatePhone - pour les numéros français
func validatePhone(phone string) bool {
    pattern := `^(?:\+33|0)[1-9](?:[0-9]{8})$`
    matched, _ := regexp.MatchString(pattern, phone)
    return matched
}

// validateForm - la fonction qui fait tout le boulot
func validateForm(this js.Value, args []js.Value) interface{} {
    if len(args) != 2 {
        return js.ValueOf(map[string]interface{}{
            "valid":  false,
            "errors": map[string]string{"system": "Arguments invalides, mon reuf !"},
        })
    }

    // Parse des données (attention, ça peut piquer)
    formDataJSON := args[0].String()
    rulesJSON := args[1].String()

    var formData map[string]interface{}
    var rules []ValidationRule

    if err := json.Unmarshal([]byte(formDataJSON), &amp;formData); err != nil {
        return js.ValueOf(map[string]interface{}{
            "valid":  false,
            "errors": map[string]string{"system": "Données formulaire pourries"},
        })
    }

    if err := json.Unmarshal([]byte(rulesJSON), &amp;rules); err != nil {
        return js.ValueOf(map[string]interface{}{
            "valid":  false,
            "errors": map[string]string{"system": "Règles de validation foireuses"},
        })
    }

    result := ValidationResult{
        Valid:  true,
        Errors: make(map[string]string),
    }

    // La magie opère ici
    for _, rule := range rules {
        value, exists := formData[rule.Field]
        valueStr := ""
        
        if exists &amp;&amp; value != nil {
            valueStr = strings.TrimSpace(value.(string))
        }

        // Champ requis ? On vérifie !
        if rule.Required &amp;&amp; valueStr == "" {
            result.Valid = false
            result.Errors[rule.Field] = "Ce champ est requis, fais un effort !"
            continue
        }

        if valueStr == "" {
            continue // On skip si pas requis et vide
        }

        // Longueur minimale
        if rule.MinLen &gt; 0 &amp;&amp; len(valueStr) &lt; rule.MinLen {
            result.Valid = false
            result.Errors[rule.Field] = fmt.Sprintf("Minimum %d caractères requis", rule.MinLen)
            continue
        }

        // Longueur maximale
        if rule.MaxLen &gt; 0 &amp;&amp; len(valueStr) &gt; rule.MaxLen {
            result.Valid = false
            result.Errors[rule.Field] = fmt.Sprintf("Maximum %d caractères autorisés", rule.MaxLen)
            continue
        }

        // Validation par type
        switch rule.Type {
        case "email":
            if !validateEmail(valueStr) {
                result.Valid = false
                result.Errors[rule.Field] = "Merci d'entrer une adresse email valide"
            }
        case "phone":
            if !validatePhone(valueStr) {
                result.Valid = false
                result.Errors[rule.Field] = "Ce numéro de téléphone, c'est n'importe quoi"
            }
        }

        // Pattern personnalisé pour les perfectionnistes
        if rule.Pattern != "" {
            matched, err := regexp.MatchString(rule.Pattern, valueStr)
            if err != nil || !matched {
                result.Valid = false
                result.Errors[rule.Field] = "Format invalide, recommence !"
            }
        }
    }

    // On retourne le tout en JSON
    resultJSON, _ := json.Marshal(result)
    return js.ValueOf(string(resultJSON))
}

func main() {
    // On expose notre fonction au monde JavaScript
    js.Global().Set("validateForm", js.FuncOf(validateForm))
    
    // Signal de prêt pour GoWM
    js.Global().Set("__gowm_ready", js.ValueOf(true))
    
    // On maintient le programme en vie (important !)
    select {}
}
</code></pre>
<h3>Script de compilation en Wasm</h3>
<p>Créons notre script <code>build.sh</code> qui va compiler tout ça proprement :</p>
<pre><code>#!/bin/bash
set -e

echo "🔨 Compilation du module de validation WASM..."

# Compilation optimisée (on veut du perf !)
GOOS=js GOARCH=wasm go build \
    -ldflags="-s -w" \
    -o validator.wasm \
    main.go

echo "📦 Copie du runtime Go..."
cp "$(go env GOROOT)/lib/wasm/wasm_exec.js" .

echo "✅ Build terminé !"
echo "📊 Taille du fichier WASM: $(du -h validator.wasm | cut -f1)"
</code></pre>
<h2>Intégration React avec GoWM</h2>
<p>Maintenant, la partie vraiment fun : intégrer tout ça dans React ! Voici un composant :</p>
<pre><code>import React, { useState, useEffect } from 'react';
import { load } from 'gowm';

const ContactForm = () =&gt; {
    const [wasm, setWasm] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() =&gt; {
        const loadWasm = async () =&gt; {
            try {
                setLoading(true);
                setError(null);
                const wasmModule = await load('/validator.wasm');
                setWasm(wasmModule);
                setLoading(false);
            } catch (err) {
                setError(err);
                setLoading(false);
            }
        };

        loadWasm();
    }, []);
    
    const [formData, setFormData] = useState({
        name: '',
        email: '',
        phone: '',
        message: ''
    });
    
    const [validationErrors, setValidationErrors] = useState({});
    const [isSubmitting, setIsSubmitting] = useState(false);

    // Nos règles de validation (modulables à souhait)
    const validationRules = [
        { field: 'name', required: true, minLen: 2, maxLen: 50 },
        { field: 'email', required: true, type: 'email' },
        { field: 'phone', required: false, type: 'phone' },
        { field: 'message', required: true, minLen: 10, maxLen: 500 }
    ];

    const handleInputChange = (e) =&gt; {
        const { name, value } = e.target;
        setFormData(prev =&gt; ({
            ...prev,
            [name]: value
        }));
        
        // Validation en temps réel (parce qu'on est des pros)
        if (wasm) {
            validateField(name, value);
        }
    };

    const validateField = async (fieldName, value) =&gt; {
        if (!wasm) {
            // Validation de fallback en JavaScript si WASM pas encore chargé
            const errors = {};
            const rules = validationRules.filter(rule =&gt; rule.field === fieldName);
            for (const rule of rules) {
                if (rule.required &amp;&amp; !value.trim()) {
                    errors[fieldName] = "Ce champ est requis, fais un effort !";
                    break;
                }
                if (value.trim() &amp;&amp; rule.minLen &amp;&amp; value.length &lt; rule.minLen) {
                    errors[fieldName] = `Minimum ${rule.minLen} caractères requis`;
                    break;
                }
                if (value.trim() &amp;&amp; rule.type === 'email') {
                    const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
                    if (!emailRegex.test(value)) {
                        errors[fieldName] = "Cet email sent le poisson pourri";
                        break;
                    }
                }
            }
            setValidationErrors(prev =&gt; ({
                ...prev,
                [fieldName]: errors[fieldName] || null
            }));
            return;
        }

        try {
            const singleFieldData = { [fieldName]: value };
            const fieldRules = validationRules.filter(rule =&gt; rule.field === fieldName);
            
            // Avec gowm, les fonctions sont disponibles globalement après le chargement
            const result = window.validateForm(
                JSON.stringify(singleFieldData), 
                JSON.stringify(fieldRules)
            );
            
            const validation = JSON.parse(result);
            
            setValidationErrors(prev =&gt; ({
                ...prev,
                [fieldName]: validation.errors[fieldName] || null
            }));
        } catch (err) {
            console.error('Oups, erreur de validation:', err);
        }
    };

    const handleSubmit = async (e) =&gt; {
        e.preventDefault();
        
        if (!wasm) {
            alert('Patience, le validateur charge encore !');
            return;
        }

        setIsSubmitting(true);

        try {
            // Validation complète (le moment de vérité)
            const result = window.validateForm(
                JSON.stringify(formData), 
                JSON.stringify(validationRules)
            );
            
            const validation = JSON.parse(result);
            
            if (validation.valid) {
                alert('Formulaire nickel ! Envoi en cours...');
                // Ici tu peux envoyer tes données
                console.log('Données prêtes à partir:', formData);
            } else {
                setValidationErrors(validation.errors);
            }
        } catch (err) {
            console.error('Erreur lors de la validation:', err);
            alert('Oups, quelque chose a foiré !');
        } finally {
            setIsSubmitting(false);
        }
    };

    if (loading) {
        return (
            &lt;div className="flex items-center justify-center p-8"&gt;
                &lt;div className="text-center"&gt;
                    &lt;div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto"&gt;&lt;/div&gt;
                    &lt;p className="mt-2 text-gray-600"&gt;Chargement du validateur...&lt;/p&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        );
    }

    if (error) {
        return (
            &lt;div className="bg-red-50 border border-red-200 rounded-lg p-4"&gt;
                &lt;p className="text-red-600"&gt;Erreur de chargement: {error.message}&lt;/p&gt;
            &lt;/div&gt;
        );
    }

    return (
        &lt;div className="max-w-md mx-auto bg-white rounded-lg shadow-md p-6"&gt;
            &lt;h2 className="text-2xl font-bold mb-6 text-gray-800"&gt;Contact&lt;/h2&gt;
            
            &lt;form onSubmit={handleSubmit} className="space-y-4"&gt;
                &lt;div&gt;
                    &lt;label className="block text-sm font-medium text-gray-700 mb-1"&gt;
                        Nom *
                    &lt;/label&gt;
                    &lt;input
                        type="text"
                        name="name"
                        value={formData.name}
                        onChange={handleInputChange}
                        className={`w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
                            validationErrors.name ? 'border-red-500' : 'border-gray-300'
                        }`}
                    /&gt;
                    {validationErrors.name &amp;&amp; (
                        &lt;p className="text-red-500 text-sm mt-1"&gt;{validationErrors.name}&lt;/p&gt;
                    )}
                &lt;/div&gt;

                &lt;div&gt;
                    &lt;label className="block text-sm font-medium text-gray-700 mb-1"&gt;
                        Email *
                    &lt;/label&gt;
                    &lt;input
                        type="email"
                        name="email"
                        value={formData.email}
                        onChange={handleInputChange}
                        className={`w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
                            validationErrors.email ? 'border-red-500' : 'border-gray-300'
                        }`}
                    /&gt;
                    {validationErrors.email &amp;&amp; (
                        &lt;p className="text-red-500 text-sm mt-1"&gt;{validationErrors.email}&lt;/p&gt;
                    )}
                &lt;/div&gt;

                &lt;div&gt;
                    &lt;label className="block text-sm font-medium text-gray-700 mb-1"&gt;
                        Téléphone
                    &lt;/label&gt;
                    &lt;input
                        type="tel"
                        name="phone"
                        value={formData.phone}
                        onChange={handleInputChange}
                        className={`w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
                            validationErrors.phone ? 'border-red-500' : 'border-gray-300'
                        }`}
                    /&gt;
                    {validationErrors.phone &amp;&amp; (
                        &lt;p className="text-red-500 text-sm mt-1"&gt;{validationErrors.phone}&lt;/p&gt;
                    )}
                &lt;/div&gt;

                &lt;div&gt;
                    &lt;label className="block text-sm font-medium text-gray-700 mb-1"&gt;
                        Message *
                    &lt;/label&gt;
                    &lt;textarea
                        name="message"
                        rows={4}
                        value={formData.message}
                        onChange={handleInputChange}
                        className={`w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 ${
                            validationErrors.message ? 'border-red-500' : 'border-gray-300'
                        }`}
                    /&gt;
                    {validationErrors.message &amp;&amp; (
                        &lt;p className="text-red-500 text-sm mt-1"&gt;{validationErrors.message}&lt;/p&gt;
                    )}
                &lt;/div&gt;

                &lt;button
                    type="submit"
                    disabled={isSubmitting}
                    className="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
                &gt;
                    {isSubmitting ? 'Validation en cours...' : 'Envoyer'}
                &lt;/button&gt;
            &lt;/form&gt;
        &lt;/div&gt;
    );
};

export default ContactForm;
</code></pre>
<h2>Pourquoi cette approche ?</h2>
<h3>Performances.</h3>
<p>Avec WebAssembly, ton code de validation tourne à la vitesse de l'éclair. Les regex complexes et la logique métier sont traitées de manière ultra-efficace. Fini les freeze d'interface !</p>
<h3>Validation en temps réel sans lag</h3>
<p>Grâce au hook <code>useWasm</code> de GoWM, tu peux valider tes champs en temps réel sans que ton interface rame.</p>
<h3>Réutilisabilité au max</h3>
<p>Ton module WASM, tu peux :</p>
<ul>
<li><p>Le publier sur NPM pour le réutiliser partout</p>
</li>
<li><p>L'utiliser côté serveur avec Node.js (pratique !)</p>
</li>
<li><p>L'intégrer dans des apps Vue.js avec les composables GoWM</p>
</li>
</ul>
<h3>Sécurité renforcée</h3>
<p>La validation côté client en WASM ajoute une couche de sécurité. Bien sûr, tu gardes ta validation côté serveur (on n'est pas fous !).</p>
<h2>Configuration avancée avec GoWM</h2>
<p>GoWM, c'est pas que basique. Tu peux faire d’autres trucs sympa :</p>
<pre><code>// Chargement simple
import { load } from 'gowm';

async function loadValidator() {
    try {
        const validator = await load('/validator.wasm');
        // Utilisation directe des fonctions exposées globalement
        const result = window.validateForm(dataJSON, rulesJSON);
        return JSON.parse(result);
    } catch (error) {
        console.error('Oops, chargement foiré:', error);
    }
}

// Gestion de plusieurs modules (pour les gourmands)
import { load, get, listModules } from 'gowm';

const loadMultipleModules = async () =&gt; {
    await load('/validator.wasm', { name: 'validator' });
    await load('/formatter.wasm', { name: 'formatter' });
    
    // Lister les modules chargés
    console.log('Modules chargés:', listModules());
    
    // Récupérer un module spécifique
    const validator = get('validator');
};
</code></pre>
<h2>Support TypeScript (pour les perfectionnistes)</h2>
<p>GoWM inclut des types TypeScript complets :</p>
<pre><code>import { load, LoadOptions } from 'gowm';

interface ValidationResult {
    valid: boolean;
    errors: Record&lt;string, string&gt;;
}

const loadValidator = async (): Promise&lt;void&gt; =&gt; {
    await load('./validator.wasm');
    
    // Les fonctions WASM sont disponibles globalement
    const result: string = (window as any).validateForm(formDataJSON, rulesJSON);
    const validation: ValidationResult = JSON.parse(result);
};
</code></pre>
<p>Alors, convaincu ? GoWM rend WebAssembly accessible à tous les développeurs JavaScript, même les plus fainéants ! Cette approche te permet de :</p>
<ul>
<li><p><strong>Booster les performances</strong> de tes validations complexes</p>
</li>
<li><p><strong>Simplifier l'intégration</strong> grâce aux hooks React tout prêts</p>
</li>
<li><p><strong>Maintenir un code propre</strong> et testable</p>
</li>
<li><p><strong>Réutiliser ta logique</strong> entre client et serveur</p>
</li>
</ul>
<p>Que ce soit pour la validation de formulaires, le traitement d'images, ou des calculs de la mort, WebAssembly avec GoWM ouvre de nouvelles possibilités pour tes applications web</p>
<p>Le code source complet de cet exemple sera bientôt disponible sur GitHub.</p>
<p>A plus ! 🚀</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>gowm</category>
            <category>WebAssembly</category>
            <category>React</category>
            <category>npm</category>
            <enclosure url="https://devbyben.fr/images/blog/webassembly-go-react-valider-tes-formulaires-comme-un-chef-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Prompt My Project - Révolutionne tes interactions avec l’IA grâce à des prompts parfaitement structurés]]></title>
            <link>https://devbyben.fr/blog/prompt-my-project-revolutionne-interactions-ia-prompts-structures</link>
            <guid>https://devbyben.fr/blog/prompt-my-project-revolutionne-interactions-ia-prompts-structures</guid>
            <pubDate>Fri, 28 Feb 2025 20:05:07 GMT</pubDate>
            <description><![CDATA[L’intelligence artificielle change profondément les méthodes de développement des logiciels. Les outils comme GPT ou Claude, bien qu’extrêmement puissants, nécessitent des prompts clairs, riches en contexte et bien structurés pour fournir des réponse...]]></description>
            <content:encoded><![CDATA[<p>L’intelligence artificielle change profondément les méthodes de développement des logiciels. Les outils comme GPT ou Claude, bien qu’extrêmement puissants, nécessitent des <strong>prompts clairs</strong>, riches en contexte et bien structurés pour fournir des réponses optimales. Cependant, écrire manuellement ces prompts pour des projets complexes peut rapidement devenir une tâche chronophage et frustrante. C'est pour résoudre cette problématique que j’ai développée <strong>Prompt My Project</strong> (PMP), un outil open source qui automatise la création de prompts détaillés directement à partir de ton projet.</p>
<hr />
<h2>Pourquoi Prompt My Project ?</h2>
<p>Les assistants IA sont devenus des alliés incontournables pour les développeurs, mais leur efficacité dépend largement de <strong>la qualité des informations qu’ils reçoivent</strong>. Fournir le contexte complet et pertinent d’un projet en mode manuel peut prendre des heures, surtout pour des projets volumineux. La mission de PMP est simple : <strong>automatiser cet effort tout en garantissant des prompts précis et pertinents</strong>.</p>
<h3>Une idée née d'un besoin quotidien</h3>
<p>En tant que développeur, j’ai constaté à quel point il était difficile de collaborer efficacement avec des IA sur des projets techniques complexes. Les prompts devaient inclure la structure du projet, des extraits de fichiers pertinents, ainsi que des détails critiques, mais rassembler ces informations à la main devenait vite un travail répétitif et fatigant. C’est ainsi qu’est apparue l’idée de PMP : un outil capable d’extraire automatiquement les éléments clés d’un projet et de les intégrer dans un prompt structuré, prêt à être utilisé avec des modèles d’IA.</p>
<hr />
<h2>Qu’est-ce que Prompt My Project ?</h2>
<p><strong>Prompt My Project</strong> est un outil en ligne de commande capable de scanner ton projet, d’en analyser la structure, et de générer un prompt détaillé contenant uniquement les informations pertinentes pour tes interactions avec une IA. En quelques secondes, PMP extrait :</p>
<ul>
<li><p>La structure hiérarchique des dossiers et fichiers.</p>
</li>
<li><p>Le contenu sélectionné des fichiers pertinents.</p>
</li>
<li><p>Une estimation du nombre de tokens utilisés.</p>
</li>
</ul>
<p>L’objectif : donner à l’IA une compréhension rapide et claire de ton projet, afin qu’elle puisse répondre de manière précise à tes besoins.</p>
<hr />
<h2>Fonctionnalités principales</h2>
<h3>1. Analyse intelligente et récursive</h3>
<p>PMP explore automatiquement l’ensemble de la structure de ton projet, détectant les dossiers et les fichiers importants. Cette exploration récursive établit une <strong>cartographie complète</strong> de ton projet, ce qui permet à l’IA de mieux comprendre le contexte global.</p>
<h3>2. Détection automatique des fichiers binaires et respect des règles <code>.gitignore</code></h3>
<ul>
<li><p>PMP identifie et exclut les fichiers binaires (images, exécutables, etc.) pour se concentrer uniquement sur les fichiers texte pertinents.</p>
</li>
<li><p>L’outil respecte également les règles définies dans ton fichier <code>.gitignore</code>, garantissant que seuls les fichiers nécessaires sont inclus dans le prompt.</p>
</li>
</ul>
<h3>3. Inclusion et exclusion personnalisées des fichiers</h3>
<p>Tu peux affiner les résultats en spécifiant :</p>
<ul>
<li><p><strong>Les fichiers ou extensions à inclure</strong> (par exemple, uniquement les fichiers <code>.py</code> ou <code>.md</code>).</p>
</li>
<li><p><strong>Les répertoires ou fichiers à exclure</strong> (comme les dossiers <code>node_modules</code> ou <code>tests</code>).</p>
</li>
</ul>
<p>Cette flexibilité te permet de personnaliser le prompt en fonction de tes besoins spécifiques.</p>
<h3>4. Performance optimisée</h3>
<p>Grâce à un <strong>système de traitement concurrent avancé</strong>, PMP est capable d’analyser rapidement même les plus grands projets. L’outil utilise des techniques telles que :</p>
<ul>
<li><p>Le traitement parallèle via un pool de workers.</p>
</li>
<li><p>La mise en cache des fichiers pour éviter des lectures multiples.</p>
</li>
<li><p>La gestion optimisée des ressources mémoire.</p>
</li>
</ul>
<h3>5. Génération de prompts structurés</h3>
<p>PMP produit un fichier contenant :</p>
<ol>
<li><p><strong>Résumé global</strong> : Une description concise de la structure du projet.</p>
</li>
<li><p><strong>Structure hiérarchique</strong> : Une vue complète des dossiers et fichiers.</p>
</li>
<li><p><strong>Extraits de contenu</strong> : Les parties importantes des fichiers sélectionnés.</p>
</li>
<li><p><strong>Estimation des tokens</strong> : Calcul précis du nombre de caractères et de tokens pour anticiper les limites des modèles d’IA.</p>
</li>
</ol>
<p>Les prompts sont générés dans un répertoire dédié (<code>./prompts/</code> par défaut), avec un nom horodaté (<code>prompt_YYYYMMDD_HHMMSS.txt</code>) pour un suivi facile.</p>
<hr />
<h2>Installation simple sur toutes les plateformes</h2>
<p>PMP est compatible avec <strong>Linux</strong>, <strong>macOS</strong>, et <strong>Windows</strong>, prise en charge des architectures <strong>amd64 (x86_64)</strong> et <strong>arm64 (aarch64)</strong>.</p>
<h3>macOS/Linux</h3>
<pre><code>curl -fsSL https://raw.githubusercontent.com/benoitpetit/prompt-my-project/master/scripts/install.sh | bash
</code></pre>
<h3>Windows</h3>
<pre><code>irm https://raw.githubusercontent.com/benoitpetit/prompt-my-project/master/scripts/install.ps1 | iex
</code></pre>
<hr />
<h2>Commandes et exemples d’utilisation</h2>
<h3>Syntaxe de base</h3>
<pre><code>pmp [options] [path]
</code></pre>
<h3>Exemples concrets</h3>
<h4>Analyse globale du projet</h4>
<pre><code>pmp
</code></pre>
<h4>Inclure uniquement certains fichiers</h4>
<pre><code>pmp --include "*.py" --include "*.md"
</code></pre>
<h4>Exclure des répertoires spécifiques</h4>
<pre><code>pmp --exclude "tests/*" --exclude "node_modules/"
</code></pre>
<h4>Personnaliser le répertoire de sortie</h4>
<pre><code>pmp --output ./mes_prompts
</code></pre>
<h4>Analyser un projet Go</h4>
<p>Tu peux analyser uniquement les fichiers sources Go, tout en excluant les tests et les dépendances :</p>
<pre><code>pmp --include "*.go" --exclude "*_test.go" --exclude "vendor/"
</code></pre>
<h2>Exemple de Prompt généré :</h2>
<pre><code>PROJECT INFORMATION
-----------------------------------------------------
• Project Name: prompt-my-project
• Generated On: 2025-03-01 15:53:46
• Generated with: Prompt My Project (PMP) v1.0.0
• Host: master
• OS: linux/amd64

FILE STATISTICS
-----------------------------------------------------
• Total Files: 4
• Total Size: 37 kB
• Avg. File Size: 9.2 kB
• File Types:
  - .go: 1 files
  - &lt;no-extension&gt;: 1 files
  - .md: 1 files
  - .sum: 1 files

TOKEN STATISTICS
-----------------------------------------------------
• Estimated Token Count: 9318
• Character Count: 37269

=====================================================

PROJECT STRUCTURE:
-----------------------------------------------------

└── prompt-my-project/
    ├── LICENSE
    ├── README.md
    ├── go.sum
    └── main.go


FILE CONTENTS:
-----------------------------------------------------
... // contenu de vos fichiers organiser et trier proprement
..
</code></pre>
<hr />
<h2>Fonctionnement avancé sous le capot</h2>
<h3>1. Gestion des workers</h3>
<p>PMP optimise la vitesse d’analyse grâce à des <strong>pools de workers</strong>, en adaptant automatiquement le nombre de threads disponibles en fonction des ressources matérielles.</p>
<h3>2. Détection binaire sophistiquée</h3>
<p>L'outil combine plusieurs mécanismes pour identifier les fichiers binaires :</p>
<ul>
<li><p>L’analyse de l’extension (ex. <code>.png</code>, <code>.exe</code>).</p>
</li>
<li><p>La vérification du type MIME.</p>
</li>
<li><p>La détection de caractères non textuels dans le contenu.</p>
</li>
</ul>
<h3>3. Mise en cache intelligente</h3>
<p>Le contenu des fichiers est mis en cache temporairement pour éviter des lectures répétées lors de l’analyse.</p>
<hr />
<h2>Configuration par défaut de PMP</h2>
<p>PMP propose un ensemble de paramètres par défaut, ajustables selon tes besoins via des options en ligne de commande ou des variables d’environnement.</p>
<table>
<thead>
<tr>
<th>Paramètre</th>
<th>Valeur par défaut</th>
</tr>
</thead>
<tbody><tr>
<td>Taille minimale des fichiers</td>
<td>1 KB</td>
</tr>
<tr>
<td>Taille maximale des fichiers</td>
<td>100 MB</td>
</tr>
<tr>
<td>Répertoire de sortie</td>
<td><code>./prompts</code></td>
</tr>
<tr>
<td>Respect des règles <code>.gitignore</code></td>
<td>Activé</td>
</tr>
</tbody></table>
<hr />
<h2>Utilisation dans un pipeline CI/CD</h2>
<p>PMP s’intègre facilement dans un pipeline <strong>CI/CD</strong> pour générer automatiquement des prompts à chaque modification importante du projet. Voici un exemple de configuration dans <strong>GitLab CI</strong> :</p>
<pre><code>generate_ia_prompt:
  stage: analysis
  image: golang:1.21
  script:
    - curl -sSL https://raw.githubusercontent.com/benoitpetit/prompt-my-project/master/scripts/install.sh | bash
    - pmp --output ./artifacts/prompts
  artifacts:
    paths:
      - ./artifacts/prompts/
</code></pre>
<hr />
<h2>Conclusion</h2>
<p><strong>Prompt My Project</strong> marque une avancée dans l’optimisation des interactions entre les développeurs et les modèles d’intelligence artificielle. En automatisant la création de prompts bien structurés, PMP te fait gagner un temps précieux, améliore la précision des réponses de l’IA et simplifie la gestion technique de ton projet.</p>
<p><a href="https://github.com/benoitpetit/prompt-my-project">GitHub</a> pour découvrir, contribuer ou partager cet outil open source. Ensemble, améliorons la collaboration entre les développeurs et l’intelligence artificielle !</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>aitools</category>
            <category>AI prompts</category>
            <category>cli</category>
            <enclosure url="https://devbyben.fr/images/blog/prompt-my-project-revolutionne-interactions-ia-prompts-structures-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[10 Bibliothèques golang indispensables à connaître pour les développeurs Go]]></title>
            <link>https://devbyben.fr/blog/10-bibliotheques-golang-indispensables-a-connaitre-pour-les-developpeurs-go</link>
            <guid>https://devbyben.fr/blog/10-bibliotheques-golang-indispensables-a-connaitre-pour-les-developpeurs-go</guid>
            <pubDate>Sun, 20 Oct 2024 07:00:09 GMT</pubDate>
            <description><![CDATA[Allez, prends ta tasse de café et installe-toi bien, car on va parler des 10 bibliothèques Go indispensables que tout développeur Go devrait connaître. Que tu développes des applications web, des micro-services, du mobile, ou que tu cherches à renfor...]]></description>
            <content:encoded><![CDATA[<p>Allez, prends ta tasse de café et installe-toi bien, car on va parler des 10 bibliothèques Go indispensables que tout développeur Go devrait connaître. Que tu développes des applications web, des micro-services, du mobile, ou que tu cherches à renforcer tes tests, on a ce qu’il te faut. L’idée, c’est de te donner les clés pour naviguer facilement dans l’écosystème de Go, peu importe ton projet. Let’s go!</p>
<ol>
<li><p><strong>GORM – Le magicien des bases de donnée</strong></p>
<p> ![](<a href="https://cdn.hashnode.com/res/hashnode/image/upload/v1729236364753/c42de14d-595a-4083-9323-daec7ced61d3.png">https://cdn.hashnode.com/res/hashnode/image/upload/v1729236364753/c42de14d-595a-4083-9323-daec7ced61d3.png</a> align="left")</p>
</li>
</ol>
<p>Tu bosses avec des bases de données relationnelles comme MySQL ou PostgreSQL ? <a href="https://gorm.io/">GORM</a> est là pour toi. C’est un ORM (Object-Relational Mapping) qui te permet de gérer tes bases de données comme un pro : migrations, relations complexes, tout ça en un claquement de doigts. Tu gagnes du temps et tes requêtes deviennent du velours.</p>
<ol>
<li><p><strong>Gin – Ton framework web ultra-léger</strong></p>
<p> <a href="https://gin-gonic.com/">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173585187/c8b2464d-83e9-44b5-bbee-6913803684f7.png align="center")</a></p>
</li>
</ol>
<p><a href="https://gin-gonic.com/">Gin</a> est parfait si tu cherches à développer des API ultrarapides. Il est simple, performant, et super utilisé dans l’écosystème Go. Pour les micro-services ou les architectures modernes, c’est le framework à avoir dans ta boîte à outils.</p>
<ol>
<li><p><strong>Echo – L’alternative plus flexible</strong></p>
<p> <a href="https://echo.labstack.com/">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173612298/3129f11b-3394-45cb-94b9-70f8152b64c8.png align="center")</a></p>
</li>
</ol>
<p>T’as entendu parler de <a href="https://echo.labstack.com/">Echo</a> ? C’est une alternative à Gin, mais avec un poil plus de flexibilité, notamment pour gérer des middlewares et personnaliser le traitement des erreurs. Si tu construis une API qui a besoin de souplesse, tu devrais tester.</p>
<ol>
<li><p><strong>Viper – Gestion des configurations en mode expert</strong></p>
<p> <a href="https://github.com/spf13/viper">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173652131/91671e49-b324-412f-8b2e-c4ec03cedf64.png align="center")</a></p>
</li>
</ol>
<p>Ton projet a besoin de configurations différentes pour chaque environnement ? <a href="https://github.com/spf13/viper">Viper</a> s’occupe de tout. Que tu utilises des fichiers YAML, JSON, ou des variables d’environnement, cette bibliothèque te permet de charger et de gérer les configurations à la volée. C’est l’une des plus appréciées dans le monde Go.</p>
<ol>
<li><p><strong>Cobra – La référence pour créer des CLI</strong></p>
<p> <a href="https://github.com/spf13/cobra">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173680978/c0e344e3-df7f-4516-a8fc-77d94718e1ff.png align="center")</a></p>
</li>
</ol>
<p>Si tu rêves de créer des outils en ligne de commande stylés (et utiles !), <a href="https://github.com/spf13/cobra">Cobra</a> est ta meilleure option. En plus d'être simple à prendre en main, il te génère de la doc automatiquement. Imagine pouvoir créer un CLI aussi clean que ceux de Kubernetes, c’est exactement ça avec Cobra.</p>
<ol>
<li><p><strong>Gorilla Mux – La flexibilité des routes HTTP</strong></p>
<p> <a href="https://github.com/gorilla/mux">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173698130/5b2470c5-8506-4524-8116-2dbffb278fe0.png align="center")</a></p>
</li>
</ol>
<p>Si tu construis une API ou un serveur HTTP, <a href="https://github.com/gorilla/mux">Gorilla Mux</a> est l’outil de routing dont tu as besoin. Il te permet de gérer des routes dynamiques avec des expressions régulières, et il est hyper performant. C’est un excellent choix pour des applications web qui ont besoin de flexibilité dans la gestion des URL.</p>
<ol>
<li><p><strong>GoMobile – Développement mobile avec Go</strong></p>
<p> <a href="https://pkg.go.dev/golang.org/x/mobile">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173709739/59d8cf8d-0a01-454f-b3c8-ff63d6ad834d.png align="center")</a></p>
</li>
</ol>
<p>Oui, Go est aussi capable de faire du développement mobile ! Avec <a href="https://pkg.go.dev/golang.org/x/mobile">GoMobile</a>, tu peux créer des apps pour Android et iOS. Go étant réputé pour sa performance, c’est une belle option pour ceux qui veulent éviter les surcouches comme Flutter ou React Native. Tu écris ton code Go et il est transpilé en natif pour les deux plateformes. Du mobile léger et performant, ça te tente ?</p>
<ol>
<li><p><strong>GoKit – Parfait pour les micro-services</strong></p>
<p> <a href="https://gokit.io/">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173732089/3c9600ad-8c1f-4804-96d2-ebc171876cef.png align="center")</a></p>
</li>
</ol>
<p>Si tu travailles sur des systèmes distribués ou des micro-services, <a href="https://gokit.io/">GoKit</a> est fait pour toi. Ce framework est modulaire, donc tu n’embarques que ce dont tu as besoin. Pas de superflu, juste l’essentiel pour gérer le load balancing, le service discovery, etc. Super utile pour les environnements cloud ou les architectures micro-services.</p>
<ol>
<li><p><strong>GoConvey – Tests automatisés à la cool</strong></p>
<p> <a href="https://github.com/smartystreets/goconvey">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173769294/43ffd2e2-8e3c-4a2d-8467-55df340fb1d4.png align="center")</a></p>
</li>
</ol>
<p>Tester, c’est crucial, mais ça peut vite devenir barbant. <a href="https://github.com/smartystreets/goconvey">GoConvey</a> rend ça beaucoup plus agréable en te fournissant une interface visuelle en temps réel pour suivre tes tests. En plus, il est super léger et intègre des fonctions d’assertions puissantes.</p>
<ol>
<li><p><strong>Prometheus – Monitoring avancé pour tes services</strong></p>
<p><a href="https://prometheus.io/">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173788390/3f02585b-6790-4e7e-9324-a60c453ce8a6.png align="center")</a></p>
</li>
</ol>
<p>Si tu veux surveiller tes applications en production, <a href="https://prometheus.io/">Prometheus</a> est LA solution. C’est une plateforme de monitoring open-source qui collecte des métriques en temps réel. Il est idéal pour tout ce qui est cloud-native, et il est largement adopté dans le monde DevOps. Un must pour assurer la stabilité de ton infrastructure.</p>
<p><strong>Bonus : Fyne – Crée des interfaces graphiques (GUI)</strong></p>
<p><a href="https://fyne.io/">![](https://cdn.hashnode.com/res/hashnode/image/upload/v1729173801088/02f024ff-760f-44d4-8760-7a29f9004cb3.png align="center")</a></p>
<p>Tu as envie de faire du développement d’applications desktop avec Go ? <a href="https://fyne.io/">Fyne</a> est un framework pour créer des interfaces graphiques qui tournent sur Windows, macOS et Linux. Il est facile à utiliser et produit des interfaces modernes avec du code Go, sans avoir à te plonger dans du C++ ou d'autres frameworks lourds.</p>
<hr />
<p>Voilà, tu es armé pour affronter tes projets Go avec ces bibliothèques indispensables. Que tu fasses du web, du mobile, des micro-services, ou du desktop, il y a forcément une librairie qui te simplifiera la vie. Si tu n’as pas encore testé certaines de ces pépites, c’est le moment de te lancer !</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>golang</category>
            <category>developers</category>
            <category>bestpackages</category>
            <enclosure url="https://devbyben.fr/images/blog/10-bibliotheques-golang-indispensables-a-connaitre-pour-les-developpeurs-go-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Better Auth : L’authentification en TypeScript à portée de main]]></title>
            <link>https://devbyben.fr/blog/better-auth-lauthentification-en-typescript-a-portee-de-main</link>
            <guid>https://devbyben.fr/blog/better-auth-lauthentification-en-typescript-a-portee-de-main</guid>
            <pubDate>Mon, 14 Oct 2024 22:00:39 GMT</pubDate>
            <description><![CDATA[Imagine-toi en plein développement d'une application TypeScript. Tout roule, mais arrive LE moment où tu dois implémenter l'authentification. Soudain, tu te retrouves plongé dans une jungle de configurations, des solutions trop simplistes ou au contr...]]></description>
            <content:encoded><![CDATA[<p>Imagine-toi en plein développement d'une application TypeScript. Tout roule, mais arrive LE moment où tu dois implémenter l'authentification. Soudain, tu te retrouves plongé dans une jungle de configurations, des solutions trop simplistes ou au contraire, tellement complexes que tu perds des heures à tout comprendre. Eh bien, laisse-moi te présenter <strong>Better Auth</strong>, la bibliothèque qui pourrait bien te changer la vie !</p>
<h3><strong>Pourquoi Better Auth, c’est une vraie révolution ?</strong></h3>
<p>Tu vois, Better Auth, c’est un peu comme le couteau suisse des bibliothèques d'authentification. Que tu bosses avec <strong>React</strong>, <strong>Vue</strong>, <strong>Next.js</strong> ou même des frameworks plus exotiques comme <strong>Astro</strong> ou <strong>Svelte</strong>, cette solution est <strong>agnostique</strong>. Elle s'intègre partout et surtout, sans douleur. Tu n’as plus à jongler avec des plugins qui ne fonctionnent que dans tel ou tel écosystème.</p>
<h4><strong>Focus sur la simplicité… mais pas au détriment de la puissance</strong></h4>
<p>Si tu as déjà tenté de mettre en place une authentification manuellement, tu sais combien ça peut devenir un casse-tête. Mais avec Better Auth, c’est presque magique : tu veux intégrer une connexion via email et mot de passe ? Boum, c'est fait. Tu veux rajouter une couche de <strong>sécurité avec du 2FA</strong> ? C’est inclus et activable en quelques lignes.</p>
<p>Imagine, tu travailles sur une grosse application multi-utilisateur : tu peux gérer des organisations entières avec des accès différenciés. Pas mal, non ? Et tout ça, sans que tu te retrouves à configurer mille options obscures.</p>
<h3><strong>L’écosystème Better Auth : extensibilité à fond</strong></h3>
<p>Là où Better Auth marque vraiment des points, c’est dans son <strong>écosystème de plugins</strong>. Tu as besoin de fonctionnalités spécifiques ? Tu n’as qu’à piocher dans les plugins, qu’ils soient créés par la communauté ou directement par l’équipe Better Auth. Et comme tout est en TypeScript, la <strong>sécurité des types</strong> est omniprésente. Ton code devient plus robuste, sans que tu aies à réfléchir deux heures à chaque manipulation.</p>
<h4><strong>Et pour les réfractaires aux jetons JWT ?</strong></h4>
<p>Je te vois venir : « encore un outil qui va me forcer à utiliser des JWT partout… ». Eh bien non ! Better Auth a fait un choix intéressant : <strong>pas de support natif pour les jetons JWT</strong>. Leur approche se concentre sur des <strong>meilleures pratiques</strong>, en évitant les solutions "universelles" parfois trop rigides. Si tu as absolument besoin de JWT, tu pourras l’ajouter via un plugin tiers, mais la philosophie de Better Auth est avant tout de te proposer des solutions adaptées et optimisées pour ton projet.</p>
<h3><strong>Un projet jeune mais prometteur</strong></h3>
<p>Lancé il y a seulement quelques mois, <strong>Better Auth</strong> a déjà conquis de nombreux développeurs. Avec plus de <strong>1,800 stars sur GitHub</strong> et une communauté en pleine effervescence, c’est clairement un projet à suivre de près. Et ne t’inquiète pas, bien qu’il soit encore en <strong>bêta</strong>, il est déjà assez mature pour être intégré dans des projets en production.</p>
<h3><strong>Un exemple d’utilisation</strong></h3>
<p>Bon, c’est bien beau tout ça, mais comment ça marche concrètement ? Voici un exemple basique pour que tu voies à quel point c’est simple de démarrer avec Better Auth.</p>
<pre><code>import { betterAuth } from 'better-auth';

const auth = betterAuth({
  database: {
    provider: 'postgresql',
    url: process.env.DATABASE_URL,  // On récupère l'URL de la base de données depuis les variables d'environnement
  },
  emailAndPassword: {
    enabled: true,  // Authentification par email et mot de passe activée
  },
  plugins: [
    organization(),  // Gestion des organisations
    twoFactor(),     // Authentification à deux facteurs
  ],
});

// Exemple d'utilisation pour gérer un utilisateur :
auth.createUser({
  email: 'user@example.com',
  password: 'securepassword123',
}).then(user =&gt; {
  console.log('Utilisateur créé:', user);
}).catch(err =&gt; {
  console.error('Erreur lors de la création de l\'utilisateur:', err);
});
</code></pre>
<p>Tu vois, avec seulement quelques lignes, tu peux déjà connecter une base de données PostgreSQL, activer l’authentification par email et mot de passe, et ajouter des plugins comme le 2FA ou la gestion des organisations. C’est super rapide à mettre en place !</p>
<h3><strong>Prêt à te lancer ?</strong></h3>
<p>Si tu veux essayer par toi-même, rien de plus simple. En quelques minutes, tu peux mettre en place un système d'authentification qui t'appartient vraiment. Pas besoin de t’appuyer sur des services tiers coûteux ou de perdre du temps sur des configurations complexes. Tu veux voir comment ça marche en vrai ? Une <a href="https://demo.better-auth.com">démo en ligne</a> t’attend, prête à te montrer la puissance de cette bibliothèque.</p>
<p><strong>Pour conclure</strong>, Better Auth, c’est un peu le superhéros discret de l'authentification en TypeScript : complet, agnostique, facile à utiliser et extensible. Que demander de plus ? Allez, va tester tout ça et prépare-toi à dire adieu aux galères d’auth !</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>TypeScript</category>
            <category>authentication</category>
            <category>betterauth</category>
            <enclosure url="https://devbyben.fr/images/blog/better-auth-lauthentification-en-typescript-a-portee-de-main-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Découvre JSrun : L’outil qui va simplifier ta vie de développeur JavaScript]]></title>
            <link>https://devbyben.fr/blog/decouvre-jsrun-loutil-qui-va-simplifier-ta-vie-de-developpeur-javascript</link>
            <guid>https://devbyben.fr/blog/decouvre-jsrun-loutil-qui-va-simplifier-ta-vie-de-developpeur-javascript</guid>
            <pubDate>Sun, 13 Oct 2024 10:15:06 GMT</pubDate>
            <description><![CDATA[Hey ! Aujourd'hui, je suis super excité de te parler d'un petit outil que j'ai récemment développé : JSrun. Si tu galères parfois avec la gestion des modules et des dépendances dans tes projets JavaScript ou TypeScript, cet outil va clairement te cha...]]></description>
            <content:encoded><![CDATA[<p>Hey ! Aujourd'hui, je suis super excité de te parler d'un petit outil que j'ai récemment développé : <strong>JSrun</strong>. Si tu galères parfois avec la gestion des modules et des dépendances dans tes projets JavaScript ou TypeScript, cet outil va clairement te changer la donne. L’idée derrière <strong>JSrun</strong>, c’est de te libérer de tous les tracas techniques : plus de nœuds au cerveau avec les <code>node_modules</code> ou les versions de packages. Toi, tu te concentres sur ton code, et <strong>JSrun</strong> s’occupe du reste.</p>
<h3><strong>Pourquoi j’ai créé JSrun ?</strong></h3>
<p>Tout est parti d’un projet perso où je bossais sur un petit bot. Je voulais pouvoir <strong>exécuter mes scripts rapidement</strong>, mais entre les dépendances Node.js, les versions de modules à jongler, et ces fameux dossiers <code>node_modules</code> qui bouffent de l’espace, c'était la galère. Et là, je me suis dit : <em>« Pourquoi ne pas créer un outil qui gère tout ça pour moi ? »</em> C’est comme ça qu’est né <strong>JSrun</strong> !</p>
<p>Avec <strong>JSrun</strong>, tu peux exécuter des scripts <code>.jsr</code>, <code>.js</code>, <code>.mjs</code> et même <code>.ts</code> sans te prendre la tête. <strong>Plus besoin d'installer manuellement les packages à chaque fois</strong>. Tu lances ton script et si une dépendance manque, <strong>JSrun l'installe automatiquement</strong> pour toi. Tranquille, non ?</p>
<h3><strong>Le format</strong> <code>.jsr</code> : C’est quoi exactement ?</h3>
<p>Le <code>.jsr</code>, c’est une petite touche perso que j’ai ajoutée. Ce n’est pas un nouveau langage ou quoi que ce soit. En fait, <strong>c’est toujours du pur JavaScript ou TypeScript</strong>, mais avec une extension dédiée à <strong>JSrun</strong>. Ça permet simplement de repérer facilement les scripts qui sont destinés à être exécutés avec cet outil. C’est une manière pratique d’organiser tes projets et de rendre tout ça plus propre.</p>
<p>Mais ne t'inquiète pas, <strong>JSrun</strong> fonctionne aussi très bien avec les extensions classiques comme <code>.js</code> ou <code>.ts</code>. Le format <code>.jsr</code> est là pour les adeptes de l’organisation !</p>
<h3><strong>JSrun : Les fonctionnalités qui vont te plaire</strong></h3>
<p>C’est pas juste un lanceur de scripts, c’est un vrai couteau suisse. Voilà ce qu’il peut faire pour toi :</p>
<ul>
<li><p><strong>Gestion automatique des modules</strong> : Fini les <code>npm install</code>. Si un module manque, <strong>JSrun</strong> le télécharge pour toi.</p>
</li>
<li><p><strong>Spécification des versions dans les imports</strong> : Tu peux directement définir la version d’un module dans tes imports, et <strong>JSrun</strong> gère tout.</p>
</li>
<li><p><strong>Mise en cache intelligente</strong> : Les modules sont mis en cache localement pour accélérer les exécutions suivantes.</p>
</li>
<li><p><strong>Journalisation colorée</strong> : Grâce à <code>chalk</code>, tes logs sont non seulement plus lisibles, mais aussi plus stylés !</p>
</li>
<li><p><strong>Gestion des erreurs</strong> : Des messages clairs et détaillés pour déboguer sans prise de tête.</p>
</li>
<li><p><strong>Extensible</strong> : Prêt à évoluer selon tes besoins !</p>
</li>
</ul>
<h3><strong>Installation : Simple et rapide</strong></h3>
<p>Avant de commencer, assure-toi d’avoir Node.js sur ta machine. Si ce n’est pas le cas, <a href="https://nodejs.org/">télécharge-le ici</a>.</p>
<p>Pour installer <strong>JSrun</strong>, une seule commande suffit :</p>
<pre><code>npm install -g jsrun-cli
</code></pre>
<h3><strong>Comment utiliser JSrun ?</strong></h3>
<h4><strong>Lancer un script</strong></h4>
<p>Une fois installé, tu peux exécuter n'importe quel script, où que tu sois sur ton système. Par exemple, si tu as un fichier <code>monscript.jsr</code> :</p>
<pre><code>jsrun monscript.jsr
</code></pre>
<p>Ça prend en charge les extensions <code>.jsr</code>, <code>.js</code>, <code>.mjs</code>, et <code>.ts</code>. Peu importe le format, il gère tout !</p>
<h4><strong>Passer des arguments au script</strong></h4>
<p>Besoin de passer des options à ton script ? Facile avec <strong>JSrun</strong> :</p>
<pre><code>jsrun monscript.jsr --port=4000 --env=production
</code></pre>
<p>Dans ton script, tu peux récupérer ces arguments comme ceci :</p>
<pre><code>const args = process.argv.slice(2);
const port = args.find((arg) =&gt; arg.startsWith("--port="))?.split("=")[1] || 3000;
const env = args.find((arg) =&gt; arg.startsWith("--env="))?.split("=")[1] || "development";

console.log(`Exécution sur le port ${port} en mode ${env}.`);
</code></pre>
<h4><strong>Créer un nouveau script</strong></h4>
<p>Envie de démarrer avec un nouveau script ? Rien de plus simple :</p>
<pre><code>jsrun create monscript.jsr
</code></pre>
<p>Cela te génère un fichier de script prêt à être utilisé avec <strong>JSrun</strong>.</p>
<h4><strong>Simuler l'exécution du script</strong></h4>
<p>Si tu veux vérifier ce que ton script ferait sans réellement l’exécuter, tu peux utiliser l’option <code>--dry-run</code> pour une simulation :</p>
<pre><code>jsrun monscript.jsr --dry-run
</code></pre>
<p>Cela permet de voir ce qu'il se passerait lors de l'exécution, sans toucher aux modules ni exécuter de code.</p>
<h4><strong>Afficher le retour en format JSON</strong></h4>
<p>Besoin de voir les résultats d’exécution en format JSON ? Facile avec l’option <code>--json</code> :</p>
<pre><code>jsrun monscript.jsr --json
</code></pre>
<p>Super pratique pour des retours structurés et facilement intégrables dans des workflows automatisés.</p>
<h4><strong>Nettoyer les packages installés</strong></h4>
<p>Quand ton projet commence à accumuler des modules dont tu n'as plus besoin, un bon nettoyage s’impose. <strong>JSrun</strong> peut s’en charger avec une simple commande :</p>
<pre><code>jsrun --clean
</code></pre>
<h3><strong>Des performances au top, sans efforts</strong></h3>
<p>Un des gros points forts de <strong>JSrun</strong>, c’est sa <strong>mise en cache</strong> des modules. Les modules que tu utilises sont stockés localement dans <code>~/.jsrun/node_modules</code>. Résultat : les exécutions suivantes sont <strong>beaucoup plus rapides</strong>. Et tout ça, sans que tu aies à lever le petit doigt !</p>
<h3><strong>Exemples et contributions</strong></h3>
<p>Si tu veux voir des exemples de scripts <code>.jsr</code>, va faire un tour dans le dossier <code>/examples</code> du projet sur <a href="https://github.com/benoitpetit/jsrun-cli">GitHub</a>. J’ai mis quelques exemples sympas pour t’inspirer.</p>
<p>Et si tu as des idées d’amélioration, <strong>n’hésite pas à contribuer</strong> ! Forke le dépôt, fais tes modifs, et soumets un pull request. Toutes les idées sont les bienvenues.</p>
<h3><strong>Conclusion</strong></h3>
<p>Avec <strong>JSrun</strong>, mon but était de simplifier au maximum l’exécution de scripts JavaScript et TypeScript, sans avoir à se battre avec les dépendances ou les versions de modules. Que tu bosses sur un projet rapide ou quelque chose de plus complexe, <strong>JSrun</strong> te permet de <strong>te concentrer sur le code</strong>, en laissant de côté les aspects techniques.</p>
<p>Télécharge-le dès maintenant sur <a href="https://www.npmjs.com/package/jsrun-cli">npm</a> et lance-toi !</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>JSrun</category>
            <category>JavaScript</category>
            <category>Developer</category>
            <enclosure url="https://devbyben.fr/images/blog/decouvre-jsrun-loutil-qui-va-simplifier-ta-vie-de-developpeur-javascript-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Découvre Check My Logs (CML) ton outil de gestion de logs en ligne de commande]]></title>
            <link>https://devbyben.fr/blog/decouvre-check-my-logs-cml-ton-outil-de-gestion-de-logs-en-ligne-de-commande--deleted</link>
            <guid>https://devbyben.fr/blog/decouvre-check-my-logs-cml-ton-outil-de-gestion-de-logs-en-ligne-de-commande--deleted</guid>
            <pubDate>Mon, 07 Oct 2024 22:24:40 GMT</pubDate>
            <description><![CDATA[Si tu galères avec tes fichiers de logs, j’ai la solution : Check My Logs (ou CML pour les intimes) C’est un outil en ligne de commande que j’ai développé pour te simplifier la gestion de tes logs. Que tu sois dev, sysadmin, ou juste quelqu’un qui do...]]></description>
            <content:encoded><![CDATA[<p>Si tu galères avec tes fichiers de logs, j’ai la solution : Check My Logs (ou CML pour les intimes) C’est un outil en ligne de commande que j’ai développé pour te simplifier la gestion de tes logs. Que tu sois dev, sysadmin, ou juste quelqu’un qui doit jongler avec des fichiers de logs, <strong>CML</strong> est là pour t’aider à analyser tout ça facilement et efficacement.</p>
<h3>Qu’est-ce que fait CML exactement ?</h3>
<p>Imagine un couteau suisse pour tes fichiers de logs : <strong>CML</strong> te permet de <strong>lire</strong>, <strong>filtrer</strong>, <strong>exporter</strong>, et même <strong>suivre en temps réel</strong> les fichiers de logs, directement depuis ton terminal. Tu navigues dans tes logs avec des commandes simples, tu peux filtrer par niveau (INFO, WARNING, ERROR), rechercher des termes spécifiques, et exporter le tout pour un traitement ultérieur. Plus besoin de fouiller dans des tonnes de lignes inutiles, tu récupères juste ce qui t’intéresse.</p>
<h3>Quelques fonctionnalités clés :</h3>
<ul>
<li><p><strong>Pagination</strong> : Lis tes logs : page par page avec une taille que tu choisis.</p>
</li>
<li><p><strong>Filtrage avancé</strong> : Recherche par niveau de logs (INFO, WARNING, ERROR) et par mot-clé.</p>
</li>
<li><p><strong>Mode live</strong> : Suis les nouveaux logs qui arrivent en temps réel, comme un pro avec <code>tail -f</code> mais en mieux, sans te prendre la tête avec des commandes interminables.</p>
</li>
<li><p><strong>Export</strong> : Tu peux exporter directement les logs filtrés dans un fichier. c’est pratique !</p>
</li>
<li><p><strong>Interface interactive</strong> : Utilise ton clavier pour naviguer et chercher dans les logs, avec : Haut, Bas, etc..</p>
</li>
</ul>
<h2>Installation :</h2>
<p>Télécharge et installe <strong>CML</strong> comme un chef avec <code>wget</code> et <code>tar</code> :</p>
<pre><code>
wget -O /tmp/cml.tar.gz https://github.com/benoitpetit/cml/releases/download/v1.2.0/cml-linux-amd64.tar.gz
sudo tar -xzvf /tmp/cml.tar.gz -C /usr/local/bin/
sudo chmod +x /usr/local/bin/cml
</code></pre>
<p>Et voilà, <strong>CML</strong> est installé. Vérifie avec :</p>
<pre><code>cml --help
</code></pre>
<h3>Comment utiliser CML ?</h3>
<p>La commande de base est simple :</p>
<pre><code>cml &lt;chemin_fichier_logs&gt; [options]
</code></pre>
<p>Voici les options disponibles :</p>
<ul>
<li><p><code>--filter &lt;niveau&gt;</code> : Filtre les logs par niveau (INFO, ERROR…)</p>
</li>
<li><p><code>--search &lt;terme&gt;</code> : Cherche un terme dans les logs.</p>
</li>
<li><p><code>--pagesize &lt;taille&gt;</code> : Définit le nombre de logs par page.</p>
</li>
<li><p><code>--export &lt;fichier&gt;</code> : Exporte les logs filtrés dans un fichier.</p>
</li>
<li><p><code>--live</code> : Active le mode temps réel pour suivre les logs au fur et à mesure.</p>
</li>
</ul>
<h3>Exemples d’utilisation</h3>
<ol>
<li><p><strong>Filtrage et export</strong> : Filtrer les erreurs et chercher "timeout", puis exporter dans un fichier.</p>
<pre><code>cml logs.txt --filter ERROR --search "timeout" --export erreurs_timeout.txt
</code></pre>
</li>
<li><p><strong>Suivi en temps réel</strong> : Suivre les logs en temps réel avec une pagination de 20 lignes :</p>
<pre><code>cml logs.txt --live --pagesize 20
</code></pre>
</li>
</ol>
<h3>Pourquoi tu devrais essayer ?</h3>
<p><strong>CML</strong>, c’est un peu comme <code>grep</code>, <code>tail</code>, et <code>less</code> réunis dans un outil conçu pour rendre tes fichiers de logs plus faciles à gérer. Plus besoin de multiplier les commandes ou de galérer avec des sorties interminables. Que tu veuilles juste checker un log en direct ou extraire les erreurs d’un fichier énorme, <strong>CML</strong> t’offre une expérience optimisée, fluide et surtout ultrarapide.</p>
<p><strong>CML</strong> n’est pas parfait, on va dire qui est en <strong>beta</strong>, il peut y avoir des <strong>erreurs</strong>, mais si tu veux l’essayer, va faire un tour sur <a href="https://github.com/benoitpetit/cml">mon GitHub</a>. Fais-moi savoir ce que tu en penses, et n’hésite pas à contribuer si le cœur t’en dit !</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>CheckMyLogs</category>
            <category>cli</category>
            <category>opensource</category>
            <enclosure url="https://devbyben.fr/images/blog/decouvre-check-my-logs-cml-ton-outil-de-gestion-de-logs-en-ligne-de-commande--deleted-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Deploy your own database with Supabase and Docker]]></title>
            <link>https://devbyben.fr/blog/deploy-your-own-database-with-supabase-and-docker</link>
            <guid>https://devbyben.fr/blog/deploy-your-own-database-with-supabase-and-docker</guid>
            <pubDate>Fri, 24 Nov 2023 23:00:00 GMT</pubDate>
            <description><![CDATA[If you’re looking for a powerful and user-friendly NoSQL database solution, Supabase stands out as an excellent option. As an open-source alternative to Firebase, Supabase accelerates the development of web and mobile applications while leveraging th...]]></description>
            <content:encoded><![CDATA[<p>If you’re looking for a powerful and user-friendly NoSQL database solution, <strong>Supabase</strong> stands out as an excellent option. As an open-source alternative to Firebase, Supabase accelerates the development of web and mobile applications while leveraging the flexibility and strength of a PostgreSQL database.</p>
<h2>Prerequisites</h2>
<ul>
<li>A computer with <strong>Docker</strong> and <strong>Docker Compose</strong> installed.</li>
<li>A <strong>GitHub account</strong> to access configuration files.</li>
</ul>
<h2>Step 1: Retrieve Configuration Files</h2>
<p>Begin by downloading Supabase's configuration files from GitHub. Navigate to the <a href="https://github.com/supabase/supabase">Supabase GitHub repository</a> and obtain the configuration files. You can either download them as a ZIP file or clone the repository using the command line.</p>
<h3>Clone the Repository</h3>
<p>To clone the repository, execute the following command:</p>
<pre><code>git clone https://github.com/supabase/supabase.git
</code></pre>
<h3>Navigate to the Configuration Directory</h3>
<p>Change your working directory to the Docker configuration files:</p>
<pre><code>cd supabase/docker/
</code></pre>
<h3>Copy the Example Environment File</h3>
<p>Create a <code>.env</code> file based on the example provided:</p>
<pre><code>cp .env.example .env
</code></pre>
<h2>Step 2: Modify the <code>.env</code> Configuration File</h2>
<p>Before launching Supabase, you need to configure essential parameters. Open the <code>.env</code> file for editing:</p>
<pre><code>nano .env
</code></pre>
<p>Adjust the following lines accordingly:</p>
<ul>
<li><strong>POSTGRES_USER</strong>: Change "supabase" to your preferred database username.</li>
<li><strong>POSTGRES_PASSWORD</strong>: Change "supabase" to your chosen database password.</li>
<li><strong>PGDATA</strong>: Update the path (e.g., "/var/lib/postgresql/data/pgdata") to your desired location for storing database data.</li>
</ul>
<h2>Step 3: Launch Supabase with Docker</h2>
<p>Once your configurations are set, you can start Supabase using Docker. In the terminal, while still in the <code>supabase/docker/</code> directory, run:</p>
<pre><code>docker-compose up -d
</code></pre>
<p>This command runs Supabase in daemon mode, allowing it to operate in the background while displaying startup messages in the terminal.</p>
<h2>Step 4: Configure Supabase</h2>
<p>After launching Supabase, access the admin interface by navigating to <code>http://localhost:3000</code> in your web browser. Log in with the username and password specified in your <code>.env</code> file. Once logged in, you can create tables, add data, and configure access permissions. Additionally, utilize the REST API to interact with your database from both front-end and back-end applications.</p>
<h2>Conclusion</h2>
<p>Setting up a self-hosted Supabase instance using Docker is a straightforward process that requires minimal configuration. This method allows you to deploy Supabase on your server or private cloud, giving you greater control over your data and performance. Explore Supabase’s advanced features to fully leverage its capabilities and enhance your development experience.</p>
<p>If you found this content helpful, consider supporting the creator on <a href="https://liberapay.com/devbyben/donate">Liberapay</a> or <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>supabase</category>
            <category>Docker</category>
            <category>SelfHosting</category>
            <enclosure url="https://devbyben.fr/images/blog/deploy-your-own-database-with-supabase-and-docker-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Ljdhar : Votre passerelle vers le Journal du Hacker]]></title>
            <link>https://devbyben.fr/blog/ljdhar-votre-passerelle-vers-le-journal-du-hacker</link>
            <guid>https://devbyben.fr/blog/ljdhar-votre-passerelle-vers-le-journal-du-hacker</guid>
            <pubDate>Sun, 12 Nov 2023 23:00:00 GMT</pubDate>
            <description><![CDATA[Salut à tous ! 👋 J'espère que vous allez bien. Aujourd'hui, je suis ravi de partager avec vous mon petit projet personnel : ljdhar, un package NPM qui vous permet d'accéder facilement aux derniers articles du Journal du Hacker.
Qu'est-ce que ljdhar ...]]></description>
            <content:encoded><![CDATA[<p>Salut à tous ! 👋 J'espère que vous allez bien. Aujourd'hui, je suis ravi de partager avec vous mon petit projet personnel : <strong>ljdhar</strong>, un package NPM qui vous permet d'accéder facilement aux derniers articles du Journal du Hacker.</p>
<h2>Qu'est-ce que ljdhar ?</h2>
<p>Ljdhar est un outil conçu pour les fans du Journal du Hacker, le site communautaire qui référence les meilleurs contenus francophones sur l'informatique et le numérique. Ce package NPM utilise Puppeteer pour récupérer les données du Journal du Hacker et vous les renvoyer sous forme d'objets JavaScript, prêts à être intégrés dans vos projets.</p>
<p>Avec ljdhar, vous pouvez :</p>
<ul>
<li><p>Récupérer les derniers articles</p>
</li>
<li><p>Les trier par score</p>
</li>
<li><p>Les rechercher par tag ou par titre</p>
</li>
</ul>
<h2>Fonctionnalités</h2>
<p>Ljdhar offre plusieurs fonctions pour manipuler les articles du Journal du Hacker :</p>
<ol>
<li><p><code>getPostToLJDH(numStories: number)</code>: Récupère les derniers articles.</p>
</li>
<li><p><code>sortedByScore(stories: Story[])</code>: Trie les articles par score.</p>
</li>
<li><p><code>searchArticlesByTag(tag: string, numStories: number)</code>: Recherche des articles par tag.</p>
</li>
<li><p><code>searchArticles(search: string, numStories: number)</code>: Recherche des articles par titre.</p>
</li>
</ol>
<p>Chaque fonction renvoie un tableau d'objets <code>Story</code>, contenant les détails de chaque article (titre, URL, score, tags, nombre de commentaires, nom d'utilisateur de l'auteur).</p>
<h2>Installation</h2>
<p>Pour installer ljdhar, exécutez simplement :</p>
<pre><code>npm install ljdhar
</code></pre>
<h2>Utilisation</h2>
<p>Voici quelques exemples d'utilisation de ljdhar :</p>
<pre><code>import { getPostToLJDH, sortedByScore, searchArticlesByTag, searchArticles } from 'ljdhar';

// Obtenir les 10 derniers articles
getPostToLJDH(10)
  .then(stories =&gt; {
    console.log(stories);
  }).catch(err =&gt; {
    console.log(err)
  });

// Obtenir les 10 derniers articles et les trier par score
getPostToLJDH(10)
  .then(stories =&gt; {
    const sortedStories = sortedByScore(stories);
    console.log(sortedStories);
  }).catch(err =&gt; {
    console.log(err)
  });

// Rechercher des articles avec le tag 'javascript'
searchArticlesByTag('javascript', 10)
  .then(stories =&gt; {
    console.log(stories)
  }).catch(err =&gt; {
    console.log(err)
  });

// Rechercher des articles contenant 'hacker' dans le titre
searchArticles('hacker', 10)
  .then(stories =&gt; {
    console.log(stories)
  }).catch(err =&gt; {
    console.log(err)
  });
</code></pre>
<h2>Contributions et feedback</h2>
<p>Ljdhar a été initialement conçu pour un usage personnel, mais je suis ouvert aux suggestions et aux idées d'amélioration. N'hésitez pas à me contacter si vous avez des idées !</p>
<h2>Plus d'informations</h2>
<ul>
<li><p>NPM : <a href="https://www.npmjs.com/package/ljdhar">https://www.npmjs.com/package/ljdhar</a></p>
</li>
<li><p>Github : <a href="https://www.npmjs.com/package/ljdhar">https://www.npmjs.com/package/ljdhar</a></p>
</li>
</ul>
<p>Merci de votre intérêt pour ljdhar ! J'espère que cet outil vous sera utile dans vos projets. Happy coding ! 🚀</p>
<h2>Soutien</h2>
<p>Si Ljdhar vous a facilité la vie, pensez à soutenir son créateur sur <a href="https://liberapay.com/devbyben/donate">Liberapay</a> ou <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>lejournalduhacker</category>
            <category>ljdhar </category>
            <category>npm</category>
            <category>articles</category>
            <enclosure url="https://devbyben.fr/images/blog/ljdhar-votre-passerelle-vers-le-journal-du-hacker-cover.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Bun : La star montante du monde JavaScript]]></title>
            <link>https://devbyben.fr/blog/bun-la-star-montante-du-monde-javascript</link>
            <guid>https://devbyben.fr/blog/bun-la-star-montante-du-monde-javascript</guid>
            <pubDate>Wed, 08 Nov 2023 23:00:00 GMT</pubDate>
            <description><![CDATA[L'année 2022 a vu l'arrivée en force de Bun, un tout nouveau runtime JS qui secoue l'écosystème. Porté par l'ingéniosité de Jarred Sumner, le cerveau derrière Deno, Bun se positionne comme le futur remplaçant de Node offrant des performances de haut ...]]></description>
            <content:encoded><![CDATA[<p>L'année 2022 a vu l'arrivée en force de Bun, un tout nouveau <a href="https://bun.sh/docs#what-is-a-runtime">runtime</a> JS qui secoue l'écosystème. Porté par l'ingéniosité de <a href="https://github.com/Jarred-Sumner">Jarred Sumner</a>, le cerveau derrière <a href="https://deno.com/">Deno</a>, Bun se positionne comme le futur remplaçant de Node offrant des performances de haut vol et une flexibilité sans limites</p>
<p>Là où Bun frappe fort, c'est avec ses performances étonnantes, dépassant largement celles de Node Cela s'explique en partie par l'utilisation du puissant moteur <a href="https://developer.apple.com/documentation/javascriptcore">JavaScriptCore</a>, déjà utilisé dans Safari, mais optimisé de ouf  par Bun grâce à des ajouts en <a href="https://ziglang.org/">Zig</a>.</p>
<p><img src="/images/blog/bun-la-star-montante-du-monde-javascript-image-1.jpg" alt="screenshoot performance" /></p>
<p>Les tests ont parlé : Bun est en moyenne 2 voir 3 fois plus rapide que Node pour les applications simples, et les avantages se multiplient pour les applications complexes, à voir dans le temps.</p>
<p>Bun se démarque également par sa flexibilité. Conçu à partir de zéro, il a la capacité d'adopter de nouvelles fonctionnalités et API au fil du temps. Par exemple, il prend en charge les modules TypeScript natifs pour simplifier le développement, et s'entend très bien avec les modules <a href="https://webassembly.org/">WebAssembly</a>, ouvrant la porte à des applications Web à la pointe de la technologie.</p>
<p>L'installation et l'utilisation de Bun sont un jeu d'enfant. Vous téléchargez simplement le binaire correspondant à votre système d'exploitation et lancez le tout. De plus, il partage le même système de modules que Node, facilitant la transition des applications existantes.</p>
<p>Pour installer Bun, il vous suffit d'exécuter la commande suivante, et rien de plus :</p>
<pre><code>curl -fsSL https://bun.sh/install | bash
</code></pre>
<p>Plus d'informations ici : <a href="https://bun.sh/">https://bun.sh/</a></p>
<p>Lorsque vous souhaitez créer un projet, vous avez deux options : vous pouvez utiliser la commande <code>create</code> ou <code>init</code></p>
<pre><code>bun create &lt;template&gt; [&lt;destination&gt;] 
</code></pre>
<p>Plus d'informations ici : <a href="https://bun.sh/docs/cli/bun-create">https://bun.sh/docs/cli/bun-create</a></p>
<p>Alternativement, vous pouvez initialiser un projet dans un dossier en utilisant la commande init :</p>
<pre><code>bun init
</code></pre>
<p>Plus d'informations ici : <a href="https://bun.sh/docs/cli/init">https://bun.sh/docs/cli/init</a></p>
<p>Après avoir configuré votre projet, vous pouvez utiliser le gestionnaire de paquets Bun pour installer des packages, par exemple, pour installer le package NPM sqlite3, exécutez la commande suivante :</p>
<pre><code>bun add sqlite3
</code></pre>
<p>Plus d'informations ici : <a href="https://bun.sh/docs/cli/add">https://bun.sh/docs/cli/add</a></p>
<p>Pour exécuter votre projet avec Bun, utilisez la commande suivante en spécifiant le nom de votre fichier de départ :</p>
<pre><code>bun run index.ts
</code></pre>
<p>Plus d'informations ici : <a href="https://bun.sh/docs/cli/run">https://bun.sh/docs/cli/run</a>
ou en mode <code>--watch</code></p>
<pre><code>bun run --watch index.ts
</code></pre>
<p>Plus d'informations ici : <a href="https://bun.sh/docs/runtime/hot">https://bun.sh/docs/runtime/hot</a></p>
<blockquote>
<p>Bien entendu, Bun propose de nombreuses autres fonctionnalités, que vous pouvez découvrir dans la documentation complète : <a href="https://bun.sh/docs/">https://bun.sh/docs/</a> <code>une serie sur bun peu etre</code></p>
</blockquote>
<p><img src="/images/blog/bun-la-star-montante-du-monde-javascript-image-2.jpg" alt="screenshoot fonctionnalités" /></p>
<p>Bun est en train de secouer le monde JavaScript avec ces performances exceptionnelles et sa flexibilité sans limites ! Même s'il est encore jeune, je pense que c'est déjà un choix solide pour les développeurs JS. en tout qu'à, ça l'est pour moi !</p>
<blockquote>
<p>De mon côté, j'utilise Bun depuis plusieurs mois, et je dois dire que c'est le pied ! Pas de problèmes majeurs à signaler, tout roule. J'apprécie particulièrement la possibilité d'utiliser à la fois les importations ES6 et les require CommonJS dans un même fichier, une fonctionnalité super pratique.</p>
</blockquote>
<blockquote>
<p>Un autre point qui m'a tapé dans l'œil, c'est la facilité d'intégration d'un fichier .env, sans prise de tête pour installer des dépendances supplémentaires. De plus, le watcher est inclus par défaut avec le drapeau <code>--watch</code> simplifiant grandement le processus de développement.</p>
</blockquote>
<p>Et je ne peux pas passer sous silence les performances de Bun, surtout grâce au système de gestion des paquets, qui carbure à la vitesse de la lumière.</p>
<p><img src="/images/blog/bun-la-star-montante-du-monde-javascript-image-3.jpg" alt="screenshoot bun add" /></p>
<p>Bref, je prévois de continuer à explorer Bun, et je garde un œil attentif sur l'évolution du projet. C'est la solution idéale pour mes besoins, et je suis sûr qu'elle a un bel avenir. Si vous cherchez un runntime Javascript qui envoie du lourd, Bun est le choix à faire. c'est par ici : <a href="https://bun.sh/">https://bun.sh/</a></p>
<h2>Soutien</h2>
<p>Si cet article vous a plu, pensez à soutenir son créateur sur <a href="https://liberapay.com/devbyben/donate">Liberapay</a> ou <a href="https://buymeacoffee.com/devbyben">Buy Me a Coffee</a>.</p>
]]></content:encoded>
            <author>contact@devbyben.fr (DevByBen)</author>
            <category>bunjs</category>
            <category>JavaScript</category>
            <category>runtime</category>
            <enclosure url="https://devbyben.fr/images/blog/bun-la-star-montante-du-monde-javascript-cover.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>