Developer builds a Claude Code mascot that stomps while the assistant waits for your answer
A long Claude Code task often ends with the agent waiting ten minutes for you to answer "can I run this command?", while the Windows notification flashed for five seconds and vanished. The author built an open-source Electron mascot that peeks out from a corner of the screen and, if ignored, turns red and stomps along the taskbar. Its signal comes from Claude Code hooks and from the Windows notification database.
AI-processed from Habr AI; edited by Hamidun News
A familiar situation: you hand Claude Code a big task, switch to another window, and a quarter of an hour later discover that the agent stopped long ago at the question "can I run this command?" Windows did show a system notification, of course, but it sat in a corner of the screen for five seconds while you were looking the other way. The author of a write-up on Habr solved this problem radically: he built a mascot you cannot miss.
The mascot is a small orange figure. At first it peeks out from the bottom-right corner. If you ignore it, it comes out fully, turns red and stomps along the taskbar until you return. The wrapper is amusing, but the most useful part is the engineering: how to reliably detect that the assistant is waiting for something.
How to catch the waiting moment
In the terminal version of Claude Code, hooks make this simple. In ~/.claude/settings.json you can define a command that runs on a given event, and a JSON payload with the details arrives on its stdin. The Notification event fits this task. The command pipes stdin via curl to the mascot's local HTTP server (127.0.0.1:47821). The trailing || exit 0 makes the hook exit silently with zero when the mascot isn't running, so Claude Code doesn't show an error on every event. The server also rejects requests that carry an Origin header, so a random web page can't poke the local port.
The Claude desktop app (the Code tab) is harder: when it asks for permission or poses a question, it does not send the Notification event. Everything worked in the terminal, but on desktop the mascot stayed silent. The author had to subscribe to PermissionRequest as well, and to PreToolUse with the matcher AskUserQuestion|ExitPlanMode, to catch questions and plan approval. Stop, which fires after every response, is optional. The mascot registers the hooks itself: it first backs up settings.json (the five most recent copies are kept) and leaves other entries untouched.
There is a catch: sessions that are already open may not pick up new hooks until they are restarted. So a second signal source was added: the Windows notification database. The system writes every notification banner to an SQLite file, wpndatabase.db. Once a second the mascot opens it read-only and looks for records from an app matching Claude_*!Claude. Node's built-in node:sqlite module removes the need for native dependencies, and the method works even with a Claude that is already running, without injecting anything into it.
A window that is visible but doesn't get in the way
The second task is drawing the overlay. It must be transparent, sit above all windows (including fullscreen ones), stay out of the taskbar, not steal focus and let clicks pass through. In Electron this is almost entirely a matter of BrowserWindow settings: frame: false, transparent: true, skipTaskbar, alwaysOnTop, focusable: false.
The interesting trick is setIgnoreMouseEvents(true, { forward: true }). The window becomes transparent to clicks, but the page still receives mouse-move events. When the cursor enters the mascot (mouseenter), clicks are switched back on; when the cursor leaves, they are switched off. There is no need to compute the window's shape by hand.
To detect whether the Claude window is active and to bring it back to the foreground, the author uses koffi, which calls user32.dll functions without node-gyp. The active window is polled every 300 ms, and the load is negligible.
Small details worth borrowing
If the mascot and the standard Windows banner appear at the same time, you get a duplicate. For this there is an option that disables banners for Claude only, via ShowBanner = 0 in the registry. Entries in the notification center remain, so the database keeps filling up and the mascot still sees them. The previous value of the setting is saved and restored when the option is turned off, on exit, at the end of the session, and even after a crash, on the next start.
Among the build pitfalls mentioned in the write-up: electron-builder uploads files in parallel and sometimes creates duplicate releases, so in GitHub Actions the release is first created with gh release create and only then populated. In the portable version, process.execPath points to a temporary folder, so for autostart the path is taken from the PORTABLE_EXECUTABLE_FILE variable.
What to do with this
The project is free, MIT-licensed, and Windows-only. If you don't plan to install the mascot, the pattern is still useful: a Notification hook plus a local HTTP receiver is a minimal way to connect Claude Code to any external signal, whether a sound, a phone or a smart lamp. The main limitation: the solution is tied to Windows and to the internal format of the notification database, which Microsoft does not document as an API. For desktop Claude this source serves as a fallback, and it may break with a system update. For the terminal version, hooks are enough.
- Nov 12, 2026Agent Builds a 4K Blender Video and Renders It on 10 GPUs in 51 Minutes for $5.75
- Nov 12, 2026Anthropic Releases Claude Fable 5.2: Twice the Price of Opus 5.5, but Cheaper Than 5.1
- Nov 12, 2026Anthropic ported Claude to AMD chips in three days using its Mythos model
- Nov 12, 2026Developer connects AI to a 1994 Jeep's diagnostics with a $15 kit
Key Questions Answered
How to catch the waiting moment?
In the terminal version of Claude Code, hooks make this simple. In ~/.claude/settings.json you can define a command that runs on a given event, and a JSON payload with the details arrives on its stdin. The Notification event fits this task. The command pipes stdin via curl to the mascot's local HTTP server (127.0.0.1:47821). The trailing || exit 0 makes the hook exit silently with zero when the mascot isn't running, so Claude Code doesn't show an error on every event.
What are the key details on A window that is visible but doesn't get in the way?
The second task is drawing the overlay. It must be transparent, sit above all windows (including fullscreen ones), stay out of the taskbar, not steal focus and let clicks pass through. In Electron this is almost entirely a matter of BrowserWindow settings: frame: false, transparent: true, skipTaskbar, alwaysOnTop, focusable: false. The interesting trick is setIgnoreMouseEvents(true, { forward: true }). The window becomes transparent to clicks, but the page still receives mouse-move events.
What are the key details on Small details worth borrowing?
If the mascot and the standard Windows banner appear at the same time, you get a duplicate. For this there is an option that disables banners for Claude only, via ShowBanner = 0 in the registry. Entries in the notification center remain, so the database keeps filling up and the mascot still sees them. The previous value of the setting is saved and restored when the option is turned off, on exit, at the end of the session, and even after a crash, on the next start.
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.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.