तीन महीने। मैंने Claude Code hooks को डॉक्स में बिना पढ़े ही रहने दिया, जबकि मैं शिकायत करता रहा कि AI उन कोड को produce कर रहा है जो मेरे फॉर्मेटिंग conventions को छोड़ देते थे। मैंने जनवरी में Claude Code सेट अप किया था, तुरंत ही इससे फीचर्स ship करना शुरू कर दिया, और अपने आप से कहा कि मैं "बाद में hooks चीज़ को देखूँगा"। क्लासिक।
पता चला कि hooks एक nice-to-have नहीं थे। वे वह गायब टुकड़े थे जिससे Claude Code असल में agency workflow के अंदर फिट बैठ गया, बजाय यह कि एक बहुत महँगा autocomplete रहे जो कभी-कभी ESLint को नज़रअंदाज़ करे।
Claude Code Hooks असल में क्या हैं (कोई अस्पष्ट Abstraction नहीं)
Hooks वे शेल कमांड हैं जो Claude Code अपने operations के दौरान specific points पर चलाता है। इन्हें lifecycle events के तरह समझें, Git hooks से मिलते जुलते अगर आपने कभी pre-commit script लिखा हो, लेकिन Git के commit pipeline की बजाय AI के tool-use loop में wired।
अभी चार event types हैं:
PreToolUse, Claude किसी भी tool को call करने से पहले चलता है (फ़ाइल edits, bash commands, वगैरह)PostToolUse, एक tool call पूरा होने के बाद चलता हैNotification, जब Claude आपको notification भेजता है तब trigger होता हैStop, जब Claude अपना पूरा response turn पूरा करता है तब चलता है
आप इन्हें एक settings.json फ़ाइल में अपने प्रोजेक्ट के .claude/ फ़ोल्डर के अंदर configure करते हैं, या globally ~/.claude/settings.json में अगर आप चाहते हैं कि वे हर जगह हों। हर hook को एक matcher मिलता है (कौन सा tool या event इसे trigger करता है) और hooks array में शेल कमांड्स होते हैं।
आपके hook का आउटपुट Claude के context में वापस feed होता है। यही आखिरी बात है जो इसे genuinely दिलचस्प बनाती है, सिर्फ एक फैंसी cron job होने की बजाय।
यह अलग है क्यों सिर्फ Scripts को अपने आप चलाने से
आप हर Claude edit के बाद manually Prettier चला सकते थे। मैंने किया, करीब दो हफ्ते तक, जब तक मैं deadline push के दौरान भूल नहीं गया और 47 formatting violations वाला PR push नहीं कर दिया। Hooks automatically चलते हैं, session के अंदर, और Claude उनका आउटपुट पढ़ सकता है। तो अगर आपका linter warning throw करे, Claude इसे देखता है और एक ही session में इस पर action ले सकता है। यह feedback loop पूरा मतलब है।
वह Setup जो Seahawk Projects के लिए असल में काम आया
मैं यहाँ specific होने वाला हूँ क्योंकि generic "अपने config में hooks add करें" advice जो आप ज्यादातर write-ups में पाएँगे, context के बिना बेकार है।
Seahawk पर, हमारा एक बड़ा हिस्सा WordPress builds और WooCommerce customisations है। हम headless setups के लिए React frontends भी करते हैं, और हम 2022 से Next.js को heavily use कर रहे हैं। जो hook configuration मैं लेकर आया हूँ वह उन specific stacks को target करती है।
यहाँ settings.json structure है जो मैं एक Next.js प्रोजेक्ट के लिए use करता हूँ:
`` { "hooks": { "PostToolUse": [ { "matcher": "Write|Edit|MultiEdit", "hooks": [ { "type": "command", "command": "npx prettier --write $CLAUDE_FILE_PATHS && npx eslint --fix $CLAUDE_FILE_PATHS" } ] } ], "Stop": [ { "matcher": ".*", "hooks": [ { "type": "command", "command": "npx tsc --noEmit 2>&1 | head -20" } ] } ] } } ``
PostToolUse hook Claude द्वारा एक फ़ाइल को touch करने के तुरंत बाद Prettier और ESLint को fire करता है। Stop hook हर turn के अंत में एक TypeScript type-check चलाता है और किसी भी errors की पहली 20 lines को surface करता है। Claude उस output को पढ़ता है, और अगर type errors हैं, तो वह उन्हें fix करता है इससे पहले कि मैं response को भी देखूँ।
यह TypeScript check अकेले ने मुझे शायद पिछले महीने के fintech dashboard प्रोजेक्ट पर चार घंटे बचाए जहाँ client के पास strict noImplicitAny set था। Claude utility functions में any types generate करता रहा। जब मैंने Stop hook add किया, तो वह एक ही turn के अंदर self-correct करना शुरू कर दिया।
WordPress / PHP प्रोजेक्ट्स पर मैं जिन Hooks का उपयोग करता हूँ
WordPress एक अलग चीज है। TypeScript तो है ही नहीं, लेकिन WordPress Coding Standards ruleset के साथ PHP_CodeSniffer वह है जो चीजों को सही रखता है। 2022 में मेरे पास एक जूनियर डेव था जो एक WooCommerce प्रोजेक्ट पर था और दो हफ्ते बिना PHPCS चलाए चला गया। कोड रिव्यू... खुशनुमा नहीं था।
PHP-भारी प्रोजेक्ट्स के लिए मेरा PostToolUse hook चलाता है:
`` vendor/bin/phpcs --standard=WordPress $CLAUDE_FILE_PATHS 2>&1 | tail -30 ``
और मैं इसे bash कमांड पर एक PreToolUse hook के साथ जोड़ता हूँ:
`` { "matcher": "Bash", "hooks": [ { "type": "command", "command": "echo 'Bash tool triggered' >> ~/.claude/audit.log && date >> ~/.claude/audit.log" } ] } ``
वह दूसरा विशुद्ध सावधानी है। यह Claude चलाने वाली हर bash कमांड को एक ऑडिट लॉग में लिखता है। जब आप Claude Code को एक लाइव staging environment पर चला रहे हैं (हाँ, मैंने किया है, हाँ यह थोड़ा जोखिम भरा है), यह जानना कि कौन सी shell कमांड चलीं, वास्तव में आश्वस्त करने वाला है।
Hook Exit Codes के साथ व्यवहार को ब्लॉक करना
डॉक्स का यह हिस्सा मुझे खोजने में समय लगा। अगर आपका hook exit code 2 के साथ निकलता है, तो Claude Code इसे एक ब्लॉक मानता है और tool call के साथ आगे नहीं बढ़ेगा। Exit code 0 सफलता है, कुछ भी गैर-शून्य (लेकिन 2 नहीं) सिर्फ stderr को context के रूप में फीड करता है।
तो आप एक PreToolUse hook लिख सकते हैं जो actually Claude को कुछ करने से रोकता है। मैं इसे प्रोजेक्ट्स पर उपयोग करता हूँ जिनके पास एक migrations/ directory है जिसे मैं Claude को autonomously छूने नहीं देना चाहता:
`` #!/bin/bash if echo "$CLAUDE_FILE_PATHS" | grep -q "migrations/"; then echo "Migrations folder is protected. Do not edit migration files autonomously." exit 2 fi exit 0 ``
वह स्क्रिप्ट .claude/hooks/guard-migrations.sh पर रहती है। जब Claude migrations/ के अंतर्गत कुछ भी लिखने की कोशिश करता है, तो इसे ब्लॉक कर दिया जाता है और वह संदेश देखता है। फिर यह मुझसे आगे बढ़ने से पहले confirm करने के लिए पूछता है। सरल, प्रभावी।
यह वह तरह का नियंत्रण है जो "मैं इस AI को अपने codebase के साथ किसी हद तक विश्वास करता हूँ" और "मैं actually इसे अपने codebase के साथ विश्वास करता हूँ" के बीच का अंतर बनाता है।
व्यावहारिक Hook पैटर्न जो चोरी के लायक हैं
ये सैद्धांतिक नहीं हैं। प्रत्येक एक विशिष्ट समस्या से आया है।
- फाइल edits के बाद auto-run tests। मैं
npx jest --testPathPattern=$CLAUDE_FILE_PATHS --passWithNoTestsको एकPostToolUsehook में चलाता हूँ। यह सिर्फ उन tests को चलाता है जो Claude ने अभी edit किया है, पूरे suite को नहीं। तेज़ enough है कि annoying न हो। - Commit-ready formatting snapshot। एक
Stophook जोgit diff --statचलाता है और summary को Claude को फीड करता है। यह देखता है कि session भर में क्या बदला, जो इसे एक sensible commit message लिखने में मदद करता है अगर मैं किसी को ask करूँ। - Environment variable safety check। एक
PreToolUsehookWriteपर जो hardcoded secrets patterns के लिए grep करता है (चीजें जो API keys या passwords जैसी दिखती हैं)। अगर इसे कुछ suspicious दिखता है, तो exit2। मुझे यह 18 महीने पहले बनाना चाहिए था। - लंबे tasks के लिए notification hook। जब Claude एक notification भेजता है (
Notificationevent), मैं एकcurlcall को एक Pushover endpoint पर चलाता हूँ तो मुझे मेरे फोन पर एक push notification मिलता है। वास्तव में उपयोगी जब आप एक बड़े refactor को kick off करते हैं और चाय बनाने जाते हैं। - Bash से पहले PHP syntax check। WordPress प्रोजेक्ट्स पर, किसी भी bash execution से पहले एक quick
php -l $CLAUDE_FILE_PATHS। fatal syntax errors को एक staging server को तोड़ने से पहले catch करता है।
official Claude Code hooks documentation के पास hook scripts के अंदर उपलब्ध environment variables के लिए एक पूर्ण reference है। bookmark करने के लायक।
Hooks क्या Fix नहीं करते
ईमानदारी यहाँ मायने रखती है। Hooks Claude के logically गलत code generate करने का solution नहीं हैं। वे process समस्याओं को fix करते हैं: formatting, linting, type safety, test coverage। अगर Claude आपके data model को गलत समझता है और गलत feature बनाता है, तो कोई भी post-edit linting इसे catch नहीं करेगा।
Hooks भी latency add करते हैं। अगर आपका Prettier + ESLint pass चार सेकंड लेता है, तो हर file edit अब चार सेकंड लंबा है। एक session में 200 file edits वाली project पर, वह 13 मिनट का इंतज़ार है। अपने hook commands को profile करें। उन्हें fast रखें। मैं --fix variants चलाता हूँ (जो files को in place modify करते हैं) न कि report-only variants precisely क्योंकि एक single fast pass एक slow pass के बाद एक दूसरे corrective pass को beat करता है।
और उन्हें आपको actually अपनी project की failure modes को upfront सोचने की requirement होती है। क्या गलत हो सकता है अगर Claude गलत file edit करता है? कौन सी standards absolutely enforce की जानी चाहिए? वह सोच valuable है regardless, लेकिन इसका मतलब है कि hooks experienced developers को beginners से ज्यादा reward करते हैं।
Hooks Setup करना: Step-by-Step
किसी के लिए जो शून्य से शुरू कर रहा है:
- अपने प्रोजेक्ट रूट में एक
.claude/फ़ोल्डर बनाएँ अगर वह पहले से मौजूद नहीं है। - अपनी hooks कॉन्फ़िगरेशन के साथ एक
settings.jsonफ़ाइल जोड़ें (संरचना ऊपर दिखाई गई है)। - एक-पंक्ति से ज़्यादा किसी भी चीज़ के लिए, एक अलग शेल स्क्रिप्ट (.claude/hooks/your-script.sh) लिखें, इसे
chmod +xकरें, और कॉन्फ़िग से कमांड को इनलाइन करने के बजाय इसे कॉल करें। - अपने प्रोजेक्ट में
claudeचलाकर परीक्षण करें और जानबूझकर hook की शर्त को ट्रिगर करें। सेशन संदर्भ में जो कुछ वापस आता है उसे पढ़ें। - अगर कुछ अपेक्षित रूप से फ़ायर नहीं हो रहा है तो
~/.claude/logs/में hook निष्पादन लॉग देखें।
Anthropic डेवलपर दस्तावेज़ पूर्ण settings स्कीमा को कवर करता है। और अगर आप सोच रहे हैं कि hooks वास्तविक AI कोडिंग वर्कफ़्लो में कैसे फिट होते हैं, तो Simon Willison का ब्लॉग वह जगह है जहाँ मैं किसी को भी भेजूँगा जो agentic AI टूलिंग के बारे में अधिक सावधानीपूर्वक सोचना चाहता है।
एक चीज़ जो मैंने शुरुआत में गलत समझी: मैंने अपने सभी hooks को ग्लोबल ~/.claude/settings.json में डाले और फिर सोचने लगा कि मेरे PHP hooks JavaScript प्रोजेक्ट पर क्यों चल रहे हैं। प्रोजेक्ट-स्तर की सेटिंग्स ग्लोबल सेटिंग्स को ओवरराइड करती हैं। स्टैक-विशिष्ट hooks को प्रोजेक्ट के .claude/settings.json में रखें और अपनी ग्लोबल कॉन्फ़िग को उन चीज़ों के लिए बचाएँ जिन्हें हर जगह लागू होना चाहिए (जैसे ऑडिट लॉग और notification hook)।
FAQ
क्या Claude Code hooks Windows पर काम करते हैं?
Hook कमांड जो भी शेल आपका सिस्टम इस्तेमाल करता है उसमें चलते हैं। Windows पर यह डिफ़ॉल्ट रूप से PowerShell या CMD है, जिसका मतलब है कि bash-शैली स्क्रिप्ट नेटिवली काम नहीं करेंगी। WSL2 यहाँ व्यावहारिक उत्तर है। मैं अपने dev बॉक्स पर macOS और Ubuntu पर हूँ, इसलिए मैंने व्यक्तिगत रूप से इससे नहीं जूझा है, लेकिन Anthropic के दस्तावेज़ शेल निर्भरता को स्पष्ट रूप से नोट करते हैं।
क्या hooks Claude के conversation संदर्भ को एक्सेस कर सकते हैं?
सीधे नहीं। Hooks शेल कमांड के रूप में चलते हैं और CLAUDE_FILE_PATHS और CLAUDE_TOOL_NAME जैसे environment variables प्राप्त करते हैं, लेकिन उन्हें पूर्ण conversation transcript नहीं मिलता। जो वे कर सकते हैं वह stdout पर आउटपुट लिखना है, जिसे Claude hook चलाने के बाद संदर्भ के रूप में पढ़ता है।
क्या hooks मेरे Claude Code सेशन को ध्यान देने योग्य रूप से धीमा करेंगे?
पूरी तरह से इस पर निर्भर करता है कि आपके hooks क्या करते हैं। एक एकल फ़ाइल पर php -l syntax check 100ms से कम है। हर फ़ाइल संपादन पर अपनी पूर्ण Jest suite चलाना पागल होगा। व्यक्तिगत hook कमांड को दो या तीन सेकंड के तहत रखें और आप उन्हें मुश्किल से नोटिस करेंगे।
क्या hooks उत्पादन वातावरण पर उपयोग करने के लिए सुरक्षित हैं?
मैं उस सवाल को अलग तरीके से रखूँगा: क्या आप सीधे production पर Claude Code चला रहे हैं? अगर हाँ, तो hooks आपकी चिंताओं का सबसे छोटा हिस्सा हैं। उन्हें staging पर उपयोग करें, PreToolUse ब्लॉकिंग पैटर्न का उपयोग करके sensitive directories की सुरक्षा करें, और Claude को उत्पादन डेटाबेस से पूरी तरह दूर रखें।
प्रोजेक्ट-स्तर और ग्लोबल hooks के बीच अंतर क्या है?
ग्लोबल hooks ~/.claude/settings.json में रहते हैं और आपकी मशीन पर हर Claude Code सेशन पर लागू होते हैं। प्रोजेक्ट-स्तर की hooks एक विशिष्ट प्रोजेक्ट के अंदर .claude/settings.json में रहती हैं और केवल तभी फ़ायर होती हैं जब आप उस प्रोजेक्ट में हों। प्रोजेक्ट-स्तर उस जगह पहले आता है जहाँ दोनों एक ही इवेंट को परिभाषित करते हैं।
---
ईमानदार सारांश: hooks भव्य नहीं हैं। कोई भी Prettier चलाने वाली शेल स्क्रिप्ट की सुंदर आर्किटेक्चर के बारे में ब्लॉग पोस्ट नहीं लिखने वाला है। लेकिन वे Claude Code को एक प्रोटोटाइप खिलौने से कुछ ऐसा बनाने का अंतर हैं जिस पर आप वास्तव में क्लाइंट वर्क पर भरोसा करेंगे। मुझे उन्हें पहले दिन से सेट अप करना चाहिए था। आपको शायद भी करना चाहिए।
