cmux/docs-site/content/docs/claude-code-hooks.mdx
Lawrence Chen 777d6b048e Replace CLAUDE_CONFIG_DIR with claude wrapper + richer notifications
Instead of creating a merged config directory and injecting
CLAUDE_CONFIG_DIR on every terminal spawn, place a thin wrapper
script at Resources/bin/claude that intercepts claude invocations
to inject --session-id and --settings flags. This eliminates
blocking I/O on terminal creation and removes config management
complexity.

- Add Resources/bin/claude wrapper script with hook injection
- Add shell integration PATH fix (re-prepend after .zshrc/.bashrc)
- Add transcript reading for richer stop notifications
- Add set_status/clear_status to notifications socket allowlist
- Add Settings toggle to disable Claude Code integration
- Update docs to reflect automatic integration approach
- Unset CLAUDECODE env var to avoid nested session detection
2026-02-15 18:33:36 -08:00

83 lines
3.2 KiB
Text

---
title: Claude Code Integration
description: Automatic notifications and status tracking for Claude Code sessions
---
# Claude Code Integration
cmux automatically integrates with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) to show session status and notifications in the sidebar — no manual configuration needed.
## How It Works
When you run `claude` (or `clawd`) inside a cmux terminal, cmux automatically:
1. **Injects a session ID** so each Claude invocation is tracked independently
2. **Registers hooks** for `SessionStart`, `Stop`, and `Notification` events
3. **Routes notifications** to the correct workspace and surface in the sidebar
This works by placing a thin wrapper script ahead of the real `claude` binary in your PATH. The wrapper adds `--session-id` and `--settings` flags, then `exec`s the real Claude — no extra process, no config files modified.
<Callout type="info">
The wrapper only activates inside cmux terminals (when `CMUX_SURFACE_ID` is set). Running `claude` in any other terminal works normally without hooks.
</Callout>
## What You See
### Session Status
When a Claude session is active, the sidebar shows a status indicator:
- **Running** — Claude is working
- **Needs input** — Claude is waiting for your approval or response
### Notifications
When Claude finishes or needs attention, a notification appears in the sidebar with context:
- **Permission** — Claude needs approval for a tool use
- **Error** — Something went wrong
- **Completed** — Session finished, with a summary of Claude's last response
## Disabling
You can turn off the integration in **Settings > Automation > Claude Code Integration**. When disabled, `claude` runs without cmux hooks — no session tracking, no sidebar status, no notifications.
New terminals pick up the setting immediately; existing terminals keep their current state.
<Callout type="info">
You can also set `CMUX_CLAUDE_HOOKS_DISABLED=1` in your shell environment to disable per-terminal.
</Callout>
## Custom Hooks
The automatic integration covers `SessionStart`, `Stop`, and `Notification` events. If you want to add hooks for other Claude Code events (like `PostToolUse` or `PreToolUse`), add them to your `~/.claude/settings.json` as usual — cmux's hooks are merged additively and won't conflict.
### Example: Notify on Task Agent Completion
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Task",
"hooks": [
{
"type": "command",
"command": "cmux notify --title 'Claude Code' --subtitle 'Agent Finished' --body 'Task agent completed'",
"timeout": 5
}
]
}
]
}
}
```
## Technical Details
- The wrapper lives at `Resources/bin/claude` inside the app bundle
- It is prepended to PATH via cmux's shell integration (runs after `.zshrc`/`.bashrc`)
- Each invocation gets a fresh UUID session ID
- The `cmux claude-hook` CLI subcommand handles routing hook payloads to the correct workspace
- Session mappings are stored at `~/.cmuxterm/claude-hook-sessions.json` (auto-pruned after 7 days)
- The `Stop` hook reads the Claude session transcript (via `transcript_path`) to include the last assistant message in the completion notification