hook ของ Cursor: คู่มือฉบับสมบูรณ์ และทำไมบางครั้งถึงไม่ทำงาน

hook ของ Cursor ช่วยให้สคริปต์คอยดูหรือบล็อกสิ่งที่เอเจนต์ทำ: ทุกคำสั่งเชลล์ การเรียก MCP การอ่านและแก้ไขไฟล์ hook ทรงพลัง แต่เวลาล้มเหลวมักเงียบจนไม่รู้ตัว นี่คือทุกอย่างที่เราได้เรียนรู้จากการติดตั้งใช้งานจริง

โดย Aslan ทีม Pet Island · อัปเดต 26 ต.ค. 2026 · อ่าน 7 นาที

คำตอบสั้น ๆ

วาง hooks.json ที่มี "version": 1 ไว้ใน ~/.cursor/ (ทุกโปรเจกต์) หรือ .cursor/ ในรีโป ชี้แต่ละ event ไปที่คำสั่ง และพิมพ์ JSON ไปที่ stdout ใช้ beforeShellExecution และ beforeMCPExecution เพื่ออนุญาต ปฏิเสธ หรือถาม และตั้ง failClosed: true หาก hook ที่พังต้องบล็อกแทนที่จะปล่อยคำสั่งผ่าน เมื่อ hook ดูเหมือนถูกเพิกเฉย ให้เปิดช่องเอาต์พุต Hooks ก่อน ปัญหาส่วนใหญ่คือพาธ, workspace ที่ไม่ได้เชื่อถือ, JSON ไม่ถูกต้อง หรือ event ที่ Cursor CLI ยังไม่ส่ง

hook ของ Cursor คืออะไร

hook คือคำสั่งที่ Cursor รันที่จุดตายตัวในลูปของเอเจนต์ Cursor ส่งออบเจ็กต์ JSON ที่อธิบายสิ่งที่กำลังจะเกิดขึ้นเข้าไปทางอินพุตมาตรฐานของคำสั่ง รอ แล้วอ่านคำตอบ JSON จากเอาต์พุตมาตรฐาน บาง hook แค่สังเกตการณ์ (บันทึกการแก้ไข จัดรูปแบบไฟล์) บาง hook ตัดสินใจ: hook beforeShellExecution สามารถปล่อยให้คำสั่งรัน หยุดมัน หรือถามคุณก่อน

ทำให้ hook เป็นเครื่องมือที่เหมาะกับงานสามอย่าง: ราวกันตก (ห้ามรัน rm -rf หรือ git push --force โดยไม่มีคนดู), งานอัตโนมัติ (จัดรูปแบบหรือ lint หลังทุกการแก้ไข) และการมองเห็น (บันทึกหรือส่งต่อสิ่งที่เอเจนต์ทำ เพื่อให้คุณรู้ว่าเมื่อไรมันต้องการคุณ)

hooks.json อยู่ที่ไหน

Cursor อ่าน hook จากสี่ที่และรันทั้งหมด ทุก hook ที่ตรงกันจากทุกแหล่งจะรัน และ Cursor จะรวมคำตอบของพวกมันเข้าด้วยกัน

ระดับไฟล์หมายเหตุ
ผู้ใช้~/.cursor/hooks.jsonใช้กับทุกโปรเจกต์ คำสั่งแบบพาธสัมพัทธ์จะอ้างอิงจาก ~/.cursor/
โปรเจกต์<project>/.cursor/hooks.jsonคอมมิตไว้ในรีโป รันเฉพาะใน workspace ที่เชื่อถือแล้ว คำสั่งแบบพาธสัมพัทธ์จะอ้างอิงจากรูทของโปรเจกต์
ทีมแดชบอร์ดเว็บของ Cursorเฉพาะ Enterprise ซิงก์ไปยังสมาชิกทุกคน
EnterpriseC:\ProgramData\Cursor\hooks.json (Windows), /Library/Application Support/Cursor/hooks.json (macOS), /etc/cursor/hooks.json (Linux, WSL)จัดการโดยฝ่าย IT

เมื่อคำตอบขัดกัน คำตอบที่เข้มงวดที่สุดจะชนะ: deny จากแหล่งใดก็ตามชนะ ask และ ask ชนะ allow ไฟล์ที่เล็กที่สุดที่ใช้งานได้มีหน้าตาแบบนี้ (เป็นตัวอย่างจากเอกสารของ Cursor):

~/.cursor/hooks.jsonคัดลอก
{
"version": 1,
"hooks": {
"afterFileEdit": [{ "command": "./hooks/format.sh" }]
}
}

version ต้องเป็น 1 Cursor เฝ้าดูไฟล์และโหลดใหม่เมื่อคุณบันทึก หากการเปลี่ยนแปลงไม่มีผล ให้รีสตาร์ต Cursor แค่นี้ก็แก้รายงานในฟอรัมได้มากอย่างน่าประหลาดใจ

event ที่คุณใส่ hook ได้

รายการปัจจุบันจากเอกสารของ Cursor จัดกลุ่มตามจุดประสงค์:

กลุ่มEventบล็อกได้ไหม?
เชลล์และ MCPbeforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecutionhook before… สองตัว: อนุญาต ปฏิเสธ หรือถาม
เครื่องมือใดก็ได้preToolUse, postToolUse, postToolUseFailurepreToolUse: อนุญาตหรือปฏิเสธ (ปัจจุบัน ask ยังไม่ถูกบังคับใช้)
ไฟล์beforeReadFile, afterFileEditbeforeReadFile: อนุญาตหรือปฏิเสธ
พรอมต์beforeSubmitPromptได้ ด้วย continue: false
ลูปของเอเจนต์stop, afterAgentResponse, afterAgentThought, preCompactไม่ได้ (stop ส่งข้อความติดตามผลได้)
ซับเอเจนต์subagentStart, subagentStopsubagentStart: อนุญาตหรือปฏิเสธ (ask นับเป็น deny)
เซสชันและแอปsessionStart, sessionEnd, workspaceOpenไม่ได้
การเติมคำด้วย TabbeforeTabFileRead, afterTabFileEditbeforeTabFileRead: อนุญาตหรือปฏิเสธ

ทุก event ได้รับฟิลด์ทั่วไปจำนวนหนึ่ง (conversation_id, generation_id, model, hook_event_name, cursor_version, workspace_roots) รวมกับฟิลด์เฉพาะของตัวเอง beforeShellExecution ได้รับ command แบบเต็มและ cwd ส่วน stop ได้รับ status เป็น completed, aborted หรือ error

การอนุญาต การปฏิเสธ และการถาม

hook ที่ตัดสินใจจะพิมพ์ออบเจ็กต์ JSON หนึ่งตัว สำหรับ hook ของเชลล์ หน้าตาจะเป็นแบบนี้:

stdout ของ hook beforeShellExecutionคัดลอก
{
"permission": "ask",
"user_message": "This pushes to main. Run it?",
"agent_message": "The user wants to confirm pushes."
}
  • permission เป็น allow, deny หรือ ask
  • user_message คือสิ่งที่คุณเห็นใน Cursor
  • agent_message คือสิ่งที่บอกเอเจนต์ เพื่อให้มันเปลี่ยนแนวทางแทนที่จะลองคำสั่งเดิมซ้ำ

รหัสออกสำคัญพอ ๆ กับ JSON รหัสออก 0 หมายถึง “ใช้ JSON ของฉัน” รหัสออก 2 บล็อกการกระทำ เหมือนกับ deny รหัสออกอื่น ๆ จะถือว่า hook ล้มเหลว และการกระทำจะดำเนินต่อไป เว้นแต่คุณตั้ง failClosed สำหรับ hook ด้านสิทธิ์ JSON ที่ไม่ถูกต้องหรือไม่ตรงกับสคีมาจะบล็อกการกระทำ

เอกสารของ Cursor ระบุว่า ask รองรับใน beforeShellExecution และ beforeMCPExecution ในเดือนมีนาคม 2026 ทีมงาน Cursor เขียนในฟอรัมว่า hook บังคับใช้แค่ deny และ allow กับ ask นั้น “basically ignored” (แทบจะถูกเพิกเฉย) โดยเฉพาะเมื่อเปิด allowlist คำสั่งหรือแซนด์บ็อกซ์ไว้ เรายังไม่พบประกาศการแก้ไข หากราวกันตกต้องได้ผลแน่นอน ให้คืนค่า deny ไม่ใช่ ask และทดสอบในเวอร์ชันของคุณเอง

failClosed และ timeout

แต่ละรายการ hook สามารถมีตัวเลือกอยู่ข้าง command:

.cursor/hooks.jsonคัดลอก
{
"version": 1,
"hooks": {
"beforeShellExecution": [
{
"command": "./.cursor/hooks/guard.sh",
"timeout": 30,
"failClosed": true
}
]
}
}
  • failClosed: true เปลี่ยนการแครช timeout รหัสออกที่ไม่ใช่ศูนย์ หรือเอาต์พุตว่างให้กลายเป็นการบล็อก ค่าเริ่มต้นคือ false: hook ป้องกันที่พังจะปล่อยทุกอย่างผ่านแบบเงียบ ๆ สำหรับ hook ด้านความปลอดภัย คุณแทบจะต้องการ true เสมอ
  • timeout มีหน่วยเป็นวินาที เผื่อเวลาให้พอหาก hook ของคุณรอคน: คนที่อ่าน diff ต้องใช้เวลามากกว่าห้าวินาที
  • matcher กรองว่า hook จะรันเมื่อไร สำหรับ hook ของเชลล์จะจับคู่กับสตริงคำสั่งแบบเต็ม สำหรับ hook ของเครื่องมือจะจับคู่กับประเภทเครื่องมือ เช่น Shell, Read, Write หรือ MCP:<tool_name>

มีข้อแลกเปลี่ยนอยู่ ในเดือนกรกฎาคม 2026 ผู้ใช้ macOS รายหนึ่งเจอ “MainThreadShellExec not initialized”: โฮสต์เชลล์ของ Cursor เองยังไม่พร้อม และเพราะ hook เป็นแบบ fail-closed เชลล์ของเอเจนต์จึงถูกบล็อก ทีมงาน Cursor บอกว่าการแก้ไขได้เผยแพร่แล้ว และแนะนำให้คง failClosed: true ไว้ หากคุณเห็นข้อผิดพลาดนั้นในบิลด์เก่า วิธีแก้ชั่วคราวคือ “Developer: Reload Window”

hook บน Windows

บน Windows แอปเดสก์ท็อป Cursor รันคำสั่งของ hook ผ่าน PowerShell และส่ง JSON เข้าไปทางไปป์ สคริปต์ PowerShell อ่านข้อมูลจาก $input ส่วนโปรแกรมอื่น ๆ อ่านอินพุตมาตรฐานตามปกติ มีสามอย่างที่ทำให้คนพลาด:

  1. สคริปต์ Bash รันตรง ๆ ไม่ได้ guard.sh จากเพื่อนร่วมทีมที่ใช้ macOS จะล้มเหลวภายใต้ PowerShell ให้ใช้สคริปต์ .ps1 โปรแกรมที่คอมไพล์แล้ว หรือเรียกอินเทอร์พรีเตอร์โดยตรง (python .cursor/hooks/guard.py) กระทู้ในฟอรัมจากเดือนมกราคม 2026 แสดงการตั้งค่า Git Bash ที่ล้มเหลวด้วย syntax error near unexpected token '[Convert]::FromBase64String' ซึ่งคือโค้ด PowerShell ที่ไปถึง bash
  2. นโยบายการรัน (Execution policy) หาก PowerShell ไม่ยอมรันสคริปต์ ให้เริ่มด้วย powershell -NoProfile -ExecutionPolicy Bypass -File … พิมพ์ JSON และจบด้วย exit 0
  3. โปรแกรม GUI คืนการควบคุมเร็วเกินไป เรื่องนี้ทำเราเสียไปหนึ่งวัน หาก hook ของคุณเป็นโปรแกรม Windows ที่สร้างสำหรับ GUI subsystem PowerShell จะเริ่มมันแล้วไปต่อโดยไม่รอ Cursor อ่านได้เอาต์พุตว่าง hook จึงดูเหมือนไม่ได้ทำอะไร (หรือถ้ามี failClosed ก็จะบล็อกทุกอย่าง) ให้สร้าง hook เป็นโปรแกรมคอนโซล หรือห่อมันไว้เพื่อให้ PowerShell รอจนมันจบ

hook ระดับโปรเจกต์ยังต้องอยู่ใน workspace ที่เชื่อถือแล้วด้วย ทีมงาน Cursor คนหนึ่งได้ระบุสิ่งที่ต้องตรวจเมื่อมันไม่ทำอะไร: บรรทัดล็อก Hooks “Hook N produced no output”, Settings → Hooks แสดงว่า workspace เชื่อถือแล้ว และข้อผิดพลาดอย่าง spawn, ENOENT, EPERM หรือ ExecutionPolicy ในคอนโซล

hook ใน Cursor CLI

Cursor CLI (cursor-agent) อ่าน ~/.cursor/hooks.json และ .cursor/hooks.json ไฟล์เดียวกัน แต่ไม่เคยส่งทุก event ที่ตัวแก้ไขส่ง ในเดือนมกราคม 2026 มีแค่ hook ของเชลล์สองตัวที่ทำงาน พอถึงเดือนเมษายน ทีมงาน Cursor ยืนยันว่า beforeShellExecution, afterShellExecution, afterFileEdit, postToolUse, stop และ sessionStart ทำงานใน CLI ขณะที่ afterAgentResponse และ afterAgentThought ยังไม่ทำงาน (ยืนยันอีกครั้งในเดือนพฤษภาคม) event ใดที่ไม่อยู่ในรายการนั้น ให้ทดสอบก่อนพึ่งพา

เอเจนต์บนคลาวด์ยิ่งเข้มงวดกว่า: hook ระดับผู้ใช้จาก ~/.cursor/hooks.json ไม่รันที่นั่นเลย

เมื่อ hook ไม่ทำงาน: เช็กลิสต์

  1. เปิดช่องเอาต์พุต Hooks (View → Output → Hooks) หรือแท็บ Hooks ใน Customize ซึ่งแสดงว่า hook ไหนถูกโหลด การรันทุกครั้ง และข้อผิดพลาด
  2. ตรวจตัวไฟล์ JSON มี "version": 1 ชื่อ event สะกดถูกต้องทุกตัว (แยกตัวพิมพ์เล็กใหญ่) และเป็น JSON ที่ถูกต้อง
  3. ตรวจพาธ คำสั่งแบบพาธสัมพัทธ์อ้างอิงจากรูทของโปรเจกต์สำหรับ hook ระดับโปรเจกต์ และจาก ~/.cursor/ สำหรับ hook ระดับผู้ใช้
  4. เชื่อถือ workspace hook ระดับโปรเจกต์ไม่รันในโฟลเดอร์ที่ไม่ได้เชื่อถือ
  5. รัน hook ด้วยมือ ส่ง JSON ตัวอย่างผ่านไปป์เข้าไปแล้วดู stdout อะไรก็ตามที่ไม่ใช่ออบเจ็กต์ JSON เดียว (echo ที่หลงมา คำเตือน) จะทำให้การแยกวิเคราะห์พัง
  6. รีสตาร์ต Cursor การบันทึกจะโหลดไฟล์ใหม่ แต่รายงานหลายรายการในฟอรัมแก้ได้ด้วยการรีสตาร์ตเต็มรูปแบบเท่านั้น
  7. รู้ข้อจำกัด มีรายงานว่า ask และ allow ถูกเพิกเฉยเมื่อใช้ร่วมกับ allowlist และแซนด์บ็อกซ์ มีรายงานว่า subagentStart/subagentStop ไม่ทำงานในบางเวอร์ชัน และ CLI ข้ามบาง event คอมมิตจากแผง Source Control ในตัวจะไม่ถูกดักจับ: ไม่มี event hook แบบ pre-commit

hook, auto-run และ Auto-review

hook แยกจากการตั้งค่าการอนุมัติของ Cursor เอง (Settings → Agents → Approvals & Execution) Auto-run และ Auto-review ตัดสินว่า Cursor จะถามคุณในแผงของมันหรือไม่ ส่วน hook ของคุณเพิ่มการตัดสินใจของตัวเองซ้อนเข้าไป นี่คือเหตุผลที่ “hook ของฉันบอก ask แต่คำสั่งก็รันไปเลย” เป็นรายงานที่พบบ่อยมาก: เส้นทางสิทธิ์อีกทางได้อนุญาตไปแล้ว

อีกเรื่องที่เราเรียนรู้มาแบบเจ็บตัว: เมื่อใช้ Auto-review Cursor อาจถามเกี่ยวกับบางคำสั่งในหน้าต่างของตัวเอง hook จะไม่เคยเห็นคำถามนั้น เพราะมันเกิดขึ้นภายใน Cursor ไม่ใช่ในไปป์ไลน์ของ hook

Pet Island ช่วยตรงไหน

ถ้าสิ่งที่คุณต้องการจาก hook คือ “แสดงทุกคำสั่งที่เสี่ยงและให้ฉันตัดสินใจโดยไม่ต้องสลับหน้าต่าง” นั่นคือสิ่งที่ Pet Island ทำกับ Cursor มันติดตั้ง hook ให้คุณ (beforeShellExecution และ beforeMCPExecution โดยเปิด failClosed ไว้ เพื่อให้ตัวช่วย (helper) ที่หยุดทำงานไม่ปล่อยคำสั่งใดผ่าน) และนำแต่ละคำขอมาไว้บนเกาะเล็ก ๆ ที่ด้านบนของหน้าจอพร้อมคำสั่งแบบเต็ม คุณอนุญาตหรือปฏิเสธได้ที่นั่น และเอเจนต์ของ Cursor จะรอ

คำสั่งและการแก้ไขไฟล์จากตัวแก้ไข Cursor ใช้งานจากเกาะได้ คำถามและแผนจะแสดงบนเกาะ และคุณตอบใน Cursor ใน Cursor CLI คำสั่งใช้งานจากเกาะได้ ส่วน event อื่นขึ้นอยู่กับสิ่งที่ CLI ส่ง การถอนการติดตั้งจะลบเฉพาะรายการที่ Pet Island เพิ่มไว้ hook ของคุณเองจะยังอยู่

คำถามที่พบบ่อย

hook ของ Cursor ทำงานบน Windows ไหม?

ทำงาน แอปเดสก์ท็อปรัน hook ผ่าน PowerShell และส่ง JSON ทางอินพุตมาตรฐาน ($input ในสคริปต์ PowerShell) สคริปต์ Bash ที่เขียนสำหรับ macOS ต้องมีเวอร์ชัน PowerShell หรือ Python และโปรแกรมแบบ GUI subsystem ต้องถูกห่อไว้เพื่อให้ PowerShell รอ

ทำไม hook ของฉันคืนค่า ask แต่คำสั่งยังรันอยู่?

ทีมงาน Cursor กล่าวในเดือนมีนาคม 2026 ว่า hook บังคับใช้ deny ได้อย่างน่าเชื่อถือเท่านั้น ส่วน allow และ ask อาจถูก allowlist หรือแซนด์บ็อกซ์แทนที่ ให้ใช้ deny กับทุกอย่างที่ห้ามรัน และตรวจช่องเอาต์พุต Hooks เพื่อดูว่า hook ของคุณคืนค่าอะไรจริง ๆ

failClosed ทำอะไร?

เมื่อตั้ง failClosed เป็น true การแครช timeout รหัสออกที่ไม่ใช่ศูนย์ หรือเอาต์พุตว่างจะบล็อกการกระทำ หากไม่ตั้ง hook ที่พังจะปล่อยให้การกระทำดำเนินต่อไป

ดูข้อผิดพลาดของ hook ได้ที่ไหน?

ในช่องเอาต์พุต Hooks (View → Output → Hooks) และแท็บ Hooks ใน Customize

hook ทำงานใน Cursor CLI ไหม?

บางส่วน CLI อ่านไฟล์ hooks.json ไฟล์เดียวกัน ณ เดือนพฤษภาคม 2026 ทีมงาน Cursor ยืนยัน hook ของเชลล์, afterFileEdit, postToolUse, stop และ sessionStart แต่ไม่รวม afterAgentResponse หรือ afterAgentThought

hook หยุด git commit จากแผง Source Control ได้ไหม?

ไม่ได้ Cursor ไม่มี event hook แบบ pre-commit และคอมมิตที่ทำผ่าน UI Source Control ในตัวจะไม่ถูกดักจับ ให้ใช้ git pre-commit hook ปกติแทน

แหล่งข้อมูล

การตั้งค่าและพฤติกรรมทุกอย่างในหน้านี้ได้รับการตรวจสอบกับหน้าเหล่านี้เมื่อวันที่ 26 ตุลาคม 2026 เอเจนต์เปลี่ยนแปลงเร็ว หากมีอะไรไม่ตรงกันแล้ว ให้ยึดหน้าทางการเป็นหลัก

อ่านต่อ

ตอบทุกเอเจนต์ได้จากด้านบนของหน้าจอ

Windows และ Mac · ทดลองใช้ฟรี 7 วัน จากนั้นจ่ายครั้งเดียว $8.99 · $1 จากทุกการขายนำไปซื้ออาหารให้สัตว์จรจัด

ลองใช้ Pet Island ฟรี