[KongchangAI]
· 2 min read· 1,180 words

Claude Code Hooks in Practice: Auto-Format Code and Block Sensitive Operations

Claude Code Hooks in Practice: Auto-Format Code and Block Sensitive Operations

Claude Code Hooks use events, matchers, and scripts to turn verbal agreements into hard rules.

Based on episode 13 of the "Claude Code Whiteboard Course," this article explains Claude Code's Hooks mechanism. Hooks consist of lifecycle events, matchers, and scripts—upgrading prompts from "requests" to "guarantees" that execute automatically. Configured in the hooks block of settings files, they apply across user, project, and local layers and merge on trigger. Three scenarios show how: after-tool-call events auto-format files and return errors to the model for self-correction; before-tool-call events with exit code 2 block sensitive files (single-operation only); notification events send desktop alerts when confirmation is needed, enabling unattended work. Also covers loop timers (up to seven days, customizable loop.md patrol checklist) versus conditional tasks—loops are time-based, goals are condition-based.

Claude Code's Hooks mechanism turns verbal agreements like "format the code after editing" into hard rules that execute no matter what. Based on episode 13 of the "Claude Code Whiteboard Course" on Bilibili, this article breaks down the three-part structure of Hooks and demonstrates three real-world scenarios showing how to make Claude Code manage itself.

What Are Hooks: From "Request" to "Guarantee"

A prompt is essentially a request, not a promise. You can write "format after editing" a hundred times in your manual, but the model will still forget occasionally. Hooks solve this problem: they turn must-happen actions into scripts that execute automatically at the right moment.

The most satisfying automation isn't AI writing code for you—it's AI managing itself. A hook has only three components: a lifecycle event, a matcher, and your script. Events include "before tool call," "after tool call," "session start," and so on. The matcher filters for the tools you care about. What the script does is entirely up to you.

The biggest difference from prompts: prompts are requests, hooks are guarantees—they execute no matter what. Hooks can do more than run scripts—they can send network requests or call models for judgment.

Calling a model for judgment works too

Lifecycle events are the trigger anchors for Hooks—a series of fixed moments that Claude Code broadcasts during execution, such as session start, user prompt submission, before tool call, after tool call, model response completion, and session end. Each event carries structured JSON input (including session ID, tool name, tool parameters, etc.), which the script reads from standard input. The event itself doesn't care what you do with it—it just hands control to the script at the right moment. The script's exit code and output are then interpreted by the framework as "allow/block" or as additional context passed to the model. This is why the same event model can be used for code formatting, access control, and notifications.

Configuration: All Three Settings Layers Apply

Hooks are configured in the hooks block of settings files. All three settings layers discussed earlier (user-level, project-level, local-level) apply. Hooks from multiple layers are merged and triggered independently without overriding each other. Save the file and it takes effect on the next action.

One common pitfall: remember to make your script executable, or it will fail silently—nothing appears to happen, and troubleshooting takes a lot of time.

Scenario 1: Auto-Format Files After Editing

Use the "after tool call" event and match file-editing tools. The script extracts the file path from the input, passes it to the formatter, and returns the result to the session.

The key design here is error handling: if formatting fails, the error message is also returned to the model, and it will fix it itself in the next round. Once it finishes writing, someone cleans up—you don't have to watch. This is where Hooks provide the most value—not replacing the model's code writing, but adding automatic fallback to the model's behavior.

Scenario 2: Sensitive Files Off-Limits

The second scenario is stricter: run a check script on "before tool call." When it hits the protection list—environment variable files, lock files, etc.—the script exits with code 2, and the operation is blocked outright. The reason is returned to the model, which will find another way. Rules go from verbal agreements to access control.

Note the semantics of blocking: it means "not this time," not a permanent blacklist. Normal edits outside the list are unaffected, so daily development isn't disrupted.

Sensitive files off-limits

Exit code 2 is a convention with special semantics in Hooks: exit code 0 means allow, exit code 2 means "block this operation" (the standard error output is returned to the model as the reason for blocking, so it knows why it was rejected and tries another path), and other non-zero exit codes are generally treated as script errors and don't necessarily block. Therefore, blocking scripts must explicitly exit with 2, not casually use exit 1. This convention translates "the script's judgment" into "an actionable decision for the framework"—the technical prerequisite that makes blocking hooks possible.

Scenario 3: Desktop Notifications When Confirmation Is Needed

When Claude Code is waiting for your confirmation or input, it triggers a notification event. Configure a command to send a desktop notification, and you no longer have to stare at the terminal. Notifications also have types—you can configure them only for specific situations, each with its own settings.

This capability makes "walk away and do something else" a reality: let it work in the background and call you when it needs you.

Walk away and do something else

Beyond Hooks: Session Timers and Loops

Beyond Hooks, there are session-level timed loops. The slash command loop supports checking deployments every five minutes, running on its own schedule. You can omit the interval—it will pick its own pace: stop when there's activity, rest when there's none. Loops last up to seven days and stop when the session closes. Patrol results are reported back in the session, so history is visible at a glance.

The content of long-term scheduled patrols is customizable: place a loop.md in your project with your own checklist, such as "when a branch goes red, pull logs to locate the issue and push a minimal fix." If you don't write this file, the built-in logic is used—continue unfinished work, watch merge requests, do cleanup when idle.

Watch merge requests

One more command: the slash hook sets a completion condition, and it keeps working round after round until the condition is met or you stop it. The difference between loops and conditional tasks can be summarized as: loops are time-based, goals are condition-based. Combined with acceptance criteria, long-running tasks can run unattended with more confidence.

loop.md is a custom patrol checklist file placed in the project root directory, used to override the default behavior of the loop command. List in natural language the items you want checked and handled repeatedly during the loop, such as "when a branch goes red, pull logs to locate the issue and push a minimal fix" or "reply to each unread merge request comment." The slash command loop reads this checklist when started and plans each round's actions based on its items. If the file doesn't exist, it falls back to the built-in logic (continue unfinished tasks, watch merge requests, do cleanup). It's essentially handing a "duty manual" to the AI, making long-running patrol content versionable and shareable across the team.

One-Line Summary: Writing a Rule a Hundred Times Is Worse Than Blocking Once

Make must-happen actions into hooks, judgment calls into skills, and patrols into loops. These three layers form the skeleton of Claude Code automation.

Here's an action item you can do today: configure the simplest hook—auto-run Lint or formatting after file edits—then have it edit two files and check whether formatting actually executed. Once configured, you have your first hard rule. Next, add blocking and notifications.

Claude Code can already manage itself. Next episode covers sub-agents and parallelism: leave judgment to the main thread and outsource the grunt work.

#Claude Code#Hooks#auto-format#sensitive file blocking#AI coding assistant
Share:

Related articles