[FEATURE] Allow hooks to run only in interactive mode (not with -p flag)
Problem Statement
When configuring hooks like Stop and Notification in settings.json, there's no way to specify that they should only run in interactive mode.
I have hooks configured to send push notifications (via Pushover) when Claude Code stops or sends a notification. This is useful when working interactively - I can switch to other tasks and get alerted when Claude needs my attention.
However, when using Claude Code in scripts with the -p flag (e.g., claude -p "do something"), these same hooks fire, causing unwanted notifications. There's currently no way to differentiate between interactive and scripted usage in hook configuration.
Proposed Solution
Add an optional field to hook configuration that allows specifying when the hook should run:
{
"hooks": {
"Stop": [
{
"matcher": "",
"interactive_only": true,
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude stopped'"
}
]
}
]
}
}
Alternative approaches:
- A new field like
"mode": "interactive"or"mode": "scripted"or"mode": "both"(default) - Environment variable exposed to hooks indicating the mode (e.g.,
CLAUDE_INTERACTIVE=1) - Include mode information in the JSON payload passed to hook commands
Alternative Solutions
Currently, I could:
- Check for TTY in the hook command itself, but this is fragile and adds complexity to every hook
- Maintain separate settings files and switch between them, but this is cumbersome
- Not use hooks at all for notifications, losing the benefit in interactive mode
Use Case Example
- I configure Stop and Notification hooks to send push notifications via Pushover
- When using Claude Code interactively, I get notified when Claude stops - this lets me multitask
- When running
claude -p "analyze this file" > output.txtin a script or automation, I don't want notifications - With this feature, I could set
"interactive_only": trueon my notification hooks - Interactive sessions would notify me, scripted usage would stay silent
Additional Context
Relevant settings.json excerpt showing current hook configuration:
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "printf '\\a' > /dev/tty" },
{ "type": "command", "command": "...pushover notification..." }
]
}
],
"Notification": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "printf '\\a' > /dev/tty" },
{ "type": "command", "command": "...pushover notification..." }
]
}
]
}This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗