[FEATURE] Support for In-Process Hooks in Headless CLI Mode

Resolved 💬 4 comments Opened Sep 12, 2025 by coygeek Closed Jan 8, 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

The current hook system for the claude CLI is powerful but relies exclusively on executing external shell commands. For high-frequency events like PreToolUse or PostToolUse, this creates significant performance overhead by spawning a new shell process for every single event.

Furthermore, implementing complex logic (e.g., parsing JSON, making conditional API calls, maintaining state) within a shell script is cumbersome and less robust than using a language like TypeScript or Python.

This creates a major feature gap with the TypeScript SDK, which, as the documentation states, supports in-process hooks: "Unlike CLI hooks that execute bash commands, SDK hooks are JavaScript/TypeScript functions that run in-process." To access this more performant and flexible hook mechanism, users are forced to migrate from a simple CLI script to a full SDK application, which is often overkill.

Proposed Solution

I propose adding a new CLI flag for headless mode (-p) that allows specifying a script file to handle hooks in-process, mirroring the SDK's functionality.

For example:
claude -p "Refactor the auth service" --hooks-script ./my-hooks.ts

The claude CLI would load the specified script (my-hooks.ts) at startup. This script would export named functions corresponding to the hook events. When a hook event is triggered, the CLI would call the corresponding function directly, passing the event payload as an argument, instead of spawning an external process.

Example my-hooks.ts:

import type { PreToolUseHookInput, HookJSONOutput } from '@anthropic-ai/claude-code';

// This function would be called directly by the CLI process.
export async function PreToolUse(input: PreToolUseHookInput): Promise<HookJSONOutput> {
  // Complex, fast, in-process logic here.
  if (input.tool_name === 'Write' && input.tool_input.file_path.includes('production.tf')) {
    console.error('Blocking modification to production Terraform files.');
    return {
      decision: 'block',
      stopReason: 'Modification of production Terraform files is not allowed via this script.'
    };
  }
  return { continue: true };
}

export async function PostToolUse(input) {
  // Log to an external service, update a database, etc.
  console.log(`Tool '${input.tool_name}' executed successfully.`);
  return { continue: true };
}

This would bring the power and performance of SDK hooks to CLI users, enabling more advanced and efficient automation scripts.

Alternative Solutions

  1. Continue using shell-based hooks: This is the current method, but it is not suitable for performance-sensitive or complex logic. The overhead of process creation for each event is a significant bottleneck.
  2. Migrating to the full SDK: This is a heavy-handed solution for what might otherwise be a simple script. The goal of this feature request is to make the CLI a more powerful tool for scripting and automation, bridging the gap between basic use and a full SDK implementation.

Priority

Medium - Would be very helpful

Feature Category

CLI commands and flags

Use Case Example

_No response_

Additional Context

This feature would align the CLI's capabilities more closely with the SDKs, providing a consistent and powerful developer experience for automation. As the SDK documentation itself points out, the in-process nature of SDK hooks is a key advantage. Bringing this advantage to the CLI would be a massive improvement.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗