Live 18/11 · Cohorte 318 nov à 19h00 MSK — atelier pratique gratuit sur les agents IA · La Cohorte 3 démarre le 23/11Atelier 18/11 →Cohorte 3 (23/11)
SortieAnalyse · Sur le radarHabr AI→ original

Un développeur crée une mascotte pour Claude Code qui tape du pied tant que l'assistant attend une réponse

Il arrive souvent qu'une longue tâche dans Claude Code se termine ainsi : l'agent attend depuis dix minutes la réponse à « puis-je exécuter cette commande ? », alors que la notification Windows n'a clignoté que cinq secondes avant de disparaître. L'auteur a créé une mascotte open source en Electron : elle jette un coup d'œil depuis un coin de l'écran puis, si on l'ignore, devient rouge et tape du pied sur la barre des tâches. Le signal provient des hooks de Claude Code et de la base de notifications de Windows.

Traité par IA depuis Habr AI ; édité par Hamidun News
Un développeur crée une mascotte pour Claude Code qui tape du pied tant que l'assistant attend une réponse
Source : Habr AI. Collage: Hamidun News.
Écouter l'article
Fiche synthèse et chiffres clés
ParamètreDonnées
Source primaireHabr AI ↗
Rédacteur en chef
Chiffre clé #1Le hook Notification dans settings.json envoie l'événement vers un port HTTP local
Chiffre clé #2Pour l'application de bureau, il faut PermissionRequest et PreToolUse, plus la lecture de wpndatabase.db
Code sous licence MIT ; stackElectron, node:sqlite et koffi, sans node-gyp

Une situation bien connue : vous confiez une grosse tâche à Claude Code, vous passez à la fenêtre voisine, et un quart d'heure plus tard vous découvrez que l'agent s'est arrêté depuis longtemps sur la question « puis-je exécuter cette commande ? ». La notification système de Windows a bien existé, mais elle n'est restée que cinq secondes dans un coin de l'écran, pendant que vous regardiez ailleurs. L'auteur d'un article sur Habr a réglé le problème de façon radicale : il a créé une mascotte impossible à ne pas remarquer.

La mascotte est un petit bonhomme orange. Il commence par jeter un coup d'œil depuis le coin inférieur droit. Si on l'ignore, il sort entièrement, devient rouge et tape du pied sur la barre des tâches jusqu'à votre retour. L'emballage est amusant, mais le plus utile ici reste la partie ingénierie : comment savoir de façon fiable que l'assistant attend quelque chose.

Comment saisir le moment de l'attente

Dans la version terminal de Claude Code, tout est simple grâce aux hooks. Dans ~/.claude/settings.json, on peut décrire une commande qui se lancera sur l'événement voulu, et un JSON détaillé lui parviendra sur stdin. L'événement Notification convient pour cette tâche. La commande envoie stdin via curl au serveur HTTP local de la mascotte (127.0.0.1:47821). La fin || exit 0 sert à ce que, si la mascotte n'est pas lancée, le hook se termine silencieusement avec le code zéro et que Claude Code n'affiche pas d'erreur à chaque événement. Le serveur rejette en outre les requêtes portant un en-tête Origin, afin qu'une page web quelconque ne puisse pas solliciter le port local.

Avec l'application de bureau Claude (onglet Code), c'est plus compliqué : lorsqu'elle demande une autorisation ou pose une question, l'événement Notification n'est pas envoyé. Dans le terminal, tout fonctionnait ; sur le bureau, la mascotte restait muette. Il a fallu s'abonner aussi à PermissionRequest et à PreToolUse avec le matcher AskUserQuestion|ExitPlanMode, afin de capter les questions et la validation du plan. En option, il existe Stop, qui se déclenche après chaque réponse. La mascotte inscrit elle-même les hooks, après avoir sauvegardé settings.json (les cinq dernières copies sont conservées) et sans toucher aux entrées des autres.

Il y a une nuance : les sessions déjà ouvertes peuvent ne pas prendre en compte les nouveaux hooks avant un redémarrage. C'est pourquoi une seconde source de signal a été ajoutée : la base de notifications de Windows. Le système écrit chaque bandeau dans un fichier SQLite, wpndatabase.db. Une fois par seconde, la mascotte l'ouvre en lecture et cherche les entrées de l'application de la forme Claude_*!Claude. Le module node:sqlite intégré à Node évite les dépendances natives, et cette méthode fonctionne même avec un Claude déjà lancé, sans rien y injecter.

Une fenêtre visible mais non gênante

La seconde tâche consiste à dessiner l'overlay. Il doit être transparent, rester au-dessus de toutes les fenêtres (y compris plein écran), ne pas apparaître dans la barre des tâches, ne pas voler le focus et laisser passer les clics. Dans Electron, cela se résume presque entièrement aux paramètres de BrowserWindow : frame: false, transparent: true, skipTaskbar, alwaysOnTop, focusable: false.

Une astuce intéressante : setIgnoreMouseEvents(true, { forward: true }). La fenêtre devient transparente aux clics, mais la page reçoit tout de même les événements de mouvement de la souris. Quand le curseur entre sur la mascotte (mouseenter), les clics sont réactivés ; quand il s'en va, ils sont désactivés. Inutile de calculer la forme de la fenêtre à la main.

Pour déterminer si la fenêtre de Claude est active et la ramener au premier plan, l'auteur utilise koffi : il appelle les fonctions de user32.dll sans node-gyp. La fenêtre active est interrogée toutes les 300 ms, et la charge est imperceptible.

Les petits détails à emprunter

Si la mascotte et le bandeau standard de Windows apparaissent en même temps, on obtient un doublon. Pour cela, une option désactive les bannières uniquement pour Claude via ShowBanner = 0 dans le registre. Les entrées du centre de notifications restent, la base continue donc d'être alimentée et la mascotte les voit. L'ancienne valeur du paramètre est conservée puis restaurée à la désactivation de l'option, à la fermeture, à la fin de session et même après un plantage, au démarrage suivant.

Parmi les écueils de build évoqués dans l'article : electron-builder envoie les fichiers en parallèle et crée parfois des doublons de release ; dans GitHub Actions, la release est donc d'abord créée via gh release create, puis alimentée. Dans la version portable, process.execPath pointe vers un dossier temporaire ; pour le démarrage automatique, le chemin est donc pris dans la variable PORTABLE_EXECUTABLE_FILE.

Que faire de tout cela

Le projet est gratuit, sous licence MIT, pour Windows. Même si vous ne comptez pas installer la mascotte, le pattern reste utile : le hook Notification associé à un récepteur HTTP local est le moyen le plus simple de relier Claude Code à n'importe quel signal externe, qu'il s'agisse d'un son, d'un téléphone ou d'une ampoule connectée. La principale limite : la solution dépend de Windows et du format interne de la base de notifications, que Microsoft ne documente pas comme une API. Pour Claude sur bureau, cette source sert de secours et peut casser avec une mise à jour du système. Pour la version terminal, les hooks suffisent.

Dossier

Questions clés sur cet article

Comment saisir le moment de l'attente?

Dans la version terminal de Claude Code, tout est simple grâce aux hooks. Dans ~/.claude/settings.json, on peut décrire une commande qui se lancera sur l'événement voulu, et un JSON détaillé lui parviendra sur stdin. L'événement Notification convient pour cette tâche. La commande envoie stdin via curl au serveur HTTP local de la mascotte (127.0.0.1:47821).

Que sait-on sur Une fenêtre visible mais non gênante ?

La seconde tâche consiste à dessiner l'overlay. Il doit être transparent, rester au-dessus de toutes les fenêtres (y compris plein écran), ne pas apparaître dans la barre des tâches, ne pas voler le focus et laisser passer les clics. Dans Electron, cela se résume presque entièrement aux paramètres de BrowserWindow : frame: false, transparent: true, skipTaskbar, alwaysOnTop, focusable: false. Une astuce intéressante : setIgnoreMouseEvents(true, { forward: true }).

Que sait-on sur Les petits détails à emprunter ?

Si la mascotte et le bandeau standard de Windows apparaissent en même temps, on obtient un doublon. Pour cela, une option désactive les bannières uniquement pour Claude via ShowBanner = 0 dans le registre. Les entrées du centre de notifications restent, la base continue donc d'être alimentée et la mascotte les voit. L'ancienne valeur du paramètre est conservée puis restaurée à la désactivation de l'option, à la fermeture, à la fin de session et même après un plantage, au démarrage suivant.

ZK
Zhemal Khamidun — CPO d'Alpina Digital, product manager d'AlpinaGPT. Conçoit des produits IA depuis 2019. Hamidun News est un projet personnel devenu un agrégateur en production avec plus de 6 000 lecteurs.
✦ Hands-On AI Engineering · Hamidun Academy

Build & Ship Production AI Agents Without Boilerplate Code

Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.

Start 72h Free Trial →Vibe-Coding Intensive
Qu'en pensez-vous ?
Chargement des commentaires…