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
83 lines
3.2 KiB
Text
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
|