Allow hooks to trigger interactive terminal prompts with custom options

Resolved 💬 1 comment Opened Apr 23, 2026 by denis-strong-kiv Closed May 27, 2026

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 communicate with Claude Code via exit codes and stderr, but can only hard-block (exit 2) or silently allow (exit 0). There's no way for a hook to pause and ask the user a question with custom options — like the built-in permission prompt does with Allow/Deny/Always Allow.

Real use case: I have a protect-files.sh PreToolUse hook that blocks edits to sensitive files (.env, .pem, lockfiles, .git/). Currently it hard-blocks every attempt, and I have to manually work around it. I'd like the hook to show a prompt like:

Hook: protect-files wants to confirm

  Edit to .git/info/exclude — this is a protected path.

  1. Allow once
  2. Block
  3. Allow for this session

...and return the user's choice to the hook so it can decide the exit code.

Related: #51255 (asks for "ask" to work reliably in auto mode — adjacent but different; this request is about custom prompts with user-defined options, not reusing the existing permission dialog).

Proposed Solution

A hook should be able to output a structured JSON prompt request on stdout that Claude Code intercepts and renders as a terminal prompt — reusing the same TUI as the existing permission system.

Example hook stdout:

{
  "prompt": {
    "message": "Edit to .git/info/exclude — this is a protected path.",
    "options": [
      {"key": "1", "label": "Allow once", "value": "allow"},
      {"key": "2", "label": "Block", "value": "block"},
      {"key": "3", "label": "Allow for session", "value": "allow_session"}
    ]
  }
}

Claude Code renders the prompt, waits for a keypress, and pipes the selected value back to the hook's stdin (or sets an env var like $HOOK_USER_CHOICE) so the hook can decide the final exit code.

Alternative Solutions

  • macOS osascript dialogs — works but pops a separate window outside the terminal, breaking the workflow
  • Exit code 2 + stderr message — blocks unconditionally and relies on Claude (the model) to relay the message and ask the user; indirect, the user has no direct control, and the model may not relay it faithfully
  • PermissionRequest hook with "behavior": "ask" — only intercepts existing permission dialogs, can't define custom questions or options

Additional Context

The infrastructure already exists — Claude Code's terminal UI renders interactive prompts with keyboard shortcuts for the permission system. Hooks are child processes of Claude Code and already communicate via structured JSON on stdin/stdout. Bridging these two would make hooks significantly more powerful for safety and workflow gates without requiring hard blocks.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗