[FEATURE] Add turn_status field to Stop hook payload (done vs waiting_on_user)
- [x] I searched existing issues and didn't find a duplicate
- [x] This is a single feature request
Problem Statement
The Stop hook fires at every end-of-turn with the same payload (session_id, transcript_path, stop_hook_active) regardless of whether the assistant finished its work or is genuinely waiting for the user to respond. Hooks that want to react differently in those two cases — reminder/nudge systems, approval queues, "did Claude ask a question I missed?" notifications — have to parse the last assistant text themselves.
Text-based heuristics miss rhetorical questions, quoted questions, and asks phrased with unusual wording. LLM-based classifiers add 2+ seconds of latency per turn-end, which is prohibitive.
Concrete scenario: I built a nudge system that writes a reminder file when Claude finishes a turn waiting on user input. A daemon speaks that reminder aloud after 5 minutes of silence. The regex-based matcher in the hook only checks the final sentence, so responses like:
Want me to build X? Here is what it would do...
(question in the penultimate sentence) silently drop to the floor. False negatives mean I lose my train of thought because no reminder fires.
Proposed Solution
Add a turn_status field to the Stop hook payload:
{
"session_id": "...",
"transcript_path": "...",
"stop_hook_active": false,
"turn_status": "done"
}
With values "done" or "waiting_on_user". Claude already knows internally whether it ended the turn with a question/ask or a completion — this just exposes it to hooks.
Hook code becomes a one-liner:
TURN_STATUS=$(echo "$INPUT" | jq -r '.turn_status')
if [ "$TURN_STATUS" = "waiting_on_user" ]; then
# write the nudge / surface the prompt / add to approval queue
fi
Alternative Solutions
- Regex-based last-text matching — brittle, misses edge cases (rhetorical questions, unusual phrasings, asks not in the final sentence).
- Send last assistant text to an LLM classifier (
claude -p) — adds ~2 seconds per turn-end, costs capacity. - Require the model to emit a special end-of-turn token — adds prompt burden, still requires parsing.
None work as well as a deterministic server-side flag.
Priority
Medium
Feature Category
Developer tools
Use Case Example
Escalating-nudge daemon: the assistant finishes a turn asking a question. After 5 minutes of silence the daemon speaks "First reminder…" with the last two sentences of context; at 10 minutes "Second reminder…"; at 15 minutes "Final reminder…". When the user responds, a UserPromptSubmit hook clears the reminder file. Without turn_status, the Stop hook has to classify intent from text. A single .turn_status == "waiting_on_user" check would eliminate all the guessing.
Additional Context
This blocks any hook that wants to react differently to "Claude is done" vs "Claude is asking you something" — approval queues, audit logs, reminder systems, focus-mode integrations, voice modes.
Environment
- Claude Code Version: 2.1.112
- Platform: Anthropic API (Max subscription)
- Operating System: macOS 26.3.1 (arm64, Apple M2 Pro, 16 GB)
- VS Code: 1.114.0
- VS Code extension: anthropic.claude-code 2.1.112
- Terminal/Shell: VS Code integrated terminal, zsh 5.9
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗