Bahasa Indonesia

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 dalam config.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, atau Stop
  • 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:

  • description adalah metadata tingkat atas opsional untuk file hooks.json. Metadata ini tidak mengubah hook mana yang berjalan.
  • timeout dinyatakan dalam detik.
  • Jika timeout dihilangkan, Codex menggunakan 600 detik untuk sebagian besar hook.
    • SessionEnd secara default menggunakan 1 detik dan mendukung hingga 3 detik.
  • statusMessage bersifat opsional.
  • additionalContextLimit mengatur jumlah additionalContext yang 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.
  • commandWindows adalah penggantian perintah opsional khusus Windows. Dalam TOML, gunakan command_windows atau commandWindows.
  • Opsi async diurai, tetapi hook perintah asinkron belum didukung.
  • Saat ini hanya penangan type: "command" yang berjalan. Penangan prompt dan agent diurai tetapi dilewati.
  • Perintah berjalan dengan cwd sesi 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 = false

Gunakan 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_dir digunakan di macOS dan Linux.
  • windows_managed_dir digunakan 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 = true melewati hook dari sumber pengguna, proyek, sesi, dan plugin, tetapi tetap memuat hook terkelola dari requirements.toml dan 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_ROOT adalah ekstensi khusus Codex yang menunjuk ke root plugin yang terinstal.
  • PLUGIN_DATA adalah ekstensi khusus Codex yang menunjuk ke direktori data plugin yang dapat ditulisi.
  • Codex juga menetapkan CLAUDE_PLUGIN_ROOT dan CLAUDE_PLUGIN_DATA untuk 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|Write
  • mcp__filesystem__read_file
  • mcp__filesystem__.*
  • startup|resume|clear|compact
  • manual|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