Skip to content

Repository files navigation

Code Buddy

A lightweight macOS menu bar app that displays real-time status of your AI coding assistant sessions.

Code Buddy demo

Features

  • Multi-Tool Support — Claude Code, Gemini CLI, Cursor, OpenCode
  • Multi-Session — Monitor multiple AI sessions simultaneously
  • Real-Time — Instant status updates via WebSocket/HTTP
  • Floating Window — Always-on-top, visible across all desktops
  • Native macOS — SF Symbols, system appearance
  • Lightweight — Minimal CPU/memory, pauses when idle

Quick Start

Requirements: macOS 13+, uv

# Install uv (Python package runner)
curl -LsSf https://astral.sh/uv/install.sh | sh
# One-line install (Claude Code only)
curl -fsSL https://raw.githubusercontent.com/runkids/code-buddy/main/install-remote.sh | bash

Full install (all tools):

git clone https://github.com/runkids/code-buddy.git
cd code-buddy
./Scripts/install.sh

The installer will:

  1. Build and install the app
  2. Install hook scripts and wrappers
  3. Configure hooks for selected tools
  4. Optionally set up aliases (gemini, opencode)

Supported AI Tools

ToolHook TypeNotes
Claude CodeLifecycle hooksFull support
Gemini CLIWrapper + hooksUse gemini-buddy or alias
CursorShell hooksShell commands only
OpenCodePlugin + wrapperUse opencode-buddy or alias

Wrapper Aliases

Gemini CLI and OpenCode need wrappers for full session tracking. The installer can set up aliases:

# ~/.zshrc (added by installer)alias gemini=gemini-buddy
alias opencode=opencode-buddy

Without wrappers, sessions appear only after the first tool execution.

Status Indicators

StatusDescription
IdleNo active tool
StartingSession started
ThinkingAI responding / Agent working
ExecutingRunning Bash command
ReadingReading files
WritingWriting/editing files
SearchingGrep/Glob operations
Done!Tool completed
FailedTool failed
CompactingContext compaction
NotifyingPermission request
RestingPaused
Goodbye!Session ended

Architecture

┌─────────────────┐ ┌──────────────────┐
│ Claude Code │───stdin JSON───│ │
│ Gemini CLI │────────────────│ Hook Script │
│ Cursor │ │ (Python/uv) │
└─────────────────┘ └────────┬─────────┘
│
WebSocket
:8765
│
┌─────────────────┐ ▼
│ OpenCode │────HTTP POST────▶┌─────────────────┐
│ Wrappers │ │ Code Buddy │
└─────────────────┘ │ (SwiftUI) │
└─────────────────┘
  • Hook Script: Normalizes events from Claude/Gemini/Cursor → WebSocket
  • OpenCode Plugin: Sends tool events → HTTP POST
  • Wrappers: Send session start/end events
  • Server: localhost:8765 (WebSocket + HTTP)

Manual Installation

Click to expand

Build

git clone https://github.com/runkids/code-buddy.git
cd code-buddy
swift build -c release

Install

mkdir -p ~/.local/bin
# App and scripts
cp .build/release/CodeBuddy ~/.local/bin/
cp Scripts/code-buddy-hook.py ~/.local/bin/
cp Scripts/gemini-buddy.sh ~/.local/bin/gemini-buddy
cp Scripts/opencode-buddy.sh ~/.local/bin/opencode-buddy
chmod +x ~/.local/bin/{CodeBuddy,code-buddy-hook.py,gemini-buddy,opencode-buddy}
# OpenCode plugin
mkdir -p ~/.config/opencode/plugins
cp Scripts/code-buddy-opencode-plugin.js ~/.config/opencode/plugins/

Configure Claude Code

Edit ~/.claude/settings.json:

{
"hooks": {
"PreToolUse": [{"matcher": "*", "hooks": [{"type": "command", "command": "~/.local/bin/code-buddy-hook.py PreToolUse --source claude"}]}],
"PostToolUse": [{"matcher": "*", "hooks": [{"type": "command", "command": "~/.local/bin/code-buddy-hook.py PostToolUse --source claude"}]}],
"SessionStart": [{"hooks": [{"type": "command", "command": "~/.local/bin/code-buddy-hook.py SessionStart --source claude"}]}],
"SessionEnd": [{"hooks": [{"type": "command", "command": "~/.local/bin/code-buddy-hook.py SessionEnd --source claude"}]}]
}
}

Configure Gemini CLI

Edit ~/.gemini/settings.json:

{
"hooks": {
"BeforeTool": [{"matcher": "*", "hooks": [{"type": "command", "command": "~/.local/bin/code-buddy-hook.py BeforeTool --source gemini"}]}],
"AfterTool": [{"matcher": "*", "hooks": [{"type": "command", "command": "~/.local/bin/code-buddy-hook.py AfterTool --source gemini"}]}]
}
}

Add alias to ~/.zshrc: alias gemini=gemini-buddy

Configure Cursor

Edit ~/.cursor/hooks.json:

{
"version": 1,
"hooks": {
"beforeShellExecution": [{"command": "~/.local/bin/code-buddy-hook.py beforeShellExecution --source cursor"}],
"afterShellExecution": [{"command": "~/.local/bin/code-buddy-hook.py afterShellExecution --source cursor"}]
}
}

Configure OpenCode

Plugin is already installed. Add alias to ~/.zshrc: alias opencode=opencode-buddy

Start

~/.local/bin/CodeBuddy &

Auto-Start

Add to ~/.zshrc:

# Start Code Buddy if not running
pgrep -x CodeBuddy > /dev/null || nohup ~/.local/bin/CodeBuddy > /tmp/code-buddy.log 2>&1&

Uninstall

./Scripts/uninstall.sh

Or manually:

pkill -x CodeBuddy 2>/dev/null ||true
rm -f ~/.local/bin/{CodeBuddy,code-buddy-hook.py,gemini-buddy,opencode-buddy}
rm -f ~/.config/opencode/plugins/code-buddy-opencode-plugin.js
# Remove aliases from ~/.zshrc# Remove hooks from ~/.claude/settings.json, ~/.gemini/settings.json, ~/.cursor/hooks.json

Troubleshooting

"Waiting for AI tools..."

  • Check Code Buddy is running: pgrep CodeBuddy
  • Check port is listening: lsof -i :8765
  • Restart your AI tool to reload hooks

Debug logs

tail -f /tmp/code-buddy.log
# Hook script (enable with CODE_BUDDY_DEBUG=1)
tail -f /tmp/code-buddy-hook.log

Development

swift build # Debug
swift run # Run
swift build -c release # Release

License

MIT — see LICENSE

Contributing

  1. Fork → 2. Branch → 3. Commit → 4. PR

Feedback

Issues · Discussions

About

📟 Real-time AI coding assistant status monitor for macOS (Claude Code, Gemini CLI, Cursor, OpenCode)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages