Inspiration
I'm not a programmer — I run my projects entirely through AI coding agents (Claude
Code). That's great for speed, but it means I can't personally judge whether a
command an AI is about to run is safe. A single unreviewed rm -rf or force-push
could wipe out real work, and I'd have no way to know until it was too late. I
wanted a guardian that didn't require me to understand code — one that watches
the AI on my behalf, in a way that's impossible to ignore and doesn't read like a
compliance dialog.
The idea landed on a desktop pet: a cat that lives on screen, blocks danger in real time, and — instead of a boring system alert — roasts my bad habits in a speech bubble once the session ends, like a blunt senior engineer looking over my shoulder.
How I built it
The safety logic runs as two Claude Code hooks, both pure stdlib Python so they have zero dependency on the pet's UI:
- A
PreToolUseguard that pattern-matches every Bash command before it executes and hard-blocks a fixed set of destructive patterns — force pushes, hard resets, unscoped deletes,DROP TABLE/TRUNCATE,--no-verify, recursivechmod 777, fork bombs, raw writes to block devices. - A
Stophook that runs after each session and scans for four anti-patterns, reporting the first one it finds: the same command retried 3+ times without reading the error, the same file re-read 3+ times, an unscoped full-diskfind/grep, or a long session (400+ lines) that never wrote a handoff doc.
Both write into a shared status queue that the desktop pet reads to display as a speech bubble next to the cat, instead of a plain OS notification.
For the pet itself, I first tried building it from scratch in Python/Tkinter.
I later switched the rendering to an open-source Electron project
("Clawd on Desk") with genuine transparency support, and I'm patching it to add
a POST /say endpoint that calls its existing bubble-rendering function so the
supervisor's roasts show up right next to the cat, with custom art for its
different moods.
Challenges I ran into
The hardest problem was transparency, not logic. On this machine, tcl-tk
9.0.4 flattens every RGBA image's alpha channel to opaque black when rendering
— true even when bypassing Tk entirely and drawing straight into an AppKit
NSImageView. I verified this at the pixel level twice before accepting it
wasn't fixable at the app-code level.
Along the way I did solve a real fullscreen click-through bug: on macOS,
overrideredirect(True) alone doesn't clear the underlying
NSWindowStyleMaskTitled bit — you have to reach into the native NSWindow
via PyObjC and force NSWindowStyleMaskBorderless, and switch the whole app's activation policy to NSApplicationActivationPolicyAccessory to sit
above fullscreen Spaces, and only call overrideredirect after the window's
first update() — get any one of the three wrong and the window either shows
a title bar, hides behind fullscreen apps, or never renders at all.
Even with that fixed, the result still looked like a "boxed" window rather than a real floating character, and the macOS notification fallback I built as a stopgap has a color-contrast bug I can't control from script level (light text on light background in some system themes). Both pushed the decision to stop fighting the rendering layer and build on top of an existing, real transparent-window implementation instead — the lesson being: know when a platform limitation isn't a bug to debug further, but a signal to change tools.
Log in or sign up for Devpost to join the conversation.