Claude Code hooks
Everything works without hooks: sessions are visible, the feed updates. Hooks add three things you can't get otherwise.
A message is visible at once. The CLI appends a prompt to the transcript only with the agent's next reply, so during a long reply a sent message seems to vanish. The UserPromptSubmit hook delivers it immediately.
You can see what a foreign session is busy with. About a session from the terminal the api knows only what has already been written to the transcript — while a call is running it looks silent. PreToolUse and PostToolUse bring the current call, and "⚙ Bash(…)" appears in the feed header, just as it does for your own chats.
Answering a foreign session's question. When claude in the terminal asks a question, the tool call hangs inside its process. There is no way to append an answer to the JSONL — that is a log, the CLI reads nothing from it. But a hook runs in that very process, so its output is the channel for the answer.
Setting it up
In ~/.claude/settings.json:
{
"hooks": {
"PostToolUse": [
{ "hooks": [{ "type": "command", "command": "/var/www/clauder/scripts/claude-hook.sh" }] }
],
"Stop": [
{ "hooks": [{ "type": "command", "command": "/var/www/clauder/scripts/claude-hook.sh" }] }
],
"UserPromptSubmit": [
{ "hooks": [{ "type": "command", "command": "/var/www/clauder/scripts/claude-hook.sh" }] }
],
"PreToolUse": [
{
"matcher": "AskUserQuestion",
"hooks": [
{
"type": "command",
"timeout": 900,
"command": "sh /var/www/clauder/scripts/claude-question-hook.sh"
}
]
}
]
}
}The path to the scripts is the one in your clone. With the app they live next to it; the exact path is shown by the "Claude Code hooks" section in the settings.
Why Stop
For notifications. A session from the terminal has neither an agent run nor a status of its own, and without the hook nobody would learn that the reply has finished.
Together with PostToolUse it also picks up messages written to such a session from Clauder: without them what you wrote stays hanging as a bubble — there is nothing else to deliver it.
Where to send the events
That is set in Clauder itself — the "Claude Code hooks" section in the settings, one address per line.
An api in docker and an app without docker often live side by side, and both need the event: the hook fans it out to every Clauder listed. Otherwise the second one never learns about the session, and there will be nothing to answer its question with.
Intercepting questions
Interception is switched on per session — the "📥 intercept questions" button in the chat header, an item under "⋮" in the app. While it is off, a question goes to the ordinary interactive UI and the terminal isn't broken.
An intercepted question waits with no deadline
The session in the terminal stands still until the question is answered from Clauder, "Skip" is pressed, or interception is switched off. Leaving interception on for someone else's session unattended is not a good idea.