Feature request: Hooks
Let me hook into the lifecycle of the agent(s) execution.
As an MVP, when CC completes a task.
I'm aware that this might be counter intuitive with agentic behaviors and the developer goals. But there are simple and high value efficiencies that hooks would give me and that I don't want to rely on the agent to conduct.
Hi @backnotprop , how do you envision the registration to look like for your use cases? Would you pass command line flags to claude --example-flag upon startup, register them in the chat interface, or something different?
Another question: What kind of tasks you interested in subscribing too? Tasks related to file operations (FileEditTool, FileReadTool, FileWriteTool), or any task is general (AgentTool, BashTool, ...)?
@dicksontsai Not sure if this is exactly what OP had in mind but I came across this issue when I was searching for a way to add a "hook" which could be triggered before any file write. I would have it perform a review of the proposed code changes checking for things like:
- hardcoded edge cases
- modifying production code to satisfy testing requirements
- "fallbacks" etc
@dicksontsai I dont have enough time to help you all design your product - but what would be awesome:
- hook for each of the general prompt processing cycle, from start to finish. Think about the early evolution of React lifecycle. Again, the most simplest win is the ability to execute custom project/repo commands or scripts at the end of the loop where a certain tool was called - i.e. I can always just run a validate script (e.g. lint) if Claude had written code
- In a more advanced state, hooks might just be better to integrate into the tool calling - before and after, and advanced is integrate that output into Claudes loop (basically saving me a manual step). I might alway want to enforce certain things before certain tool calls - like reading a certain file for context prefacing. Simpler than me instructing claude or bloating CLAUDE.md atm.
You guys might want to hit enterprise with this (you should - cash cow - no IDE on the market truly competes with CC).
- You will need to enable enterprise guard-railing, hooks as described above are a way.
https://google.github.io/adk-docs/callbacks/
Thanks for merging @dicksontsai. There are a lot of overlaps with this request.
- For just general lifecycle hooks, it seems like tools (via MCP) and instructions to the agent, via system prompt, CLAUDE.md or else, should cover 90% of the use-cases, assuming they are not mission critical.
- For more critical use-cases, like permission prompts and other potentially mission critical hooks (aforementioned "enterprise guardrails"), dedicated, hard-coded hooks might be required.
- My request revolves specifically around directing tool permission requests to specific endpoints / tools. I assume that would cover a large number of those enterprise guardrails, too?
- The good news is:
--permission-prompt-toolwhich does almost exactly what I am looking for already exists, but only works for-pinvocations of claude. I would like to be able to use the flag when running claude using the interactive UI, too. - If not already possible, it would probably be useful to be able to configure the permission prompt tool in the MCP config (
--mcp-config), too. - To better support the enterprise guardrail use-case, there could be a command line, environment or configuration option to force the agent to always query the permission prompt tool, regardless of user or local settings. As part of that forced query, the desired user or local settings could be passed to the permission prompt tool invocation. That way it can still enforce more strict user or local settings, while also denying certain tools or tool use based on enterprise policy even if the user gave green-light.
When running multiple Claude Code sessions concurrently, it's easy to miss when a specific session displays the tool authorization approval dialog. If there were a hook triggered at the moment a tool authorization approval is requested, it would allow users to execute a shell command to generate notifications. Even a simple implementation of such a feature would be greatly appreciated.
Until a formal hook is implemented in claude code, we have created a wrapper that allows you to hook specific actions in claude code using regular expressions: https://github.com/nahco314/cc-hook
https://docs.anthropic.com/en/docs/claude-code/hooks Well done!!!
Implemented as of v1.0.38. Please review the documentation https://docs.anthropic.com/en/docs/claude-code/hooks in detail. By adding hooks, you accept all responsibility for its execution and any consequences.
Nice Job @dicksontsai & the implementation team , really powerful.
I'd like to clarify something about hook execution. If I create a shell script at the git repository root like {git repository root}/scripts/format-kotlin.sh, and configure the hook as follows:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit|MultiEdit",
"hooks": [
{
"type": "command",
"command": "./scripts/format-kotlin.sh"
}
]
}
]
}
}
Will this always work correctly? Or would it fail if Claude Code has previously used cd commands, changing the current working directory? @dicksontsai
Amazing stuff @dicksontsai and team!
@tim-watcha Yes, Claude Code can change directories (though you may be able to pair with CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR).
By the way, if you register that as a user-level setting, then Claude Code will expect ./scripts/format-kotlin.sh to be present in every repo. I would recommend just registering this hook in each project that needs it with the absolute path. You can always use Claude to help you generate the setting!
Got it, thanks! I was planning to put it in {git root}/.claude/settings.json to share with my team. I'm kind of the Claude Code evangelist at our company, so I love showing off new features like this 😄. I'll add some git root detection logic to the command to make it work reliably. @dicksontsai
Having an ability to increase the hardcoded timeout of 60 seconds for a command would be good. Running more heavy-handed validation (e.g. E2E / System tests) on "Stop" does not reliably terminate within the 60 second time window.
Is making that configurable planned?
Sure, can you file a new issue? If anyone has any other questions, feel free to open a new issue.
Thanks for this!
Are there any examples of any metadata being passed to hooks? Eg the file that was edited, tool that was run, etc?
edit: Ah, there's a JSON passed into the hook! Oops, that looks great 👍
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.