Add hook for user input/question events (UserInputRequired)

Open 💬 25 comments Opened Oct 23, 2025 by sujoychatter
💡 Likely answer: A maintainer (dicksontsai, collaborator) responded on this thread — see the highlighted reply below.

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

Currently, the Stop hook only fires when Claude completes a full
response. It does not fire when Claude pauses mid-response to:

  • Ask permission to run a tool/command
  • Ask clarifying questions
  • Wait for user confirmation

This makes it impossible to get audio/visual notifications when Claude
needs user attention during a long-running session.

Related to #6454: That issue addresses notifications for completed
prompts (which Stop hook handles). This issue addresses the gap for
mid-response input requests (which no hook currently handles).

When working in another window while Claude Code runs commands, there's no
way to know when Claude needs permission without constantly checking the
terminal.

Proposed Solution

Add a new hook type (suggested name: UserInputRequired or
AwaitingInput) that triggers whenever Claude pauses and waits for user
input.

Example configuration:


  {
    "hooks": {
      "Stop": [
        {
          "hooks": [{"type": "command", "command": "afplay
  /System/Library/Sounds/Glass.aiff"}]
        }
      ],
      "UserInputRequired": [
        {
          "hooks": [{"type": "command", "command": "afplay
  /System/Library/Sounds/Ping.aiff"}]
        }
      ]
    }
  }

Trigger conditions:

  • Claude asks for tool permission
  • Claude asks a question and waits for user response
  • Any state where Claude cannot proceed without user input

This complements #6454:

  • #6454: "Task is done" → Stop hook (already works)
  • This issue: "Claude needs you NOW" → No hook available (gap)

Alternative Solutions

Using PreToolUse hook, but it fires for every tool execution (including
auto-approved tools), making it too noisy for this use case.

Another option would be to enhance PreToolUse hook with a
requiresApproval flag:

{
"requiresApproval": true,
"tool": "Bash",
"command": "rm -rf important_files"
}

This would allow conditional notifications only for tools requiring
approval.

Priority

Medium - Would be very helpful

Feature Category

Configuration and settings

Use Case Example

Example scenario:

  1. I'm working on a React app with a Node.js backend
  2. I ask Claude to "run the tests and fix any failures"
  3. Claude starts running tests (takes 2 minutes)
  4. I switch to my browser to review documentation
  5. Tests finish, Claude finds an error and needs to run git stash
  6. Claude asks for permission to run the command
  7. Current behavior: No notification - I don't know Claude needs input
  8. Desired behavior: Audio ping alerts me to switch back to terminal

This would save time and improve multitasking, especially during long
build/test cycles where Claude occasionally needs permission.

Real example: Claude ran 5 commands successfully over 3 minutes, then
stopped to ask permission for rm -rf dist/. I didn't notice for 10
minutes because I was in another window.

Additional Context

Current Hook Behavior:

  • Stop - Only fires on completion (handles #6454 use case)
  • PreToolUse - Fires before every tool (too noisy)
  • PostToolUse - Fires after tool execution
  • UserPromptSubmit - Fires when user submits input (opposite direction)

Environment:

  • OS: macOS
  • Use case: Audio notifications via system sounds (afplay)
  • Configuration: Using hooks in ~/.claude/settings.json

Suggested hook names:

  • UserInputRequired - Clear and descriptive
  • AwaitingInput - Shorter, states current state
  • PausedForInput - Indicates temporary pause

Why this is different from #6454:
Issue #6454 wants notifications when prompts finish - the Stop hook
already supports this. This issue requests notifications when Claude
pauses mid-response waiting for input - no hook currently supports this
critical use case.

This feature would be especially valuable for:

  • Long-running build/test processes
  • Accessibility - users who rely on audio cues
  • Multi-tasking developers working across multiple windows

View original on GitHub ↗

25 Comments

github-actions[bot] · 8 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/9575
  2. https://github.com/anthropics/claude-code/issues/4690
  3. https://github.com/anthropics/claude-code/issues/9516

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

uponatime2019 · 8 months ago

Im request this too, it super userful

kierse · 8 months ago

This would be _very_ useful

hieudtr8 · 8 months ago

Hello is there a hook for this yet 🙏

edsonbrusque · 8 months ago

I also need this.

uponatime2019 · 7 months ago

Now version 2.0.45, but seem still no update for this
Oh wait, check
/hooks

  1. Permission Requests
Johanfer12 · 7 months ago

We're still waiting, please don't close for inactivity.

uponatime2019 · 7 months ago
We're still waiting, please don't close for inactivity.

This features available now. Check hooks #11

edsonbrusque · 7 months ago

@uponatime2019 I think you're referring to the new PermissionRequest hook (https://code.claude.com/docs/en/hooks#permissionrequest-decision-control).

Yes, this was released about two weeks ago but I can't find a way to make it play a sound.

So, unless it works and is properly documented, this issue should remain open.

PaulRBerg · 7 months ago

This threads mixes two different events:

  1. PermissionRequest - we already have a hook event for this ✅
  • This is when Claude presents you with a plan and asks you to proceed with "Yes" or say "No"
  • Also when it asks for permission to use a tool (e.g. Bash(npm install))
  1. AskUserQuestion - we do NOT have a hook event for this ❌
  • This is a new feature they introduced in v2.0, and it's about asking users clarificatory questions, e.g.

<img width="600" src="https://github.com/user-attachments/assets/32fcd4a9-dde9-49bb-aa60-3f1356ed8e93" />

it would be great to have a hook event for the 2nd event.

@bcherny @dicksontsai & Anthropic team, could you please confirm if my understanding is correct and if yes, if Claude will receive support for an AskUserQuestion hook event?

sujoychatter · 7 months ago

Yes Permission Request works for me with

"hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
Johanfer12 · 7 months ago
Yes Permission Request works for me with `` "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff" } ] } ], "PermissionRequest": [ { "hooks": [ { "type": "command", "command": "afplay /System/Library/Sounds/Glass.aiff" } ] } ] } ``

This format worked for me, but only in CLI, in VSCODE AddOn nope 😓

dicksontsai collaborator · 7 months ago

AskUserQuestion is a specific tool. You can use PreToolUse with "matcher": "AskUserQuestion".

PaulRBerg · 7 months ago

Ooh, I see. Thanks for the tip @dicksontsai.

edsonbrusque · 7 months ago

Well, it still doesn't work for me.

The 'Stop' hook is firing consistently, but none of the others work.

This is how I have it configured to test it on WSL:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c \"echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - STOP\\\" >> /mnt/c/temp/hook-test.log\" && powershell.exe -Command \"(New-Object Media.SoundPlayer 'C:\\Devel\\Media\\normalized\\chord.wav').PlaySync()\""
          }
        ]
      }
    ],
    "PermissionRequest": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c \"echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - PERMISSION_REQUEST\\\" >> /mnt/c/temp/hook-test.log\" && powershell.exe -Command \"(New-Object Media.SoundPlayer 'C:\\Devel\\Media\\normalized\\chimes.wav').PlaySync()\""
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "AskUserQuestion",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c \"echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - PRE_TOOL_USE_ASK\\\" >> /mnt/c/temp/hook-test.log\" && powershell.exe -Command \"(New-Object Media.SoundPlayer 'C:\\Devel\\Media\\normalized\\chimes.wav').PlaySync()\""
          }
        ]
      }
    ],
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "bash -c \"echo \\\"$(date '+%Y-%m-%d %H:%M:%S') - NOTIFICATION\\\" >> /mnt/c/temp/hook-test.log\" && powershell.exe -Command \"(New-Object Media.SoundPlayer 'C:\\Devel\\Media\\normalized\\notify.wav').PlaySync()\""
          }
        ]
      }
    ]
  }
}

The command is a little complex because I added logging to confirm if this isn't an audio issue. It isn't. The 'stop' hook is logged. The other aren't.

Anyway, I also have this on Windows native with only the command being different and the same thing happens: The 'stop' hook plays a sound. The others don't.

UPDATE: I tested with the Claude Code on the WSL CLI and the PERMISSION_REQUEST and NOTIFICATION hooks fired. It seems it only doesn't work when using the 'Claude Code for VS Code' extension.

LamWizy · 7 months ago

I can confirm that the PermissionRequest hook does not fire when permission dialogs appear, at least on Windows.

Environment:

  • OS: Windows 11
  • Tested in both VS Code extension and CLI

Configuration tested:

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "powershell -ExecutionPolicy Bypass -File \"C:\\path\\to\\notify.ps1\""
          }
        ]
      }
    ]
  }
}

The script outputs the required JSON structure:

{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow"}}}

What I tried:

  • PermissionRequest with matcher "*" - doesn't fire
  • PermissionRequest with matcher "Bash" - doesn't fire
  • PreToolUse with matcher "*" - doesn't fire before permission dialogs
  • PreToolUse with matcher "AskUserQuestion" - doesn't fire for permission dialogs

What works:

  • Stop hook fires correctly when Claude finishes
  • The script works when run directly from the command line

The PermissionRequest hook is documented but doesn't appear to be functional. A working UserInputRequired or AwaitingInput hook (as suggested in this thread) would solve this use case.

cheickmec · 6 months ago

Confirming: PreToolUse + AskUserQuestion matcher works

As @dicksontsai mentioned, you can use PreToolUse with "matcher": "AskUserQuestion" to get notified when Claude asks a question.

Working config (.claude/settings.local.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "AskUserQuestion",
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
}

Troubleshooting if it doesn't work:

  1. Restart Claude Code after modifying settings.local.json (hooks load at session start)
  2. Test with afplay first (macOS) to verify the hook fires before using custom scripts
  3. Custom scripts must handle the PreToolUse event. Check hook_input.get("hook_event_name") == "PreToolUse" and hook_input.get("tool_name") == "AskUserQuestion"
  4. There's a reported issue (#13439) about PreToolUse causing empty AskUserQuestion responses in some cases. May be version-specific.

This covers the AskUserQuestion tool specifically. Does not cover permission prompts or other input-blocking scenarios.

shanraisshan · 6 months ago

I've been working on a voice hooks implementation for Claude Code and discovered something relevant to this discussion.

I initially implemented a special sound for AskUserQuestion using the PreToolUse hook with a tool name matcher:

  if event_name == "PreToolUse":
      if tool_name == "AskUserQuestion":
          return "pretooluse-askuserquestion"

However, I found that both PreToolUse and PermissionRequest fire simultaneously for AskUserQuestion (and other permission-required tools). This causes both sounds to play at the same time, creating audio conflicts.

Looking at the hook event flow:

  1. PreToolUse fires → informational ("tool is about to run")
  2. PermissionRequest fires immediately after → requires user action ("Claude needs your input")

Since AskUserQuestion inherently requires user interaction, the PermissionRequest hook is sufficient and semantically correct for this use case. Adding special handling in PreToolUse is redundant.

Conclusion: The PermissionRequest hook already covers the "user input required" scenario that this issue requests. If you want tool-specific sounds, you can match on tool_name within the PermissionRequest handler instead of PreToolUse.

My implementation (with configurable hooks and sounds): https://github.com/shanraisshan/claude-code-voice-hooks

github-actions[bot] · 5 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

chadbyte · 5 months ago

All these hook workarounds solve the "same machine" case — you still need to be at your desk to hear the sound.

If you want notifications that reach your phone when you're away:

https://github.com/chadbyte/claude-relay

Run npx claude-relay in your project directory and you get push notifications for permission requests, completions, errors, and questions — on your phone, even with the browser closed. No hooks to configure.

npx claude-relay

No install, no cloud, free and open source.

JuriAbramov · 4 months ago

+1

## Problem

There is no hook event that fires when the user clicks Allow/Deny on a permission prompt. This makes it impossible to reliably detect when a permission prompt
has been handled.

### Existing hooks and their limitations:

| Hook | Issue |
|------|-------|
| PermissionRequest | Fires when dialog appears, not when responded |
| Notification[permission_prompt] | Same timing as PermissionRequest |
| PreToolUse | Fires before the permission dialog |
| PostToolUse | Fires after tool completes, but runs on every tool call |
| Stop | Fires when Claude finishes entire response (delayed) |
| UserPromptSubmit | Only fires for text input, not Allow/Deny clicks |

## Use case

I'm building a system that changes the Windows Terminal tab title to indicate when Claude Code needs confirmation (yellow "⚠ Claude Code [CONFIRM]") vs normal
operation. Setting the title works via Notification[permission_prompt], but clearing it after the user responds requires a hook that fires at that moment.

Currently I use the Stop hook as a workaround, but this means the CONFIRM indicator stays visible during Claude's entire subsequent work phase — not just while
waiting for user input.

## Proposed solution

Add a PermissionResponse (or PermissionGranted / PermissionDenied) hook event that fires immediately after the user clicks Allow or Deny on a permission
prompt. The input JSON should include session_id, tool_name, and the user's decision (allow/deny).

CarpeWu · 3 months ago

Adding context specific to the VS Code extension on macOS — slightly different
from terminal CLI use cases already mentioned:

Problem in VS Code context:
Both AskUserQuestion dialogs and permission approval prompts (Approve/Deny)
appear with zero notification. The session just sits idle — no sound, no Dock
bounce, no window activation. The Notification hook with empty matcher never
fires for either case; only Stop works.

Partial workaround (fragile, but functional today):

Per a side-effect bug, PermissionRequest hook currently fires when
AskUserQuestion is called. This config coincidentally covers both:

{
  "hooks": {
    "PermissionRequest": [{
      "matcher": "",
      "hooks": [{ "type": "command",
        "command": "afplay /System/Library/Sounds/Ping.aiff && osascript -e 'tell application \"Visual Studio Code\" to activate'"
      }]
    }]
  }
}

Exit code must be 0, otherwise the permission decision gets affected.
This is clearly accidental behavior and will likely break in a future release.

Why this issue matters more for VS Code extension users:
In terminal mode, you can at least glance at the terminal output. In the VS Code
extension, the only feedback channel is the sidebar UI — making a proper hook
(or native VS Code notification) the only real solution.

The UserInputRequired hook proposed here, or extending Notification to
include an awaiting_user matcher type, would solve this cleanly.

yurukusa · 3 months ago

Partial solution available in v2.1.85: PreToolUse hooks can now match AskUserQuestion and auto-respond with updatedInput, which covers the "Claude asks a clarifying question and waits" case.

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "AskUserQuestion",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/auto-answer.sh"
      }]
    }]
  }
}

The hook script can either auto-answer (for headless/autonomous mode) or trigger a notification (for the original use case):
Auto-answer example:

INPUT=$(cat)
QUESTION=$(echo "$INPUT" | jq -r '.tool_input.questions[0].question // empty' 2>/dev/null)
[ -z "$QUESTION" ] && exit 0
if echo "$QUESTION" | grep -qiE 'delete|drop|destroy|rm -rf'; then
  jq -n --arg q "$QUESTION" '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:{answers:{($q):"No. Too risky for unattended mode."}}}}'
  exit 0
fi
if echo "$QUESTION" | grep -qiE 'test|build|lint|check'; then
  jq -n --arg q "$QUESTION" '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:{answers:{($q):"Yes, proceed."}}}}'
  exit 0
fi
exit 0  # Unknown questions → pass through to human

Notification example (macOS):

INPUT=$(cat)
QUESTION=$(echo "$INPUT" | jq -r '.tool_input.questions[0].question // empty' 2>/dev/null)
[ -z "$QUESTION" ] && exit 0
osascript -e "display notification \"$QUESTION\" with title \"Claude needs input\"" 2>/dev/null
exit 0

Key details:

  • AskUserQuestion uses questions array (not singular question): tool_input.questions[0].question
  • Auto-answer returns updatedInput.answers object: { "question text": "answer text" }
  • permissionDecision: "allow" is required alongside updatedInput
  • If hook exits 0 with no JSON output, the question passes through to the user normally

What this covers: AskUserQuestion events (clarifying questions, confirmations).
What this doesn't cover: Permission prompts (tool approval). Those fire as PermissionRequest hooks, which already existed before v2.1.85.
So between PreToolUse on AskUserQuestion (v2.1.85) and PermissionRequest hooks, the two main "waiting for input" scenarios now have hook-based solutions.

bouvens · 2 months ago

The existing workarounds in this thread (PermissionRequest, PreToolUse with matcher: AskUserQuestion) cover tool-based input requests. They miss a common scenario: plain-text checkpoints where the model writes a prompt and stops, with no tool call involved — e.g. UAT checkpoints in skill-driven workflows like:

CHECKPOINT: Verification Required
Test 4: ...
Type pass or describe what's wrong.

For these, only idle_prompt fires. But idle_prompt also fires when the model is idle waiting on a long-running background shell (e.g. polling for CI/code-review completion via run_in_background: true). Same notification_type, same message — indistinguishable in payload.

Result: bell on real checkpoint = good; bell every time the bg shell idles past threshold = false positive that trains me to ignore the bell.

Concrete need: a way to differentiate "model is blocked on user response" from "model is idle while async work is pending" in the Notification payload (e.g. an is_async_pending field, or a separate notification_type).

Dongyang0810 · 2 months ago

I really do need this feature.
The current version is 2.1.141, but this feature is still not available.