Cursor hooks: पूरी गाइड, और वे कभी-कभी fire क्यों नहीं होते

Cursor hooks किसी script को एजेंट के कामों पर नज़र रखने या उन्हें block करने देते हैं: हर shell command, MCP call, फ़ाइल पढ़ना और edit करना। ये ताक़तवर हैं, और चुपचाप fail होते हैं। इन्हें असल में जोड़ते समय हमने जो कुछ सीखा, वह सब यहाँ है।

लेखक: Aslan, Pet Island टीम · अपडेट: 26 अक्टू॰ 2026 · पढ़ने में 7 मिनट

संक्षेप में

"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.jsonRepo में check in होता है। सिर्फ़ trusted workspace में चलता है। Relative commands project root से resolve होते हैं।
TeamCursor web dashboardसिर्फ़ Enterprise, हर सदस्य तक sync होता है।
EnterpriseC:\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 का उदाहरण है):

~/.cursor/hooks.jsonकॉपी करें
{
"version": 1,
"hooks": {
"afterFileEdit": [{ "command": "./hooks/format.sh" }]
}
}

version का 1 होना ज़रूरी है। Cursor फ़ाइल पर नज़र रखता है और save करने पर उसे reload करता है। अगर कोई बदलाव लागू नहीं होता, तो Cursor restart करें। सिर्फ़ इतने से forum की हैरान करने वाली संख्या में रिपोर्टें ठीक हो जाती हैं।

जिन events पर आप hook लगा सकते हैं

Cursor के docs की मौजूदा list, उनके काम के हिसाब से समूहों में:

समूहEventsक्या block कर सकता है?
Shell और MCPbeforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecutionदोनों before… hooks: allow, deny या ask
कोई भी toolpreToolUse, postToolUse, postToolUseFailurepreToolUse: allow या deny (ask अभी लागू नहीं होता)
फ़ाइलेंbeforeReadFile, afterFileEditbeforeReadFile: allow या deny
PromptbeforeSubmitPromptहाँ, continue: false के साथ
Agent loopstop, afterAgentResponse, afterAgentThought, preCompactनहीं (stop एक follow-up message भेज सकता है)
SubagentssubagentStart, subagentStopsubagentStart: allow या deny (ask को deny माना जाता है)
Session और appsessionStart, sessionEnd, workspaceOpenनहीं
Tab completionsbeforeTabFileRead, afterTabFileEditbeforeTabFileRead: 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 के लिए यह ऐसा दिखता है:

beforeShellExecution hook का stdoutकॉपी करें
{
"permission": "ask",
"user_message": "This pushes to main. Run it?",
"agent_message": "The user wants to confirm pushes."
}
  • permission की value allow, 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 हो सकते हैं:

.cursor/hooks.jsonकॉपी करें
{
"version": 1,
"hooks": {
"beforeShellExecution": [
{
"command": "./.cursor/hooks/guard.sh",
"timeout": 30,
"failClosed": true
}
]
}
}
  • failClosed: true crash, timeout, non-zero exit या खाली output को block में बदल देता है। Default false है: टूटा हुआ 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 पढ़ता है। तीन बातें लोगों को उलझा देती हैं:

  1. Bash scripts जैसी हैं वैसी नहीं चलतीं। macOS वाले teammate की guard.sh PowerShell में fail होती है। .ps1 script, 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 है।
  2. Execution policy। अगर PowerShell scripts चलाने से मना करे, तो उन्हें powershell -NoProfile -ExecutionPolicy Bypass -File … से शुरू करें, JSON print करें, और exit 0 के साथ ख़त्म करें।
  3. 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

  1. Hooks output channel खोलें (View → Output → Hooks) या Customize में Hooks tab। यह दिखाता है कि कौन-से hooks load हुए, हर run, और errors।
  2. JSON फ़ाइल ख़ुद जाँचें। "version": 1 मौजूद है, event names बिल्कुल सही लिखे हैं (वे case-sensitive हैं), JSON valid है।
  3. Path जाँचें। Relative commands project hooks के लिए project root से और user hooks के लिए ~/.cursor/ से resolve होते हैं।
  4. Workspace को trust करें। Project hooks untrusted folder में नहीं चलते।
  5. Hook को हाथ से चलाएँ। उसमें sample JSON pipe करें और stdout देखें। एक JSON object के अलावा कुछ भी (भटका हुआ echo, कोई warning) parsing तोड़ देता है।
  6. Cursor restart करें। Save करने से फ़ाइल reload होती है, लेकिन forum की कई रिपोर्टें सिर्फ़ पूरे restart से ठीक हुईं।
  7. कमियाँ जानें। 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 को इन पेजों से मिलाकर जाँचा गया। एजेंट तेज़ी से बदलते हैं; अगर कुछ अब मेल नहीं खाता, तो आधिकारिक पेज ही मान्य है।

आगे पढ़ें

हर एजेंट को अपनी स्क्रीन के ऊपर से जवाब दें।

Windows और Mac · 7 दिन मुफ़्त, फिर एक बार $8.99 · हर बिक्री से $1 सड़क के बेसहारा जानवरों के खाने पर जाता है

Pet Island मुफ़्त आज़माएँ