- Add Fumadocs-based docs site (docs-site/) - Document all features: tabs, notifications, splits, socket API, CLI - Add Claude Code hooks guide with cmuxterm detection - Update README with native macOS emphasis and brew install - Add homebrew-cmuxterm to .gitignore (has its own repo)
266 lines
5.4 KiB
Text
266 lines
5.4 KiB
Text
---
|
|
title: Claude Code Hooks
|
|
description: Set up notifications for Claude Code using cmuxterm hooks
|
|
---
|
|
|
|
# Claude Code Hooks
|
|
|
|
cmuxterm integrates with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) via hooks to notify you when tasks complete or when Claude needs attention.
|
|
|
|
## Detecting cmuxterm
|
|
|
|
Before sending notifications, you should detect if you're running inside cmuxterm to avoid conflicts with other terminals.
|
|
|
|
### Detection Methods
|
|
|
|
**1. Check for the socket:**
|
|
|
|
```bash
|
|
[ -S /tmp/cmuxterm.sock ] && echo "In cmuxterm"
|
|
```
|
|
|
|
**2. Check for the CLI:**
|
|
|
|
```bash
|
|
command -v cmuxterm &>/dev/null && echo "cmuxterm available"
|
|
```
|
|
|
|
**3. Check the TERM_PROGRAM environment variable:**
|
|
|
|
```bash
|
|
[ "$TERM_PROGRAM" = "ghostty" ] && [ -S /tmp/cmuxterm.sock ] && echo "In cmuxterm"
|
|
```
|
|
|
|
<Callout type="info">
|
|
cmuxterm sets `TERM_PROGRAM=ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty.
|
|
</Callout>
|
|
|
|
## Setting Up Hooks
|
|
|
|
Claude Code supports hooks that run on specific events. Add these to your `~/.claude/settings.json`:
|
|
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": "Task",
|
|
"hooks": [
|
|
"/path/to/cmuxterm-notify.sh"
|
|
]
|
|
}
|
|
],
|
|
"Stop": [
|
|
"/path/to/cmuxterm-notify.sh"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
## Notification Hook Script
|
|
|
|
Create a script that checks for cmuxterm and sends notifications:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# ~/.claude/hooks/cmuxterm-notify.sh
|
|
|
|
# Only proceed if we're in cmuxterm
|
|
if [ ! -S /tmp/cmuxterm.sock ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Parse the hook event from stdin (Claude Code passes JSON)
|
|
EVENT=$(cat)
|
|
|
|
# Extract event type and details
|
|
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
|
TOOL_NAME=$(echo "$EVENT" | jq -r '.tool_name // ""')
|
|
SESSION=$(echo "$EVENT" | jq -r '.session_id // ""' | cut -c1-8)
|
|
|
|
case "$EVENT_TYPE" in
|
|
"Stop")
|
|
cmuxterm notify \
|
|
--title "Claude Code" \
|
|
--subtitle "Task Complete" \
|
|
--body "Session $SESSION finished"
|
|
;;
|
|
"PostToolUse")
|
|
if [ "$TOOL_NAME" = "Task" ]; then
|
|
cmuxterm notify \
|
|
--title "Claude Code" \
|
|
--subtitle "Agent Finished" \
|
|
--body "Task agent completed in session $SESSION"
|
|
fi
|
|
;;
|
|
esac
|
|
```
|
|
|
|
Make it executable:
|
|
|
|
```bash
|
|
chmod +x ~/.claude/hooks/cmuxterm-notify.sh
|
|
```
|
|
|
|
## Example Configurations
|
|
|
|
### Notify on All Completions
|
|
|
|
Get notified whenever Claude Code finishes a task:
|
|
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"Stop": [
|
|
"~/.claude/hooks/cmuxterm-notify.sh"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Notify on Long-Running Tasks
|
|
|
|
Only notify for Task tool completions (agent subprocesses):
|
|
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": "Task",
|
|
"hooks": ["~/.claude/hooks/cmuxterm-notify.sh"]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Notify on Errors
|
|
|
|
Add error notifications:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# cmuxterm-notify.sh with error handling
|
|
|
|
if [ ! -S /tmp/cmuxterm.sock ]; then
|
|
exit 0
|
|
fi
|
|
|
|
EVENT=$(cat)
|
|
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
|
ERROR=$(echo "$EVENT" | jq -r '.error // ""')
|
|
|
|
if [ -n "$ERROR" ] && [ "$ERROR" != "null" ]; then
|
|
cmuxterm notify \
|
|
--title "Claude Code Error" \
|
|
--body "$ERROR"
|
|
elif [ "$EVENT_TYPE" = "Stop" ]; then
|
|
cmuxterm notify \
|
|
--title "Claude Code" \
|
|
--body "Task complete"
|
|
fi
|
|
```
|
|
|
|
## Advanced: Conditional Notifications
|
|
|
|
Only notify if the terminal is not focused:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# cmuxterm-notify.sh with focus detection
|
|
|
|
if [ ! -S /tmp/cmuxterm.sock ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# cmuxterm automatically suppresses notifications for focused tabs,
|
|
# so we can always send - it will handle suppression for us
|
|
|
|
EVENT=$(cat)
|
|
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
|
|
|
if [ "$EVENT_TYPE" = "Stop" ]; then
|
|
cmuxterm notify \
|
|
--title "Claude Code" \
|
|
--subtitle "Ready" \
|
|
--body "Waiting for your input"
|
|
fi
|
|
```
|
|
|
|
## Using OSC Sequences Directly
|
|
|
|
If you prefer not to use the CLI, you can emit OSC sequences directly:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Direct OSC notification (no CLI needed)
|
|
|
|
if [ ! -S /tmp/cmuxterm.sock ]; then
|
|
exit 0
|
|
fi
|
|
|
|
EVENT=$(cat)
|
|
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
|
|
|
if [ "$EVENT_TYPE" = "Stop" ]; then
|
|
# OSC 777 notification
|
|
printf '\e]777;notify;Claude Code;Task complete\a'
|
|
fi
|
|
```
|
|
|
|
## Full Example Setup
|
|
|
|
1. Create the hooks directory:
|
|
|
|
```bash
|
|
mkdir -p ~/.claude/hooks
|
|
```
|
|
|
|
2. Create the notification script:
|
|
|
|
```bash
|
|
cat > ~/.claude/hooks/cmuxterm-notify.sh << 'EOF'
|
|
#!/bin/bash
|
|
# cmuxterm notification hook for Claude Code
|
|
|
|
# Skip if not in cmuxterm
|
|
[ -S /tmp/cmuxterm.sock ] || exit 0
|
|
|
|
EVENT=$(cat)
|
|
EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"')
|
|
TOOL=$(echo "$EVENT" | jq -r '.tool_name // ""')
|
|
|
|
case "$EVENT_TYPE" in
|
|
"Stop")
|
|
cmuxterm notify --title "Claude Code" --body "Session complete"
|
|
;;
|
|
"PostToolUse")
|
|
[ "$TOOL" = "Task" ] && cmuxterm notify --title "Claude Code" --body "Agent finished"
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x ~/.claude/hooks/cmuxterm-notify.sh
|
|
```
|
|
|
|
3. Configure Claude Code:
|
|
|
|
```bash
|
|
cat > ~/.claude/settings.json << 'EOF'
|
|
{
|
|
"hooks": {
|
|
"Stop": ["~/.claude/hooks/cmuxterm-notify.sh"],
|
|
"PostToolUse": [
|
|
{
|
|
"matcher": "Task",
|
|
"hooks": ["~/.claude/hooks/cmuxterm-notify.sh"]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
EOF
|
|
```
|
|
|
|
4. Restart Claude Code to apply the hooks.
|
|
|
|
Now you'll receive desktop notifications in cmuxterm whenever Claude Code finishes a task or needs attention.
|