विषय-सूची
"मैं चाहता हूँ कि हर एडिट के बाद ऑटो-फ़ॉर्मैटिंग हो।" ".env या package-lock.json को कभी कोई रीराइट न कर पाए।" "ख़तरनाक rm -rf कमांड रोक दिए जाएँ।" इन "ऐसा हमेशा होना ही चाहिए" वाले नियमों को AI की मर्ज़ी पर निर्भर हुए बिना सच में लागू करने का तरीक़ा है Claude Code hooks। एक hook वह shell कमांड है जो Claude Code के लाइफ़साइकल में निश्चित बिंदुओं पर अपने-आप चलता है, और hooks plugins का एक बुनियादी हिस्सा भी हैं।
यह लेख आधिकारिक दस्तावेज़ के आधार पर बताता है कि hooks क्या हैं, इवेंट की सूची, उन्हें कैसे कॉन्फ़िगर करें, इनपुट/आउटपुट कॉन्ट्रैक्ट, उपयोग-केस और सुरक्षा। पहले तीन मुख्य बातें। ① एक hook "हार्नेस (यानी Claude Code ख़ुद) द्वारा चलाया जाने वाला डिटरमिनिस्टिक लॉजिक" है—यह पक्का चलता है, मॉडल के "करने का फ़ैसला" लेने का इंतज़ार किए बिना। ② आप hooks को settings.json में इवेंट नाम → matcher → command के रूप में लिखते हैं। ③ PreToolUse जैसे इवेंट exit code 2 या JSON के ज़रिए "ब्लॉक" कर सकते हैं—सुरक्षित फ़ाइलों में एडिट या ख़तरनाक कमांड रोककर।
मुख्य लाइफ़साइकल बिंदुओं पर "पक्का" चलता है
— इसे हार्नेस डिटरमिनिस्टिक रूप से चलाता है, मॉडल के फ़ैसले से नहीं
SessionStart
सेशन शुरू होता है। आउटपुट कॉन्टेक्स्ट के रूप में जोड़ा जाता है
UserPromptSubmit
जब कोई प्रॉम्प्ट सबमिट होता है [ब्लॉक कर सकता है]
PreToolUse
किसी टूल के चलने से ठीक पहले = गेटकीपर [ब्लॉक कर सकता है]
PostToolUse
किसी टूल के सफल होने के बाद = ऑटो-फ़ॉर्मैट / ऑडिट
Stop
जब कोई रिस्पॉन्स ख़त्म होता है = टेस्ट पास होने तक चलते रहो, आदि [ब्लॉक कर सकता है]
हर बिंदु पर आपका shell कमांड चलता है। क्लासिक उदाहरण: PreToolUse से ख़तरनाक कार्रवाइयाँ दरवाज़े पर ही रोकना, PostToolUse से ऑटो-फ़ॉर्मैट।
1. Claude Code hooks क्या हैं?
आधिकारिक परिभाषा इस तरह है: "Hooks यूज़र द्वारा परिभाषित shell कमांड हैं जो Claude Code के लाइफ़साइकल में निश्चित बिंदुओं पर चलते हैं। ये Claude Code के व्यवहार पर डिटरमिनिस्टिक नियंत्रण देते हैं, यह सुनिश्चित करते हुए कि कुछ कार्रवाइयाँ हमेशा हों, बजाय इसके कि LLM उन्हें चलाने का चुनाव करे।" आप इनका इस्तेमाल प्रोजेक्ट नियम लागू करने, दोहराव वाले कामों को ऑटोमेट करने, और Claude Code को अपने मौजूदा टूल्स से जोड़ने के लिए करते हैं।
इसका मूल है डिटरमिनिज़्म। Claude से कहिए "टेस्ट चलाओ" और वह चलाएगा या नहीं, यह उसके "फ़ैसले" पर निर्भर करता है। पर एक hook के साथ हार्नेस उसे हमेशा चलाता है—कोई मर्ज़ी बीच में नहीं आती। कमांड (command) के अलावा अब HTTP, MCP टूल्स, LLM प्रॉम्प्ट और सबएजेंट वेरिफ़िकेशन जैसे हैंडलर टाइप भी हैं—पर शुरुआत के लिए hooks को "मुख्य बिंदुओं पर हमेशा एक shell कमांड चलाने की एक व्यवस्था" के रूप में सोचना काफ़ी है। ध्यान दें कि LLM प्रॉम्प्ट और सबएजेंट वाले हुक में एक बग था: "ऐसे कमांड ब्लॉक करो जो..." जैसे निर्देश के रूप में लिखे जाने पर वे वह भी आगे जाने देते थे जिसे रोकना था; इसे v2.1.294 में ठीक किया गया (आधिकारिक changelog)।
2. hook इवेंट
एक इवेंट दर्शाता है कि "लाइफ़साइकल में यह कहाँ चलता है।" नौ क्लासिक इवेंट से शुरू करें ("ब्लॉक कर सकता है" = आप उस कार्रवाई को exit code 2 या JSON के ज़रिए रोक सकते हैं)।
| इवेंट | कब चलता है | ब्लॉक |
|---|---|---|
| SessionStart | कोई सेशन शुरू या रिज़्यूम होता है (stdout कॉन्टेक्स्ट के रूप में जोड़ा जाता है) | नहीं |
| UserPromptSubmit | आप कोई प्रॉम्प्ट सबमिट करते हैं, Claude द्वारा उसे प्रोसेस करने से पहले (v2.1.299 से स्किल्स और कस्टम स्लैश कमांड विस्तारित होने से पहले होता है, और इसे ब्लॉक करने पर कमांड में एम्बेड किए गए शेल कमांड भी नहीं चलते। आधिकारिक दस्तावेज़ · चेंजलॉग, 18 अक्टूबर 2026 को पुष्टि की गई) | हाँ |
| PreToolUse | किसी टूल कॉल से ठीक पहले (मुख्य गेटकीपर) | हाँ |
| PostToolUse | किसी टूल के सफल होने के बाद (कार्रवाई ख़ुद अनडू नहीं हो सकती) | नहीं |
| Notification | किसी नोटिफ़िकेशन पर (इनपुट/अनुमति का इंतज़ार, आदि) | नहीं |
| Stop | जब Claude जवाब देना ख़त्म करता है (ब्लॉक = काम करते रहो) | हाँ |
| SubagentStop | जब कोई सबएजेंट ख़त्म होता है | हाँ |
| SessionEnd | जब कोई सेशन समाप्त होता है | नहीं |
| PreCompact | कॉन्टेक्स्ट कॉम्पैक्शन से पहले | हाँ |
2026 के दस्तावेज़ में कई और इवेंट जोड़े गए हैं—PermissionRequest, PostToolUseFailure, ConfigChange, FileChanged, WorktreeCreate और अन्य। पर इवेंट नाम वर्शन के बीच जोड़े या बदले जा सकते हैं, इसलिए यह लेख स्थिर नौ क्लासिक इवेंट और अगले सेक्शन के कॉन्ट्रैक्ट पर आधारित है (मौजूदा पूरी सूची के लिए आधिकारिक दस्तावेज़ देखें)।
3. hooks कैसे कॉन्फ़िगर करें
आप hooks को settings.json में "hooks" की के तहत लिखते हैं। स्थान दायरा (scope) तय करता है: यूज़र (~/.claude/settings.json) / प्रोजेक्ट (.claude/settings.json, git-शेयर करने योग्य) / लोकल (.claude/settings.local.json) / मैनेज्ड पॉलिसी (संगठन) / किसी plugin का hooks/hooks.json। JSON का स्वरूप इस तरह दिखता है।
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
संरचना इस तरह है: "hooks → इवेंट नाम → { matcher, hooks:[...] } का एक ऐरे → हर hook में type + command।" matcher लक्ष्य टूल का नाम बताता है: "*" (या छोड़ देने पर) सभी से मैच करता है, "Edit|Write" एक |-विभाजित सूची है, और अन्य कैरेक्टर regex होते हैं (उदा. mcp__memory__.*)। यह केस-सेंसिटिव है। /hooks कमांड कॉन्फ़िगर किए गए hooks की सूची दिखाता है पर केवल-पढ़ने वाला (read-only) है—जोड़ने या बदलने के लिए सीधे settings.json एडिट करें। सबको बंद करने के लिए "disableAllHooks": true इस्तेमाल करें।
4. इनपुट/आउटपुट कॉन्ट्रैक्ट
एक hook स्टैंडर्ड इनपुट (stdin) पर JSON प्राप्त करता है और अपना परिणाम exit code या स्टैंडर्ड आउटपुट पर JSON के ज़रिए लौटाता है।
इनपुट (stdin): सामान्य फ़ील्ड में session_id, transcript_path, cwd और hook_event_name शामिल हैं। टूल इवेंट tool_name और tool_input जोड़ते हैं (उदा. {"command":"rm -rf /tmp/build"}); UserPromptSubmit prompt जोड़ता है। Exit codes: 0 = सफलता (कुछ इवेंट के लिए stdout कॉन्टेक्स्ट में जोड़ा जाता है—हालाँकि PreToolUse पर exit 0 "मंज़ूरी" नहीं है; सामान्य अनुमति प्रवाह फिर भी लागू रहता है), 2 = ब्लॉक (stderr को Claude को समायोजन की सामग्री के रूप में दिया जाता है, और JSON में "allow" लौटाकर भी इस ब्लॉक को पलटा नहीं जा सकता)।
जब हुक ख़ुद विफल हो (शुरू ही न हो, टाइमआउट हो जाए, या अप्रत्याशित exit code से ख़त्म हो), तो ज़्यादातर इवेंट पर डिफ़ॉल्ट रूप से कार्रवाई आगे बढ़ जाती है। ग़लत पाथ वाला पहरेदार हुक बस एक एरर सूचना दिखाता है और कुछ नहीं रोकता। v2.1.295 से command या http हुक में "onFailure": "block" जोड़ने पर हुक विफल होने की स्थिति में कार्रवाई रोक दी जाती है (डिफ़ॉल्ट "continue" है)।
# उदाहरण: स्ट्रक्चर्ड JSON आउटपुट के ज़रिए PreToolUse से "deny" (stdout पर प्रिंट)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Database writes are not allowed"
}
}
# सामान्य फ़ील्ड: continue (false = पूरी तरह रुको) / decision:"block"+reason /
# additionalContext (Claude के लिए जोड़ा जाता है) / updatedInput (आर्ग्स रीराइट करें)
v2.1.300 (14 अक्टूबर 2026) से, PreToolUse और PermissionRequest हुक द्वारा लौटाया गया updatedInput Claude के अपने इनपुट की तरह ही वैलिडेट किया जाता है। टूल जो कीज़ नहीं पहचानता वे हटा दी जाती हैं, और अगर हुक ऐसा इनपुट लौटाता है जो टूल स्वीकार नहीं करता, तो वह कॉल अस्वीकार कर दी जाती है (चेंजलॉग, 18 अक्टूबर 2026 को पुष्टि की गई)।
सबसे अहम सिद्धांत: "hooks पाबंदियाँ सख़्त कर सकते हैं पर ढीली नहीं।" allow लौटाना केवल प्रॉम्प्ट छोड़ देता है; किसी भी दायरे (मैनेज्ड सेटिंग्स सहित) में deny नियम हमेशा प्राथमिकता पाते हैं। एक PreToolUse deny bypassPermissions / --dangerously-skip-permissions के तहत भी ब्लॉक करता है। यह सिद्धांत सेटिंग्स फ़ाइलों में लिखे hooks पर लागू होता है, जिन्हें mods के डॉक्यूमेंटेशन में "settings hooks" कहा गया है: v2.1.287 से, tool.check का जवाब देने वाला mod (ऐसा plugin जिसके hooks फ़ंक्शन होते हैं) उस कॉल को मंज़ूर कर सकता है जिस पर ask नियम पुष्टि माँगता या जिसे PreToolUse hook ने ब्लॉक किया हो (जब तक वह hook मैनेज्ड सेटिंग्स में न हो); auto मोड में उसकी मंज़ूरी classifier से नहीं गुज़रती, और मैनेज्ड सेटिंग्स वाली मशीनों या Team या Enterprise प्लान से साइन-इन को छोड़कर वह deny नियम द्वारा ठुकराई गई कॉल भी मंज़ूर कर सकता है (आधिकारिक डॉक्यूमेंटेशन)। केवल भरोसेमंद लेखकों के mods ही इंस्टॉल करें। यानी hooks यह बढ़ा सकते हैं कि अनुमतियाँ कैसे मूल्यांकित हों, पर बुनियादी नियम कहीं और रहते हैं: Claude Code के परमिशन रूल्स (allow/ask/deny) settings.json में परिभाषित होते हैं। व्यापक अनुमति मॉडल के लिए, देखें अनुमति मोड और सुरक्षा।
5. उदाहरण उपयोग-केस
आधिकारिक क्लासिक उदाहरण, उनके कॉन्फ़िगरेशन के साथ।
क्लासिक ऑटोमेशन
PostToolUse + Edit|Write अपने-आप prettier / एक linter चलाता है।PreToolUse .env, .git/ आदि में एडिट को ब्लॉक करता है (exit 2)।PreToolUse rm -rf आदि का पता लगाकर deny लौटाता है।SessionStart stdout हर बार नियम और नोट फिर से लोड करता है (कॉम्पैक्शन के बाद भी)।Notification डेस्कटॉप अलर्ट के लिए; PostToolUse कमांड हिस्ट्री लॉग करने के लिए।Stop टेस्ट पास होने तक Claude को रुकने नहीं देता (हरा होने तक काम करते रहो)।
ध्यान दें: Claude Bash के ज़रिए भी फ़ाइलें बदल सकता है। हर बदलाव पकड़ने के लिए, एक Stop hook जोड़ें जो प्रति टर्न एक बार वर्किंग ट्री को स्कैन करे।
अगर आपको Stop hook ख़ुद लिखे बिना सिर्फ़ "शर्त पूरी होने तक काम जारी रखो" वाला व्यवहार चाहिए, तो /goal तुरंत इस्तेमाल किया जा सकता है (यह एक प्रॉम्प्ट-आधारित hook है जो सिर्फ़ बातचीत के भीतर काम करता है)।
6. सुरक्षा
Hooks शक्तिशाली हैं, पर वे आपके अधिकारों के साथ अपने-आप मनमाने shell कमांड चलाते हैं—इसे हल्के में न लें।
⚠️ आधिकारिक चेतावनी
"Command hooks आपकी पूरी यूज़र अनुमतियों के साथ shell कमांड चलाते हैं। आपका यूज़र अकाउंट जिन फ़ाइलों तक पहुँच सकता है, उन्हें वे बदल सकते हैं, हटा सकते हैं या पढ़ सकते हैं। कॉन्फ़िगरेशन में जोड़ने से पहले सभी hook कमांड की समीक्षा और परीक्षण करें।" Hooks फ़ाइलें पढ़ सकते हैं, आपका कोडबेस बदल सकते हैं, डेटा बाहर भेज सकते हैं, या कोई भी कमांड चला सकते हैं—केवल वही कॉन्फ़िगर करें जिन पर आप पूरी तरह भरोसा करते हैं।
फ़ोल्डर पर भरोसा (एक अहम सुरक्षा तंत्र): इंटरैक्टिव सेशन में, जब तक आप फ़ोल्डर का trust डायलॉग स्वीकार नहीं करते, सेटिंग्स फ़ाइलों के hooks नहीं चलते (आपकी अपनी ~/.claude/settings.json वाले भी)। -p या SDK सेशन में डायलॉग नहीं आता और फ़ोल्डर को भरोसेमंद मान लिया जाता है, इसलिए किसी रिपॉज़िटरी में चलाने से पहले उसकी .claude/ सेटिंग्स जाँच लें। सेटिंग्स फ़ाइलों में hooks के सीधे बदलाव आम तौर पर अपने-आप लागू हो जाते हैं।
व्यवहार में: हमेशा इनपुट को वैलिडेट और कोट करें (jq से निकालें; बिना कोट वाले वैरिएबल अतिरिक्त आर्ग्स या shell सिंटैक्स बन सकते हैं), एब्सोल्यूट पाथ और ${CLAUDE_PROJECT_DIR} इस्तेमाल करें, .env या .ssh जैसी संवेदनशील फ़ाइलों को न छुएँ, और टूल आउटपुट को कभी eval न करें। Hooks बिना किसी कंट्रोलिंग टर्मिनल के चलते हैं (कोई /dev/tty नहीं)। संगठनों में, एडमिन allowManagedHooksOnly से hooks पर पाबंदी लगा सकते हैं।
सारांश
Claude Code hooks यूज़र द्वारा परिभाषित shell कमांड हैं जो मुख्य लाइफ़साइकल बिंदुओं पर अपने-आप चलते हैं, और "ऐसा हमेशा होना ही चाहिए" को मॉडल के फ़ैसले पर निर्भर हुए बिना सच और डिटरमिनिस्टिक बना देते हैं। क्लासिक इवेंट नौ हैं: SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / Notification / Stop / SubagentStop / SessionEnd / PreCompact (PreToolUse और अन्य ब्लॉक कर सकते हैं—सुरक्षित फ़ाइलों में एडिट या ख़तरनाक कमांड रोककर)। आप इन्हें settings.json में "hooks" के तहत इवेंट → matcher → type + command के रूप में कॉन्फ़िगर करते हैं।
I/O है stdin पर JSON, exit code 0 (सफलता) / 2 (ब्लॉक), या stdout पर स्ट्रक्चर्ड JSON। सिद्धांत: "आप पाबंदियाँ सख़्त कर सकते हैं पर ढीली नहीं" (deny हमेशा जीतता है, mods वाले अपवाद को छोड़कर — खंड 4 देखें)। क्लासिक उपयोग-केस: ऑटो-फ़ॉर्मैट, फ़ाइलों की सुरक्षा, ख़तरनाक कमांड रोकना, कॉन्टेक्स्ट फिर से इंजेक्ट करना, ऑडिट, रुकने से पहले टेस्ट। पर चूँकि वे मनमाना कोड चलाते हैं, केवल सुरक्षित hooks पर भरोसा करने और इनपुट को वैलिडेट/कोट करने के बारे में सख़्त रहें, और समझें कि इंटरैक्टिव सेशन में फ़ोल्डर पर भरोसा जताने तक सेटिंग्स फ़ाइलों के hooks नहीं चलते। संबंधित: plugins, MCP, Claude Code त्रुटियाँ, mods (आधिकारिक ओवरव्यू), और विस्तृत गाइड: Claude Code Mods क्या हैं।
FAQ
Q. hooks किसलिए हैं?
A. वे "ऐसा हमेशा होना ही चाहिए" को डिटरमिनिस्टिक रूप से ऑटोमेट करते हैं। "एडिट के बाद फ़ॉर्मैट करो," "सुरक्षित फ़ाइलें कभी रीराइट न हों," "ख़तरनाक rm -rf रोको," और "रुकने से पहले टेस्ट पास करो" जैसी चीज़ें AI के फ़ैसले पर निर्भर हुए बिना हार्नेस द्वारा पक्के तौर पर चलाई जाती हैं। एक hook एक shell कमांड है जो मुख्य लाइफ़साइकल बिंदुओं पर चलता है, और settings.json में कॉन्फ़िगर किया जाता है।
Q. कौन-कौन से इवेंट (समय) हैं?
A. क्लासिक नौ हैं: SessionStart (शुरू), UserPromptSubmit (सबमिट पर), PreToolUse (टूल से ठीक पहले), PostToolUse (टूल के बाद), Notification, Stop (रिस्पॉन्स ख़त्म), SubagentStop, SessionEnd (समाप्त), PreCompact (कॉम्पैक्शन से पहले)। इनमें से PreToolUse, UserPromptSubmit, Stop, PreCompact और अन्य ब्लॉक कर सकते हैं और कार्रवाई रोक सकते हैं। 2026 रिलीज़ कई और इवेंट जोड़ती है, पर नाम वर्शन के बीच बदल सकते हैं, इसलिए नवीनतम के लिए आधिकारिक दस्तावेज़ देखें।
Q. क्या मैं सुरक्षित फ़ाइलों में एडिट या ख़तरनाक कमांड रोक सकता हूँ?
A. हाँ—एक PreToolUse hook के साथ। एक स्क्रिप्ट tool_input में फ़ाइल पाथ या कमांड का निरीक्षण करती है, और अगर वह .env, rm -rf आदि से मैच करता है, तो उसे ब्लॉक करने के लिए exit code 2 (या permissionDecision:"deny" वाला JSON) लौटाती है। ख़ास बात, deny हमेशा प्राथमिकता पाता है और bypassPermissions के तहत भी रोकता है। Hooks केवल "पाबंदियाँ सख़्त करने" की दिशा में काम करते हैं। अपवाद है mod (ऐसा plugin जिसके hooks फ़ंक्शन होते हैं): tool.check का जवाब देकर वह इन फ़ैसलों को पलट सकता है, और मैनेज्ड सेटिंग्स वाली मशीनों या Team या Enterprise प्लान से साइन-इन को छोड़कर deny नियम द्वारा ठुकराई गई कॉल भी मंज़ूर कर सकता है (आधिकारिक डॉक्यूमेंटेशन)। केवल भरोसेमंद लेखकों के mods ही इंस्टॉल करें।
Q. मैंने अपना कॉन्फ़िग बदला पर यह लागू नहीं हो रहा।
A. आम तौर पर बदलाव अपने-आप लागू हो जाते हैं: जब आप सेटिंग्स फ़ाइल सीधे संपादित करते हैं, तो फ़ाइल वॉचर बदलाव पकड़ लेता है। अगर कुछ सेकंड बाद भी लागू न हो, तो हो सकता है वॉचर से बदलाव छूट गया हो—सेशन रीस्टार्ट करें। यह भी जाँचें कि JSON वैध है (आख़िर में अतिरिक्त कॉमा या टिप्पणियाँ न हों)। इंटरैक्टिव सेशन में, जब तक आप फ़ोल्डर का trust डायलॉग स्वीकार नहीं करते, सेटिंग्स फ़ाइलों के hooks नहीं चलते। ध्यान दें कि /hooks एक केवल-पढ़ने वाली सूची है; hooks जोड़ने या बदलने के लिए settings.json को सीधे संपादित करें।
Q. क्या hooks सुरक्षित हैं?
A. बिना शर्त नहीं। Hooks आपके अधिकारों के साथ मनमाने shell कमांड चलाते हैं, इसीलिए दस्तावेज़ चेतावनी देते हैं कि वे "आपकी पूरी यूज़र अनुमतियों के साथ" चलते हैं। केवल उन hooks को कॉन्फ़िगर करें जिन पर आप भरोसा करते हैं, इनपुट को jq से वैलिडेट और कोट करें, एब्सोल्यूट पाथ इस्तेमाल करें और .env / .ssh को न छुएँ, और टूल आउटपुट को कभी eval न करें। संगठनों में, एडमिन allowManagedHooksOnly से hooks पर पाबंदी लगा सकते हैं।