GoodBusy uses hooks in Claude Code and Cursor to track your AI coding sessions automatically. No manual logging. No browser extension. Just a single install command.
Copy a prompt, paste it into Claude Code or Cursor, and your AI assistant configures the hooks for you. Sign up to get your install prompt.
Sign in to see your personalised install prompt.
The prompt works with any agentic AI assistant that can edit files. It skips tools you don't have installed and leaves your existing hooks untouched.
Just use Claude Code, Cursor, or Conductor like you always do. GoodBusy hooks fire in the background on every session start, turn, and session end. Zero friction.
| Event | Claude Code | Cursor | Description |
|---|---|---|---|
| session_start | SessionStart | sessionStart | When you start a new session |
| turn_complete | Stop | stop | Every time the AI finishes a response |
| session_end | SessionEnd | sessionEnd | When the session ends |
Visit your profile to see sessions, streaks, and coding patterns. Show up on the leaderboard. Share your profile with others.
GoodBusy only sends metadata. We never see your code, prompts, file paths, or project names. Here's exactly what each event contains:
{
"event": "session_end",
"source": "claude-code", // or "cursor"
"ts": "2026-04-13T10:30:00Z",
"session_id": "abc123"
}That's it. No project names. No file paths. No code. No prompts. Just timestamps and counts.
The install prompt tells your AI assistant to write a shared hook script to ~/.goodbusy/goodbusy-hook.sh and configure hooks for each detected tool. Each hook calls the script with the right event type.
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "GOODBUSY_HOOK_EVENT=session_start ~/.goodbusy/goodbusy-hook.sh"
}]
}],
"Stop": [{
"hooks": [{
"type": "command",
"command": "GOODBUSY_HOOK_EVENT=turn_complete ~/.goodbusy/goodbusy-hook.sh",
"async": true
}]
}],
"SessionEnd": [{
"hooks": [{
"type": "command",
"command": "GOODBUSY_HOOK_EVENT=session_end ~/.goodbusy/goodbusy-hook.sh",
"async": true
}]
}]
}
}{
"version": 1,
"hooks": {
"sessionStart": [{
"command": "GOODBUSY_HOOK_EVENT=session_start GOODBUSY_SOURCE=cursor ~/.goodbusy/goodbusy-hook.sh"
}],
"stop": [{
"command": "GOODBUSY_HOOK_EVENT=turn_complete GOODBUSY_SOURCE=cursor ~/.goodbusy/goodbusy-hook.sh"
}],
"sessionEnd": [{
"command": "GOODBUSY_HOOK_EVENT=session_end GOODBUSY_SOURCE=cursor ~/.goodbusy/goodbusy-hook.sh"
}],
}
}This is the entire script that runs on each event. Your API key and URL are baked in at install time. It fires a curl with a 2-second timeout and exits. If the network is down, it silently fails. The GOODBUSY_SOURCE env var identifies whether the event came from Claude Code or Cursor.
#!/bin/bash
set -uo pipefail
API_KEY="your-api-key"
API_URL="https://goodbusy.ai"
EVENT="${GOODBUSY_HOOK_EVENT:-}"
[ -z "$EVENT" ] && exit 0
SOURCE="${GOODBUSY_SOURCE:-claude-code}"
# Read stdin (hook event data)
STDIN_DATA=""
if [ ! -t 0 ]; then
STDIN_DATA=$(cat)
fi
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
# Fire and forget (2s timeout, silent failure)
curl -s --max-time 2 -X POST "$API_URL/api/events" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $API_KEY" \
-d "{\"event\":\"$EVENT\",\"source\":\"$SOURCE\",\"ts\":\"$TS\"}" \
> /dev/null 2>&1 &
exit 0# Remove hooks from Claude Code settings $ sed -i.bak '/goodbusy/d' ~/.claude/settings.json # Remove hooks from Cursor settings $ sed -i.bak '/goodbusy/d' ~/.cursor/hooks.json # Delete hook script and config $ rm -rf ~/.goodbusy
Remove the GoodBusy entries from your settings and delete the local hook script. Your data on goodbusy.ai stays until you delete your account.