Cursor hooks: पूरी गाइड, और वे कभी-कभी fire क्यों नहीं होते
Cursor hooks किसी script को एजेंट के कामों पर नज़र रखने या उन्हें block करने देते हैं: हर shell command, MCP call, फ़ाइल पढ़ना और edit करना। ये ताक़तवर हैं, और चुपचाप fail होते हैं। इन्हें असल में जोड़ते समय हमने जो कुछ सीखा, वह सब यहाँ है।
संक्षेप में
"version": 1 वाली एक hooks.json फ़ाइल ~/.cursor/ (सभी projects) में या किसी repo के .cursor/ में रखें, हर event को एक command से जोड़ें, और stdout पर JSON print करें। Allow, deny या ask के लिए beforeShellExecution और beforeMCPExecution इस्तेमाल करें, और अगर टूटे हुए hook को command जाने देने के बजाय block करना चाहिए तो failClosed: true सेट करें। जब कोई hook ignore होता लगे, तो पहले Hooks output channel खोलें: ज़्यादातर समस्याएँ path, untrusted workspace, invalid JSON, या ऐसे event की होती हैं जिसे Cursor CLI अभी नहीं भेजता।
Cursor hooks क्या हैं
Hook एक command है जिसे Cursor एजेंट loop में एक तय जगह पर चलाता है। Cursor command के standard input पर एक JSON object भेजता है जो बताता है कि क्या होने वाला है, इंतज़ार करता है, और उसके standard output से JSON जवाब पढ़ता है। कुछ hooks सिर्फ़ देखते हैं (edit को log करना, फ़ाइल को format करना)। कुछ फ़ैसला करते हैं: beforeShellExecution hook किसी command को चलने दे सकता है, रोक सकता है, या पहले आपसे पूछ सकता है।
इसलिए hooks तीन कामों के लिए सही tool हैं: guardrails (किसी इंसान के बिना कभी rm -rf या git push --force न चलाना), automation (हर edit के बाद format या lint करना), और visibility (एजेंट के कामों को log या forward करना ताकि आपको पता चले कि उसे कब आपकी ज़रूरत है)।
hooks.json कहाँ रहती है
Cursor चार जगहों से hooks पढ़ता है और सभी को चलाता है। हर source का हर matching hook चलता है, और Cursor उनके जवाबों को मिला देता है।
| Level | फ़ाइल | नोट्स |
|---|---|---|
| User | ~/.cursor/hooks.json | हर project पर लागू होता है। Relative commands ~/.cursor/ से resolve होते हैं। |
| Project | <project>/.cursor/hooks.json | Repo में check in होता है। सिर्फ़ trusted workspace में चलता है। Relative commands project root से resolve होते हैं। |
| Team | Cursor web dashboard | सिर्फ़ Enterprise, हर सदस्य तक sync होता है। |
| Enterprise | C:\ProgramData\Cursor\hooks.json (Windows), /Library/Application Support/Cursor/hooks.json (macOS), /etc/cursor/hooks.json (Linux, WSL) | IT द्वारा managed। |
जब जवाब अलग-अलग हों, तो सबसे सख़्त जवाब जीतता है: किसी भी source का deny ask से ऊपर है, और ask allow से ऊपर। सबसे छोटी काम करने वाली फ़ाइल ऐसी दिखती है (यह Cursor के docs का उदाहरण है):
version का 1 होना ज़रूरी है। Cursor फ़ाइल पर नज़र रखता है और save करने पर उसे reload करता है। अगर कोई बदलाव लागू नहीं होता, तो Cursor restart करें। सिर्फ़ इतने से forum की हैरान करने वाली संख्या में रिपोर्टें ठीक हो जाती हैं।
जिन events पर आप hook लगा सकते हैं
Cursor के docs की मौजूदा list, उनके काम के हिसाब से समूहों में:
| समूह | Events | क्या block कर सकता है? |
|---|---|---|
| Shell और MCP | beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution | दोनों before… hooks: allow, deny या ask |
| कोई भी tool | preToolUse, postToolUse, postToolUseFailure | preToolUse: allow या deny (ask अभी लागू नहीं होता) |
| फ़ाइलें | beforeReadFile, afterFileEdit | beforeReadFile: allow या deny |
| Prompt | beforeSubmitPrompt | हाँ, continue: false के साथ |
| Agent loop | stop, afterAgentResponse, afterAgentThought, preCompact | नहीं (stop एक follow-up message भेज सकता है) |
| Subagents | subagentStart, subagentStop | subagentStart: allow या deny (ask को deny माना जाता है) |
| Session और app | sessionStart, sessionEnd, workspaceOpen | नहीं |
| Tab completions | beforeTabFileRead, afterTabFileEdit | beforeTabFileRead: allow या deny |
हर event को कुछ common fields मिलते हैं (conversation_id, generation_id, model, hook_event_name, cursor_version, workspace_roots) और साथ में उसके अपने fields। beforeShellExecution को पूरा command और उसका cwd मिलता है; stop को completed, aborted या error वाला status मिलता है।
Allow, deny और ask करना
फ़ैसला करने वाला hook एक JSON object print करता है। Shell hook के लिए यह ऐसा दिखता है:
permissionकी valueallow,denyयाaskहोती है।user_messageवह है जो आपको Cursor में दिखता है।agent_messageवह है जो एजेंट को बताया जाता है, ताकि वह वही command दोबारा आज़माने के बजाय रास्ता बदल सके।
Exit codes उतने ही मायने रखते हैं जितना JSON। Exit 0 का मतलब है “मेरा JSON इस्तेमाल करो”। Exit 2 action को block करता है, बिल्कुल deny की तरह। कोई भी दूसरा exit code fail हुआ hook माना जाता है, और action आगे बढ़ जाता है, जब तक आप failClosed सेट न करें। Permission hooks में invalid JSON या schema से मेल न खाने वाला JSON action को block करता है।
Cursor के docs beforeShellExecution और beforeMCPExecution के लिए ask को supported बताते हैं। मार्च 2026 में Cursor staff ने forum पर लिखा कि hooks सिर्फ़ deny लागू करते थे और allow व ask “basically ignored” (लगभग ignore) थे, ख़ासकर तब जब command allowlist या sandbox चालू हो। हमें किसी fix की घोषणा नहीं मिली। अगर किसी guardrail का टिकना ज़रूरी है, तो ask नहीं, deny लौटाएँ, और उसे अपने version में टेस्ट करें।
failClosed और timeout
हर hook entry में command के बगल में options हो सकते हैं:
failClosed: truecrash, timeout, non-zero exit या खाली output को block में बदल देता है। Defaultfalseहै: टूटा हुआ guard चुपचाप हर चीज़ को जाने देता है। Safety hook के लिए आप लगभग हमेशाtrueचाहेंगे।timeoutसेकंड में होता है। अगर आपका hook किसी इंसान का इंतज़ार करता है तो पर्याप्त समय रखें: diff पढ़ने वाले व्यक्ति को पाँच सेकंड से ज़्यादा चाहिए।matcherतय करता है कि hook कब चलेगा। Shell hooks के लिए यह पूरी command string से match होता है; tool hooks के लिए tool type से, जैसेShell,Read,WriteयाMCP:<tool_name>।
इसमें एक समझौता है। जुलाई 2026 में macOS पर एक user को “MainThreadShellExec not initialized” error मिली: Cursor का अपना shell host तैयार नहीं था, और क्योंकि hook fail-closed था, एजेंट का shell block हो गया। Cursor staff ने कहा कि fix ship हो चुका है और failClosed: true बनाए रखने की सलाह दी। अगर आपको किसी पुराने build पर यह error दिखे, तो “Developer: Reload Window” इसका workaround था।
Windows पर hooks
Windows पर Cursor desktop app hook commands को PowerShell से चलाता है और JSON pipe करता है। PowerShell script इसे $input से पढ़ती है; कोई भी दूसरा program हमेशा की तरह standard input पढ़ता है। तीन बातें लोगों को उलझा देती हैं:
- Bash scripts जैसी हैं वैसी नहीं चलतीं। macOS वाले teammate की
guard.shPowerShell में fail होती है।.ps1script, compiled program इस्तेमाल करें, या अपने interpreter को सीधे call करें (python .cursor/hooks/guard.py)। जनवरी 2026 का एक forum thread Git Bash setup कोsyntax error near unexpected token '[Convert]::FromBase64String'के साथ fail होते दिखाता है, जो bash तक पहुँचा PowerShell code है। - Execution policy। अगर PowerShell scripts चलाने से मना करे, तो उन्हें
powershell -NoProfile -ExecutionPolicy Bypass -File …से शुरू करें, JSON print करें, औरexit 0के साथ ख़त्म करें। - GUI programs बहुत जल्दी लौट आते हैं। इसमें हमारा एक दिन चला गया। अगर आपका hook GUI subsystem के लिए बना Windows program है, तो PowerShell उसे शुरू करके बिना इंतज़ार किए आगे बढ़ जाता है। Cursor खाली output पढ़ता है, इसलिए लगता है कि hook ने कुछ नहीं किया (या
failClosedके साथ, सब कुछ block हो जाता है)। Hook को console program के रूप में build करें, या उसे wrap करें ताकि PowerShell उसके exit होने का इंतज़ार करे।
Project-level hooks को trusted workspace भी चाहिए। Cursor staff के एक सदस्य ने बताया कि जब वे कुछ न करें तो क्या जाँचें: Hooks log की line “Hook N produced no output”, Settings → Hooks में workspace का trusted दिखना, और console में spawn, ENOENT, EPERM या ExecutionPolicy जैसी errors।
Cursor CLI में hooks
Cursor CLI (cursor-agent) वही ~/.cursor/hooks.json और .cursor/hooks.json पढ़ता है, लेकिन इसने कभी भी वे सारे events नहीं भेजे जो editor भेजता है। जनवरी 2026 में सिर्फ़ दो shell hooks fire होते थे। अप्रैल तक Cursor staff ने पुष्टि की कि beforeShellExecution, afterShellExecution, afterFileEdit, postToolUse, stop और sessionStart CLI में काम करते हैं, जबकि afterAgentResponse और afterAgentThought अब भी नहीं करते थे (मई में फिर से पुष्टि हुई)। जो event इस list में नहीं है, उस पर भरोसा करने से पहले उसे टेस्ट करें।
Cloud agents और भी सख़्त हैं: ~/.cursor/hooks.json के user-level hooks वहाँ बिल्कुल नहीं चलते।
जब hook fire न हो: एक checklist
- Hooks output channel खोलें (View → Output → Hooks) या Customize में Hooks tab। यह दिखाता है कि कौन-से hooks load हुए, हर run, और errors।
- JSON फ़ाइल ख़ुद जाँचें।
"version": 1मौजूद है, event names बिल्कुल सही लिखे हैं (वे case-sensitive हैं), JSON valid है। - Path जाँचें। Relative commands project hooks के लिए project root से और user hooks के लिए
~/.cursor/से resolve होते हैं। - Workspace को trust करें। Project hooks untrusted folder में नहीं चलते।
- Hook को हाथ से चलाएँ। उसमें sample JSON pipe करें और stdout देखें। एक JSON object के अलावा कुछ भी (भटका हुआ
echo, कोई warning) parsing तोड़ देता है। - Cursor restart करें। Save करने से फ़ाइल reload होती है, लेकिन forum की कई रिपोर्टें सिर्फ़ पूरे restart से ठीक हुईं।
- कमियाँ जानें। Allowlist और sandbox के साथ
askऔरallowके ignore होने की रिपोर्टें आई हैं; कुछ versions मेंsubagentStart/subagentStopके fire न होने की रिपोर्टें आई हैं; CLI कुछ events छोड़ देता है। Built-in Source Control panel से किए गए commits intercept नहीं होते: कोई pre-commit hook event नहीं है।
Hooks, auto-run और Auto-review
Hooks Cursor की अपनी approval settings (Settings → Agents → Approvals & Execution) से अलग हैं। Auto-run और Auto-review तय करते हैं कि Cursor अपने panel में आपसे पूछेगा या नहीं; आपका hook उसके ऊपर अपना फ़ैसला जोड़ता है। इसीलिए “मेरे hook ने ask कहा, लेकिन command सीधे चल गया” इतनी आम रिपोर्ट है: किसी दूसरे permission रास्ते ने उसे पहले ही allow कर दिया था।
एक और बात जो हमने मुश्किल से सीखी: Auto-review के साथ Cursor कुछ commands के बारे में अपनी window में पूछ सकता है। Hook को वह सवाल कभी नहीं दिखता। यह Cursor के अंदर होता है, hook pipeline में नहीं।
Pet Island कहाँ काम आता है
अगर hooks से आप यह चाहते हैं कि “हर जोखिम वाला command दिखाओ और window बदले बिना मुझे फ़ैसला करने दो”, तो Pet Island Cursor के साथ यही करता है। यह आपके लिए hooks इंस्टॉल करता है (beforeShellExecution और beforeMCPExecution, failClosed चालू रखकर ताकि बंद पड़ा helper कभी कोई command न जाने दे) और हर request को पूरे command के साथ आपकी स्क्रीन के ऊपर एक छोटे island पर रखता है। आप उसे वहीं allow या deny करते हैं; Cursor का अपना एजेंट इंतज़ार करता है।
Cursor editor के commands और फ़ाइल edits island से काम करते हैं। सवाल और plans island पर दिखते हैं, और आप उनका जवाब Cursor में देते हैं। Cursor CLI में commands island से काम करते हैं; बाक़ी events इस पर निर्भर हैं कि CLI क्या भेजता है। Uninstall करने पर सिर्फ़ वही entries हटती हैं जो Pet Island ने जोड़ी थीं; आपके अपने hooks बने रहते हैं।
अक्सर पूछे जाने वाले सवाल
क्या Cursor hooks Windows पर काम करते हैं?
हाँ। Desktop app उन्हें PowerShell से चलाता है और JSON को standard input पर देता है (PowerShell script में $input)। macOS के लिए लिखी Bash scripts का PowerShell या Python version चाहिए, और GUI-subsystem programs को wrap करना ज़रूरी है ताकि PowerShell उनका इंतज़ार करे।
मेरा hook ask लौटाता है, फिर भी command क्यों चल जाता है?
Cursor staff ने मार्च 2026 में कहा कि hooks भरोसेमंद रूप से सिर्फ़ deny लागू करते थे; allow और ask को allowlist या sandbox override कर सकते थे। जो कुछ भी नहीं चलना चाहिए उसके लिए deny इस्तेमाल करें, और Hooks output channel में देखें कि आपके hook ने असल में क्या लौटाया।
failClosed क्या करता है?
failClosed को true पर सेट करने से crash, timeout, non-zero exit या खाली output action को block कर देता है। इसके बिना टूटा हुआ hook action को आगे बढ़ने देता है।
Hook errors कहाँ दिखती हैं?
Hooks output channel (View → Output → Hooks) में और Customize के Hooks tab में।
क्या hooks Cursor CLI में काम करते हैं?
आंशिक रूप से। CLI वही hooks.json फ़ाइलें पढ़ता है। मई 2026 तक Cursor staff ने shell hooks, afterFileEdit, postToolUse, stop और sessionStart की पुष्टि की, लेकिन afterAgentResponse या afterAgentThought की नहीं।
क्या कोई hook Source Control panel से होने वाले git commit को रोक सकता है?
नहीं। Cursor में कोई pre-commit hook event नहीं है, और built-in Source Control UI से किए गए commits intercept नहीं होते। इसके लिए सामान्य git pre-commit hook इस्तेमाल करें।
स्रोत
इस पेज की हर setting और हर व्यवहार को 26 अक्टूबर 2026 को इन पेजों से मिलाकर जाँचा गया। एजेंट तेज़ी से बदलते हैं; अगर कुछ अब मेल नहीं खाता, तो आधिकारिक पेज ही मान्य है।
- Cursor Docs: Hooks
- Cursor forum: Cursor hooks उम्मीद के मुताबिक़ execute नहीं हुए (staff: सिर्फ़ deny लागू होता है)
- Cursor forum: beforeShellExecution में allow/ask ignore, allow-list को प्राथमिकता
- Cursor forum: Fail-closed hook और MainThreadShellExec not initialized
- Cursor forum: Hook से आए malformed JSON ने चुपचाप command को allow किया (ठीक हो गया)
- Cursor forum: Cursor CLI सारे hook events नहीं भेजता
- Cursor forum: Project-level hooks Windows पर execute नहीं होते
- Cursor forum: Project hooks Windows पर Git Bash के साथ fail होते हैं
- Cursor forum: subagentStart और subagentStop कभी fire नहीं होते