Skip to content

Conversation

@pahud
Copy link
Contributor

@pahud pahud commented Jan 10, 2026

Description

Implements decision: ask support for PreToolUse hooks, allowing hooks to prompt users for confirmation before tool execution.

Closes #3596

Changes

  • Added HookDecision enum (Allow, Ask, Block) and HookResponse struct for parsing JSON responses from hooks
  • Updated HookOutput type to include parsed HookResponse
  • Added prompt_hook_confirmation() helper for user y/n prompts
  • Updated PreToolUse hook handling to process JSON decision responses
  • Added unit tests for JSON parsing
  • Updated documentation with examples

How it works

PreToolUse hooks can now output JSON to STDOUT with a decision field:

json
{"decision": "ask", "message": "⚠️ This command uses sudo. Allow execution?"}

Exit Code STDOUT Behavior
0 Empty Allow
0 {"decision": "allow"} Allow
0 {"decision": "ask", "message": "..."} Prompt user (y/n)
0 {"decision": "block", "message": "..."} Block, return message to LLM
2 - Block (existing behavior)

Example hook

#!/usr/bin/env python3
import json, sys, re

input_data = json.load(sys.stdin)
command = input_data.get("tool_input", {}).get("command", "")

if re.search(r'(^|;|&&|\|\||\|)\s*sudo(\s|$)', command):
    print(json.dumps({
        "decision": "ask",
        "message": f"⚠️ This command uses sudo:\n\n  {command}\n\nAllow execution?"
    }))
sys.exit(0)

Testing

  • Added unit tests for HookResponse::from_stdout() parsing
  • Manual testing with sample hooks

- Add HookDecision enum with Allow, Ask, and Block variants for hook responses
- Add HookResponse struct to parse JSON responses from hook stdout
- Implement from_stdout() method to parse decision and optional message from JSON
- Update HookOutput type to include parsed HookResponse as third tuple element
- Add comprehensive unit tests for HookResponse parsing with various scenarios
- Add prompt_hook_confirmation() function to prompt users for hook confirmation
- Update hook execution to parse and return HookResponse from successful hook runs
- Cached hooks now return None for HookResponse since Ask decisions aren't cached
- Enable hooks to communicate decisions (allow/ask/block) back to the CLI for tool execution control
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FR: Add decision: ask support for PreToolUse hooks

1 participant