clawdhue
v0.1.1
Published
System tray monitor showing Claude Code's real-time status as a colored Claude logo icon
Maintainers
Readme
Clawd Hue
System tray monitor showing Claude Code's real-time status as a colored Claude logo icon. Hooks write per-session status files; the tray polls them every 200ms with zero flicker.
States
| Icon | Status | Meaning | | ------------------- | ------- | ---------------------------------------------------------------- | | ⚫ Gray | Idle | No active session | | 🟢 Green (animated) | Working | Processing, streaming, tool executing — 13-frame clawd animation | | 🟡 Yellow (animated) | Waiting | Permission prompt — 21-frame jump animation until user responds | | 🔴 Red (blinking) | Error | Tool execution failed — red icon blinks on/off at 800ms period |
Green and Yellow use pre-rendered sprite-sheet animations from the Claude logo. Red is a simple blink: the red-tinted icon alternates with a fully transparent icon — no frames needed.
Install
git clone https://github.com/cuihp/clawdhue.git
cd clawdhue
go build -o clawdhue ./cmd/clawdhue/Usage
clawdhue # Start tray (same as start)
clawdhue start # Start tray (auto-configures hooks on first run)
clawdhue stop # Stop tray
clawdhue restart # Restart
clawdhue status # Show running state + current detected status
clawdhue setup-hooks # Auto-configure Claude Code hooks in ~/.claude/settings.json
clawdhue unsetup-hooks # Remove Claude Code hooks managed by clawdhue
clawdhue setup-opencode-hooks # Install OpenCode plugin for status monitoring
clawdhue unsetup-opencode-hooks # Remove OpenCode plugin
clawdhue --once # Print current status and exit
clawdhue --version # Print version and exitOn first start, hooks are automatically configured in ~/.claude/settings.json.
You can also right-click the tray icon → Setup Hooks / Remove Hooks.
For OpenCode users, run clawdhue setup-opencode-hooks to install a plugin
that writes status files on tool execution, permission requests, and session
lifecycle events.
Tray Menu
Right-click the tray icon:
Status: Working
─────────────────
Setup Hooks → Auto-configure Claude Code hooks
Remove Hooks → Remove Claude Code hooks
─────────────────
QuitHow It Works
Six Claude Code lifecycle hooks write per-session status files to
~/.clawdhue/sessions/<sessionId>.json. The tray polls this directory every
200ms and picks the highest-priority status across all active sessions.
OpenCode users get the same result via an auto-installed plugin that hooks
into tool.execute.before, permission.asked, and session lifecycle events.
| Hook / Event | Fires when | Written state |
| -------------------- | --------------------------------- | ------------- |
| UserPromptSubmit | User sends a prompt | working |
| PreToolUse | Tool about to execute | working |
| PostToolUse | Tool execution succeeded | working |
| PermissionRequest | Permission dialog appears | waiting |
| Stop | Turn finished normally | completed |
| StopFailure | API error — Claude can't continue | error |
| tool.execute.before (OpenCode) | Tool starts executing | working |
| permission.asked (OpenCode) | Permission dialog appears | waiting |
| session.idle (OpenCode) | Session finished | completed |
| session.error (OpenCode) | Session errored | error |
Claude event → hook → ~/.clawdhue/sessions/<id>.json → tray iconWhy no flicker: UserPromptSubmit writes working immediately, covering the thinking
phase. Streaming keeps working via PostToolUse → stays Green. Only explicit events
change state.
Why Yellow stays: waiting is written by PermissionRequest for all permission
dialogs (including Bash commands). It never auto-promotes — the user must respond
(PostToolUse → working) or the turn must end (Stop → completed).
Red means fatal: error only appears when StopFailure fires (API error, Claude
truly cannot continue). Tool-level failures are NOT treated as errors — Claude may
continue after a failed tool.
Safety net: working auto-promotes to completed after 120s if the Stop hook was
missed. Session files older than 5 minutes are cleaned up automatically.
Process verification: When a session claims to be working, the monitor verifies the
Claude Code process is still alive. If the process is gone (crash / force-quit), the
status is immediately downgraded to prevent a stuck Green icon.
JSONL fallback: When no hook session files exist (hooks not yet configured), the
monitor falls back to scanning Claude's project directories for .jsonl files and
checking whether the last line is incomplete JSON (streaming). This provides basic
detection out of the box.
Performance
Icon data is pre-generated at build time by cmd/genicons — all ICO files are
embedded as-is, eliminating the ~8-second CPU-intensive PNG downscaling that previously
ran at startup. Runtime init() simply reads pre-built bytes from the embedded
filesystem.
Session polling uses a session→PID index (built once per poll cycle) and a process-liveness cache (2-second TTL) to avoid redundant filesystem scans and syscalls on every tick.
Platform Support
| Platform | Build | Notes |
| -------- | ---------- | ---------------------------- |
| Windows | go build | No extra deps |
| macOS | go build | Requires Xcode (CGO + Cocoa) |
| Linux | go build | Requires libgtk-3-dev |
Project Structure
cmd/
clawdhue/ Application entry point
main.go CLI flag parsing, command routing
tray.go System tray lifecycle, polling loop, animation
start.go / start_unix.go Platform-specific background launch
pid.go PID file read/write
stop.go Stop command (kill by PID)
status.go Status command (running state + detection)
genicons/ ⚒ ICO pre-generation tool (build-time only)
main.go Downscales source PNGs → embedded .ico files
internal/
icon/ Tray icon data
icon.go Status type, embed directives, animation maps
ico_static/ Pre-generated static ICOs (gray/green/yellow/red)
ico_frames/ Pre-generated animation frame ICOs
working/ 13 frames — Green working animation
jump/ 21 frames — Yellow jump animation
clawd.png / clawd_* Source PNGs (used by genicons, not embedded)
monitor/ Status detection engine
monitor.go Session-file polling, staleness, process verification,
session→PID index, process-liveness cache, JSONL fallback
process_windows.go Windows IsProcessRunning (OpenProcess)
process_unix.go Unix IsProcessRunning (syscall.Kill)
hooks/ Claude Code hook integration
handler.go Hook subcommand: stdin JSON → per-session status file
setup.go settings.json management: setup/unsetup/validate hooks
paths/ Cross-platform path resolution
paths.go ConfigDir, SessionsDir, ClaudeSettingsPath, etc.Rebuilding Icons
If the source PNGs change, regenerate the embedded ICO files:
go run ./cmd/genicons/