Hook
Jalankan skrip deterministik selama siklus hidup Codex
Hook adalah kerangka kerja ekstensibilitas untuk Codex. Hook memungkinkan Anda menyisipkan skrip sendiri ke dalam loop agen, sehingga mendukung fitur seperti:
- Mengirim percakapan ke mesin pencatatan/analitik khusus
- Memindai prompt tim Anda untuk mencegah penempelan API key secara tidak sengaja
- Meringkas percakapan untuk membuat memori persisten secara otomatis
- Menjalankan pemeriksaan validasi khusus saat giliran percakapan berhenti untuk menegakkan standar
- Menyesuaikan prompt saat berada di direktori tertentu
Perilaku runtime yang perlu diperhatikan:
- Semua hook yang cocok dari beberapa file akan dijalankan.
- Beberapa hook perintah yang cocok untuk peristiwa yang sama diluncurkan secara bersamaan, sehingga satu hook tidak dapat mencegah hook lain yang cocok untuk dimulai.
- Hook perintah yang tidak dikelola harus ditinjau dan dipercaya sebelum dijalankan.
Hook berjalan pada titik yang berbeda dalam percakapan:
| Waktu | Hook |
|---|---|
| Selama satu giliran | PreToolUse, PermissionRequest, PostToolUse, PreCompact, PostCompact, UserPromptSubmit, SubagentStop, Stop |
| Saat sesi atau subagen dimulai | SessionStart, SubagentStart |
| Saat utas utama berakhir | SessionEnd (tidak berjalan untuk subagen) |
Tempat Codex mencari hook
Codex menemukan hook di sebelah lapisan konfigurasi aktif dalam salah satu bentuk berikut:
hooks.json- tabel
[hooks]inline di dalamconfig.toml
Plugin yang terinstal juga dapat menyertakan konfigurasi siklus hidup melalui manifes plugin
atau file hooks/hooks.json default. Lihat Membuat
plugin untuk
aturan pengemasan plugin.
Dalam praktiknya, empat lokasi yang paling berguna adalah:
~/.codex/hooks.json~/.codex/config.toml<repo>/.codex/hooks.json<repo>/.codex/config.toml
Jika terdapat lebih dari satu sumber hook, Codex memuat semua hook yang cocok.
Lapisan konfigurasi dengan prioritas lebih tinggi tidak menggantikan hook dari lapisan berprioritas lebih rendah.
Jika satu lapisan berisi hooks.json dan [hooks] inline, Codex
menggabungkannya dan menampilkan peringatan saat dimulai. Sebaiknya gunakan satu representasi per lapisan.
Codex juga dapat menemukan hook yang disertakan dalam plugin aktif. Hook bawaan plugin dimuat bersama sumber hook lainnya dan menggunakan alur peninjauan kepercayaan yang sama seperti hook lain yang tidak dikelola.
Hook lokal proyek hanya dimuat jika lapisan .codex/ proyek dipercaya. Dalam
proyek yang tidak dipercaya, Codex tetap memuat hook pengguna dan sistem dari
lapisan konfigurasi aktifnya masing-masing.
Meninjau dan memercayai hook
Codex mencantumkan hook yang dikonfigurasi sebelum menentukan hook mana yang dapat berjalan. Sebelum hook perintah yang tidak dikelola dapat berjalan, Codex mengharuskan Anda meninjau dan memercayai definisi hook yang tepat. Codex mencatat kepercayaan berdasarkan hash hook saat ini, sehingga hook baru atau yang diubah ditandai untuk ditinjau dan dilewati hingga dipercaya.
Gunakan /hooks di CLI untuk memeriksa sumber hook, meninjau hook baru atau yang diubah,
memercayai hook, atau menonaktifkan hook tertentu yang tidak dikelola. Jika hook perlu ditinjau saat
startup, Codex menampilkan peringatan yang meminta Anda membuka /hooks.
Hook terkelola dari sumber sistem, MDM, cloud, atau requirements.toml ditandai
sebagai terkelola, dipercaya berdasarkan kebijakan, dan tidak dapat dinonaktifkan dari browser hook pengguna.
Untuk otomatisasi sekali jalan yang telah memeriksa sumber hook di luar Codex, gunakan
--dangerously-bypass-hook-trust untuk menjalankan hook aktif tanpa memerlukan
kepercayaan hook yang disimpan untuk pemanggilan tersebut.
Bentuk konfigurasi
Hook diatur dalam tiga tingkat:
- Peristiwa hook seperti
PreToolUse,PostToolUse,PreCompact,SubagentStart, atauStop - Grup pencocok yang menentukan kapan peristiwa tersebut cocok
- Satu atau beberapa penangan hook yang berjalan saat grup pencocok cocok
{
"description": "Optional lifecycle hooks for this workspace.",
"hooks": {
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"statusMessage": "Loading session notes",
"additionalContextLimit": 5000
}
]
}
],
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_end.py",
"timeout": 3
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py\"",
"statusMessage": "Checking Bash command"
}
]
}
],
"PermissionRequest": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/permission_request.py\"",
"statusMessage": "Checking approval request"
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py\"",
"statusMessage": "Reviewing Bash output"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/user_prompt_submit_data_flywheel.py\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/stop_continue.py\"",
"timeout": 30
}
]
}
]
}
}Catatan:
descriptionadalah metadata tingkat atas opsional untuk filehooks.json. Metadata ini tidak mengubah hook mana yang berjalan.timeoutdinyatakan dalam detik.- Jika
timeoutdihilangkan, Codex menggunakan600detik untuk sebagian besar hook.SessionEndsecara default menggunakan1detik dan mendukung hingga3detik.
statusMessagebersifat opsional.additionalContextLimitmengatur jumlahadditionalContextyang dapat dikirim hook perintah ke model sebelum Codex menyimpan teks lengkap ke disk dan mengirim pratinjau yang lebih singkat sebagai gantinya. Lihat Output hook berukuran besar.commandWindowsadalah penggantian perintah opsional khusus Windows. Dalam TOML, gunakancommand_windowsataucommandWindows.- Opsi
asyncdiurai, tetapi hook perintah asinkron belum didukung. - Saat ini hanya penangan
type: "command"yang berjalan. Penanganpromptdanagentdiurai tetapi dilewati. - Perintah berjalan dengan
cwdsesi sebagai direktori kerjanya. - Untuk hook lokal repositori, sebaiknya selesaikan jalur dari root git alih-alih menggunakan
jalur relatif seperti
.codex/hooks/.... Codex dapat dimulai dari subdirektori, dan jalur berbasis root git menjaga lokasi hook tetap stabil.
TOML inline yang setara dalam config.toml:
[[hooks.SessionStart]]
matcher = "^compact$"
[[hooks.SessionStart.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/session_start.py"'
additionalContextLimit = 5000
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use_policy.py"'
timeout = 30
statusMessage = "Checking Bash command"
[[hooks.PostToolUse]]
matcher = "^Bash$"
[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use_review.py"'
timeout = 30
statusMessage = "Reviewing Bash output"Menonaktifkan hook
Hook aktif secara default. Untuk menonaktifkannya di config.toml, tetapkan:
[features]
hooks = falseGunakan hooks sebagai kunci fitur kanonis. codex_hooks masih berfungsi sebagai
alias yang tidak digunakan lagi. Admin dapat memaksa hook dinonaktifkan dengan cara yang sama di
requirements.toml menggunakan [features].hooks = false.
Hook terkelola dari requirements.toml
Persyaratan yang dikelola perusahaan juga dapat menentukan hook secara inline di bawah [hooks].
Ini berguna ketika admin ingin memberlakukan konfigurasi hook sekaligus
mengirimkan skrip sebenarnya melalui MDM atau sistem pengelolaan perangkat lain.
Untuk memberlakukan hook terkelola bahkan bagi pengguna yang menonaktifkan hook secara lokal, sematkan
[features].hooks = true di requirements.toml bersama [hooks]. Untuk mengabaikan
hook pengguna, proyek, sesi, dan plugin sambil tetap mengizinkan hook terkelola
administrator, tetapkan allow_managed_hooks_only = true.
allow_managed_hooks_only = true
[features]
hooks = true
[hooks]
managed_dir = "/enterprise/hooks"
windows_managed_dir = 'C:\enterprise\hooks'
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "python3 /enterprise/hooks/pre_tool_use_policy.py"
command_windows = 'py -3 C:\enterprise\hooks\pre_tool_use_policy.py'
timeout = 30
statusMessage = "Checking managed Bash command"Catatan untuk hook terkelola:
managed_dirdigunakan di macOS dan Linux.windows_managed_dirdigunakan di Windows.- Codex tidak mendistribusikan skrip dalam
managed_dir; alat perusahaan Anda harus menginstal dan memperbaruinya secara terpisah. - Perintah hook terkelola harus menggunakan jalur skrip absolut di bawah direktori terkelola yang dikonfigurasi.
allow_managed_hooks_only = truemelewati hook dari sumber pengguna, proyek, sesi, dan plugin, tetapi tetap memuat hook terkelola darirequirements.tomldan lapisan konfigurasi terkelola lainnya.
Hook bawaan plugin
Saat plugin diaktifkan, Codex dapat memuat hook siklus hidup dari plugin tersebut bersama hook pengguna, proyek, dan terkelola.
Secara default, Codex mencari hooks/hooks.json di dalam root plugin. Manifes plugin
dapat mengganti default tersebut dengan entri hooks dalam
.codex-plugin/plugin.json. Entri manifes dapat berupa jalur berawalan ./,
larik jalur berawalan ./, objek hook inline, atau larik objek
hook inline.
{
"name": "repo-policy",
"hooks": "./hooks/hooks.json"
}Jalur hook manifes diselesaikan relatif terhadap root plugin dan harus tetap berada
di dalam root tersebut. Jika manifes menentukan hooks, Codex menggunakan entri
manifes tersebut alih-alih hooks/hooks.json default.
Perintah hook plugin menerima variabel lingkungan berikut:
PLUGIN_ROOTadalah ekstensi khusus Codex yang menunjuk ke root plugin yang terinstal.PLUGIN_DATAadalah ekstensi khusus Codex yang menunjuk ke direktori data plugin yang dapat ditulisi.- Codex juga menetapkan
CLAUDE_PLUGIN_ROOTdanCLAUDE_PLUGIN_DATAuntuk kompatibilitas dengan hook plugin yang ada.
Hook plugin menggunakan skema peristiwa yang sama dengan hook lainnya. Menginstal atau mengaktifkan plugin tidak otomatis membuat hook-nya dipercaya; Codex melewati hook bawaan plugin hingga Anda meninjau dan memercayai definisi hook saat ini.
Pola pencocok
Kolom matcher adalah string regex yang memfilter kapan hook dipicu. Gunakan "*",
"", atau hilangkan matcher sepenuhnya untuk mencocokkan setiap kemunculan peristiwa
yang didukung.
Hanya beberapa peristiwa Codex saat ini yang mematuhi matcher:
| Peristiwa | Yang difilter matcher |
Catatan |
|---|---|---|
PermissionRequest |
nama alat | Dukungan mencakup Bash, apply_patch*, dan nama alat MCP |
PostToolUse |
nama alat | Lihat Cakupan alat |
PostCompact |
pemicu pemadatan | Nilainya adalah manual atau auto |
PreCompact |
pemicu pemadatan | Nilainya adalah manual atau auto |
PreToolUse |
nama alat | Lihat Cakupan alat |
SessionEnd |
alasan berakhir | Saat ini hanya other |
SessionStart |
sumber mulai | Nilainya adalah startup, resume, clear, dan compact |
SubagentStart |
jenis subagen | Nilai bergantung pada subagen yang dimulai |
SubagentStop |
jenis subagen | Nilai bergantung pada subagen yang berhenti |
UserPromptSubmit |
tidak didukung | Setiap matcher yang dikonfigurasi diabaikan untuk peristiwa ini |
Stop |
tidak didukung | Setiap matcher yang dikonfigurasi diabaikan untuk peristiwa ini |
*Untuk apply_patch, nilai matcher juga dapat menggunakan Edit atau Write.
Contoh:
Bash^apply_patch$Edit|Writemcp__filesystem__read_filemcp__filesystem__.*startup|resume|clear|compactmanual|auto
Cakupan alat
PreToolUse dan PostToolUse dapat mengamati lebih dari sekadar panggilan shell dan MCP. Sebagian besar
alat fungsi lokal menggunakan jalur hook yang sama, sehingga Anda dapat mencocokkan nama alatnya,
memeriksa argumen JSON-nya, dan, untuk PreToolUse, memblokir atau menulis ulang panggilan.
| Jalur alat | PreToolUse |
PostToolUse |
Catatan |
|---|---|---|---|
| Perintah shell | Ya | Ya | Cocokkan sebagai Bash. |
Unified exec (exec_command) |
Ya | Ya | Cocokkan sebagai Bash. Polling write_stdin berikutnya dapat mengirimkan PostToolUse perintah asli saat perintah tersebut selesai. |
apply_patch |
Ya | Ya | Cocokkan sebagai apply_patch, Edit, atau Write. |
| Alat MCP | Ya | Ya | Cocokkan nama alat MCP, seperti mcp__filesystem__read_file. |
| Alat fungsi lokal lainnya | Ya | Ya | Cocokkan nama alat fungsi, seperti update_plan. spawn_agent juga cocok dengan Agent. |
Alat yang dihosting, seperti WebSearch |
Tidak | Tidak | Alat ini tidak menggunakan jalur hook alat fungsi lokal. |
write_stdin adalah transportasi untuk sesi unified-exec yang sudah ada. Transportasi ini tidak menjalankan
PreToolUse lagi saat mengirim input atau melakukan polling terhadap perintah yang telah melewati
PreToolUse.
Beberapa jalur alat khusus dapat memilih untuk tidak menggunakan jalur hook default. Perlakukan hook alat sebagai pagar pengaman yang berguna, bukan sebagai batas penegakan yang menyeluruh.
Kolom input umum
Setiap hook perintah menerima satu objek JSON melalui stdin.
Berikut kolom bersama yang biasanya akan Anda gunakan:
| Kolom | Jenis | Arti |
|---|---|---|
session_id |
string |
ID sesi Codex saat ini. Hook subagen menggunakan ID sesi induk. |
transcript_path |
string | null |
Jalur ke file transkrip sesi, jika ada |
cwd |
string |
Direktori kerja untuk sesi |
hook_event_name |
string |
Nama peristiwa hook saat ini |
model |
string |
Ekstensi khusus Codex. Slug model aktif |
Hook dalam cakupan giliran mencantumkan turn_id sebagai ekstensi khusus Codex dalam
tabel khusus peristiwanya.
SessionStart, PreToolUse, PermissionRequest, PostToolUse,
UserPromptSubmit, SubagentStart, SubagentStop, dan Stop juga menyertakan
permission_mode, yang menjelaskan mode izin saat ini sebagai default,
acceptEdits, plan, dontAsk, atau bypassPermissions.
transcript_path menunjuk ke transkrip percakapan untuk kemudahan, tetapi
format transkrip bukan antarmuka stabil untuk hook dan dapat berubah seiring waktu.
Jika Anda memerlukan format wire lengkap, lihat Skema.
Kolom output umum
SessionStart, PreCompact, PostCompact, UserPromptSubmit,
SubagentStop, dan Stop mendukung kolom JSON bersama berikut. SubagentStart
menerima bentuk yang sama untuk systemMessage dan konteks khusus hook, tetapi
continue: false tidak menghentikan subagen:
{
"continue": true,
"stopReason": "optional",
"systemMessage": "optional",
"suppressOutput": false
}| Kolom | Efek |
|---|---|
continue |
Jika false, menandai eksekusi hook tersebut sebagai dihentikan |
stopReason |
Dicatat sebagai alasan penghentian |
systemMessage |
Ditampilkan sebagai peringatan di UI atau aliran peristiwa |
suppressOutput |
Saat ini diurai tetapi belum diimplementasikan |
Keluar dengan 0 tanpa output dianggap berhasil dan Codex melanjutkan.
PreToolUse dan PermissionRequest mendukung systemMessage, tetapi continue,
stopReason, dan suppressOutput saat ini tidak didukung untuk peristiwa tersebut.
Jika hook PreToolUse mengembalikan salah satu kolom yang tidak didukung itu, Codex menandai
eksekusi hook tersebut sebagai gagal, melaporkan kesalahan, dan melanjutkan panggilan alat.
PostToolUse mendukung systemMessage, continue: false, dan stopReason.
suppressOutput diurai tetapi saat ini tidak didukung untuk peristiwa tersebut.
Output hook berukuran besar
Secara default, Codex membatasi setiap pesan output hook yang terlihat oleh model hingga sekitar
2.500 token. Jika hook mengembalikan lebih banyak, Codex menyimpan teks lengkap di bawah
<temp_dir>/hook_outputs/<session_id>/<uuid>.txt dan memberi model
pratinjau bagian awal dan akhir beserta jalur file yang disimpan. Perilaku ini disebut
spilling: Codex menyimpan output berukuran besar di disk dan menggantinya dengan
pratinjau lebih singkat yang terlihat oleh model. Jika file tidak dapat ditulis, model tetap
menerima pratinjau yang dipotong.
Untuk setiap hook perintah yang mengembalikan additionalContext, tetapkan
additionalContextLimit pada penangan untuk menyesuaikan perkiraan ambang
token:
{
"type": "command",
"command": "python3 ~/.codex/hooks/session_start.py",
"additionalContextLimit": 5000
}Hilangkan additionalContextLimit untuk menggunakan ambang default 2500 token. Gunakan
bilangan bulat positif untuk memilih ambang lain, atau 0 untuk meneruskan konteks
tambahan lengkap milik penangan langsung ke model. Codex mengevaluasi setiap
penangan yang cocok secara terpisah. Untuk peristiwa yang tidak dapat menghasilkan konteks
tambahan, Codex mengabaikan additionalContextLimit dan melaporkan peringatan
konfigurasi.
Pengaturan ini hanya berlaku untuk additionalContext. Umpan balik alat dan prompt
kelanjutan tetap menggunakan batas default.
Karena output berukuran besar dapat ditulis ke disk, hindari mengembalikan rahasia atau data sensitif lain dalam output hook.
Hook
SessionStart
matcher diterapkan ke source untuk peristiwa ini.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
source |
string |
Cara sesi dimulai: startup, resume, clear, atau compact |
Teks biasa pada stdout ditambahkan sebagai konteks developer tambahan.
JSON pada stdout mendukung Kolom output umum dan bentuk
khusus hook berikut:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Load the workspace conventions before editing."
}
}Teks additionalContext tersebut ditambahkan sebagai konteks developer tambahan.
Setelah Codex memadatkan sesi root, hook SessionStart yang cocok dengan
source: "compact" berjalan sebelum permintaan model berikutnya. Hal ini juga berlaku saat
pemadatan otomatis terjadi di tengah giliran: Codex mengirimkan konteks tambahan hook ke
kelanjutan langsung, bukan menunggu giliran pengguna berikutnya.
Jika hook mengembalikan continue: false, Codex mengakhiri giliran
tanpa mengirim permintaan model lagi.
SessionEnd
SessionEnd memungkinkan Anda menjalankan perintah saat sesi berakhir, seperti menyimpan catatan
akhir atau membersihkan file. Hook ini berjalan untuk utas utama saat Anda mengarsipkan atau
menghapus percakapan yang masih terbuka, saat Codex ditutup secara normal, atau setelah
percakapan tidak aktif dan tidak dibuka di klien mana pun selama 30
menit. Hook ini tidak berjalan untuk subagen.
Beralih dari percakapan atau memanggil thread/unsubscribe tidak langsung mengakhiri
sesi, sehingga SessionEnd tidak akan segera berjalan. Hook Anda tetap dapat
membaca transkrip sesi saat berjalan.
matcher memfilter reason untuk peristiwa ini. Untuk saat ini, reason selalu other.
Anda dapat menghilangkan matcher atau menggunakan other agar berjalan pada setiap peristiwa SessionEnd.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
reason |
string |
Alasan sesi berakhir: other |
Sebagai contoh, perintah SessionEnd menerima:
{
"session_id": "thr_123",
"transcript_path": "/workspace/.codex/rollout.jsonl",
"cwd": "/workspace",
"hook_event_name": "SessionEnd",
"reason": "other"
}Hook SessionEnd bersifat informatif. Outputnya tidak akan mengarahkan Codex atau menjaga
utas tetap terbuka. Jika perintah mengalami waktu habis atau keluar dengan kesalahan, Codex melaporkannya sebagai
kegagalan hook.
SubagentStart
matcher diterapkan ke agent_type untuk peristiwa ini.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
agent_id |
string |
Pengidentifikasi subagen |
agent_type |
string |
Jenis atau profil subagen |
permission_mode |
string |
Mode izin saat ini |
Teks biasa pada stdout ditambahkan sebagai konteks developer tambahan untuk subagen.
JSON pada stdout mendukung systemMessage dan bentuk khusus hook berikut:
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "Review the repository test conventions first."
}
}Teks additionalContext tersebut ditambahkan sebagai konteks developer tambahan untuk
subagen. continue: false diurai untuk kompatibilitas, tetapi tidak menghentikan
subagen untuk dimulai.
PreToolUse
PreToolUse dapat mencegat Bash, pengeditan file yang dilakukan melalui apply_patch,
panggilan alat MCP, dan alat fungsi lokal lainnya. Lihat Cakupan
alat untuk jalur dan pengecualian yang didukung.
matcher diterapkan ke tool_name dan alias pencocok. Untuk pengeditan file melalui
apply_patch, nilai matcher dapat menggunakan apply_patch, Edit, atau Write; input hook
tetap melaporkan tool_name: "apply_patch".
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
tool_name |
string |
Nama alat hook kanonis, seperti Bash, apply_patch, atau nama MCP seperti mcp__fs__read |
tool_use_id |
string |
ID panggilan alat untuk pemanggilan ini |
tool_input |
JSON value |
Input khusus alat. Bash dan apply_patch menggunakan tool_input.command. MCP dan alat fungsi lokal lainnya mengirimkan argumennya. |
Teks biasa pada stdout diabaikan.
JSON pada stdout dapat menggunakan systemMessage. Untuk menolak panggilan alat yang didukung, kembalikan
bentuk khusus hook berikut:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by hook."
}
}Codex juga menerima bentuk blok lama berikut:
{
"decision": "block",
"reason": "Destructive command blocked by hook."
}Anda juga dapat menggunakan kode keluar 2 dan menulis alasan pemblokiran ke stderr.
Untuk menambahkan konteks yang terlihat oleh model tanpa memblokir, kembalikan
hookSpecificOutput.additionalContext:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"additionalContext": "The pending command touches generated files."
}
}Untuk menulis ulang panggilan alat yang didukung tanpa memblokir, kembalikan
permissionDecision: "allow" dengan updatedInput:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": {
"command": "echo rewritten"
}
}
}Untuk perintah Bash dan apply_patch, updatedInput harus menyertakan kolom string
command. Untuk MCP dan alat fungsi lokal lainnya, updatedInput adalah
objek argumen pengganti. Kembalikan updatedInput hanya dengan
permissionDecision: "allow"; bentuk updatedInput lainnya dilaporkan sebagai
kesalahan.
permissionDecision: "ask", decision: "approve" lama, continue: false,
stopReason, dan suppressOutput diurai tetapi belum didukung. Codex menandai
eksekusi hook sebagai gagal, melaporkan kesalahan, dan melanjutkan panggilan alat.
PermissionRequest
PermissionRequest berjalan saat Codex akan meminta persetujuan, seperti untuk
eskalasi shell atau persetujuan jaringan terkelola. Hook ini dapat mengizinkan permintaan, menolak
permintaan, atau memilih untuk tidak memutuskan dan membiarkan prompt persetujuan normal dilanjutkan.
Hook ini tidak berjalan untuk perintah yang tidak memerlukan persetujuan.
matcher diterapkan ke tool_name dan alias pencocok. Nilai kanonis saat ini
mencakup Bash, apply_patch, dan nama alat MCP seperti
mcp__server__tool; apply_patch juga cocok dengan Edit dan Write.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
tool_name |
string |
Nama alat hook kanonis, seperti Bash, apply_patch, atau nama MCP seperti mcp__fs__read |
tool_input |
JSON value |
Input khusus alat. Bash dan apply_patch menggunakan tool_input.command sedangkan alat MCP mengirim semua argumen. |
tool_input.description |
string | null |
Alasan persetujuan yang mudah dibaca manusia, jika tersedia dari Codex |
Teks biasa pada stdout diabaikan.
Beberapa input alat mungkin menyertakan deskripsi yang mudah dibaca manusia, tetapi jangan mengandalkan
kolom tool_input.description untuk setiap alat.
Untuk menyetujui permintaan, kembalikan:
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow"
}
}
}Untuk menolak permintaan, kembalikan:
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "deny",
"message": "Blocked by repository policy."
}
}
}Jika beberapa hook yang cocok mengembalikan keputusan, setiap deny akan menang. Jika tidak,
allow memungkinkan permintaan dilanjutkan tanpa menampilkan prompt persetujuan. Jika tidak ada
hook yang cocok yang memutuskan, Codex menggunakan alur persetujuan normal.
Jangan kembalikan updatedInput, updatedPermissions, atau interrupt untuk
PermissionRequest; kolom tersebut dicadangkan untuk perilaku mendatang dan saat ini akan gagal
secara tertutup.
PostToolUse
PostToolUse berjalan setelah alat yang didukung menghasilkan output, termasuk Bash,
apply_patch, panggilan alat MCP, dan alat fungsi lokal lainnya. Untuk Bash, hook ini
juga berjalan setelah perintah keluar dengan status bukan nol. Hook ini tidak dapat membatalkan efek
samping dari alat yang sudah berjalan. Lihat Cakupan alat untuk
jalur dan pengecualian yang didukung.
matcher diterapkan ke tool_name dan alias pencocok. Untuk pengeditan file melalui
apply_patch, nilai matcher dapat menggunakan apply_patch, Edit, atau Write; input hook
tetap melaporkan tool_name: "apply_patch".
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
tool_name |
string |
Nama alat hook kanonis, seperti Bash, apply_patch, atau nama MCP seperti mcp__fs__read |
tool_use_id |
string |
ID panggilan alat untuk pemanggilan ini |
tool_input |
JSON value |
Input khusus alat. Bash dan apply_patch menggunakan tool_input.command. MCP dan alat fungsi lokal lainnya mengirimkan argumennya. |
tool_response |
JSON value |
Output khusus alat. Alat MCP mengirim hasil panggilan MCP. Alat fungsi lokal lainnya biasanya mengirim output yang ditujukan ke model. |
Teks biasa pada stdout diabaikan.
JSON pada stdout dapat menggunakan systemMessage dan bentuk khusus hook berikut:
{
"decision": "block",
"reason": "The Bash output needs review before continuing.",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "The command updated generated files."
}
}Teks additionalContext tersebut ditambahkan sebagai konteks developer tambahan.
Untuk peristiwa ini, decision: "block" tidak membatalkan perintah Bash yang telah selesai.
Sebagai gantinya, Codex mencatat umpan balik, mengganti hasil alat dengan
umpan balik tersebut, dan melanjutkan model dari pesan yang diberikan hook.
Anda juga dapat menggunakan kode keluar 2 dan menulis alasan umpan balik ke stderr.
Untuk menghentikan pemrosesan normal hasil alat asli setelah perintah telah
dijalankan, kembalikan continue: false. Codex akan mengganti hasil alat dengan
umpan balik atau teks penghentian Anda dan melanjutkan dari sana.
updatedMCPToolOutput dan suppressOutput diurai tetapi belum didukung.
Codex menandai eksekusi hook sebagai gagal, melaporkan kesalahan, dan melanjutkan pemrosesan
normal hasil alat.
Panggilan alat dari mode kode
Saat model menggunakan mode kode untuk memanggil alat dari JavaScript, keputusan hook berlaku
pada panggilan bertingkat tersebut. PreToolUse dapat menghentikan alat sebelum berjalan atau menulis ulang
inputnya. PostToolUse yang memblokir tidak dapat membatalkan efek samping alat, tetapi dapat
mencegah hasil asli mencapai skrip yang sedang berjalan.
| Hasil hook | Yang dilihat mode kode |
|---|---|
PreToolUse memblokir |
Promise alat ditolak sebelum alat berjalan. |
PreToolUse mengembalikan updatedInput |
Alat berjalan dengan input yang ditulis ulang dan promise diselesaikan dengan hasil tersebut. |
PostToolUse mengembalikan decision: "block" atau keluar dengan kode 2 |
Alat berjalan, lalu promise ditolak dengan alasan dari hook. |
PostToolUse mengembalikan continue: false |
Codex menggunakan umpan balik hook sebagai hasil yang terlihat model, tetapi tidak menolak promise alat bertingkat. |
PreCompact
PreCompact berjalan sebelum Codex memadatkan percakapan. matcher diterapkan
ke trigger, yang nilainya adalah manual dan auto.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
trigger |
string |
Pemicu pemadatan: manual atau auto |
Teks biasa pada stdout diabaikan.
JSON pada stdout mendukung Kolom output umum. Jika hook
PreCompact yang cocok mengembalikan continue: false, Codex berhenti sebelum
melakukan pemadatan.
PostCompact
PostCompact berjalan setelah Codex memadatkan percakapan. matcher diterapkan
ke trigger, yang nilainya adalah manual dan auto.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
trigger |
string |
Pemicu pemadatan: manual atau auto |
Teks biasa pada stdout diabaikan.
JSON pada stdout mendukung Kolom output umum. Jika hook
PostCompact yang cocok mengembalikan continue: false, Codex berhenti setelah
melakukan pemadatan.
UserPromptSubmit
matcher saat ini tidak digunakan untuk peristiwa ini.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
prompt |
string |
Prompt pengguna yang akan dikirim |
Teks biasa pada stdout ditambahkan sebagai konteks developer tambahan.
JSON pada stdout mendukung Kolom output umum dan
bentuk khusus hook berikut:
{
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "Ask for a clearer reproduction before editing files."
}
}Teks additionalContext tersebut ditambahkan sebagai konteks developer tambahan.
Untuk memblokir prompt, kembalikan:
{
"decision": "block",
"reason": "Ask for confirmation before doing that."
}Anda juga dapat menggunakan kode keluar 2 dan menulis alasan pemblokiran ke stderr.
SubagentStop
matcher diterapkan ke agent_type untuk peristiwa ini.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
agent_id |
string |
Pengidentifikasi subagen |
agent_type |
string |
Jenis atau profil subagen |
agent_transcript_path |
string | null |
Jalur ke file transkrip subagen, jika ada |
stop_hook_active |
boolean |
Apakah subagen ini sudah dilanjutkan |
last_assistant_message |
string | null |
Pesan asisten subagen terbaru, jika tersedia |
SubagentStop mengharapkan JSON pada stdout saat keluar dengan 0. Output teks biasa
tidak valid untuk peristiwa ini.
JSON pada stdout mendukung Kolom output umum. Untuk meminta
Codex melanjutkan alur subagen, kembalikan:
{
"decision": "block",
"reason": "Run one more focused pass inside the subagent."
}Anda juga dapat menggunakan kode keluar 2 dan menulis alasan kelanjutan ke stderr.
Jika hook SubagentStop mana pun yang cocok mengembalikan continue: false, hasil tersebut
lebih diutamakan daripada keputusan kelanjutan dari hook SubagentStop lain yang cocok.
Stop
matcher saat ini tidak digunakan untuk peristiwa ini.
Kolom selain Kolom input umum:
| Kolom | Jenis | Arti |
|---|---|---|
turn_id |
string |
Ekstensi khusus Codex. ID giliran Codex aktif |
stop_hook_active |
boolean |
Apakah giliran ini sudah dilanjutkan oleh Stop |
last_assistant_message |
string | null |
Teks pesan asisten terbaru, jika tersedia |
Stop mengharapkan JSON pada stdout saat keluar dengan 0. Output teks biasa tidak valid
untuk peristiwa ini.
JSON pada stdout mendukung Kolom output umum. Agar
Codex terus berjalan, kembalikan:
{
"decision": "block",
"reason": "Run one more pass over the failing tests."
}Anda juga dapat menggunakan kode keluar 2 dan menulis alasan kelanjutan ke stderr.
Untuk peristiwa ini, decision: "block" tidak menolak giliran. Sebaliknya, kolom ini meminta
Codex melanjutkan dan secara otomatis membuat prompt kelanjutan baru yang bertindak
sebagai prompt pengguna baru, menggunakan reason Anda sebagai teks prompt tersebut.
Jika hook Stop mana pun yang cocok mengembalikan continue: false, hasil tersebut lebih diutamakan
daripada keputusan kelanjutan dari hook Stop lain yang cocok.
Skema
Jika Anda memerlukan format wire saat ini secara tepat, lihat skema yang dihasilkan di repositori GitHub Codex.
Alias teks biasa
- string | null