[FEATURE] Add hook for when Claude is waiting for user input

Open 💬 26 comments Opened Dec 4, 2025 by currenthandle

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

When Claude stops to wait for user input (like the AskUserQuestion interactive prompt), there's no configurable hook that fires. I want to play an audio chime whenever Claude needs my attention so I know to check back on it.

Currently:

  • Stop hook only fires when Claude finishes completely, not when waiting for input
  • Notification hook with idle_prompt only fires after 60+ seconds idle (too slow for immediate feedback)

This means if Claude asks me a question via the interactive UI picker, I have no way to get notified. Claude just sits there waiting while I'm doing something else, not knowing it needs my input.

Proposed Solution

Either:

  1. Add a new hook like WaitingForInput or Yield that fires whenever Claude yields control back to the user (including AskUserQuestion prompts, permission dialogs, etc.)

Or:

  1. Expand the Stop hook to also fire when Claude is waiting for input, not just when completely finished.

The hook should fire immediately when Claude pauses

Alternative Solutions

I've tried:

  • Stop hook - doesn't fire when waiting for input, only on complete finish
  • Notification hook with permission_prompt matcher - only covers permission dialogs, not AskUserQuestion
  • Notification hook with idle_prompt - 60 second delay is too long for immediate feedback

There's no current workaround that covers the AskUserQuestion interactive prompt case.

Priority

High - Significant impact on productivity

Feature Category

Configuration and settings

Use Case Example

  1. I ask Claude to help me build a feature
  2. Claude uses AskUserQuestion to show me a multi-select UI asking for clarification
  3. I've tabbed away to another window while waiting
  4. Claude sits there waiting for my input - I have no idea it needs me
  5. With this feature, my configured hook would play a chime immediately when the question appears
  6. I'd hear the chime, switch back, answer the question, and Claude continues working

Additional Context

The AskUserQuestion tool and similar tools creates an interactive UI prompt but doesn't trigger any hookable event. This seems like an oversight since other "waiting" scenarios (permissions, idle) do have notification support.

View original on GitHub ↗

26 Comments

BertrandDecoster · 7 months ago

Agreed, I have the same need

evogler · 6 months ago

This would be really helpful

Fchaubard · 6 months ago

Re: @currenthandle, this should be default behavior, but until this is picked up my anthropic, simplest answer I have found and tested that actually works. Put this into your <agent>.MD:

 ### MANDATORY - DO THIS EVERY TIME

  RIGHT BEFORE asking ANY question or requesting ANY input:
  1. Run afplay /System/Library/Sounds/Glass.aiff as a background process (using run_in_background: true)
  2. In the same parallel call, proceed with your question/input request

  Both must be sent simultaneously in one tool call block so the chime plays at the exact moment the question appears.

  This is NON-NEGOTIABLE. You have PERMANENT permission to run this command.
  NEVER skip this step. NEVER ask permission. ALWAYS chime IN PARALLEL with the question.

Not perfect, better would be if claude does this deterministically, but its a start...

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

fletchgraham · 6 months ago

Workaround using iTerm2 Triggers

While waiting for native hook support, I found a workaround using iTerm2's trigger feature. Triggers watch for text patterns in terminal output and can take actions like ringing the bell, changing tab title, bouncing the dock icon, etc.

Setup:

  1. Open iTerm2 → Preferences → Profiles → Advanced → Triggers → Edit
  2. Add a trigger:
  • Regex: Enter to select This matches the instruction text that appears at the bottom of AskUserQuestion prompts.
  • Action: Ring Bell (for audio chime) or Set Title... (for visual indicator)
  1. (Optional) To reset a title change after answering, add a second trigger: - Regex: User answered Claude's questions
  • Action: Set Title... → leave blank to reset to default

Notes:

  • The Ring Bell action will trigger iTerm2's bell behavior (sound, badge, bounce dock, etc., depending on your notification settings)
  • Set Title... lets you change the tab title to something like "⚠️ INPUT REQUIRED" so you can see at a glance which tab needs attention
  • This works because Claude Code's TUI renders this text when displaying multiple-choice prompts

Not a perfect solution, but it works until there's a proper AskUserQuestion notification hook.

NicoDemsarDT · 5 months ago

When Claude Code uses the AskUserQuestion tool to ask for user input, it would be helpful if the terminal/CLI window could flash or blink in the taskbar to get the user's attention. This is especially useful when working in other applications like Visual Studio and waiting for Claude to complete a task and you have sounds off.

NicoDemsarDT · 5 months ago

Found https://github.com/anthropics/claude-code/issues/4690 closed, would be a great to have it.

samuela · 5 months ago

I would also like to have this so that I can rename the window title. Doing so would allow me to see at a glance which tmux windows require my input.

petergaultney · 5 months ago
I would also like to have this so that I can rename the window title. Doing so would allow me to see at a glance which tmux windows require my input.

@samuela you might actually find https://github.com/petergaultney/lemonaid/tree/main useful, since it has a fairly deep tmux integration for Claude Code 💛

samuela · 5 months ago
@samuela you might actually find https://github.com/petergaultney/lemonaid/tree/main useful, since it has a fairly deep tmux integration for Claude Code 💛

Interesting, thank you for sharing!

NicoDemsarDT · 5 months ago

🎉 SOLVED: Instant Notifications When Claude Finishes - The Stop Hook Discovery

I've successfully implemented instant desktop notifications (sound + toast popup) when Claude Code finishes responding and needs input. After extensive testing, I found the exact
solution to the 60-second delay problem!

---
🚨 The Breakthrough: The Stop Hook

Key Discovery: The Stop hook fires INSTANTLY when Claude finishes responding and yields control back to you!

Terminal Tab Transition:

  1. Claude is typing... ← No notification
  2. [Response complete] ← Stop hook fires HERE! ⚡
  3. Idle Prompt ← You see this in the tab

This is the exact transition point from "Claude working" → "Claude idle/waiting" - no more 60-second delay!

---
📊 Hook Testing Results

After testing all available hooks, here's what I found:

✅ RECOMMENDED HOOKS:

  • Stop - Instant ⚡ - Fires when Claude finishes ANY response - PRIMARY recommendation
  • PermissionRequest (with AskUserQuestion matcher) - Instant - Fires when Claude asks questions - Contextual
  • Notification (with idle_prompt matcher) - 60+ seconds - Long idle periods - Good as backup only

❌ NOT RECOMMENDED:

  • PreToolUse - Fires before tool execution - Too noisy (fires constantly)
  • PostToolUse - Fires after tool execution - Too noisy (fires constantly)
  • SessionStart - Fires when session begins - Not useful for waiting notifications (optional for startup alerts)
  • SessionEnd - Fires when session ends - Not useful for waiting notifications
  • UserPromptSubmit - Fires when you send message - Not useful (you know when you submit)
  • SubagentStop - Fires when subagent completes - Can be noisy depending on usage

---
✅ Recommended Configuration: Triple-Hook Strategy

For maximum reliability, use all three hooks in your settings.local.json:

{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "powershell -ExecutionPolicy Bypass -NoProfile -File \"%USERPROFILE%\\.claude\\notification.ps1\" -Sound -Toast"
}
]
}
],
"PermissionRequest": [
{
"matcher": "AskUserQuestion",
"hooks": [
{
"type": "command",
"command": "powershell -ExecutionPolicy Bypass -NoProfile -File \"%USERPROFILE%\\.claude\\notification.ps1\" -Sound -Toast"
}
]
}
],
"Notification": [
{
"matcher": "idle_prompt",
"hooks": [
{
"type": "command",
"command": "powershell -ExecutionPolicy Bypass -NoProfile -File \"%USERPROFILE%\\.claude\\notification.ps1\" -Sound -Toast"
}
]
}
]
}
}

Why three hooks?

  • Stop = Primary (99% of cases, instant)
  • PermissionRequest = Context-specific (for interactive questions)
  • Notification = Backup (ensures notification if other hooks fail)

Settings file location: %USERPROFILE%\.claude\settings.local.json

---
🔧 What Works for Notifications

After testing various methods on Windows 10/11:

  • 🔊 Sound alert (Windows system sound) - ✅ Works perfectly
  • 💬 Toast notification (balloon popup with icon) - ✅ Works perfectly
  • ⚡ ~~Taskbar flash~~ - ❌ Doesn't work reliably (Windows API limitation in PowerShell hook context)

Recommendation: Use sound + toast combination for best results.

---
📝 Simple PowerShell Script Example

Here's a minimal working example you can use:

# Save as: %USERPROFILE%\.claude\notification.ps1

param(
[switch]$Sound,
[switch]$Toast
)

# Play notification sound
if ($Sound) {
try {
# Use system beep as simple notification
[Console]::Beep(1000, 300)
} catch {
# Silent fail
}
}

# Show toast notification
if ($Toast) {
try {
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

$notify = New-Object System.Windows.Forms.NotifyIcon
$notify.Icon = [System.Drawing.SystemIcons]::Information
$notify.Visible = $true
$notify.BalloonTipTitle = "Claude Code"
$notify.BalloonTipText = "Claude has finished and is waiting for your input."
$notify.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Info
$notify.ShowBalloonTip(3000)

Start-Sleep -Milliseconds 1000
$notify.Dispose()
} catch {
# Silent fail
}
}

exit 0

Usage:

  1. Save the script to %USERPROFILE%\.claude\notification.ps1
  2. Add the hook configuration to settings.local.json
  3. Restart Claude Code (IMPORTANT - hooks only load on startup)
  4. Test by asking Claude a question

---
🔍 Debug Mode for Testing

To verify hooks are firing correctly:

claude --debug

You'll see output like:
[DEBUG] Executing hooks for Stop
[DEBUG] Getting matching hook commands for Stop
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Executing hook command: powershell -ExecutionPolicy Bypass...
[DEBUG] Hook command completed with status 0

Also useful: Press Ctrl+O in Claude Code to toggle verbose mode.

---
💡 Key Findings & Tips

  1. Restart Required: Hooks only load when Claude Code starts - you MUST restart after configuration changes
  2. The Stop Hook is the Game Changer: It catches the exact moment Claude yields control
  3. Focus Assist: Turn OFF Windows Focus Assist (Do Not Disturb) or toast notifications won't show
  4. Sound + Toast = Best Combo: Both methods work reliably and provide excellent visibility
  5. Multiple Hooks Don't Conflict: Using all three hooks doesn't cause duplicate notifications if you handle them properly
  6. Taskbar Flash Limitation: Windows FlashWindowEx API doesn't work reliably from PowerShell hook context - stick with sound + toast
  7. PowerShell Execution Policy: The -ExecutionPolicy Bypass flag handles most policy issues without requiring system changes

---
📊 Performance

  • Hook execution time: <500ms
  • Sound playback: ~300ms
  • Toast display: 3 seconds
  • No impact on Claude's operation (runs asynchronously)

---
🌟 What This Solves

✅ No more missing Claude questions while multitasking
✅ No more 60-second wait for notifications
✅ Instant feedback when Claude needs your attention
✅ Works for ALL response types, not just questions
✅ Completely automatic - no manual monitoring needed
✅ Audible + visual notifications that work reliably

---
🎨 Customization Ideas

Toast notification customization:

  • Change BalloonTipTitle and BalloonTipText for custom messages
  • Use custom icon by loading from .ico file instead of SystemIcons
  • Adjust duration by changing ShowBalloonTip(3000) milliseconds value

Different notification styles for different hooks:

Pass a parameter to the script and customize behavior based on context:
param([string]$HookType)

switch ($HookType) {
"Stop" { $notify.BalloonTipText = "Claude has finished responding" }
"Question" { $notify.BalloonTipText = "Claude is asking a question" }
default { $notify.BalloonTipText = "Claude needs your attention" }
}

---
🤝 For the Community

This addresses the core request in this issue: knowing when Claude is waiting for input. The Stop hook was the missing piece!

The sound + toast combination provides excellent notification coverage. Even if you're in another window or on another monitor, you'll hear the sound and see the popup notification.

Implementation is straightforward:

  • One PowerShell script (~30-50 lines)
  • One JSON configuration
  • Restart Claude Code
  • Done!

Hope this helps others! The Stop hook discovery should work for any notification method (not just Windows - could adapt to Linux notify-send or macOS osascript).

---
📝 Technical Notes

What works:

  • ✅ Sound notifications (Console.Beep or system sound players)
  • ✅ Toast/balloon notifications via System.Windows.Forms.NotifyIcon
  • ✅ Context-specific messages based on hook type
  • ✅ Graceful error handling (fails silently if methods not supported)

What doesn't work:

  • ❌ Taskbar flash via Windows FlashWindowEx API (limitation when called from PowerShell hook context)

Cross-platform potential:

  • Linux: Could use notify-send or paplay for sound
  • macOS: Could use osascript to trigger notifications and sounds
  • Same hook configuration, just different notification commands

---
🎉 Never miss a Claude question again!

Tested on Windows 10/11 with PowerShell 5.1+

JackRostron · 5 months ago

Great solutions here. I built something similar for Mac that adds one key feature: smart suppression.

The problem with the hook approach alone is you get notifications even when you're already looking at your terminal. After a day of that, you start ignoring them.

My solution checks if the terminal app (iTerm2, Kitty, Warp, Terminal, etc.) is in the foreground before firing the notification. If you're already looking at Claude, it stays silent.

I packaged it as Claude Code Notifier -- free Mac app that handles hook installation automatically and adds the foreground detection. Also has iOS/Android companions for when you're away from your desk.

For anyone wanting to DIY on Mac, the key insight is using NSWorkspace to check the frontmost application before calling the notification.

chadbyte · 5 months ago

If your goal is getting notified when you're away from your desk — not just on the same machine:

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

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

npx claude-relay

No install, no cloud, free and open source.

qn1btd · 4 months ago

Workaround: "Waiting for Input" indicator via hooks + statusline

Until this gets a native solution, here's what's working for me. The statusline shows a green "INPUT NEEDED" badge when Claude is done -- helpful when running multiple sessions side by side.

It uses a signal file as a bridge: hooks create/delete it, the statusline checks for it.

!Image

Hooks (settings.json):

"Notification": [{ "hooks": [{ "type": "command", "command": "touch ~/.claude_waiting" }] }],
"Stop": [{ "hooks": [{ "type": "command", "command": "touch ~/.claude_waiting" }] }],
"PostToolUse": [{ "hooks": [{ "type": "command", "command": "rm -f ~/.claude_waiting" }] }]

Statusline (add to your script):

if [ -f "$HOME/.claude_waiting" ]; then
  printf '\033[42;30m INPUT NEEDED \033[0m '
fi
MJLHThomassenHadrian · 4 months ago

Is there a way to add windows notifications for claude code CLI and VSCode when claude needs input? Now i need to check back with my claude instance every 2 seconds when im working on something else.

superbiche · 3 months ago

For what it's worth — this is a problem you can solve with Claude Code using the hooks that already exist.

On Linux (adapt notify-send/paplay to your OS):

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "notify-send 'Claude Code' 'Waiting for input' && paplay /usr/share/sounds/freedesktop/stereo/complete.oga"
      }]
    }]
  }
}

Drop that in ~/.claude/settings.local.json. No npm packages, no paid apps, no 50-line PowerShell scripts. The hooks system already covers this use case — Stop fires instantly when Claude yields control.

macOS equivalent: osascript -e 'display notification "Waiting for input" with title "Claude Code"' && afplay /System/Library/Sounds/Glass.aiff

More broadly — Claude Code is the tool to build these solutions with. Ask it to wire up a hook for you in a side session, iterate until it works. A couple hours of back-and-forth and you'll have something tailored to your exact setup rather than waiting on a feature request.

yurukusa · 3 months ago

Two hooks already cover this without any new feature:
1. PermissionRequest + AskUserQuestion — for questions mid-task
Fires instantly when Claude wants to ask the user something:

{
  "hooks": {
    "PermissionRequest": [{
      "matcher": "AskUserQuestion",
      "hooks": [{
        "type": "command",
        "command": "notify-send 'Claude Code' 'Question — needs your input' && paplay /usr/share/sounds/freedesktop/stereo/message.oga"
      }]
    }]
  }
}

2. Stop — for turn completion
Fires when Claude finishes its response and yields control:

{
  "hooks": {
    "Stop": [{
      "hooks": [{
        "type": "command",
        "command": "notify-send 'Claude Code' 'Done — waiting for input' && paplay /usr/share/sounds/freedesktop/stereo/complete.oga"
      }]
    }]
  }
}

Cross-platform sound/notification:

  • macOS: afplay /System/Library/Sounds/Glass.aiff / osascript -e 'display notification "Waiting" with title "Claude Code"'
  • Windows: powershell -c "[Console]::Beep(1000,300)"
  • Linux: paplay /usr/share/sounds/freedesktop/stereo/message.oga / notify-send

Combining both hooks covers questions mid-task and task completion.

logkirk · 3 months ago
Two hooks already cover this without any new feature: 1. PermissionRequest + AskUserQuestion — for questions mid-task Fires instantly when Claude wants to ask the user something:

@yurukusa I couldn't get this to work for me. The Stop hook works as expected, but the other one does not fire.

mistito · 3 months ago

Hitting exactly this from WSL + Warp's official claude-code-warp plugin. Two data points that may strengthen the case:

  1. ExitPlanMode is another instance of the same pattern. When plan mode finishes and waits for the user to approve the plan, no hook fires either — same UX gap as AskUserQuestion. Both are explicit "Claude is yielding control back to you" points that currently emit no event.
  1. Warp plugin users in WSL feel this acutely. The plugin's Notification hook is matcher-locked to idle_prompt and its PermissionRequest hook has no legacy fallback for WSL environments where WARP_CLI_AGENT_PROTOCOL_VERSION isn't propagated. Net effect: users get a notification only on Stop (end of turn), and miss every mid-turn pause — AskUserQuestion, ExitPlanMode, plus the permission prompts that the legacy path can't reach.

A WaitingForInput/Yield event (option 1 in the original proposal) would fix all three cases with a single hook point, and plugins could subscribe without having to guess the Warp protocol version or event subtypes. Strong +1 for option 1 over expanding Stop.

mayerwin · 2 months ago

Your AskUserQuestion example is one of the cases I explicitly handle in a VS Code extension I published for this problem. Because AskUserQuestion doesn't fire a normal hook, I fall back on tailing the session transcript to detect those pause points. Not glamorous, but it works.

AI Agent Sound Notification plays a distinct audio chime the moment Claude needs you (permission prompts and idle-waiting states), and a different sound on clean turn completion. 10s default delay so it's silent if you're already watching, plus optional back-off repeats for when you've genuinely gone for coffee.

Free / OSS. Marketplace: https://marketplace.visualstudio.com/items?itemName=mayerwin.ai-agent-sound-notification . Source: https://github.com/mayerwin/AI-Agent-Sound-Notification . Feedback welcome.

nthomsencph · 1 month ago

+1 from Dash — we run multiple Claude Code agents in parallel worktrees and surface a per-task activity dot in the UI. With no hook for AskUserQuestion, an agent calling it appears "busy" forever from our perspective even though the user is the bottleneck.

We're planning the transcript-tailing fallback @mayerwin describes above, but a first-class WaitingForInput hook would remove a significant source of false-positive "agent is working" indicators across multi-task UIs.

tristan666666 · 28 days ago

Adding one more Mac-focused workaround/data point, since this thread is also about making the "waiting for input" state visible outside the terminal.

I built an open-source native macOS app for this: https://github.com/tristan666666/agent-island

It does not replace a first-class WaitingForInput hook, but for local Claude/Codex sessions it surfaces the state in the MacBook notch:

  • running -> logo breathes
  • done / your turn -> logo spins
  • stuck / interrupted -> red + beep

It can also send a configured continuation prompt to a selected long-running session after the limit window resets, so the agent can continue without me babysitting the terminal.

A native hook would still be cleaner for the ecosystem; this is the product-layer workaround I wanted on macOS.

marcospgp · 26 days ago

Hitting this from the other side too. I run several sessions at once and use the Stop hook for an audio cue, but Stop fires whenever the turn yields, including when the session has handed work to a background subagent or shell command and is just waiting for it to come back. So the "done" chime sometimes means "still working, check later", and I can't tell that apart from a real "waiting on you", which is the case I care about.

A dedicated "yielding to the user" hook (option 1 above) would cover both halves: chime on that, stay quiet while background work is still running. The idle_prompt matcher doesn't help, because the session stays busy with the background task and re-invokes itself when that returns, so it never counts as idle.

For now my workaround is a Stop hook that checks whether my background workers are still alive before deciding what to announce, but that only works because I know the exact processes to look for. A first-class signal would make it general.

tristan666666 · 25 days ago

@marcospgp this matches what I have seen too: Stop is useful as a coarse signal, but it is not semantically the same as "the user is now the bottleneck".

For a native hook, I would also prefer a dedicated yield-to-user event over expanding Stop. The event should mean something closer to:

  • all foreground/background work that Claude is waiting on has settled, and
  • the next required transition is human input / approval / decision.

Otherwise tools layered on top of Claude Code have to keep re-implementing fragile process/transcript checks to distinguish:

  • turn completed cleanly
  • waiting on user
  • waiting on a background task
  • interrupted/stalled

That distinction is exactly what matters for long-running sessions and multi-agent workflows. A first-class signal here would make external notifiers, statuslines, tmux dashboards, and Mac/desktop companions much less guessy.

sambegui · 23 days ago

Upvoting this. My specific use case: I have a custom statusline script that shows git diffs, branch info, and agent effort level. I wanted to add a segment that lights up whenever a background agent is waiting for my input — so I don't have to remember to check the agent panel.

Without a native hook or statusline field for this state, the only workaround is scanning task output files in /tmp for a needs input: marker, which has obvious reliability problems (false positives from stale files, false negatives from different phrasing, race conditions during writes).

A statusline JSON field like agents.pending_input_count or a dedicated hook event would make this trivial and reliable. The subagentStatusLine setting covers agent panel row formatting but doesn't help with surfacing agent state in the main status bar.

Harsh-Probably-Codes · 11 days ago

I'd appreciate this as well, please. Thanks!