NAME
ani-mime — Floating macOS status pill that tracks terminal & Claude Code activity
SYNOPSIS
sudo apt install .INFO
DESCRIPTION
Floating macOS status pill that tracks terminal & Claude Code activity
README
Ani-Mime
A floating pixel mascot that mirrors your terminal & Claude Code activity on macOS and Linux.
What is Ani-Mime?
A tiny always-on-top pixel dog that reacts to what your terminal is doing. It sniffs when you're building, barks when a dev server is running, sits when you're free, and sleeps when nothing's happening.
It also integrates with Claude Code — the dog knows when Claude is thinking vs waiting for you.
Contributors
Ani-Mime wouldn't be the same without these wonderful people. Thank you for your time, ideas, and code — you made this project better.
|
thnh-dng |
yanmad27 |
thanh-dong |
setnsail |
QuangHo0911 |
cuongtranba |
Mascot States
| Status | Dot | Mascot | Meaning |
|---|---|---|---|
| Free | Green | Sitting | Terminal idle, ready for commands |
| Working | Red (pulse) | Sniffing | Running a task (build, git push, etc.) |
| Service | Blue | Barking | Dev server launched (vite, metro, etc.) |
| Searching | Yellow (pulse) | Idle | Waiting for connection |
| Sleep | Gray | Sleeping | Terminal closed or 10s of inactivity |
Features
- Pixel Art Mascot — animated sprite sheet dog above the status pill
- Custom Sprites — upload your own PNG sprite sheets via manual import or smart extraction with chroma-key background removal
- Frame Range Expressions — specify frames as ranges like
1-5or41-55,57,58when importing custom sprites - Display Scale — resize your mascot with Tiny / Normal / Large / XL presets
- Peer Visits — discover other Ani-Mime users on your local network via Bonjour/mDNS; right-click to send your pet to visit theirs
- Manual Tagging — zsh hooks classify commands as
taskorservice - Heartbeat + OS Scan — hooks drive state transitions; a 2s libproc scan auto-discovers every live shell and cleans up zombies
- Session Dropdown — click the status pill to see every open terminal grouped by project path, with the foreground command (
claude,bun, etc.), and click any row to jump straight to that tab (see Session List & Click-to-Focus) - Claude Code Hooks — tracks when Claude is actively working vs waiting
- Claude Code Management UI — view and manage your Claude Code configuration from Settings → Claude Code: list installed plugins with enable/disable toggles, inspect global and per-project MCP servers, browse and delete custom slash commands, and review/remove hooks
- MCP Server — Claude Code can talk to your pet: trigger speech bubbles, play reaction animations, and check pet status via MCP tools
- Multi-Session — handles multiple terminals, priority: busy > service > idle
- Auto-Setup — first launch configures zsh hooks and Claude Code hooks via native macOS dialogs
- All Workspaces — visible on every macOS Space/desktop
- Menu Bar Tray Icon — always-visible tray icon with right-click menu; left-click toggles mascot visibility
- Hide from Dock — optional setting to remove the app from Dock and Cmd+Tab, running as a menu bar-only app
- Low Footprint — Rust + Tauri, minimal CPU and RAM
Screenshots
![]() | ![]() | ![]() |
| General settings | Customize your favorite Mime | Shadow Clone feature |
![]() | ![]() | ![]() |
| Show on menu bar | One-click import & export your Mime | Claude Code management UI |
Session List & Click-to-Focus
Click the status pill to open a dropdown listing every open terminal, grouped by working directory:
Click any row and Ani-Mime brings that terminal to the front. For apps with scripting support it jumps to the specific tab; for the rest it just activates the app. The walk up the process tree uses pidpath + a ps-based ppid map, so it works even across root-owned ancestors like /usr/bin/login.
Terminal app support matrix
| App | Activate | Tab-precise focus | How |
|---|---|---|---|
| iTerm2 | ✅ | ✅ | AppleScript: matches the tty property on every session |
| Terminal.app | ✅ | ✅ | AppleScript: matches the tty property on every tab |
| VS Code | ✅ | ⚠️ Window | System Events + window title contains the workspace folder name (can't target individual panes — Electron) |
| Cursor | ✅ | ⚠️ Window | Same approach as VS Code |
| tmux (inside any host) | ✅ | ✅ | tmux select-pane -t + select-window + switch-client matched by pane_tty; host app also activated |
| Warp | ✅ | ❌ | No public scripting API for tabs — activation only |
| WezTerm | ✅ | ❌ | Has a wezterm cli pane API but no pid→pane mapping from outside |
| Alacritty / kitty / Hyper / Ghostty | ✅ | ❌ | No inter-app scripting exposed — activation only |
| ssh session | ✅ | ❌ | Remote shells resolve to the local ssh ancestor — activate the local terminal |
Permissions
The first time Ani-Mime tries to script another app, macOS will prompt:
- iTerm / Terminal — Automation permission. Grant once; subsequent clicks target the exact tab.
- VS Code / Cursor — Accessibility permission (required by System Events to raise windows). Find Ani-Mime under System Settings → Privacy & Security → Accessibility and enable it.
Without these permissions, the click still brings the app to the front via open -a (Launch Services, no permission needed) — you just lose the precise tab / window targeting.
Install
macOS — Homebrew (recommended)
brew tap vietnguyenhoangw/ani-mime
brew install --cask ani-mime
Open the app. On first launch, Ani-Mime will:
- Ask to add a hook to your
~/.zshrc(required for terminal tracking) - Ask to configure Claude Code hooks (optional)
Open a new terminal tab and the mascot starts reacting.
The MCP server is also auto-configured so Claude Code can interact with your pet directly (see MCP Server below).
Linux — .deb, .rpm, or .AppImage
Download the bundle for your distro and arch from the Releases page:
# Debian / Ubuntu sudo apt install ./ani-mime_X.Y.Z_amd64.deb # or _arm64.deb on ARMFedora / RHEL / openSUSE
sudo rpm -i ani-mime-X.Y.Z-1.x86_64.rpm # or .aarch64.rpm
AppImage (any distro)
chmod +x ani-mime_X.Y.Z_amd64.AppImage && ./ani-mime_X.Y.Z_amd64.AppImage
Runtime deps (installed automatically by apt/rpm; required manually for AppImage):
sudo apt install libwebkit2gtk-4.1-0 libayatana-appindicator3-1 zenity xdg-utils
WSL2
Install the Linux .deb inside your WSL2 distro. Always-on-top works via a WSLg-specific SetWindowPos(HWND_TOPMOST) shim — no extra setup required.
Manual (from source)
git clone https://github.com/vietnguyenhoangw/ani-mime.git
cd ani-mime
bun install
bun tauri dev
On Linux you also need the build deps:
sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev \
librsvg2-dev libxdo-dev libglib2.0-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev \
xdg-utils pkg-config build-essential zenity
Then source the shell script for your shell (terminal-mirror.zsh, .bash, or .fish):
echo 'source "/path/to/ani-mime/src-tauri/script/terminal-mirror.zsh"' >> ~/.zshrc
source ~/.zshrc
Requirements
- macOS (Intel or Apple Silicon) — full feature set
- Linux (x86_64 or aarch64) — runs with shell hooks; some click-to-focus integrations are macOS-only
- WSL2 / WSLg — runs as a Linux build with a WSLg-aware always-on-top shim
- Shell — zsh / bash / fish (hooks provided for each)
- Claude Code (optional) — for Claude activity tracking
Platform feature matrix
| Feature | macOS | Linux | WSL2 |
|---|---|---|---|
| Mascot + speech bubbles | ✅ | ✅ | ✅ |
| Shell hook tracking (zsh/bash/fish) | ✅ | ✅ | ✅ |
| Claude Code hooks + MCP server | ✅ | ✅ | ✅ |
| Always-on-top over full-screen apps | ✅ | ✅ | ✅ |
| Peer discovery (mDNS / Bonjour) | ✅ | ✅ | ⚠️ |
| Session list dropdown | ✅ | ✅ | ✅ |
| Click-to-focus terminal tabs | ✅ | ❌ | ❌ |
| Auto shell discovery (libproc scan) | ✅ | ❌ | ❌ |
| Homebrew cask install | ✅ | — | — |
Auto-install update via brew | ✅ | — | — |
Linux and WSL2 fall back to the shell-hook based path for terminal tracking — you get the full mascot + Claude Code + MCP experience, just without the macOS-only auto-discovery and tab-precise focus.
Tech Stack
- Frontend: React 19, TypeScript, Vite
- Backend: Rust, Tauri v2, tiny_http
- Shell: zsh hooks (preexec / precmd)
- Sprites: CSS sprite sheet animation (128×128 pixel art, scalable)
- Testing: Vitest (unit), Playwright (e2e)
Testing
# Unit tests bun run testE2E tests (requires dev server on :1420)
npx playwright test --config=e2e/playwright.config.ts
The e2e suite covers app startup, status transitions, speech bubbles, scenario mode, settings, custom sprite upload (including frame range expressions), sprite display sizing, and custom sprite editing.
Peer Visits
Ani-Mime instances on the same local network automatically discover each other via mDNS (Bonjour). Right-click your mascot to see nearby peers and send your pet to visit them.
Requirements
- Both machines on the same WiFi / LAN subnet
- macOS Local Network permission — allow when prompted on first launch (or enable in System Settings > Privacy & Security > Local Network)
Troubleshooting
If peers can't find each other:
- Check that both machines are on the same network (
192.168.x.xsubnet) - Verify Local Network permission is enabled for ani-mime on both machines
- Run
dns-sd -B _ani-mime._tcp local.in Terminal — you should see both instances - Run
curl http://127.0.0.1:1234/debugto check the registered IP and peer list - If sharing the app via DMG without a Developer ID, the recipient must run:
xattr -cr /Applications/ani-mime.app
See docs/peer-discovery.md for the full protocol reference.
MCP Server
Ani-Mime includes an MCP (Model Context Protocol) server that lets Claude Code interact with your pet during conversations.
What It Does
| Tool | Description |
|---|---|
pet_say | Make your pet say something via a speech bubble |
pet_react | Trigger a reaction animation (celebrate, nervous, confused, excited, sleep) |
pet_status | Check what your pet is doing, who's visiting, nearby peers, and uptime |
Setup
The MCP server is automatically configured during first-launch setup (when you accept Claude Code hooks). If you need to set it up manually:
claude mcp add ani-mime -- node ~/.ani-mime/mcp/server.mjs
The server script is updated automatically on every app launch.
How It Works
Claude Code <--stdio--> MCP Server (Node.js) <--HTTP--> Ani-Mime :1234 --> Pet UI
Claude Code calls MCP tools during conversations. The MCP server translates them to HTTP requests to the local Ani-Mime server, which emits Tauri events to the frontend. The pet reacts with speech bubbles or animation changes.
Building for Release
macOS (DMG)
# Build the Tauri app bun run tauri buildRe-sign with entitlements and re-create the DMG
(required because Tauri doesn't embed entitlements for ad-hoc signing)
bash src-tauri/script/post-build-sign.sh
The signed DMG is output to src-tauri/target/release/bundle/dmg/.
Without the post-build sign step, the app will run on the build machine but peer discovery (mDNS) and the HTTP server will silently fail on other machines due to missing network entitlements.
If the recipient sees "app is damaged", they need to remove the quarantine attribute:
xattr -cr /Applications/ani-mime.app
Linux (.deb, .rpm, .AppImage)
bun run tauri build
Produces all three bundle formats under src-tauri/target/release/bundle/{deb,rpm,appimage}/. No post-build signing step required on Linux.
CI release pipeline
Tag pushes (v*) trigger .github/workflows/release.yml, which runs a 4-job matrix:
| Job | Runner | Target | Artifact |
|---|---|---|---|
| macOS aarch64 | macos-latest | aarch64-apple-darwin | .dmg |
| macOS x86_64 | macos-latest | x86_64-apple-darwin | .dmg |
| Linux aarch64 | ubuntu-22.04-arm | aarch64-unknown-linux-gnu | .deb + .rpm + .AppImage |
| Linux x86_64 | ubuntu-22.04 | x86_64-unknown-linux-gnu | .deb + .rpm + .AppImage |
Each release publishes 8 artifacts total.
Contributing
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing) - Commit your changes (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing) - Open a Pull Request
Contributions for new pixel art sprites, Rust logic improvements, or UI enhancements are welcome.
License
MIT. See LICENSE for details.





