[Go to site: main page, start]

Skip to main content

Command Palette

Search for a command to run...

Sesuaikan

Hook

Hook memungkinkan Anda mengamati, mengontrol, dan memperluas Agent Loop dengan skrip kustom. Definisikan hook dalam file hooks.json di tingkat proyek atau pengguna, atau instal melalui plugin dari Sesuaikan. Hook adalah proses terpisah yang berkomunikasi dua arah melalui stdio menggunakan JSON. Hook berjalan sebelum atau sesudah tahap tertentu dalam Agent Loop dan dapat mengamati, memblokir, atau mengubah perilaku.

Dengan hook, Anda dapat:

  • Menjalankan formatter setelah pengeditan
  • Menambahkan analitik untuk peristiwa
  • Memindai PII atau secret
  • Membatasi operasi berisiko (misalnya, penulisan SQL)
  • Mengontrol eksekusi subagent (tool Task)
  • Menyisipkan konteks saat sesi dimulai

Kategori hook

Hook dibagi menjadi tiga kategori berdasarkan pemicunya:

Hook agent (Cmd+K/Agent Chat) berjalan selama sesi agent:

  • sessionStart / sessionEnd - Manajemen siklus hidup sesi
  • preToolUse / postToolUse / postToolUseFailure - Hook penggunaan tool umum (berjalan untuk semua tool)
  • subagentStart / subagentStop - Siklus hidup subagent (tool Task)
  • beforeShellExecution / afterShellExecution - Mengontrol perintah shell
  • beforeMCPExecution / afterMCPExecution - Mengontrol penggunaan tool MCP
  • beforeReadFile / afterFileEdit - Mengontrol akses dan pengeditan file
  • beforeSubmitPrompt - Memvalidasi prompt sebelum dikirim
  • preCompact - Memantau pemadatan jendela konteks
  • stop - Menangani selesainya agent
  • afterAgentResponse / afterAgentThought - Melacak respons agent

Hook Tab (inline completions) berjalan untuk operasi Tab otonom:

  • beforeTabFileRead - Mengontrol akses file untuk Tab completion
  • afterTabFileEdit - Memproses pengeditan Tab setelahnya

Hook siklus hidup aplikasi berjalan di luar sesi agent mana pun:

  • workspaceOpen - Berjalan saat Cursor membuka workspace dan setiap kali folder workspace berubah. Dapat mengembalikan path plugin tambahan untuk dimuat di workspace saat ini.

Antarmuka hook yang terpisah ini memungkinkan Anda menerapkan kebijakan berbeda untuk operasi Tab otonom, operasi Agent yang diarahkan pengguna, dan startup workspace.

Dukungan agen cloud

Agen cloud menjalankan hook berbasis perintah dari repositori Anda. Jika hook didefinisikan dalam .cursor/hooks.json di direktori root proyek Anda, agen cloud akan mendeteksi dan menjalankannya saat bekerja.

Pada paket Enterprise, agen cloud juga menjalankan Team hooks dan hook yang dikelola perusahaan, yang diatur melalui dashboard web.

Agen cloud terkadang memulai giliran eksplorasi awal dalam lingkungan baca saja. Hook tidak dijalankan selama giliran tersebut. Hook mulai dijalankan setelah agen memiliki lingkungan yang dapat ditulisi.

Hook yang didukung

Hook berikut berjalan pada agen cloud:

HookDidukung
beforeShellExecutionYa
afterShellExecutionYa
beforeReadFileYa
afterFileEditYa
preToolUseYa
postToolUseYa
postToolUseFailureYa
subagentStartYa
subagentStopYa
beforeSubmitPromptYa
preCompactYa
afterAgentResponseYa
afterAgentThoughtYa
stopYa

Hook tidak tersedia di agen cloud

Beberapa hook tidak berlaku untuk agen cloud karena perbedaan lingkungan eksekusi:

HookAlasan
sessionStartDitunda karena agen cloud masih dapat dimulai di lingkungan baca saja. Hook tidak dimuat di sana, sehingga sessionStart cloud akan dipicu terlambat (setelah penulisan pertama), bukan pada awal sesi yang sebenarnya.
sessionEndAgen cloud tidak memiliki batas sesi berdasarkan masa aktif Editor. sessionEnd terikat pada sesi IDE, bukan chat agen cloud.
beforeMCPExecution / afterMCPExecutionDitunda karena agen cloud masih dapat dimulai di lingkungan baca saja, tempat hook tidak dimuat dan waktu pemicu hook MCP tidak jelas.
beforeTabFileRead / afterTabFileEditTab completion adalah fitur IDE dan tidak berjalan di agen cloud.
workspaceOpenIni adalah hook siklus hidup aplikasi IDE dan tidak berlaku untuk agen cloud.

Sumber konfigurasi

Agen cloud memuat hooks dari sumber berikut:

  • Hooks proyek (.cursor/hooks.json di repo Anda): Dimuat dan dijalankan saat agen cloud bekerja.
  • Team hooks (Enterprise): Didistribusikan melalui Dashboard dan dijalankan di agen cloud.
  • Hooks Enterprise (Enterprise): Hooks terkelola di seluruh sistem yang dijalankan di agen cloud.

Hooks tingkat pengguna (~/.cursor/hooks.json) tidak tersedia di agen cloud. VM agen cloud tidak dapat mengakses konfigurasi direktori beranda lokal Anda.

Batasan jenis eksekusi

Agen cloud hanya menjalankan hook berbasis perintah. Hook berbasis prompt memerlukan integrasi autentikasi antara hook dan Agent Loop, yang tidak tersedia di lingkungan eksekusi cloud.

Mulai Cepat

Buat file hooks.json. Anda dapat membuatnya di tingkat proyek (<project>/.cursor/hooks.json) atau di direktori beranda (~/.cursor/hooks.json). Hooks tingkat proyek hanya berlaku untuk proyek tersebut, sedangkan hooks di direktori beranda berlaku secara global.

Untuk hooks tingkat pengguna yang berlaku secara global, buat ~/.cursor/hooks.json:

{  "version": 1,  "hooks": {    "afterFileEdit": [{ "command": "./hooks/format.sh" }]  }}

Buat skrip hook di ~/.cursor/hooks/format.sh:

#!/bin/bash# Baca input, lakukan sesuatu, lalu keluar dengan kode 0cat > /dev/nullexit 0

Jadikan skrip dapat dieksekusi:

chmod +x ~/.cursor/hooks/format.sh

Cursor memantau file konfigurasi hooks dan memuat ulang secara otomatis. Hook Anda berjalan setelah setiap pengeditan file.

Jenis Hook

Hook mendukung dua jenis eksekusi: berbasis perintah (default) dan berbasis prompt (dievaluasi LLM).

Hook Berbasis Perintah

Hook perintah menjalankan skrip shell yang menerima input JSON melalui stdin dan menghasilkan output JSON melalui stdout.

{  "hooks": {    "beforeShellExecution": [      {        "command": "./scripts/approve-network.sh",        "timeout": 30,        "matcher": "curl|wget|nc"      }    ]  }}

Perilaku exit code:

  • Exit code 0 - Hook berhasil, gunakan output JSON
  • Exit code 2 - Blokir action (setara dengan mengembalikan permission: "deny")
  • Exit code lainnya - Hook gagal, action tetap dilanjutkan (secara default, gagal-terbuka)

Hook Berbasis Prompt

Hook berbasis prompt menggunakan LLM untuk mengevaluasi kondisi dalam bahasa alami. Hook ini berguna untuk menerapkan kebijakan tanpa perlu menulis skrip kustom.

{  "hooks": {    "beforeShellExecution": [      {        "type": "prompt",        "prompt": "Does this command look safe to execute? Only allow read-only operations.",        "timeout": 10      }    ]  }}

Fitur:

  • Menghasilkan respons terstruktur { ok: boolean, reason?: string }
  • Menggunakan model cepat untuk evaluasi singkat
  • Placeholder $ARGUMENTS otomatis diganti dengan JSON input hook
  • Jika $ARGUMENTS tidak ada, input hook otomatis ditambahkan
  • Field model opsional untuk mengganti model LLM default

Contoh

{  "version": 1,  "hooks": {    "sessionStart": [      {        "command": "./hooks/session-init.sh"      }    ],    "sessionEnd": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeShellExecution": [      {        "command": "./hooks/audit.sh"      },      {        "command": "./hooks/block-git.sh"      }    ],    "beforeMCPExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterShellExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterMCPExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterFileEdit": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeSubmitPrompt": [      {        "command": "./hooks/audit.sh"      }    ],    "preCompact": [      {        "command": "./hooks/audit.sh"      }    ],    "stop": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeTabFileRead": [      {        "command": "./hooks/redact-secrets-tab.sh"      }    ],    "afterTabFileEdit": [      {        "command": "./hooks/format-tab.sh"      }    ]  }}

Hook otomatisasi stop TypeScript

Pilih TypeScript jika Anda memerlukan JSON bertipe, I/O file persisten, dan panggilan HTTP dalam satu hook. Hook stop berbasis Bun ini melacak jumlah kegagalan per percakapan di disk, meneruskan telemetri terstruktur ke API internal, dan dapat menjadwalkan percobaan ulang secara otomatis jika agent gagal dua kali berturut-turut.

{  "version": 1,  "hooks": {    "stop": [      {        "command": "bun run .cursor/hooks/track-stop.ts --stop"      }    ]  }}

Atur AGENT_TELEMETRY_URL ke endpoint internal yang akan menerima ringkasan run.

Hook pengaman manifes Python

Python sangat cocok saat Anda memerlukan pustaka parsing yang lengkap. Hook ini menggunakan pyyaml untuk memeriksa manifes Kubernetes sebelum kubectl apply dijalankan; Bash akan kesulitan mem-parsing YAML multi-dokumen dengan aman.

{  "version": 1,  "hooks": {    "beforeShellExecution": [      {        "command": "python3 .cursor/hooks/kube_guard.py"      }    ]  }}

Instal PyYAML (misalnya, pip install pyyaml) di setiap lingkungan tempat skrip hook Anda dijalankan agar impor parser berhasil.

Integrasi Mitra

Kami bermitra dengan penyedia dalam ekosistem yang telah membangun dukungan hook untuk Cursor. Integrasi ini mencakup pemindaian keamanan, tata kelola, manajemen secret, dan lainnya.

Tata kelola dan visibilitas MCP

MitraDeskripsi
MintMCPBangun inventaris lengkap server MCP, pantau pola penggunaan alat, dan pindai respons untuk mendeteksi data sensitif sebelum mencapai model AI.
Oasis SecurityTerapkan kebijakan hak istimewa minimum pada tindakan agent AI dan pertahankan jejak audit lengkap di seluruh sistem perusahaan.
RunlayerBungkus alat MCP dan integrasikan dengan broker MCP mereka untuk kontrol dan visibilitas terpusat atas interaksi antara agent dan alat.

Keamanan kode dan praktik terbaik

MitraDeskripsi
CorridorDapatkan feedback real-time tentang implementasi kode dan keputusan desain keamanan saat kode sedang ditulis.
SemgrepSecara otomatis memindai kode yang dihasilkan AI untuk mendeteksi kerentanan, dengan feedback real-time untuk membuat ulang kode hingga masalah keamanan selesai.

Keamanan dependency

PartnerDeskripsi
Endor LabsMencegat instalasi package dan memindai dependency berbahaya untuk mencegah serangan rantai pasokan sebelum mencapai codebase Anda.

Keamanan dan keselamatan agent

PartnerDeskripsi
SnykTinjau tindakan agent secara real-time dengan Evo Agent Guard untuk mendeteksi dan mencegah masalah seperti prompt injection dan pemanggilan tool berbahaya.

Manajemen secret

PartnerDeskripsi
1PasswordPastikan file lingkungan dari 1Password Environments ter-mount dengan benar sebelum perintah shell dijalankan, sehingga secret dapat diakses tepat saat dibutuhkan tanpa menulis kredensial ke disk.

Untuk informasi selengkapnya tentang partner hooks kami, lihat postingan blog Hooks for security and platform teams.

Konfigurasi

Tentukan hook dalam file hooks.json. Konfigurasi dapat diterapkan di beberapa tingkat. Semua hook yang cocok dari setiap sumber akan dijalankan; jika respons saling bertentangan, sumber dengan prioritas lebih tinggi akan diutamakan saat penggabungan:

~/.cursor/├── hooks.json└── hooks/    ├── audit.sh    └── block-git.sh
  • Enterprise (dikelola oleh MDM, berlaku di seluruh sistem):
    • macOS: /Library/Application Support/Cursor/hooks.json
    • Linux/WSL: /etc/cursor/hooks.json
    • Windows: C:\\ProgramData\\Cursor\\hooks.json
  • Tim (didistribusikan melalui Cloud, hanya Enterprise):
    • Dikonfigurasi di web dashboard dan otomatis disinkronkan ke semua anggota tim
  • Proyek (khusus proyek):
    • <project-root>/.cursor/hooks.json
    • hook proyek dijalankan di workspace tepercaya mana pun dan disertakan dalam sistem kontrol versi bersama proyek Anda
  • Pengguna (khusus pengguna):
    • ~/.cursor/hooks.json

Urutan prioritas (tertinggi hingga terendah): Enterprise → Tim → Proyek → Pengguna

Objek hooks memetakan nama hook ke array definisi hook. Setiap definisi saat ini mendukung properti command, yang dapat berupa string shell, path absolut, atau path relatif. Direktori kerja bergantung pada sumber hook:

  • hook proyek (.cursor/hooks.json dalam repositori): Dijalankan dari root proyek
  • hook pengguna (~/.cursor/hooks.json): Dijalankan dari ~/.cursor/
  • hook Enterprise (config di seluruh sistem): Dijalankan dari direktori config perusahaan
  • Team hooks (didistribusikan melalui cloud): Dijalankan dari direktori hooks yang dikelola

Untuk hook proyek, gunakan path seperti .cursor/hooks/script.sh (relatif terhadap root proyek), bukan ./hooks/script.sh (yang akan mencari <project>/hooks/script.sh).

File konfigurasi

Contoh ini menunjukkan file hooks tingkat pengguna (~/.cursor/hooks.json). Untuk hooks tingkat proyek, ubah path seperti ./hooks/script.sh menjadi .cursor/hooks/script.sh:

{  "version": 1,  "hooks": {    "sessionStart": [{ "command": "./session-init.sh" }],    "sessionEnd": [{ "command": "./audit.sh" }],    "preToolUse": [      {        "command": "./hooks/validate-tool.sh",        "matcher": "Shell|Read|Write"      }    ],    "postToolUse": [{ "command": "./hooks/audit-tool.sh" }],    "subagentStart": [{ "command": "./hooks/validate-subagent.sh" }],    "subagentStop": [{ "command": "./hooks/audit-subagent.sh" }],    "beforeShellExecution": [{ "command": "./script.sh" }],    "afterShellExecution": [{ "command": "./script.sh" }],    "afterMCPExecution": [{ "command": "./script.sh" }],    "afterFileEdit": [{ "command": "./format.sh" }],    "preCompact": [{ "command": "./audit.sh" }],    "stop": [{ "command": "./audit.sh", "loop_limit": 10 }],    "beforeTabFileRead": [{ "command": "./redact-secrets-tab.sh" }],    "afterTabFileEdit": [{ "command": "./format-tab.sh" }],    "workspaceOpen": [{ "command": "./register-workspace-plugins.sh" }]  }}

Hook agent (sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse, afterAgentThought) berlaku untuk operasi Cmd+K dan Agent Chat. Hook Tab (beforeTabFileRead, afterTabFileEdit) khusus berlaku untuk Tab completion inline. Hook siklus hidup aplikasi (workspaceOpen) dipicu saat workspace dibuka dan ketika folder workspace berubah, terlepas dari sesi agent apa pun.

Opsi Konfigurasi Global

OpsiJenisDefaultDeskripsi
versionnumber1Versi skema konfigurasi

Opsi Konfigurasi per Skrip

OpsiJenisDefaultDeskripsi
commandstringwajibPath atau perintah skrip
type"command""prompt""command"
timeoutnumberdefault platformBatas waktu eksekusi dalam detik
loop_limitnumbernull5
failClosedbooleanfalseJika true, kegagalan hook (crash, batas waktu, JSON tidak valid) memblokir tindakan, bukan mengizinkannya. Berguna untuk hook yang sangat penting bagi keamanan.
matcherobject-Kriteria filter untuk menentukan kapan hook dijalankan

Konfigurasi Matcher

Matcher memungkinkan Anda memfilter kondisi kapan hook dijalankan. Field yang digunakan matcher bergantung pada hook:

{  "hooks": {    "preToolUse": [      {        "command": "./validate-shell.sh",        "matcher": "Shell"      }    ],    "subagentStart": [      {        "command": "./validate-explore.sh",        "matcher": "explore|shell"      }    ],    "beforeShellExecution": [      {        "command": "./approve-network.sh",        "matcher": "curl|wget|nc "      }    ]  }}
  • subagentStart: Matcher diterapkan pada jenis subagent (misalnya explore, shell, generalPurpose). Gunakan untuk menjalankan hook hanya saat subagent jenis tertentu dimulai. Contoh di atas menjalankan validate-explore.sh hanya untuk subagent explore atau shell.
  • beforeShellExecution: Matcher diterapkan pada string perintah shell. Gunakan untuk menjalankan hook hanya saat perintah cocok dengan pola tertentu (misalnya panggilan jaringan atau penghapusan file). Contoh di atas menjalankan approve-network.sh hanya saat perintah berisi curl, wget, atau nc .

Matcher yang tersedia untuk setiap hook:

  • preToolUse / postToolUse / postToolUseFailure: Filter berdasarkan jenis alat. Nilainya mencakup Shell, Read, Write, Grep, Delete, Task, dan alat MCP dengan format MCP:<tool_name>.
  • subagentStart / subagentStop: Filter berdasarkan jenis subagent (generalPurpose, explore, shell, dll.).
  • beforeShellExecution / afterShellExecution: Filter berdasarkan teks perintah shell; matcher dibandingkan dengan seluruh string perintah.
  • beforeReadFile: Filter berdasarkan jenis alat (TabRead, Read, dll.).
  • afterFileEdit: Filter berdasarkan jenis alat (TabWrite, Write, dll.).
  • beforeSubmitPrompt: Dicocokkan dengan nilai UserPromptSubmit.
  • stop: Dicocokkan dengan nilai Stop.
  • afterAgentResponse: Dicocokkan dengan nilai AgentResponse.
  • afterAgentThought: Dicocokkan dengan nilai AgentThought.

Distribusi Tim

Hook dapat dibagikan kepada anggota tim melalui hook proyek (menggunakan sistem kontrol versi), alat MDM, atau sistem distribusi cloud Cursor.

Hook Proyek (Sistem Kontrol Versi)

Hook proyek adalah cara paling sederhana untuk membagikan hook kepada tim Anda. Letakkan file hooks.json di <project-root>/.cursor/hooks.json, lalu commit file tersebut ke repositori Anda. Saat anggota tim membuka proyek di workspace tepercaya, Cursor akan otomatis memuat dan menjalankan hook proyek.

Agen cloud juga memuat hook proyek ini saat mengerjakan repositori Anda di cloud.

Hook proyek:

  • Disimpan dalam sistem kontrol versi bersama kode Anda
  • Otomatis dimuat untuk semua anggota tim di workspace tepercaya
  • Dapat bersifat khusus untuk proyek tertentu (misalnya, menerapkan standar pemformatan untuk codebase tertentu)
  • Memerlukan workspace tepercaya agar dapat dijalankan (demi keamanan)

Distribusi MDM

Distribusikan hook di seluruh organisasi Anda menggunakan alat Mobile Device Management (MDM). Tempatkan file hooks.json dan skrip hook di direktori target pada setiap mesin.

Direktori home pengguna (distribusi per pengguna):

  • ~/.cursor/hooks.json
  • ~/.cursor/hooks/ (untuk skrip hook)

Direktori global (distribusi seluruh sistem):

  • macOS: /Library/Application Support/Cursor/hooks.json
  • Linux/WSL: /etc/cursor/hooks.json
  • Windows: C:\\ProgramData\\Cursor\\hooks.json

Catatan: Distribusi berbasis MDM sepenuhnya dikelola oleh organisasi Anda. Cursor tidak men-deploy atau mengelola file melalui solusi MDM Anda. Pastikan tim TI atau keamanan internal Anda menangani konfigurasi, deployment, dan pembaruan sesuai dengan kebijakan organisasi Anda.

Distribusi Cloud (Hanya Enterprise)

Tim Enterprise dapat menggunakan distribusi cloud bawaan Cursor untuk menyinkronkan hook secara otomatis ke semua anggota tim. Atur hook di dashboard web. Cursor secara otomatis mengirimkan hook yang telah dikonfigurasi ke semua mesin klien saat anggota tim masuk.

Distribusi cloud menyediakan:

  • Sinkronisasi otomatis ke semua anggota tim (setiap tiga puluh menit)
  • Penargetan sistem operasi untuk hook khusus platform
  • Manajemen terpusat melalui dashboard

Administrator Enterprise dapat membuat, mengedit, dan mengelola team hooks dari dashboard tanpa memerlukan akses ke mesin masing-masing.

Hubungi sales untuk mendapatkan distribusi hook cloud Enterprise.

Referensi

Skema umum

Input (semua hook)

Semua hook menerima serangkaian field dasar, selain field khusus masing-masing hook:

{  "conversation_id": "string",  "generation_id": "string",  "model": "string",  "model_id": "string",  "model_params": [{ "id": "string", "value": "string" }],  "hook_event_name": "string",  "cursor_version": "string",  "workspace_roots": ["<path>"],  "user_email": "string | null",  "transcript_path": "string | null"}
FieldJenisDeskripsi
conversation_idstringID percakapan yang tetap sama di banyak giliran
generation_idstringGenerasi saat ini yang berubah setiap kali ada pesan pengguna
modelstringSlug model lama yang dikonfigurasi untuk composer yang memicu hook
model_idstring (opsional)ID terstruktur untuk model yang dipilih, jika tersedia
model_paramsarray (opsional)Parameter model yang dipilih, seperti thinking, konteks, atau effort. Setiap item memiliki id dan value.
hook_event_namestringHook yang sedang dijalankan
cursor_versionstringVersi aplikasi Cursor (misalnya "1.7.2")
workspace_rootsstring[]Daftar folder root di workspace (biasanya hanya satu, tetapi workspace multi-root dapat memiliki beberapa)
user_emailstringnullAlamat email pengguna yang telah diautentikasi, jika tersedia
transcript_pathstringnullPath ke file transkrip percakapan utama (null jika transkrip dinonaktifkan)

Peristiwa hook

preToolUse

Dipanggil sebelum eksekusi tool apa pun. Hook generik ini berjalan untuk semua jenis tool (Shell, Read, Write, MCP, Task, dll.). Gunakan matcher untuk memfilter tool tertentu.

// Input{  "tool_name": "Shell",  "tool_input": { "command": "npm install", "working_directory": "/project" },  "tool_use_id": "abc123",  "cwd": "/project",  "model": "claude-opus-4-7-thinking-max",  "model_id": "claude-opus-4-7",  "model_params": [    { "id": "thinking", "value": "true" },    { "id": "context", "value": "1m" },    { "id": "effort", "value": "max" }  ],  "agent_message": "Installing dependencies..."}// Output{  "permission": "allow" | "deny",  "user_message": "<message shown in client when denied>",  "agent_message": "<message sent to agent when denied>",  "updated_input": { "command": "npm ci" }}
Field OutputJenisDeskripsi
permissionstring"allow" untuk melanjutkan, "deny" untuk memblokir. "ask" diterima oleh skema, tetapi saat ini tidak enforced untuk preToolUse.
user_messagestring (opsional)Pesan yang ditampilkan kepada pengguna saat action ditolak
agent_messagestring (opsional)Pesan yang dikirim kembali ke agent saat action ditolak
updated_inputobject (opsional)Input tool yang telah dimodifikasi untuk digunakan sebagai gantinya

postToolUse

Dipanggil setelah tool berhasil dijalankan. Berguna untuk audit, analitik, dan menyisipkan konteks.

// input{  "tool_name": "Shell",  "tool_input": { "command": "npm test" },  "tool_output": "{\"exitCode\":0,\"stdout\":\"All tests passed\"}",  "tool_use_id": "abc123",  "cwd": "/project",  "duration": 5432,  "model": "claude-opus-4-7-thinking-max",  "model_id": "claude-opus-4-7",  "model_params": [    { "id": "thinking", "value": "true" },    { "id": "context", "value": "1m" },    { "id": "effort", "value": "max" }  ]}// Output{  "updated_mcp_tool_output": { "modified": "output" },  "additional_context": "Test coverage report attached."}
Field inputJenisDeskripsi
durationnumberWaktu eksekusi dalam milidetik
tool_outputstringPayload hasil dari tool yang diserialisasi sebagai string JSON (bukan teks terminal mentah)
Field OutputJenisDeskripsi
updated_mcp_tool_outputobject (optional)Khusus untuk alat MCP: menggantikan output tool yang dilihat model
additional_contextstring (optional)Konteks tambahan yang disisipkan ke dalam percakapan setelah hasil tool

postToolUseFailure

Dipanggil saat tool gagal, mengalami timeout, atau ditolak. Berguna untuk pelacakan error dan logika pemulihan.

// Input{  "tool_name": "Shell",  "tool_input": { "command": "npm test" },  "tool_use_id": "abc123",  "cwd": "/project",  "error_message": "Command timed out after 30s",  "failure_type": "timeout" | "error" | "permission_denied",  "duration": 5000,  "is_interrupt": false}// Output{  // Tidak ada kolom output yang didukung saat ini}
Field inputJenisDeskripsi
error_messagestringDeskripsi kegagalan
failure_typestringJenis kegagalan: "error", "timeout", atau "permission_denied"
durationnumberWaktu dalam milidetik hingga kegagalan terjadi
is_interruptbooleanApakah kegagalan ini disebabkan oleh interupsi atau pembatalan oleh pengguna

subagentStart

Dipanggil sebelum subagent dibuat (tool Task). Dapat mengizinkan atau melarang pembuatan subagent.

// Input{  "subagent_id": "abc-123",  "subagent_type": "generalPurpose",  "task": "Explore the authentication flow",  "parent_conversation_id": "conv-456",  "tool_call_id": "tc-789",  "subagent_model": "claude-sonnet-4-20250514",  "is_parallel_worker": false,  "git_branch": "feature/auth"}// Output{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
Field inputJenisDeskripsi
subagent_idstringPengidentifikasi unik untuk instance subagent ini
subagent_typestringJenis subagent: generalPurpose, explore, shell, dll.
taskstringDeskripsi tugas yang diberikan kepada subagent
parent_conversation_idstringID percakapan sesi agent induk
tool_call_idstringID pemanggilan tool yang memicu subagent
subagent_modelstringModel yang akan digunakan oleh subagent
is_parallel_workerbooleanApakah subagent ini berjalan sebagai worker paralel
git_branchstring (opsional)Branch Git yang akan digunakan subagent, jika relevan
Field outputJenisDeskripsi
permissionstring"allow" untuk melanjutkan, "deny" untuk memblokir. "ask" tidak didukung untuk subagentStart dan diperlakukan sebagai "deny".
user_messagestring (opsional)Pesan yang ditampilkan kepada pengguna ketika subagent dilarang

subagentStop

Dipanggil saat subagent selesai, mengalami error, atau dibatalkan. Dapat memicu tindakan tindak lanjut.

// input{  "subagent_type": "generalPurpose",  "status": "completed" | "error" | "aborted",  "task": "Explore the authentication flow",  "description": "Exploring auth flow",  "summary": "<subagent output summary>",  "duration_ms": 45000,  "message_count": 12,  "tool_call_count": 8,  "loop_count": 0,  "modified_files": ["src/auth.ts"],  "agent_transcript_path": "/path/to/subagent/transcript.txt"}// Output{  "followup_message": "<auto-continue with this message>"}
Field inputJenisDeskripsi
subagent_typestringJenis subagent: generalPurpose, explore, shell, dll.
statusstring"completed", "error", atau "aborted"
taskstringDeskripsi tugas yang diberikan kepada subagent
descriptionstringDeskripsi singkat tujuan subagent
summarystringRingkasan output subagent
duration_msnumberWaktu eksekusi dalam milidetik
message_countnumberJumlah pesan yang dipertukarkan selama sesi subagent
tool_call_countnumberJumlah pemanggilan tool yang dilakukan subagent
loop_countnumberJumlah tindak lanjut subagentStop yang telah dipicu untuk subagent ini (dimulai dari 0)
modified_filesstring[]File yang dimodifikasi subagent
agent_transcript_pathstringnullPath ke file transkrip subagent sendiri (terpisah dari percakapan induk)
Field outputJenisDeskripsi
followup_messagestring (opsional)Lanjutkan otomatis dengan pesan ini. Hanya digunakan jika status adalah "completed".

Field followup_message memungkinkan alur berbasis loop, dengan penyelesaian subagent memicu iterasi berikutnya. Tindak lanjut tunduk pada batas loop yang dapat dikonfigurasi, sama seperti hook stop (default 5, dapat dikonfigurasi melalui loop_limit).

beforeShellExecution / beforeMCPExecution

Dipanggil sebelum shell command atau tool MCP dijalankan. Kembalikan keputusan permission.

// Input beforeShellExecution{  "command": "<full terminal command>",  "cwd": "<current working directory>",  "sandbox": false}// Input beforeMCPExecution{  "tool_name": "<tool name>",  "tool_input": "<json params>"}// Tambahkan salah satu:{ "url": "<server url>" }// Atau:{ "command": "<command string>" }// Output{  "permission": "allow" | "deny" | "ask",  "user_message": "<message shown in client>",  "agent_message": "<message sent to agent>"}

afterShellExecution

Dipicu setelah perintah shell dieksekusi; berguna untuk audit atau mengumpulkan metrik dari output perintah.

// input{  "command": "<full terminal command>",  "output": "<full terminal output>",  "duration": 1234,  "sandbox": false}
FieldJenisDeskripsi
commandstringPerintah terminal lengkap yang dijalankan
outputstringSeluruh output yang ditangkap dari terminal
durationnumberDurasi dalam milidetik untuk menjalankan perintah shell (tidak termasuk waktu tunggu persetujuan)
sandboxbooleanApakah perintah dijalankan di lingkungan tersandbox

afterMCPExecution

Dipicu setelah tool MCP dieksekusi; mencakup parameter input tool dan hasil JSON lengkap.

// input{  "tool_name": "<nama alat>",  "tool_input": "<parameter json>",  "result_json": "<hasil json alat>",  "duration": 1234}
FieldJenisDeskripsi
tool_namestringNama tool MCP yang dijalankan
tool_inputstringString parameter JSON yang diteruskan ke tool
result_jsonstringString JSON dari respons tool
durationnumberDurasi dalam milidetik untuk menjalankan tool MCP (tidak termasuk waktu tunggu persetujuan)

afterFileEdit

Dipicu setelah Agent mengedit file; berguna untuk pemformatan atau pencatatan kode yang ditulis agent.

// input{  "file_path": "<absolute path>",  "edits": [{ "old_string": "<search>", "new_string": "<replace>" }]}

beforeReadFile

Dipanggil sebelum Agent membaca file. Gunakan untuk kontrol akses guna mencegah file sensitif dikirim ke model.

// input{  "file_path": "<absolute path>",  "content": "<file contents>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// Output{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
Field inputJenisDeskripsi
file_pathstringPath absolut file yang dibaca
contentstringSeluruh isi file
attachmentsarrayLampiran konteks yang terkait dengan prompt. Setiap entri memiliki type ("file" atau "rule") dan file_path.
Field OutputJenisDeskripsi
permissionstring"allow" untuk melanjutkan, "deny" untuk memblokir
user_messagestring (opsional)Pesan yang ditampilkan kepada pengguna saat ditolak

beforeTabFileRead

Dipanggil sebelum Tab (inline completions) membaca file. Aktifkan penyamaran data atau kontrol akses sebelum Tab mengakses isi file.

Perbedaan utama dengan beforeReadFile:

  • Hanya dipicu oleh Tab, bukan Agent
  • Tidak mencakup field attachments (Tab tidak menggunakan lampiran prompt)
  • Berguna untuk menerapkan kebijakan yang berbeda pada operasi Tab otonom
// input{  "file_path": "<absolute path>",  "content": "<file contents>"}// Output{  "permission": "allow" | "deny"}

afterTabFileEdit

Dipanggil setelah Tab (inline completion) mengedit file. Berguna untuk pemformat atau mengaudit kode yang ditulis oleh Tab.

Perbedaan utama dengan afterFileEdit:

  • Hanya dipicu oleh Tab, bukan Agent
  • Mencakup informasi edit terperinci: range, old_line, dan new_line untuk melacak edit secara akurat
  • Berguna untuk pemformatan atau analisis edit Tab secara terperinci
// input{  "file_path": "<absolute path>",  "edits": [    {      "old_string": "<search>",      "new_string": "<replace>",      "range": {        "start_line_number": 10,        "start_column": 5,        "end_line_number": 10,        "end_column": 20      },      "old_line": "<line before edit>",      "new_line": "<line after edit>"    }  ]}// Output{  // Tidak ada kolom output yang didukung saat ini}

beforeSubmitPrompt

Dipanggil tepat setelah pengguna menekan Kirim, tetapi sebelum permintaan dikirim ke backend. Dapat mencegah pengiriman.

// Input{  "prompt": "<user prompt text>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// Output{  "continue": true | false,  "user_message": "<message shown to user when blocked>"}
Field OutputJenisDeskripsi
continuebooleanMenentukan apakah pengiriman prompt dapat dilanjutkan
user_messagestring (optional)Pesan yang ditampilkan kepada pengguna saat prompt diblokir

afterAgentResponse

Dipanggil setelah agent selesai membuat pesan asisten.

// input{  "text": "<assistant final text>"}

afterAgentThought

Dipanggil setelah agent menyelesaikan blok pemikiran. Berguna untuk mengamati proses penalaran agent.

// Input{  "text": "<fully aggregated thinking text>",  "duration_ms": 5000}// Output{  // Tidak ada kolom output yang didukung saat ini}
FieldTypeDeskripsi
textstringTeks thinking gabungan lengkap untuk blok yang telah selesai
duration_msnumber (opsional)Durasi blok thinking dalam milidetik

stop

Dipanggil saat Agent Loop berakhir. Secara opsional, dapat otomatis mengirim pesan tindak lanjut pengguna untuk melanjutkan iterasi.

// input{  "status": "completed" | "aborted" | "error",  "loop_count": 0}
// Output{  "followup_message": "<message text>"}
  • followup_message opsional berupa string. Jika diberikan dan tidak kosong, Cursor akan otomatis mengirimkannya sebagai pesan pengguna berikutnya. Ini memungkinkan alur berbasis loop (misalnya, mengulang hingga tujuan tercapai).
  • Field loop_count menunjukkan berapa kali hook stop telah memicu tindak lanjut otomatis untuk percakapan ini (mulai dari 0). Batas defaultnya adalah 5 tindak lanjut otomatis per skrip dan dapat dikonfigurasi melalui opsi loop_limit. Atur loop_limit ke null untuk menghapus batas tersebut. Batas yang sama berlaku untuk tindak lanjut subagentStop.

sessionStart

Dipanggil saat percakapan composer baru dibuat. Hook ini berjalan secara fire-and-forget; Agent Loop tidak menunggu atau mewajibkan respons yang memblokir. Gunakan untuk menyiapkan variabel lingkungan khusus sesi atau menyuntikkan konteks tambahan.

// input{  "session_id": "<unique session identifier>",  "is_background_agent": true | false,  "composer_mode": "agent" | "ask" | "edit"}
// Output{  "env": { "<key>": "<value>" },  "additional_context": "<context to add to conversation>"}
Field inputJenisDeskripsi
session_idstringPengidentifikasi unik untuk sesi ini (sama dengan conversation_id)
is_background_agentbooleanMenunjukkan apakah ini sesi agen latar belakang atau sesi interaktif
composer_modestring (opsional)Mode saat composer dimulai (misalnya, "agent", "ask", "edit")
Field OutputJenisDeskripsi
envobject (opsional)Variabel lingkungan yang diatur untuk sesi ini. Tersedia untuk semua eksekusi hook berikutnya
additional_contextstring (opsional)Konteks tambahan yang ditambahkan ke konteks sistem awal percakapan

sessionEnd

Dipanggil saat percakapan composer berakhir. Hook fire-and-forget ini berguna untuk tugas logging, analytics, atau cleanup. Respons dicatat, tetapi tidak digunakan.

// Input{  "session_id": "<pengidentifikasi sesi unik>",  "reason": "completed" | "aborted" | "error" | "window_close" | "user_close",  "duration_ms": 45000,  "is_background_agent": true | false,  "final_status": "<string status>",  "error_message": "<detail kesalahan jika reason adalah 'error'>"}
// Output{  // Tidak ada field output — jalankan tanpa menunggu hasil}
Field inputJenisDeskripsi
session_idstringPengidentifikasi unik untuk sesi yang berakhir
reasonstringAlasan sesi berakhir: "completed", "aborted", "error", "window_close", atau "user_close"
duration_msnumberTotal durasi sesi dalam milidetik
is_background_agentbooleanApakah ini adalah sesi agen latar belakang
final_statusstringStatus akhir sesi
error_messagestring (optional)Pesan kesalahan jika reason adalah "error"

preCompact

Dipanggil sebelum pemadatan/peringkasan jendela konteks dilakukan. Hook observasional ini tidak dapat memblokir atau mengubah perilaku pemadatan. Berguna untuk mencatat kapan pemadatan dilakukan atau memberi tahu pengguna.

// input{  "trigger": "auto" | "manual",  "context_usage_percent": 85,  "context_tokens": 120000,  "context_window_size": 128000,  "message_count": 45,  "messages_to_compact": 30,  "is_first_compaction": true | false}
// Output{  "user_message": "<message to show when compaction occurs>"}
Field inputJenisDeskripsi
triggerstringPemicu compaction: "auto" atau "manual"
context_usage_percentnumberPenggunaan jendela konteks saat ini dalam persentase (0-100)
context_tokensnumberJumlah token saat ini dalam jendela konteks
context_window_sizenumberUkuran maksimum jendela konteks dalam token
message_countnumberJumlah pesan dalam percakapan
messages_to_compactnumberJumlah pesan yang akan diringkas
is_first_compactionbooleanApakah ini compaction pertama dalam percakapan ini
Field outputJenisDeskripsi
user_messagestring (optional)Pesan yang ditampilkan kepada pengguna saat compaction terjadi

workspaceOpen

Dipicu satu kali saat Cursor membuka workspace, lalu kembali dipicu setiap kali folder workspace berubah. Tidak dipicu jika jendela tidak memiliki folder workspace. Berjalan di aplikasi desktop Cursor dan CLI.

// Input{  "hook_event_name": "workspaceOpen",  "cursor_version": "string",  "workspace_roots": ["<absolute path>"],  "user_email": "string | null"}// Output{  "pluginPaths": ["<absolute path>", "..."]}
Field OutputJenisDeskripsi
pluginPathsstring[] (opsional)Path absolut ke direktori plugin yang dimuat untuk workspace saat ini.

Variabel Lingkungan

Skrip hook menerima variabel lingkungan saat dijalankan:

VariabelDeskripsiSelalu Tersedia
CURSOR_PROJECT_DIRDirektori root workspaceYa
CURSOR_VERSIONString versi CursorYa
CURSOR_USER_EMAILEmail pengguna yang diautentikasiJika sudah login
CURSOR_TRANSCRIPT_PATHPath ke file transkrip percakapanJika transkrip diaktifkan
CURSOR_CODE_REMOTEDiatur ke string "true" saat berjalan di workspace remoteUntuk workspace remote
CLAUDE_PROJECT_DIRAlias untuk direktori proyek (kompatibilitas Claude)Ya

Variabel lingkungan cakupan sesi dari hook sessionStart diteruskan ke semua eksekusi hook berikutnya dalam sesi tersebut.

Pemecahan masalah

Cara memastikan hook aktif

Terdapat tab Hooks di Customize dan channel output Hooks untuk men-debug hook yang telah diatur dan dijalankan, serta melihat error.

Jika hook tidak berfungsi

  • Cursor memantau file hooks.json dan memuat ulang saat disimpan. Jika hook tetap tidak dimuat, mulai ulang Cursor.
  • Pastikan path relatif sudah benar untuk sumber hook Anda:
    • Untuk hook proyek, path relatif terhadap root proyek (misalnya, .cursor/hooks/script.sh)
    • Untuk hook pengguna, path relatif terhadap ~/.cursor/ (misalnya, ./hooks/script.sh atau hooks/script.sh)

Pemblokiran kode keluar

Kode keluar 2 dari hook perintah memblokir tindakan (setara dengan mengembalikan permission: "deny"). Ini sesuai dengan perilaku Claude Code untuk compatibility.

Hook Enterprise dan distribusi

Distribusi Cloud dan manajemen hook di seluruh tim tersedia di Enterprise.

Contact Sales