Expose invocation mode to hooks (interactive vs -p/pipe mode)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Hooks currently have no way to determine whether Claude Code was invoked interactively or via -p (pipe/non-interactive mode). The hook input includes session_id, transcript_path, cwd, permission_mode, and hook_event_name, but nothing about invocation context.
Proposed Solution
Add an invocation_mode field (or similar) to the hook input JSON, e.g.:
{
"session_id": "abc123",
"hook_event_name": "Stop",
"invocation_mode": "interactive",
...
}
Possible values: interactive, pipe, remote (or whatever maps to the current invocation modes).
This would let hook authors conditionally run logic based on how Claude was started, without needing external workarounds.
Alternative Solutions
_No response_
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
I have a Stop hook that should only run during interactive sessions — it doesn't make sense when Claude is invoked programmatically with -p. Today the only workaround is wrapping the CLI call with a custom environment variable (CLAUDE_PIPE=1 claude -p "...") and checking for it in the hook script, which is fragile and easy to forget.
Ex. playing audio on stop hook
Additional Context
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗