Live Nov 18 · Cohort 3Nov 18, 19:00 MSK — free hands-on AI agents live workshop · Live Cohort 3 starts Nov 23Join Nov 18 Live →Cohort 3 (Nov 23)
ReleaseCode / SDK · ActionableHabr AI→ original

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
Developer builds a Claude Code mascot that stomps while the assistant waits for your answer
Source: Habr AI. Collage: Hamidun News.
Listen to article
Article Fact Sheet & Key Figures
ParameterDetails
Primary sourceHabr AI ↗
Editor-in-Chief
Key metric #1The Notification hook in settings.json sends an event to a local HTTP port
Key metric #2The desktop app also needs PermissionRequest and PreToolUse, plus reading wpndatabase.db
MIT-licensed; stackElectron, node:sqlite and koffi, with no node-gyp

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.

Story

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.

ZK
Zhemal Khamidun — CPO at Alpina Digital, product manager of AlpinaGPT. Building AI products since 2019. Hamidun News is a pet project that grew into a production aggregator with 6,000+ readers.
✦ 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
What do you think?
Loading comments…