[FEATURE] Support for In-Process Hooks in Headless CLI Mode
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
- 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.
- 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.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗