827 827
828Exit code hook Anda memberi tahu Claude Code apakah akan melanjutkan tindakan yang memicu hook, seperti panggilan tool atau prompt. Eksekusi yang selesai memiliki salah satu dari tiga hasil:828Exit code hook Anda memberi tahu Claude Code apakah akan melanjutkan tindakan yang memicu hook, seperti panggilan tool atau prompt. Eksekusi yang selesai memiliki salah satu dari tiga hasil:
829 829
830* **Berhasil**: hook Anda keluar dengan 0. Claude Code menerapkan field [output JSON](#json-output) apa pun yang dicetak hook Anda, dan tindakan dilanjutkan kecuali field tersebut memblokir atau menolaknya.830* **Berhasil**: hook Anda keluar dengan 0. Claude Code menerapkan field [output JSON](#json-output) apa pun yang dicetak hook Anda, dan tindakan dilanjutkan kecuali field tersebut memblokir atau menolaknya. [Hook yang memulai proses latar belakang](#hooks-that-start-a-background-process) membahas pengecualiannya.
831* **Error blocking**: hook Anda keluar dengan 2. Pada [event yang dapat memblokir](#exit-code-2-behavior-per-event), Claude Code menghentikan tindakan.831* **Error blocking**: hook Anda keluar dengan 2. Pada [event yang dapat memblokir](#exit-code-2-behavior-per-event), Claude Code menghentikan tindakan.
832* **Error non-blocking**: hook Anda keluar dengan kode lain, atau gagal dengan cara lain, seperti tidak dapat dimulai atau mencetak JSON yang tidak valid. Tindakan dilanjutkan, dan pada event seperti `PreToolUse` Anda melihat pemberitahuan `<hook name> hook error` di transkrip. Jika Anda ingin hook yang gagal memblokir tindakan, atur [`onFailure: "block"`](#block-the-action-when-a-hook-fails).832* **Error non-blocking**: hook Anda keluar dengan kode lain, atau gagal dengan cara lain, seperti tidak dapat dimulai atau mencetak JSON yang tidak valid. Tindakan dilanjutkan, dan pada event seperti `PreToolUse` Anda melihat pemberitahuan `<hook name> hook error` di transkrip. Jika Anda ingin hook yang gagal memblokir tindakan, atur [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
833 833
932* Hook `command`, `http`, atau `mcp_tool` yang mengalami timeout tidak memblokir panggilan tool. Panggilan berlanjut melalui [alur izin](/docs/id/permissions) normal, jadi jangan mengandalkan hook yang macet untuk berfungsi sebagai gerbang. Untuk memblokir panggilan ketika hook `command` atau `http` mengalami timeout, atur [`onFailure: "block"`](#block-the-action-when-a-hook-fails).932* Hook `command`, `http`, atau `mcp_tool` yang mengalami timeout tidak memblokir panggilan tool. Panggilan berlanjut melalui [alur izin](/docs/id/permissions) normal, jadi jangan mengandalkan hook yang macet untuk berfungsi sebagai gerbang. Untuk memblokir panggilan ketika hook `command` atau `http` mengalami timeout, atur [`onFailure: "block"`](#block-the-action-when-a-hook-fails).
933* [Callback hook Agent SDK](/docs/id/agent-sdk/hooks) yang melebihi timeout-nya [memblokir panggilan tool](#pretooluse).933* [Callback hook Agent SDK](/docs/id/agent-sdk/hooks) yang melebihi timeout-nya [memblokir panggilan tool](#pretooluse).
934 934
935<h4 id="hooks-that-start-a-background-process">
936 Hook yang memulai proses latar belakang
937</h4>
938
939Jika hook perintah Anda membuat keputusannya dalam proses latar belakang lalu keluar, penolakan yang dicetak proses tersebut setelah Claude Code berhenti membaca tidak memblokir panggilan tool. Untuk hook yang tidak [async](#run-hooks-in-the-background), Claude Code selesai membaca output hook sesaat setelah proses hook itu sendiri keluar.
940
941Cetak keputusan sebelum Anda memulai proses latar belakang, dan alihkan stdout dan stderr proses tersebut. Jika skrip Anda mencetak allow, lalu memulai proses latar belakang tanpa mengalihkan stdout dan stderr proses tersebut, Claude Code memblokir panggilan tool. Error hook menyertakan `refusing to honor the suspect capture`.
942
943Skrip hook `PreToolUse` ini mencetak keputusan dengan `policy-check.sh`, lalu mengunggah metrik di latar belakang:
944
945```bash theme={null}
946#!/bin/bash
947"$CLAUDE_PROJECT_DIR"/.claude/hooks/policy-check.sh || exit $?
948"$CLAUDE_PROJECT_DIR"/.claude/hooks/upload-metrics.sh >/dev/null 2>&1 &
949```
950
951Bagian lain dari skrip melakukan hal berikut:
952
953* **`|| exit $?`**: menjadikan exit code pemeriksaan sebagai exit code hook itu sendiri, sehingga pemeriksaan yang keluar dengan 2 untuk menolak tetap memblokir. Jika tidak, hook keluar dengan kode dari baris terakhir, yaitu 0.
954* **`>/dev/null 2>&1 &`**: menjalankan `upload-metrics.sh` di latar belakang dengan output yang dialihkan, sehingga proses tersebut tidak membuat output hook tetap terbuka.
955
956Untuk menguji skrip, buat `policy-check.sh` keluar dengan 2, lalu picu panggilan tool yang cocok dengan hook. Panggilan tool diblokir.
957
935<h4 id="block-the-action-when-a-hook-fails">958<h4 id="block-the-action-when-a-hook-fails">
936 Memblokir tindakan ketika hook gagal959 Memblokir tindakan ketika hook gagal
937</h4>960</h4>
1245 Event hook1268 Event hook
1246</h2>1269</h2>
1247 1270
1248Setiap event berkaitan dengan suatu titik dalam siklus hidup Claude Code tempat hook dapat berjalan. Bagian-bagian di bawah ini diurutkan sesuai siklus hidup tersebut: dari penyiapan sesi melalui agentic loop hingga akhir sesi. Setiap bagian menjelaskan kapan event dipicu, matcher apa yang didukungnya, input JSON yang diterimanya, dan cara mengontrol perilaku melalui output.1271Setiap event berkaitan dengan satu titik dalam siklus hidup Claude Code tempat hook dapat dijalankan. Bagian-bagian di bawah ini diurutkan sesuai siklus hidup tersebut: dari penyiapan sesi melalui agentic loop hingga akhir sesi. Setiap bagian menjelaskan kapan event dipicu, matcher apa yang didukungnya, input JSON yang diterimanya, dan cara mengontrol perilaku melalui output.
1249 1272
1250<h3 id="sessionstart">1273<h3 id="sessionstart">
1251 SessionStart1274 SessionStart
1253 1276
1254Berjalan saat Claude Code memulai sesi baru atau melanjutkan sesi yang sudah ada. Berguna untuk memuat konteks pengembangan seperti issue yang ada atau perubahan terbaru pada codebase Anda, atau untuk menyiapkan environment variable. Untuk konteks statis yang tidak memerlukan skrip, gunakan [CLAUDE.md](/docs/id/memory) sebagai gantinya.1277Berjalan saat Claude Code memulai sesi baru atau melanjutkan sesi yang sudah ada. Berguna untuk memuat konteks pengembangan seperti issue yang ada atau perubahan terbaru pada codebase Anda, atau untuk menyiapkan environment variable. Untuk konteks statis yang tidak memerlukan skrip, gunakan [CLAUDE.md](/docs/id/memory) sebagai gantinya.
1255 1278
1256SessionStart berjalan di setiap sesi, jadi jaga agar hook ini tetap cepat. Hanya hook `type: "command"` dan `type: "mcp_tool"` yang didukung. Lihat [field hook tool MCP](#mcp-tool-hook-fields) untuk mengetahui kapan hook `mcp_tool` berjalan.1279SessionStart berjalan di setiap sesi, jadi jaga agar hook ini tetap cepat. Hanya hook `type: "command"` dan `type: "mcp_tool"` yang didukung. Lihat [kolom hook tool MCP](#mcp-tool-hook-fields) untuk mengetahui kapan hook `mcp_tool` berjalan.
1257 1280
1258Nilai matcher berkaitan dengan cara sesi dimulai:1281Nilai matcher berkaitan dengan cara sesi dimulai:
1259 1282
1265| `compact` | Compaction otomatis atau manual |1288| `compact` | Compaction otomatis atau manual |
1266| `fork` | Sesi baru yang di-fork dari sesi yang sudah ada: `--fork-session` dengan `--resume` atau `--continue`, salinan latar belakang `/fork`, `/branch`, atau percakapan yang Anda [pindahkan ke latar belakang](/docs/id/agent-view#from-inside-a-session) |1289| `fork` | Sesi baru yang di-fork dari sesi yang sudah ada: `--fork-session` dengan `--resume` atau `--continue`, salinan latar belakang `/fork`, `/branch`, atau percakapan yang Anda [pindahkan ke latar belakang](/docs/id/agent-view#from-inside-a-session) |
1267 1290
1268Sebelum v2.1.214, sesi yang di-fork melaporkan source `"resume"`.1291Sebelum v2.1.214, sesi hasil fork melaporkan source `"resume"`.
1269 1292
1270Saat Anda memulai sesi interaktif, melanjutkan percakapan saat peluncuran dengan `--continue` atau `--resume`, atau menjalankan `/clear`, hook SessionStart berjalan di latar belakang. Anda dapat langsung mengetik, dan percakapan yang Anda lanjutkan muncul tanpa menunggu hook. Respons pertama Claude tetap menunggu hook selesai, sehingga konteksnya sampai ke Claude.1293Saat Anda memulai sesi interaktif, melanjutkan percakapan saat peluncuran dengan `--continue` atau `--resume`, atau menjalankan `/clear`, hook SessionStart berjalan di latar belakang. Anda dapat langsung mengetik, dan percakapan yang Anda lanjutkan muncul tanpa menunggu hook. Respons pertama Claude tetap menunggu hook selesai, sehingga konteksnya sampai ke Claude.
1271 1294
1273 1296
1274Penantian yang sama berlaku saat peluncuran, termasuk sesi yang dilanjutkan: prompt yang Anda kirim saat hook SessionStart masih berjalan tidak sampai ke Claude hingga hook tersebut selesai.1297Penantian yang sama berlaku saat peluncuran, termasuk sesi yang dilanjutkan: prompt yang Anda kirim saat hook SessionStart masih berjalan tidak sampai ke Claude hingga hook tersebut selesai.
1275 1298
1276Selama salah satu penantian tersebut, tekan `Esc` untuk mengambil kembali prompt ke input tanpa mengirimnya. Hook tetap berjalan.1299Selama salah satu penantian tersebut, tekan `Esc` untuk mengembalikan prompt ke input tanpa mengirimnya. Hook tetap berjalan.
1277 1300
1278<h4 id="sessionstart-input">1301<h4 id="sessionstart-input">
1279 Input SessionStart1302 Input SessionStart
1280</h4>1303</h4>
1281 1304
1282Selain [field input umum](#common-input-fields), hook SessionStart menerima `source` dan secara opsional `model`, `agent_type`, dan `session_title`:1305Selain [kolom input umum](#common-input-fields), hook SessionStart menerima `source` serta secara opsional `model`, `agent_type`, dan `session_title`:
1283 1306
1284| Field | Deskripsi |1307| Kolom | Deskripsi |
1285| :- | :- |1308| :- | :- |
1286| `source` | Cara sesi dimulai: `"startup"` untuk sesi baru, `"resume"` untuk sesi yang dilanjutkan, `"clear"` setelah `/clear`, `"compact"` setelah compaction, atau `"fork"` untuk sesi baru yang di-fork dari sesi yang sudah ada |1309| `source` | Cara sesi dimulai: `"startup"` untuk sesi baru, `"resume"` untuk sesi yang dilanjutkan, `"clear"` setelah `/clear`, `"compact"` setelah compaction, atau `"fork"` untuk sesi baru yang di-fork dari sesi yang sudah ada |
1287| `model` | Pengenal model yang aktif. Field ini dapat dihilangkan, misalnya setelah `/clear` atau saat sesi dipulihkan melalui pemulihan percakapan, jadi periksa keberadaan field sebelum membacanya |1310| `model` | Pengidentifikasi model yang aktif. Kolom ini dapat tidak disertakan, misalnya setelah `/clear` atau saat sesi dipulihkan melalui pemulihan percakapan, jadi periksa keberadaan kolom ini sebelum membacanya |
1288| `agent_type` | Nama agent, ada saat Anda memulai Claude Code dengan `claude --agent <name>` |1311| `agent_type` | Nama agent, ada saat Anda memulai Claude Code dengan `claude --agent <name>` |
1289| `session_title` | Judul kustom sesi, ada saat judul tersebut ditetapkan, misalnya dengan `--name`, `/rename`, output `sessionTitle` dari hook, atau `renameSession()` dari Agent SDK. Hook yang mengeluarkan `sessionTitle` dapat memeriksa field ini terlebih dahulu agar tidak menimpa judul kustom yang sudah ada |1312| `session_title` | Judul kustom sesi, ada jika telah ditetapkan, misalnya dengan `--name`, `/rename`, output `sessionTitle` dari hook, atau `renameSession()` dari Agent SDK. Hook yang menghasilkan `sessionTitle` dapat memeriksa kolom ini terlebih dahulu agar tidak menimpa judul kustom yang sudah ada |
1290 1313
1291Sesi yang belum Anda beri nama tetap dapat memiliki [judul yang dihasilkan](/docs/id/sessions#name-your-sessions). Judul tersebut bukan judul kustom dan tidak muncul di `session_title`.1314Sesi yang belum Anda beri nama tetap dapat memiliki [judul yang dihasilkan](/docs/id/sessions#name-your-sessions). Judul tersebut bukan judul kustom dan tidak muncul di `session_title`.
1292 1315
1293Saat `source` bernilai `"resume"` atau `"fork"` dan transkrip berisi setidaknya satu respons dari Claude, hook SessionStart juga menerima empat field di bawah ini. Hook Anda dapat menggunakannya untuk melaporkan biaya melanjutkan percakapan yang sudah lama sebelum permintaan pertama, misalnya dalam [`systemMessage`](#json-output). Field ini memerlukan Claude Code v2.1.251 atau yang lebih baru.1316Saat `source` bernilai `"resume"` atau `"fork"` dan transkrip berisi setidaknya satu respons dari Claude, hook SessionStart juga menerima empat kolom di bawah ini. Hook Anda dapat menggunakannya untuk melaporkan biaya melanjutkan percakapan yang sudah lama sebelum permintaan pertama, misalnya dalam [`systemMessage`](#json-output). Kolom-kolom ini memerlukan Claude Code v2.1.251 atau lebih baru.
1294 1317
1295| Field | Deskripsi |1318| Kolom | Deskripsi |
1296| :- | :- |1319| :- | :- |
1297| `seconds_since_last_response` | Detik waktu nyata sejak respons terakhir dalam transkrip yang dilanjutkan |1320| `seconds_since_last_response` | Detik waktu nyata sejak respons terakhir dalam transkrip yang dilanjutkan |
1298| `context_tokens` | Token yang dikirim ulang oleh permintaan pertama sesi yang dilanjutkan sebagai prompt-nya |1321| `context_tokens` | Token yang dikirim ulang oleh permintaan pertama sesi yang dilanjutkan sebagai prompt-nya |
1299| `prompt_cache_likely_expired` | `true` saat respons terakhir lebih lama daripada [masa berlaku prompt cache](/docs/id/prompt-caching#cache-lifetime) sesi atau compaction setelahnya menggantikan percakapan yang di-cache |1322| `prompt_cache_likely_expired` | `true` saat respons terakhir lebih lama daripada [masa berlaku prompt cache](/docs/id/prompt-caching#cache-lifetime) sesi atau compaction setelahnya telah menggantikan percakapan yang di-cache |
1300| `estimated_cache_write_usd` | Estimasi biaya dalam dolar AS untuk menulis `context_tokens` ke prompt cache pada model sesi, tidak termasuk respons |1323| `estimated_cache_write_usd` | Perkiraan biaya dalam dolar AS untuk menulis `context_tokens` ke prompt cache pada model sesi, tidak termasuk respons |
1301 1324
1302Contoh ini menunjukkan input untuk sesi yang dilanjutkan 90 menit setelah respons terakhirnya:1325Contoh ini menunjukkan input untuk sesi yang dilanjutkan 90 menit setelah respons terakhirnya:
1303 1326
1320 Kontrol keputusan SessionStart1343 Kontrol keputusan SessionStart
1321</h4>1344</h4>
1322 1345
1323Hook SessionStart dapat menambahkan konteks untuk Claude, menyediakan pesan pengguna pertama, menetapkan judul sesi, memantau file, dan memuat ulang skill. Kembalikan field untuk masing-masing, selain [field output JSON](#json-output) yang tersedia untuk semua hook:1346Hook SessionStart dapat menambahkan konteks untuk Claude, menyediakan pesan pengguna pertama, menetapkan judul sesi, memantau file, dan memuat ulang skill. Kembalikan kolom untuk masing-masing, selain [kolom output JSON](#json-output) yang tersedia untuk semua hook:
1324 1347
1325| Field | Deskripsi |1348| Kolom | Deskripsi |
1326| :- | :- |1349| :- | :- |
1327| `additionalContext` | String yang ditambahkan ke konteks Claude di awal percakapan, sebelum prompt pertama. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) untuk cara teks dikirimkan dan apa yang perlu dimasukkan ke dalamnya |1350| `additionalContext` | String yang ditambahkan ke konteks Claude di awal percakapan, sebelum prompt pertama. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) untuk cara teks dikirimkan dan apa yang perlu dimasukkan |
1328| `initialUserMessage` | String yang digunakan sebagai pesan pengguna pertama dari sesi, dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`. String ini menjadi giliran pertama meskipun Anda tidak memberikan prompt. Prompt yang Anda berikan akan mengikuti sebagai giliran berikutnya |1351| `initialUserMessage` | String yang digunakan sebagai pesan pengguna pertama sesi, dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`. String ini menjadi giliran pertama meskipun Anda tidak memberikan prompt. Prompt yang Anda berikan menyusul sebagai giliran berikutnya |
1329| `sessionTitle` | Menetapkan judul sesi, dengan efek yang sama seperti `/rename`. Berlaku ketika `source` bernilai `"startup"`, `"resume"`, atau `"fork"` |1352| `sessionTitle` | Menetapkan judul sesi, dengan efek yang sama seperti `/rename`. Berlaku saat `source` bernilai `"startup"`, `"resume"`, atau `"fork"` |
1330| `watchPaths` | Array path absolut yang dipantau untuk event [FileChanged](#filechanged) selama sesi ini |1353| `watchPaths` | Array path absolut yang dipantau untuk event [FileChanged](#filechanged) selama sesi ini |
1331| `reloadSkills` | Boolean. Ketika `true`, Claude Code memindai ulang direktori [skill](/docs/id/skills) dan perintah setelah hook SessionStart selesai. Lihat [Memuat ulang skill yang dipasang hook](#reload-skills-that-a-hook-installs) |1354| `reloadSkills` | Boolean. Saat `true`, Claude Code memindai ulang direktori [skill](/docs/id/skills) dan perintah setelah hook SessionStart selesai. Lihat [Memuat ulang skill yang diinstal hook](#reload-skills-that-a-hook-installs) |
1332 1355
1333Output ini menambahkan konteks dan memberi nama sesi:1356Output ini menambahkan konteks dan memberi nama sesi:
1334 1357
1344 1367
1345Hook yang hanya menambahkan konteks dapat mencetaknya tanpa membangun JSON, karena Claude Code menambahkan [stdout teks biasa](#exit-code-0) dari hook SessionStart ke konteks Claude.1368Hook yang hanya menambahkan konteks dapat mencetaknya tanpa membangun JSON, karena Claude Code menambahkan [stdout teks biasa](#exit-code-0) dari hook SessionStart ke konteks Claude.
1346 1369
1347Jika hook SessionStart dari plugin Anda menyediakan `initialUserMessage` atau `sessionTitle`, pasang plugin tersebut sebelum sesi dimulai. Claude Code mengabaikan kedua field tersebut dari plugin yang selesai dipasang setelah hook SessionStart berjalan.1370Jika hook SessionStart plugin Anda menyediakan `initialUserMessage` atau `sessionTitle`, instal plugin sebelum sesi dimulai. Claude Code mengabaikan kedua kolom tersebut dari plugin yang selesai diinstal setelah hook SessionStart berjalan.
1348 1371
1349<h4 id="reload-skills-that-a-hook-installs">1372<h4 id="reload-skills-that-a-hook-installs">
1350 Memuat ulang skill yang dipasang hook1373 Memuat ulang skill yang diinstal hook
1351</h4>1374</h4>
1352 1375
1353Agar skill yang dipasang oleh hook SessionStart tersedia dalam sesi yang sama, kembalikan `reloadSkills`. Penemuan skill biasanya berjalan sebelum hook SessionStart selesai, sehingga tanpanya, file yang ditulis hook ke `~/.claude/skills/` atau `.claude/skills/` bisa belum ada ketika prompt pertama berjalan.1376Agar skill yang diinstal oleh hook SessionStart tersedia dalam sesi yang sama, kembalikan `reloadSkills`. Penemuan skill biasanya berjalan sebelum hook SessionStart selesai, sehingga tanpanya, file yang ditulis hook ke `~/.claude/skills/` atau `.claude/skills/` dapat belum ada saat prompt pertama berjalan.
1354 1377
1355Contoh ini menyinkronkan repositori skill bersama dan meminta pemindaian ulang:1378Contoh ini menyinkronkan repositori skill bersama dan meminta pemindaian ulang:
1356 1379
1369 Mempertahankan environment variable1392 Mempertahankan environment variable
1370</h4>1393</h4>
1371 1394
1372Hook SessionStart memiliki akses ke environment variable `CLAUDE_ENV_FILE`, yang menyediakan path file tempat Anda dapat mempertahankan environment variable untuk perintah shell yang dijalankan Claude di kemudian waktu dalam sesi.1395Hook SessionStart memiliki akses ke environment variable `CLAUDE_ENV_FILE`, yang menyediakan path file tempat Anda dapat mempertahankan environment variable untuk perintah shell yang dijalankan Claude nanti dalam sesi.
1373 1396
1374Untuk menetapkan environment variable satu per satu, tulis pernyataan `export` ke `CLAUDE_ENV_FILE`. Gunakan append (`>>`) untuk mempertahankan variabel yang ditetapkan oleh hook lain:1397Untuk menetapkan environment variable satu per satu, tulis pernyataan `export` ke `CLAUDE_ENV_FILE`. Gunakan append (`>>`) untuk mempertahankan variabel yang ditetapkan oleh hook lain:
1375 1398
1404exit 01427exit 0
1405```1428```
1406 1429
1407Setiap perintah Bash menjalankan isi file sebagai kode shell sebelum perintah itu sendiri, sehingga baris di sana dapat menggunakan apa pun yang dievaluasi Bash, seperti referensi `$PATH` dalam `export PATH="$PATH:./node_modules/.bin"`.1430Setiap perintah Bash menjalankan isi file sebagai kode shell sebelum perintah itu sendiri, sehingga baris di dalamnya dapat menggunakan apa pun yang dievaluasi Bash, seperti referensi `$PATH` dalam `export PATH="$PATH:./node_modules/.bin"`.
1408 1431
1409<a id="persisted-variables-in-powershell-commands" />1432<a id="persisted-variables-in-powershell-commands" />
1410 1433
1412 Variabel yang dipertahankan dalam perintah PowerShell1435 Variabel yang dipertahankan dalam perintah PowerShell
1413</h5>1436</h5>
1414 1437
1415Perintah [PowerShell](/docs/id/tools-reference#powershell-tool) juga menerima variabel dari `CLAUDE_ENV_FILE`, di Claude Code v2.1.296 atau yang lebih baru, tetapi PowerShell tidak pernah menjalankan file tersebut. Sebagai gantinya, Claude Code membaca penetapan di dalamnya dan menyalinnya ke environment perintah PowerShell. Hal ini hanya dilakukan ketika setiap baris merupakan salah satu dari berikut, di seluruh yang ditulis oleh setiap hook dalam sesi ini dan skrip apa pun yang Anda [tetapkan sebagai `CLAUDE_ENV_FILE`](/docs/id/env-vars) sebelum peluncuran:1438Perintah [PowerShell](/docs/id/tools-reference#powershell-tool) juga menerima variabel dari `CLAUDE_ENV_FILE`, di Claude Code v2.1.296 atau lebih baru, tetapi PowerShell tidak pernah menjalankan file tersebut. Sebagai gantinya, Claude Code membaca penugasan dari file itu dan menyalinnya ke environment perintah PowerShell. Hal ini hanya dilakukan jika setiap baris merupakan salah satu dari berikut ini, mencakup semua yang ditulis oleh setiap hook dalam sesi ini dan skrip apa pun yang [Anda tetapkan sebagai `CLAUDE_ENV_FILE`](/docs/id/env-vars) sebelum peluncuran:
1416 1439
1417* Baris kosong atau komentar `#`1440* Baris kosong atau komentar `#`
1418* Satu penetapan di awal baris, ditulis `export NAME=value`, `declare -x NAME=value`, atau `NAME=value`, dengan nilai yang akan digunakan Bash persis seperti yang tertulis, terdiri dari campuran bagian-bagian berikut: teks tanpa tanda kutip yang hanya menggunakan huruf, angka, dan karakter `_ @ % + = : , . / -`, teks dalam tanda kutip tunggal, dan teks dalam tanda kutip ganda di mana setiap `$`, backtick, atau `"` di dalamnya di-escape dengan backslash1441* Satu penugasan di awal baris, ditulis `export NAME=value`, `declare -x NAME=value`, atau `NAME=value`, dengan nilai yang akan digunakan Bash persis seperti yang ditulis, tersusun dari campuran bagian-bagian berikut: teks tanpa tanda kutip yang hanya menggunakan huruf, angka, dan karakter `_ @ % + = : , . / -`, teks dalam tanda kutip tunggal, dan teks dalam tanda kutip ganda yang setiap `$`, backtick, atau `"` di dalamnya di-escape dengan backslash
1419 1442
1420Jika ada baris dengan jenis lain, seperti `export PATH="$PATH:./node_modules/.bin"` dengan `$PATH` yang tidak di-escape, perintah `source`, atau string `$'...'` yang dicetak oleh `direnv export bash`, perintah PowerShell tidak menerima variabel apa pun, dan `claude --debug` mencatat `Session environment is not all plain assignments`. Perintah Bash tetap menerima semuanya. Di Windows, perintah PowerShell juga tidak menerima variabel yang nilainya mengandung `/` atau `\`, karena Git Bash dan Windows menulis path secara berbeda. Perintah PowerShell yang berjalan dalam [sandbox](/docs/id/sandboxing) tidak menerima variabel apa pun.1443Jika ada baris dari jenis lain, seperti `export PATH="$PATH:./node_modules/.bin"` dengan `$PATH` yang tidak di-escape, perintah `source`, atau string `$'...'` yang dicetak oleh `direnv export bash`, perintah PowerShell tidak menerima satu pun variabel, dan `claude --debug` mencatat `Session environment is not all plain assignments`. Perintah Bash tetap menerima semuanya. Di Windows, perintah PowerShell juga tidak menerima variabel yang nilainya mengandung `/` atau `\`, karena Git Bash dan Windows menulis path secara berbeda. Perintah PowerShell yang berjalan dalam [sandbox](/docs/id/sandboxing) tidak menerima satu pun variabel.
1421 1444
1422<Note>1445<Note>
1423 `CLAUDE_ENV_FILE` tersedia untuk hook SessionStart, [Setup](#setup), [CwdChanged](#cwdchanged), dan [FileChanged](#filechanged). Event hook lain tidak memiliki akses ke variabel ini, begitu pula hook yang berjalan di PowerShell, baik melalui [`"shell": "powershell"`](#command-hook-fields) maupun secara default di Windows tanpa Git Bash.1446 `CLAUDE_ENV_FILE` tersedia untuk hook SessionStart, [Setup](#setup), [CwdChanged](#cwdchanged), dan [FileChanged](#filechanged). Event hook lainnya tidak memiliki akses ke variabel ini, demikian pula hook yang berjalan di PowerShell, baik melalui [`"shell": "powershell"`](#command-hook-fields) maupun secara default di Windows tanpa Git Bash.
1424</Note>1447</Note>
1425 1448
1426<h3 id="setup">1449<h3 id="setup">
1427 Setup1450 Setup
1428</h3>1451</h3>
1429 1452
1430Hanya dipicu saat Anda meluncurkan Claude Code dengan `--init-only`, atau dengan `--init` atau `--maintenance` dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`. Event ini tidak dipicu pada startup normal. Gunakan untuk pemasangan dependensi satu kali atau pembersihan terjadwal yang Anda picu secara eksplisit dari CI atau skrip, terpisah dari startup sesi normal. Untuk inisialisasi per sesi, gunakan [SessionStart](#sessionstart) sebagai gantinya.1453Hanya dipicu saat Anda meluncurkan Claude Code dengan `--init-only`, atau dengan `--init` atau `--maintenance` dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`. Event ini tidak dipicu pada startup normal. Gunakan untuk instalasi dependensi satu kali atau pembersihan terjadwal yang Anda picu secara eksplisit dari CI atau skrip, terpisah dari startup sesi normal. Untuk inisialisasi per sesi, gunakan [SessionStart](#sessionstart) sebagai gantinya.
1431 1454
1432Nilai matcher berkaitan dengan flag CLI yang memicu hook:1455Nilai matcher berkaitan dengan flag CLI yang memicu hook:
1433 1456
1438 1461
1439Saat Anda menjalankan `claude --init-only`, Claude Code menjalankan hook Setup dan hook `SessionStart` dengan matcher `startup`, lalu keluar tanpa memulai percakapan.1462Saat Anda menjalankan `claude --init-only`, Claude Code menjalankan hook Setup dan hook `SessionStart` dengan matcher `startup`, lalu keluar tanpa memulai percakapan.
1440 1463
1441Saat Anda memulai atau melanjutkan percakapan dengan `-p`, Anda juga perlu memberikan prompt, sebagai argumen atau disalurkan melalui stdin. Anda dapat melewati prompt saat hook `SessionStart` memberikan [`initialUserMessage`](#sessionstart-decision-control) atau saat Anda melanjutkan sesi dengan [panggilan tool yang ditangguhkan](#defer-a-tool-call-for-later).1464Saat Anda memulai atau melanjutkan percakapan dengan `-p`, Anda juga perlu menyediakan prompt, sebagai argumen atau di-pipe melalui stdin. Anda dapat melewati prompt saat hook `SessionStart` menyediakan [`initialUserMessage`](#sessionstart-decision-control) atau saat Anda melanjutkan sesi dengan [panggilan tool yang ditangguhkan](#defer-a-tool-call-for-later).
1442 1465
1443Jika berhasil, `--init-only` tidak mencetak apa pun ke terminal. Untuk memastikan hook berjalan, mulai dengan `claude --debug-file <path> --init-only`, ganti `<path>` dengan lokasi file log, lalu periksa log untuk entri hook Setup dan SessionStart.1466Jika berhasil, `--init-only` tidak mencetak apa pun ke terminal. Untuk memastikan hook telah berjalan, mulai dengan `claude --debug-file <path> --init-only`, ganti `<path>` dengan lokasi file log, lalu periksa log untuk entri hook Setup dan SessionStart.
1444 1467
1445Karena Setup tidak dipicu di setiap peluncuran, plugin yang memerlukan dependensi terpasang tidak dapat hanya mengandalkan Setup. Pola praktisnya adalah memeriksa dependensi saat penggunaan pertama dan memasangnya jika tidak ada, misalnya hook atau skill yang memeriksa `${CLAUDE_PLUGIN_DATA}/node_modules` dan menjalankan `npm install` jika tidak ada. Lihat [direktori data persisten](/docs/id/plugins/components#path-variables-and-persistent-data) untuk lokasi penyimpanan dependensi yang terpasang. Jika Anda mendistribusikan plugin melalui marketplace, Anda mungkin tidak memerlukan pola ini: Claude Code [memasang dependensi paket Node.js yang memenuhi syarat secara otomatis](/docs/id/plugins/loading#node-js-package-dependencies) saat meng-cache plugin.1468Karena Setup tidak dipicu di setiap peluncuran, plugin yang memerlukan dependensi terinstal tidak dapat hanya mengandalkan Setup. Pola praktisnya adalah memeriksa dependensi pada penggunaan pertama dan menginstalnya jika belum ada, misalnya hook atau skill yang memeriksa `${CLAUDE_PLUGIN_DATA}/node_modules` dan menjalankan `npm install` jika tidak ada. Lihat [direktori data persisten](/docs/id/plugins/components#path-variables-and-persistent-data) untuk tempat menyimpan dependensi yang diinstal. Jika Anda mendistribusikan plugin melalui marketplace, Anda mungkin tidak memerlukan pola ini: Claude Code [menginstal dependensi paket Node.js yang memenuhi syarat secara otomatis](/docs/id/plugins/loading#node-js-package-dependencies) saat melakukan cache plugin.
1446 1469
1447<h4 id="setup-input">1470<h4 id="setup-input">
1448 Input Setup1471 Input Setup
1449</h4>1472</h4>
1450 1473
1451Selain [field input umum](#common-input-fields), hook Setup menerima field `trigger` yang bernilai `"init"` atau `"maintenance"`:1474Selain [kolom input umum](#common-input-fields), hook Setup menerima kolom `trigger` yang bernilai `"init"` atau `"maintenance"`:
1452 1475
1453```json theme={null}1476```json theme={null}
1454{1477{
1464 Kontrol keputusan Setup1487 Kontrol keputusan Setup
1465</h4>1488</h4>
1466 1489
1467Hook Setup tidak dapat memblokir; eksekusi berlanjut pada exit code apa pun. Pada setiap exit code, Claude Code membuang [field output JSON](#json-output) hook Setup, seperti `systemMessage`, `continue`, dan `hookSpecificOutput.additionalContext`. Dengan `-p`, stdout, stderr, dan exit code hook Setup muncul di output run hanya sebagai [event `hook_response`](/docs/id/headless#read-session-metadata) saat Anda meluncurkan dengan `--output-format stream-json --verbose`.1490Hook Setup tidak dapat memblokir; eksekusi berlanjut pada exit code apa pun. Pada setiap exit code, Claude Code membuang [kolom output JSON](#json-output) dari hook Setup, seperti `systemMessage`, `continue`, dan `hookSpecificOutput.additionalContext`. Dengan `-p`, stdout, stderr, dan exit code hook Setup muncul dalam output eksekusi hanya sebagai [event `hook_response`](/docs/id/headless#read-session-metadata) saat Anda meluncurkan dengan `--output-format stream-json --verbose`.
1468 1491
1469Hook Setup memiliki akses ke `CLAUDE_ENV_FILE`. Variabel yang ditulis ke file tersebut bertahan ke perintah Bash berikutnya dalam sesi, seperti pada [hook SessionStart](#persist-environment-variables). Hanya hook `type: "command"` yang berjalan pada `Setup`. Hook `type: "mcp_tool"` pada `Setup` selalu dilewati, seperti dijelaskan di [field hook tool MCP](#mcp-tool-hook-fields).1492Hook Setup memiliki akses ke `CLAUDE_ENV_FILE`. Variabel yang ditulis ke file tersebut bertahan ke perintah Bash berikutnya dalam sesi, seperti pada [hook SessionStart](#persist-environment-variables). Hanya hook `type: "command"` yang berjalan pada `Setup`. Hook `type: "mcp_tool"` pada `Setup` selalu dilewati, seperti dijelaskan di [kolom hook tool MCP](#mcp-tool-hook-fields).
1470 1493
1471<h3 id="instructionsloaded">1494<h3 id="instructionsloaded">
1472 InstructionsLoaded1495 InstructionsLoaded
1473</h3>1496</h3>
1474 1497
1475Dipicu saat file `CLAUDE.md` atau `.claude/rules/*.md` dimuat ke dalam konteks. Event ini dipicu saat awal sesi untuk file yang dimuat secara eager dan dipicu lagi nanti saat file dimuat secara lazy, misalnya saat Claude mengakses subdirektori yang berisi `CLAUDE.md` bersarang atau saat aturan kondisional dengan frontmatter `paths:` cocok. Hook ini tidak mendukung pemblokiran atau kontrol keputusan. Hook ini berjalan secara asinkron untuk keperluan observabilitas.1498Dipicu saat file `CLAUDE.md` atau `.claude/rules/*.md` dimuat ke dalam konteks. Event ini dipicu di awal sesi untuk file yang dimuat secara langsung dan dipicu lagi nanti saat file dimuat secara lazy, misalnya saat Claude mengakses subdirektori yang berisi `CLAUDE.md` bersarang atau saat aturan kondisional dengan frontmatter `paths:` cocok. Hook ini tidak mendukung pemblokiran atau kontrol keputusan. Hook ini berjalan secara asinkron untuk tujuan observabilitas.
1476 1499
1477Event ini tidak dipicu saat Claude [membaca `AGENTS.md` secara langsung](/docs/id/memory#agents-md) melalui pengaturan **Project instructions**. Event ini tetap dipicu saat `CLAUDE.md` mengimpor `AGENTS.md` Anda, dengan `load_reason` bernilai `include` seperti file impor lainnya, dan saat `CLAUDE.md` adalah symlink ke file tersebut, sebagai pemuatan `CLAUDE.md` biasa.1500Event ini tidak dipicu saat Claude [membaca `AGENTS.md` secara langsung](/docs/id/memory#agents-md) melalui pengaturan **Project instructions**. Event ini dipicu saat `CLAUDE.md` mengimpor `AGENTS.md` Anda, dengan `load_reason` bernilai `include` seperti file impor lainnya, dan saat `CLAUDE.md` merupakan symlink ke file tersebut, sebagai pemuatan `CLAUDE.md` biasa.
1478 1501
1479Matcher dijalankan terhadap `load_reason`. Misalnya, gunakan `"matcher": "session_start"` agar hanya dipicu untuk file yang dimuat saat awal sesi, atau `"matcher": "path_glob_match|nested_traversal"` agar hanya dipicu untuk pemuatan lazy.1502Matcher dijalankan terhadap `load_reason`. Misalnya, gunakan `"matcher": "session_start"` agar hanya dipicu untuk file yang dimuat di awal sesi, atau `"matcher": "path_glob_match|nested_traversal"` agar hanya dipicu untuk pemuatan lazy.
1480 1503
1481<h4 id="instructionsloaded-input">1504<h4 id="instructionsloaded-input">
1482 Input InstructionsLoaded1505 Input InstructionsLoaded
1483</h4>1506</h4>
1484 1507
1485Selain [field input umum](#common-input-fields), hook InstructionsLoaded menerima field berikut:1508Selain [kolom input umum](#common-input-fields), hook InstructionsLoaded menerima kolom-kolom berikut:
1486 1509
1487| Field | Deskripsi |1510| Kolom | Deskripsi |
1488| :- | :- |1511| :- | :- |
1489| `file_path` | Path absolut ke file instruksi yang dimuat |1512| `file_path` | Path absolut ke file instruksi yang dimuat |
1490| `memory_type` | Cakupan file: `"User"`, `"Project"`, `"Local"`, atau `"Managed"` |1513| `memory_type` | Cakupan file: `"User"`, `"Project"`, `"Local"`, atau `"Managed"` |
1509 Kontrol keputusan InstructionsLoaded1532 Kontrol keputusan InstructionsLoaded
1510</h4>1533</h4>
1511 1534
1512Hook InstructionsLoaded tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir atau memodifikasi pemuatan instruksi. Claude Code membuang [field output JSON](#json-output) hook ini, seperti `systemMessage` dan `continue`. Gunakan event ini untuk logging audit, pelacakan kepatuhan, atau observabilitas.1535Hook InstructionsLoaded tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir atau mengubah pemuatan instruksi. Claude Code membuang [kolom output JSON](#json-output) miliknya, seperti `systemMessage` dan `continue`. Gunakan event ini untuk audit logging, pelacakan kepatuhan, atau observabilitas.
1513 1536
1514<h3 id="userpromptsubmit">1537<h3 id="userpromptsubmit">
1515 UserPromptSubmit1538 UserPromptSubmit
1516</h3>1539</h3>
1517 1540
1518Berjalan saat prompt dikirimkan, sebelum Claude memprosesnya. Ini memungkinkan Anda1541Berjalan saat prompt dikirim, sebelum Claude memprosesnya. Ini memungkinkan Anda
1519menambahkan konteks tambahan berdasarkan prompt/percakapan, memvalidasi prompt, atau1542menambahkan konteks tambahan berdasarkan prompt/percakapan, memvalidasi prompt, atau
1520memblokir jenis prompt tertentu.1543memblokir jenis prompt tertentu.
1521 1544
1525* [Subagent latar belakang](/docs/id/sub-agents#run-subagents-in-foreground-or-background) yang melapor kembali ke sesi yang memulainya1548* [Subagent latar belakang](/docs/id/sub-agents#run-subagents-in-foreground-or-background) yang melapor kembali ke sesi yang memulainya
1526* [Pesan yang dikirim sesi lain](/docs/id/cross-session-messaging) ke percakapan utama Anda1549* [Pesan yang dikirim sesi lain](/docs/id/cross-session-messaging) ke percakapan utama Anda
1527 1550
1528Hook `UserPromptSubmit` memiliki timeout default 30 detik untuk jenis `command`, `http`, dan `mcp_tool`, lebih pendek daripada default 600 detik untuk jenis tersebut pada sebagian besar event lain. Karena hook ini berjalan sebelum setiap prompt dan memblokir pemrosesan model hingga selesai, hook yang macet akan menghentikan sesi. Jika hook Anda memerlukan waktu lebih lama, tetapkan field `timeout` dalam entri hook.1551Hook `UserPromptSubmit` memiliki timeout default 30 detik untuk tipe `command`, `http`, dan `mcp_tool`, lebih singkat daripada default 600 detik untuk tipe-tipe tersebut pada sebagian besar event lainnya. Karena hook ini berjalan sebelum setiap prompt dan memblokir pemrosesan model hingga selesai, hook yang macet akan menghentikan sesi. Jika hook Anda memerlukan lebih banyak waktu, tetapkan kolom `timeout` dalam entri hook.
1529 1552
1530Selain hook perintah yang Anda jalankan dengan [`async: true`](#run-hooks-in-the-background), hook perintah, HTTP, atau tool MCP `UserPromptSubmit` yang mencapai timeout-nya akan dibatalkan dan output-nya, termasuk `additionalContext` apa pun, dibuang. Prompt tetap sampai ke Claude tanpa konteks tersebut. Untuk memblokir prompt sebagai gantinya, tetapkan [`onFailure: "block"`](#block-the-action-when-a-hook-fails) pada hook perintah atau HTTP. Transkrip menampilkan pemberitahuan yang menyebutkan hook, timeout yang dipicu, dan bahwa output telah dibuang.1553Selain hook perintah yang Anda jalankan dengan [`async: true`](#run-hooks-in-the-background), hook perintah, HTTP, atau tool MCP `UserPromptSubmit` yang mencapai timeout-nya akan dibatalkan dan output-nya, termasuk `additionalContext` apa pun, dibuang. Prompt tetap sampai ke Claude tanpa konteks tersebut. Untuk memblokir prompt sebagai gantinya, tetapkan [`onFailure: "block"`](#block-the-action-when-a-hook-fails) pada hook perintah atau HTTP. Transkrip menampilkan pemberitahuan yang menyebutkan hook, timeout yang terpicu, dan bahwa output telah dibuang.
1531 1554
1532[Hook callback Agent SDK](/docs/id/agent-sdk/hooks) pada `UserPromptSubmit` yang mencapai timeout-nya memblokir prompt dengan pesan yang menyebutkan nama hook dan timeout-nya, karena callback di sana dapat berfungsi sebagai gerbang kebijakan yang tidak boleh gagal dalam keadaan terbuka. Sesi tetap berlanjut. Sebelum v2.1.208, timeout callback pada event tersebut mengakhiri giliran dengan error eksekusi.1555[Hook callback Agent SDK](/docs/id/agent-sdk/hooks) pada `UserPromptSubmit` yang mencapai timeout-nya akan memblokir prompt dengan pesan yang menyebutkan hook dan timeout-nya, karena callback di sana dapat bertindak sebagai gerbang kebijakan yang tidak boleh gagal terbuka. Sesi tetap berlanjut. Sebelum v2.1.208, timeout callback pada event tersebut mengakhiri giliran dengan error eksekusi.
1533 1556
1534<h4 id="userpromptsubmit-input">1557<h4 id="userpromptsubmit-input">
1535 Input UserPromptSubmit1558 Input UserPromptSubmit
1536</h4>1559</h4>
1537 1560
1538Selain [field input umum](#common-input-fields), hook UserPromptSubmit menerima field `prompt` yang berisi teks yang dikirimkan. Konten tempelan yang diciutkan menjadi placeholder `[Pasted text #N]` tiba dalam keadaan diperluas di tempatnya. Dalam sesi tempat Claude Code [menandai teks tempelan untuk Claude](/docs/id/terminal-config#how-claude-treats-pasted-text), konten yang diperluas tersebut berada di antara baris `<pasted_content id="…">` dan baris `</pasted_content id="…">`, jadi perhitungkan baris-baris tersebut jika hook Anda mem-parse prompt.1561Selain [kolom input umum](#common-input-fields), hook UserPromptSubmit menerima kolom `prompt` yang berisi teks yang dikirim. Konten tempelan yang diringkas menjadi placeholder `[Pasted text #N]` tiba dalam keadaan sudah diperluas di tempatnya. Dalam sesi tempat Claude Code [menandai teks tempelan untuk Claude](/docs/id/terminal-config#how-claude-treats-pasted-text), konten yang diperluas tersebut berada di antara baris `<pasted_content id="…">` dan baris `</pasted_content id="…">`, jadi perhitungkan baris-baris tersebut jika hook Anda mengurai prompt.
1539 1562
1540Hook UserPromptSubmit juga menerima `session_title` saat sesi memiliki judul kustom, dengan makna yang sama seperti [field `session_title` SessionStart](#sessionstart-input).1563Hook UserPromptSubmit juga menerima `session_title` saat sesi memiliki judul kustom, dengan makna yang sama seperti [kolom `session_title` SessionStart](#sessionstart-input).
1541 1564
1542```json theme={null}1565```json theme={null}
1543{1566{
1554 Kontrol keputusan UserPromptSubmit1577 Kontrol keputusan UserPromptSubmit
1555</h4>1578</h4>
1556 1579
1557Hook `UserPromptSubmit` dapat mengontrol apakah prompt yang dikirimkan diproses dan menambahkan konteks. Semua [field output JSON](#json-output) tersedia.1580Hook `UserPromptSubmit` dapat mengontrol apakah prompt yang dikirim diproses dan dapat menambahkan konteks. Semua [kolom output JSON](#json-output) tersedia.
1558 1581
1559Ada dua cara untuk menambahkan konteks ke percakapan pada exit code 0:1582Ada dua cara untuk menambahkan konteks ke percakapan pada exit code 0:
1560 1583
1561* **Stdout teks biasa**: Claude Code menambahkan stdout yang [diperlakukannya sebagai teks biasa](#exit-code-0) ke konteks Claude1584* **Stdout teks biasa**: Claude Code menambahkan stdout yang [diperlakukannya sebagai teks biasa](#exit-code-0) ke konteks Claude
1562* **JSON dengan `additionalContext`**: gunakan format JSON di bawah ini untuk kontrol yang lebih besar. Field `additionalContext` ditambahkan sebagai konteks1585* **JSON dengan `additionalContext`**: gunakan format JSON di bawah ini untuk kontrol yang lebih besar. Kolom `additionalContext` ditambahkan sebagai konteks
1563 1586
1564Tidak satu pun saluran ini menghasilkan entri transkrip yang terlihat. Stdout biasa dan nilai `additionalContext` masing-masing disisipkan sebagai system reminder yang diawali dengan nama hook; Claude membaca keduanya. Untuk memastikan pengiriman, periksa [log debug](#debug-hooks).1587Tidak satu pun dari kedua saluran ini menghasilkan entri transkrip yang terlihat. Stdout biasa dan nilai `additionalContext` masing-masing disisipkan sebagai system reminder yang diawali dengan nama hook; Claude membaca keduanya. Untuk memastikan pengiriman, periksa [debug log](#debug-hooks).
1565 1588
1566Untuk memblokir prompt, kembalikan objek JSON dengan `decision` bernilai `"block"`:1589Untuk memblokir prompt, kembalikan objek JSON dengan `decision` bernilai `"block"`:
1567 1590
1568| Field | Deskripsi |1591| Kolom | Deskripsi |
1569| :- | :- |1592| :- | :- |
1570| `decision` | `"block"` menghentikan prompt sebelum sampai ke Claude. Hilangkan untuk membiarkan prompt berlanjut |1593| `decision` | `"block"` menghentikan prompt sebelum sampai ke Claude. Hilangkan untuk membiarkan prompt berlanjut |
1571| `reason` | Ditampilkan kepada pengguna saat `decision` bernilai `"block"`. Tidak ditambahkan ke konteks |1594| `reason` | Ditampilkan kepada pengguna saat `decision` bernilai `"block"`. Tidak ditambahkan ke konteks |
1572| `additionalContext` | String yang ditambahkan ke konteks Claude bersama prompt yang dikirimkan. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |1595| `additionalContext` | String yang ditambahkan ke konteks Claude bersama prompt yang dikirim. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |
1573| `sessionTitle` | Menetapkan judul sesi. Gunakan untuk memberi nama sesi secara otomatis berdasarkan konten prompt |1596| `sessionTitle` | Menetapkan judul sesi. Gunakan untuk memberi nama sesi secara otomatis berdasarkan isi prompt |
1574| `suppressOriginalPrompt` | Jika `true` saat hook memblokir prompt, teks prompt tidak dimasukkan ke pesan pemblokiran. Lihat [Apa yang ditinggalkan prompt yang diblokir](#what-a-blocked-prompt-leaves-behind) |1597| `suppressOriginalPrompt` | Jika `true` saat hook memblokir prompt, teks prompt tidak disertakan dalam pesan pemblokiran. Lihat [Jejak yang ditinggalkan prompt yang diblokir](#what-a-blocked-prompt-leaves-behind) |
1575 1598
1576Hook yang memblokir dengan keluar menggunakan 2 diarahkan dengan cara yang sama seperti `reason`: pesan pemblokiran menampilkan teks stderr kepada pengguna, dan teks tersebut tidak ditambahkan ke konteks.1599Hook yang memblokir dengan keluar menggunakan kode 2 diarahkan dengan cara yang sama seperti `reason`: pesan pemblokiran menampilkan teks stderr kepada pengguna, dan teks tersebut tidak ditambahkan ke konteks.
1577 1600
1578```json theme={null}1601```json theme={null}
1579{1602{
1589```1612```
1590 1613
1591<h4 id="what-a-blocked-prompt-leaves-behind">1614<h4 id="what-a-blocked-prompt-leaves-behind">
1592 Apa yang ditinggalkan prompt yang diblokir1615 Jejak yang ditinggalkan prompt yang diblokir
1593</h4>1616</h4>
1594 1617
1595Prompt yang diblokir tidak pernah sampai ke Claude, tetapi teksnya tidak dihapus di semua tempat. Secara default, pesan pemblokiran yang ditampilkan kepada pengguna diakhiri dengan `Original prompt:` diikuti teks yang dikirimkan, dan Claude Code menulis pesan tersebut ke file transkrip sesi di disk. Untuk menghilangkan teks dari pesan, cetak JSON dengan `"suppressOriginalPrompt": true` di dalam `hookSpecificOutput`. Ini berfungsi baik saat hook memblokir dengan `decision: "block"` maupun dengan keluar menggunakan 2.1618Prompt yang diblokir tidak pernah sampai ke Claude, tetapi teksnya tidak dihapus dari semua tempat. Secara default, pesan pemblokiran yang ditampilkan kepada pengguna diakhiri dengan `Original prompt:` diikuti teks yang dikirim, dan Claude Code menulis pesan tersebut ke file transkrip sesi di disk. Untuk menghilangkan teks dari pesan, cetak JSON dengan `"suppressOriginalPrompt": true` di dalam `hookSpecificOutput`. Ini berfungsi baik saat hook memblokir dengan `decision: "block"` maupun dengan keluar menggunakan kode 2.
1596 1619
1597`suppressOriginalPrompt` hanya mengubah pesan pemblokiran. Teks yang dikirimkan tetap dapat muncul di file lokal seperti transkrip sesi dan riwayat prompt Anda, jadi hook pemblokir bukan cara untuk mencegah rahasia tersimpan di disk. Untuk membatasi atau menghapus file tersebut, lihat [Penyimpanan plaintext](/docs/id/claude-directory#plaintext-storage) dan [Menghapus data lokal](/docs/id/claude-directory#clear-local-data).1620`suppressOriginalPrompt` hanya mengubah pesan pemblokiran. Teks yang dikirim tetap dapat muncul di file lokal seperti transkrip sesi dan riwayat prompt Anda, sehingga hook pemblokiran bukanlah cara untuk menjaga rahasia agar tidak tersimpan di disk. Untuk membatasi atau menghapus file-file tersebut, lihat [Penyimpanan plaintext](/docs/id/claude-directory#plaintext-storage) dan [Menghapus data lokal](/docs/id/claude-directory#clear-local-data).
1598 1621
1599<h3 id="userpromptexpansion">1622<h3 id="userpromptexpansion">
1600 UserPromptExpansion1623 UserPromptExpansion
1601</h3>1624</h3>
1602 1625
1603Berjalan saat perintah yang diketik pengguna diperluas menjadi prompt sebelum sampai ke Claude. Gunakan ini untuk memblokir perintah tertentu dari pemanggilan langsung, menyisipkan konteks untuk skill tertentu, atau mencatat perintah mana yang dipanggil pengguna. Misalnya, hook yang cocok dengan `deploy` dapat memblokir `/deploy` kecuali ada file persetujuan, atau hook yang cocok dengan skill review dapat menambahkan daftar periksa review tim sebagai `additionalContext`.1626Berjalan saat perintah yang diketik pengguna diperluas menjadi prompt sebelum sampai ke Claude. Gunakan ini untuk memblokir perintah tertentu agar tidak dipanggil secara langsung, menyisipkan konteks untuk skill tertentu, atau mencatat perintah mana yang dipanggil pengguna. Misalnya, hook yang cocok dengan `deploy` dapat memblokir `/deploy` kecuali ada file persetujuan, atau hook yang cocok dengan skill review dapat menambahkan daftar periksa review tim sebagai `additionalContext`.
1604 1627
1605Event ini mencakup jalur yang tidak dicakup `PreToolUse`: hook `PreToolUse` yang cocok dengan tool `Skill` hanya dipicu saat Claude memanggil tool tersebut, tetapi mengetik `/skillname` secara langsung melewati `PreToolUse`. `UserPromptExpansion` dipicu pada jalur langsung tersebut.1628Event ini mencakup jalur yang tidak dicakup `PreToolUse`: hook `PreToolUse` yang cocok dengan tool `Skill` hanya dipicu saat Claude memanggil tool tersebut, tetapi mengetik `/skillname` secara langsung melewati `PreToolUse`. `UserPromptExpansion` dipicu pada jalur langsung tersebut.
1606 1629
1607Dicocokkan pada `command_name`. Biarkan matcher kosong agar dipicu pada setiap perintah berjenis prompt.1630Dicocokkan pada `command_name`. Biarkan matcher kosong agar dipicu pada setiap perintah bertipe prompt.
1608 1631
1609<h4 id="userpromptexpansion-input">1632<h4 id="userpromptexpansion-input">
1610 Input UserPromptExpansion1633 Input UserPromptExpansion
1611</h4>1634</h4>
1612 1635
1613Selain [field input umum](#common-input-fields), hook UserPromptExpansion menerima `expansion_type`, `command_name`, `command_args`, `command_source`, dan string `prompt` asli. Field `expansion_type` bernilai `slash_command` untuk skill dan perintah kustom, atau `mcp_prompt` untuk prompt server MCP.1636Selain [kolom input umum](#common-input-fields), hook UserPromptExpansion menerima `expansion_type`, `command_name`, `command_args`, `command_source`, dan string `prompt` asli. Kolom `expansion_type` bernilai `slash_command` untuk skill dan perintah kustom, atau `mcp_prompt` untuk prompt server MCP.
1614 1637
1615```json theme={null}1638```json theme={null}
1616{1639{
1631 Kontrol keputusan UserPromptExpansion1654 Kontrol keputusan UserPromptExpansion
1632</h4>1655</h4>
1633 1656
1634Hook `UserPromptExpansion` dapat memblokir perluasan atau menambahkan konteks. Semua [field output JSON](#json-output) tersedia.1657Hook `UserPromptExpansion` dapat memblokir perluasan atau menambahkan konteks. Semua [kolom output JSON](#json-output) tersedia.
1635 1658
1636| Field | Deskripsi |1659| Kolom | Deskripsi |
1637| :- | :- |1660| :- | :- |
1638| `decision` | `"block"` mencegah perintah diperluas. Hilangkan untuk membiarkannya berlanjut |1661| `decision` | `"block"` mencegah perintah diperluas. Hilangkan untuk membiarkannya berlanjut |
1639| `reason` | Ditampilkan kepada pengguna saat `decision` bernilai `"block"` |1662| `reason` | Ditampilkan kepada pengguna saat `decision` bernilai `"block"` |
1640| `additionalContext` | String yang ditambahkan ke konteks Claude bersama prompt yang diperluas. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |1663| `additionalContext` | String yang ditambahkan ke konteks Claude bersama prompt yang diperluas. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |
1641 1664
1642Hook yang memblokir dengan keluar menggunakan 2 diarahkan dengan cara yang sama seperti `reason`: pesan pemblokiran menampilkan teks stderr kepada pengguna.1665Hook yang memblokir dengan keluar menggunakan kode 2 diarahkan dengan cara yang sama seperti `reason`: pesan pemblokiran menampilkan teks stderr kepada pengguna.
1643 1666
1644```json theme={null}1667```json theme={null}
1645{1668{
1656 MessageDisplay1679 MessageDisplay
1657</h3>1680</h3>
1658 1681
1659Berjalan saat pesan asisten di-streaming ke layar. Claude Code menampilkan pesan secara bertahap: setiap kali sekelompok baris yang baru selesai siap dirender, hook berjalan sekali dengan baris-baris tersebut dan Claude Code merender teks pengganti dari hook di tempatnya. Pesan yang panjang menghasilkan beberapa panggilan; pesan yang pendek mungkin hanya menghasilkan satu.1682Berjalan saat pesan asisten di-stream ke layar. Claude Code menampilkan pesan secara bertahap: setiap kali sekelompok baris yang baru selesai siap dirender, hook berjalan sekali dengan baris-baris tersebut dan Claude Code merender teks pengganti dari hook di tempatnya. Pesan yang panjang menghasilkan beberapa panggilan; pesan yang pendek mungkin hanya menghasilkan satu.
1660 1683
1661Gunakan MessageDisplay untuk:1684Gunakan MessageDisplay untuk:
1662 1685
1663* menghapus markdown untuk tampilan minimal1686* menghapus markdown untuk tampilan minimal
1664* mentransformasi teks yang ditampilkan aplikasi Agent SDK kepada penggunanya1687* mengubah teks yang ditampilkan aplikasi Agent SDK kepada penggunanya
1665* menyamarkan kunci API atau hostname internal dari respons Claude1688* menyamarkan kunci API atau hostname internal dari respons Claude
1666 1689
1667Claude Code menahan setiap kelompok hingga hook Anda kembali, jadi jaga agar hook tetap cepat. Jika hook gagal atau mencapai timeout, Claude Code menampilkan teks asli. Timeout default untuk event ini adalah 10 detik; jika hook Anda memerlukan waktu lebih lama, tetapkan field `timeout` dalam entri hook.1690Claude Code menahan setiap kelompok hingga hook Anda kembali, jadi jaga agar hook tetap cepat. Jika hook gagal atau mengalami timeout, Claude Code menampilkan teks asli. Timeout default untuk event ini adalah 10 detik; jika hook Anda memerlukan lebih banyak waktu, tetapkan kolom `timeout` dalam entri hook.
1668 1691
1669MessageDisplay hanya untuk tampilan: teks pengganti hanya mengubah apa yang dirender di layar. Transkrip dan apa yang dilihat Claude tetap menyimpan teks asli, sehingga Claude tidak pernah melihat penggantinya, dan mode verbose menampilkan teks asli. Hook hanya menerima teks pesan asisten, sehingga hasil tool dan teks yang Anda ketik dirender tanpa perubahan.1692MessageDisplay hanya untuk tampilan: teks pengganti hanya mengubah apa yang dirender di layar. Transkrip dan apa yang dilihat Claude tetap menggunakan teks asli, sehingga Claude tidak pernah melihat teks pengganti, dan mode verbose menampilkan teks asli. Hook hanya menerima teks pesan asisten, sehingga hasil tool dan teks yang Anda ketik dirender tanpa perubahan.
1670 1693
1671MessageDisplay tidak mendukung matcher dan dipicu untuk setiap pesan asisten yang men-streaming teks; pesan tanpa teks, seperti respons yang hanya berisi panggilan tool, tidak memicunya.1694MessageDisplay tidak mendukung matcher dan dipicu untuk setiap pesan asisten yang men-stream teks; pesan tanpa teks, seperti respons yang hanya berisi panggilan tool, tidak memicunya.
1672 1695
1673Dalam run non-interaktif, termasuk kueri Agent SDK dan `claude -p`, MessageDisplay berjalan sekali per pesan asisten, bukan sekali per kelompok baris. Panggilan tunggal tersebut tiba setelah pesan selesai dan membawa teks pesan lengkap: `index` bernilai `0`, `final` bernilai `true`, dan `delta` berisi seluruh pesan. Hook yang mengumpulkan teks `delta` untuk setiap pesan menerima total teks yang sama di kedua mode.1696Dalam eksekusi non-interaktif, termasuk kueri Agent SDK dan `claude -p`, MessageDisplay berjalan sekali per pesan asisten alih-alih sekali per kelompok baris. Panggilan tunggal tersebut tiba setelah pesan selesai dan membawa teks pesan lengkap: `index` bernilai `0`, `final` bernilai `true`, dan `delta` berisi seluruh pesan. Hook yang mengumpulkan teks `delta` untuk setiap pesan menerima total teks yang sama di kedua mode.
1674 1697
1675<h4 id="messagedisplay-input">1698<h4 id="messagedisplay-input">
1676 Input MessageDisplay1699 Input MessageDisplay
1677</h4>1700</h4>
1678 1701
1679Selain [field input umum](#common-input-fields), hook MessageDisplay menerima pengenal untuk giliran dan pesan, posisi panggilan ini dalam pesan, dan teks baru di `delta`. Batas kelompok bergantung pada cara teks di-streaming, jadi gunakan `index` dan `final` untuk melacak kemajuan melalui pesan alih-alih mengharapkan baris dikelompokkan dengan cara tertentu.1702Selain [kolom input umum](#common-input-fields), hook MessageDisplay menerima pengidentifikasi untuk giliran dan pesan, posisi panggilan ini di dalam pesan, dan teks baru dalam `delta`. Batas kelompok bergantung pada cara teks di-stream, jadi gunakan `index` dan `final` untuk melacak kemajuan melalui pesan alih-alih mengharapkan baris dikelompokkan dengan cara tertentu.
1680 1703
1681| Field | Deskripsi |1704| Kolom | Deskripsi |
1682| :- | :- |1705| :- | :- |
1683| `turn_id` | UUID giliran saat ini |1706| `turn_id` | UUID giliran saat ini |
1684| `message_id` | UUID pesan asisten yang sedang ditampilkan. Stabil di setiap kelompok dari pesan yang sama. Ini bukan id `msg_…` dari API, sehingga tidak dapat dikorelasikan dengan id pesan transkrip |1707| `message_id` | UUID pesan asisten yang sedang ditampilkan. Tetap sama di setiap kelompok dari pesan yang sama. Ini bukan id API `msg_…`, sehingga tidak dapat dikorelasikan dengan id pesan transkrip |
1685| `index` | Indeks berbasis nol dari kelompok ini dalam pesan |1708| `index` | Indeks berbasis nol dari kelompok ini di dalam pesan |
1686| `final` | `true` pada kelompok terakhir pesan. Setiap pesan memiliki tepat satu kelompok final |1709| `final` | `true` pada kelompok terakhir pesan. Setiap pesan memiliki tepat satu kelompok final |
1687| `delta` | Baris yang baru selesai sejak kelompok sebelumnya, termasuk baris baru penutupnya. Selalu berupa baris utuh, kecuali kelompok final yang dapat berakhir di tengah baris. Dalam run interaktif, delta kelompok final kosong saat pesan berakhir dengan baris baru, jadi perlakukan `final`, bukan delta yang tidak kosong, sebagai sinyal akhir pesan. Dalam run Agent SDK dan `claude -p`, panggilan tunggal membawa seluruh pesan |1710| `delta` | Baris-baris yang baru selesai sejak kelompok sebelumnya, termasuk newline penutupnya. Selalu berupa baris utuh, kecuali kelompok final yang dapat berakhir di tengah baris. Dalam eksekusi interaktif, delta kelompok final kosong jika pesan berakhir dengan newline, jadi perlakukan `final`, bukan delta yang tidak kosong, sebagai sinyal akhir pesan. Dalam eksekusi Agent SDK dan `claude -p`, panggilan tunggal membawa seluruh pesan |
1688 1711
1689```json theme={null}1712```json theme={null}
1690{1713{
1704 Output MessageDisplay1727 Output MessageDisplay
1705</h4>1728</h4>
1706 1729
1707Selain [field output JSON](#json-output) yang tersedia untuk semua hook, hook MessageDisplay dapat mengembalikan `displayContent` untuk menggantikan delta di layar:1730Selain [kolom output JSON](#json-output) yang tersedia untuk semua hook, hook MessageDisplay dapat mengembalikan `displayContent` untuk menggantikan delta di layar:
1708 1731
1709| Field | Deskripsi |1732| Kolom | Deskripsi |
1710| :- | :- |1733| :- | :- |
1711| `displayContent` | Teks yang ditampilkan sebagai pengganti delta. Hilangkan untuk menampilkan teks asli |1734| `displayContent` | Teks yang ditampilkan sebagai pengganti delta. Hilangkan untuk menampilkan teks asli |
1712 1735
1788 </Tab>1811 </Tab>
1789</Tabs>1812</Tabs>
1790 1813
1791Kelompok tanpa markdown diteruskan tanpa perubahan. Jika skrip gagal, misalnya karena `jq` tidak ada, Claude Code menampilkan teks asli dan mencatat kegagalan hanya di [output debug](#debug-hooks), bukan di sesi.1814Kelompok tanpa markdown diteruskan tanpa perubahan. Jika skrip gagal, misalnya karena `jq` tidak ada, Claude Code menampilkan teks asli dan mencatat kegagalan tersebut hanya di [output debug](#debug-hooks), bukan di dalam sesi.
1792 1815
1793<h3 id="pretooluse">1816<h3 id="pretooluse">
1794 PreToolUse1817 PreToolUse
1795</h3>1818</h3>
1796 1819
1797Berjalan setelah Claude membuat parameter tool dan sebelum memproses panggilan tool. Dicocokkan pada nama tool apa pun kecuali `EndConversation`: tool bawaan seperti `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion`, dan `ExitPlanMode`, serta [nama tool MCP](#match-mcp-tools) apa pun.1820Berjalan setelah Claude membuat parameter tool dan sebelum memproses panggilan tool. Cocok dengan nama tool apa pun kecuali `EndConversation`: tool bawaan seperti `Bash`, `PowerShell`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `Agent`, `Workflow`, `WebFetch`, `WebSearch`, `AskUserQuestion`, dan `ExitPlanMode`, serta [nama tool MCP](#match-mcp-tools) apa pun.
1798 1821
1799Untuk menjalankan hook saat file tertentu berubah di disk, apa pun yang menulisnya, gunakan [FileChanged](#filechanged) alih-alih mencocokkan tool pengedit file berdasarkan nama. Tidak seperti PreToolUse, Claude Code menjalankan hook FileChanged setelah perubahan, dan hook tersebut tidak memiliki kontrol keputusan, sehingga tidak dapat memblokir penulisan.1822Untuk menjalankan hook saat file tertentu berubah di disk, apa pun yang menulisnya, gunakan [FileChanged](#filechanged) alih-alih mencocokkan tool pengeditan file berdasarkan nama. Tidak seperti PreToolUse, Claude Code menjalankan hook FileChanged setelah perubahan terjadi, dan hook tersebut tidak memiliki kontrol keputusan, sehingga tidak dapat memblokir penulisan.
1800 1823
1801<Warning>1824<Warning>
1802 PreToolUse hanya berjalan saat Claude memanggil tool. File yang Anda [referensikan dengan `@` dalam prompt](/docs/id/common-workflows#reference-files-and-directories) ditambahkan tanpa panggilan tool apa pun: Claude Code menyisipkan kontennya saat menyusun prompt, sehingga tidak ada hook PreToolUse yang dipicu untuk file tersebut, termasuk hook yang cocok dengan `Read`. Untuk memblokir path tertentu dari referensi `@`, gunakan [aturan deny `Read`](/docs/id/permissions#read-and-edit) sebagai gantinya.1825 PreToolUse hanya berjalan saat Claude memanggil tool. Secara default, file yang Anda [rujuk dengan `@` di prompt Anda](/docs/id/common-workflows#reference-files-and-directories) ditambahkan tanpa panggilan tool apa pun. Claude Code menyisipkan isinya saat membangun prompt, sehingga tidak ada hook PreToolUse yang dipicu untuk file tersebut, termasuk hook yang cocok dengan `Read`. PreToolUse juga tidak dipicu untuk [`EndConversation`](/docs/id/tools-reference#endconversation-tool-behavior).
1803 1826
1804 PreToolUse juga tidak dipicu untuk [`EndConversation`](/docs/id/tools-reference#endconversation-tool-behavior).1827 Anda dapat memblokir path tertentu dari referensi `@`, atau mematikan penyisipan:
1828
1829 * **Memblokir path tertentu**: tambahkan [aturan deny `Read`](/docs/id/permissions#read-and-edit) untuk path tersebut
1830 * **Mematikan penyisipan**: tetapkan [`CLAUDE_CODE_DISABLE_FILE_MENTIONS=1`](/docs/id/env-vars#variables) di shell, pengaturan pengguna, atau pengaturan terkelola Anda. Claude kemudian mendapatkan path yang disebutkan beserta catatan untuk membacanya menggunakan tool file-nya. Jika Claude melakukannya, hook PreToolUse Anda yang cocok akan berjalan. Variabel ini memerlukan Claude Code v2.1.299 atau lebih baru, dan Claude Code mengabaikannya di pengaturan proyek dan lokal.
1805</Warning>1831</Warning>
1806 1832
1807Gunakan [kontrol keputusan PreToolUse](#pretooluse-decision-control) untuk mengizinkan, menolak, meminta konfirmasi, atau menangguhkan panggilan tool.1833Gunakan [kontrol keputusan PreToolUse](#pretooluse-decision-control) untuk mengizinkan, menolak, meminta konfirmasi, atau menangguhkan panggilan tool.
1808 1834
1809[Hook callback Agent SDK](/docs/id/agent-sdk/hooks) pada `PreToolUse` yang melebihi timeout-nya memblokir panggilan tool, dan Claude menerima hasil error yang menyebutkan timeout tersebut. Penolakan eksplisit yang dikembalikan oleh hook lain tetap diutamakan.1835[Hook callback Agent SDK](/docs/id/agent-sdk/hooks) pada `PreToolUse` yang melampaui timeout-nya akan memblokir panggilan tool, dan Claude menerima hasil error yang menyebutkan timeout tersebut. Penolakan eksplisit yang dikembalikan oleh hook lain tetap diutamakan.
1810 1836
1811<h4 id="pretooluse-input">1837<h4 id="pretooluse-input">
1812 Input PreToolUse1838 Input PreToolUse
1813</h4>1839</h4>
1814 1840
1815Selain [field input umum](#common-input-fields), hook PreToolUse menerima `tool_name`, `tool_input`, dan `tool_use_id`.1841Selain [kolom input umum](#common-input-fields), hook PreToolUse menerima `tool_name`, `tool_input`, dan `tool_use_id`.
1816 1842
1817Untuk [tool MCP](#match-mcp-tools), input juga membawa `mcp_server`, sebuah objek dengan `name` server dan `source` yang menyatakan dari mana definisi server berasal. Nilai `source` mencakup `plugin`, `sdk`, dan cakupan konfigurasi seperti `user` dan `project`. [`McpServerProvenance`](/docs/id/agent-sdk/typescript#mcpserverprovenance) dalam referensi Agent SDK mencantumkan semuanya dan menjelaskan cara memperlakukan nilai yang tidak Anda kenali. Dasarkan keputusan kepercayaan pada `source`, bukan pada `name` atau prefiks nama tool `mcp__<server>__`. Field `mcp_server` memerlukan Claude Code v2.1.274 atau yang lebih baru.1843Untuk [tool MCP](#match-mcp-tools), input juga membawa `mcp_server`, sebuah objek dengan `name` server dan `source` yang menyatakan asal definisi server tersebut. Nilai `source` mencakup `plugin`, `sdk`, dan cakupan konfigurasi seperti `user` dan `project`. [`McpServerProvenance`](/docs/id/agent-sdk/typescript#mcpserverprovenance) dalam referensi Agent SDK mencantumkan semuanya dan menjelaskan cara memperlakukan nilai yang tidak Anda kenali. Dasarkan keputusan kepercayaan pada `source`, bukan pada `name` atau prefiks nama tool `mcp__<server>__`. Kolom `mcp_server` memerlukan Claude Code v2.1.274 atau lebih baru.
1818 1844
1819Untuk tool file `Write`, `Edit`, dan `Read`, `tool_input.file_path` selalu absolut:1845Untuk tool file `Write`, `Edit`, dan `Read`, `tool_input.file_path` selalu absolut:
1820 1846
1821* Claude Code memperluas `~` dan path relatif sebelum hook berjalan, sehingga hook yang mencocokkan path tidak dapat dilewati melalui `~` atau penulisan relatif dari path yang sama1847* Claude Code memperluas `~` dan path relatif sebelum hook berjalan, sehingga hook yang mencocokkan path tidak dapat dilewati melalui `~` atau penulisan relatif dari path yang sama
1822* Di Windows, path tiba dengan pemisah backslash, bahkan saat hook Anda berjalan di Git Bash tempat `$PWD` terlihat seperti `/c/project`1848* Di Windows, path tiba dengan pemisah backslash, bahkan saat hook Anda berjalan di Git Bash tempat `$PWD` terlihat seperti `/c/project`
1823* Perbandingan yang ditulis dengan garis miring maju, seperti pemeriksaan `/src/`, tidak pernah cocok dengan path backslash, dan panggilan tool berlanjut seolah-olah hook tidak memiliki apa pun untuk diblokir1849* Perbandingan yang ditulis dengan garis miring, seperti pemeriksaan `/src/`, tidak pernah cocok dengan path backslash, dan panggilan tool berlanjut seolah-olah hook tidak menemukan apa pun untuk diblokir
1824* Normalisasikan pemisah sebelum membandingkan: `FILE_PATH="${FILE_PATH//\\//}"` di Bash, atau `file_path.replace("\\", "/")` di Python, lalu cocokkan segmen path seperti `/src/` alih-alih menjangkar dengan `^`, karena path bersifat absolut1850* Normalisasikan pemisah sebelum membandingkan: `FILE_PATH="${FILE_PATH//\\//}"` di Bash, atau `file_path.replace("\\", "/")` di Python, lalu cocokkan segmen path seperti `/src/` alih-alih menambatkan dengan `^`, karena path-nya absolut
1825 1851
1826Panggilan `Write` di Windows mengirimkan:1852Panggilan `Write` di Windows mengirimkan:
1827 1853
1837}1863}
1838```1864```
1839 1865
1840Field `tool_input` bergantung pada tool:1866Kolom `tool_input` bergantung pada tool:
1841 1867
1842<a id="bash" />1868<a id="bash" />
1843 1869
1847 1873
1848Menjalankan perintah shell.1874Menjalankan perintah shell.
1849 1875
1850| Field | Tipe | Contoh | Deskripsi |1876| Kolom | Tipe | Contoh | Deskripsi |
1851| :- | :- | :- | :- |1877| :- | :- | :- | :- |
1852| `command` | string | `"npm test"` | Perintah shell yang akan dijalankan |1878| `command` | string | `"npm test"` | Perintah shell yang akan dijalankan |
1853| `description` | string | `"Run test suite"` | Deskripsi opsional tentang apa yang dilakukan perintah |1879| `description` | string | `"Run test suite"` | Deskripsi opsional tentang apa yang dilakukan perintah |
1854| `timeout` | number | `120000` | Timeout opsional dalam milidetik. Nilai di atas [maksimum](/docs/id/tools-reference#bash-tool-behavior) dikurangi menjadi maksimum alih-alih ditolak |1880| `timeout` | number | `120000` | Timeout opsional dalam milidetik. Nilai di atas [batas maksimum](/docs/id/tools-reference#bash-tool-behavior) dikurangi ke batas maksimum alih-alih ditolak |
1855| `run_in_background` | boolean | `false` | Apakah perintah dijalankan di latar belakang |1881| `run_in_background` | boolean | `false` | Apakah perintah dijalankan di latar belakang |
1856 1882
1857Saat perintah Bash mengubah file dalam repositori Git, Claude Code dapat merekam apa yang berubah. Claude Code merekam perubahan di setiap mode izin saat pengaturan [`bashEditDiffEnabled`](/docs/id/settings-reference#basheditdiffenabled) mengaktifkan perekaman; entri pengaturan tersebut menjelaskan file mana yang dapat menetapkannya. Jika tidak, Claude Code merekamnya hanya dalam auto mode dan mode `bypassPermissions`, dan hanya saat Claude Code mengarahkan Claude untuk mengedit file melalui Bash. Tetapkan `bashEditDiffEnabled` ke `false` untuk mematikan perekaman. Perintah latar belakang dan perintah read-only tidak membawa diff.1883Saat perintah Bash mengubah file di repositori Git, Claude Code dapat mencatat apa yang berubah. Claude Code mencatat perubahan di setiap mode izin saat pengaturan [`bashEditDiffEnabled`](/docs/id/settings-reference#basheditdiffenabled) mengaktifkan pencatatan; entri pengaturan tersebut menjelaskan file mana yang dapat menetapkannya. Jika tidak, Claude Code hanya mencatatnya di auto mode dan mode `bypassPermissions`, dan hanya saat Claude Code mengarahkan Claude untuk mengedit file melalui Bash. Tetapkan `bashEditDiffEnabled` ke `false` untuk mematikan pencatatan. Perintah latar belakang dan perintah read-only tidak membawa diff.
1858 1884
1859[Hook PostToolUse](#posttooluse) Anda kemudian menerima file yang berubah di `tool_response.bashEditDiff`. Daftar tersebut mencakup apa yang berubah di bawah repositori saat perintah berjalan. File yang diabaikan Git dan file di submodule tidak dicantumkan. Memerlukan Claude Code v2.1.269 atau yang lebih baru.1885[Hook PostToolUse](#posttooluse) Anda kemudian menerima file yang berubah dalam `tool_response.bashEditDiff`. Daftar tersebut mencakup apa yang berubah di dalam repositori selama perintah berjalan. File yang diabaikan Git dan file di submodule tidak dicantumkan. Memerlukan Claude Code v2.1.269 atau lebih baru.
1860 1886
1861<Note>1887<Note>
1862 Daftar ini bersifat best effort dan dalam beta publik. Claude Code dapat melewatkan perubahan, menyertakan file yang diubah proses lain pada saat yang sama, atau berhenti pada batas ukurannya. Bentuk field dapat berubah. Gunakan daftar ini untuk menemukan apa yang perlu ditinjau, bukan untuk menegakkan kebijakan.1888 Daftar ini bersifat upaya terbaik dan dalam beta publik. Claude Code dapat melewatkan perubahan, menyertakan file yang diubah oleh proses lain pada saat yang sama, atau berhenti pada batas ukurannya. Bentuk kolom dapat berubah. Gunakan daftar ini untuk menemukan apa yang perlu ditinjau, bukan untuk menegakkan kebijakan.
1863</Note>1889</Note>
1864 1890
1865`changedFiles` dan `files` mencantumkan apa yang diubah perintah; field lainnya menyatakan seberapa lengkap dan seberapa andal daftar tersebut.1891`changedFiles` dan `files` mencantumkan apa yang diubah oleh perintah; kolom lainnya menyatakan seberapa lengkap dan seberapa andal daftar tersebut.
1866 1892
1867| Field | Tipe | Contoh | Deskripsi |1893| Kolom | Tipe | Contoh | Deskripsi |
1868| :- | :- | :- | :- |1894| :- | :- | :- | :- |
1869| `changedFiles` | array | `["/path/to/src/app.ts"]` | Path absolut file yang diubah perintah, paling banyak 200. Ada setiap kali `files` berisi diff atau `moreFiles` di atas nol |1895| `changedFiles` | array | `["/path/to/src/app.ts"]` | Path absolut dari file yang diubah perintah, paling banyak 200. Ada setiap kali `files` berisi diff atau `moreFiles` di atas nol |
1870| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diff hingga 5 file yang berubah, untuk ditampilkan. `created` atau `deleted` bernilai `true` untuk file yang ditambahkan atau dihapus oleh perintah |1896| `files` | array | `[{"filePath": "/path/to/src/app.ts", "hunks": [...]}]` | Diff dari hingga 5 file yang berubah, untuk ditampilkan. `created` atau `deleted` bernilai `true` untuk file yang ditambahkan atau dihapus perintah |
1871| `moreFiles` | number | `2` | Jumlah file yang berubah tanpa diff di `files` |1897| `moreFiles` | number | `2` | Jumlah file yang berubah tanpa diff di `files` |
1872| `unavailable` | boolean | `true` | Ditetapkan saat diff tidak lengkap atau tidak dapat diambil |1898| `unavailable` | boolean | `true` | Ditetapkan saat diff tidak lengkap atau tidak dapat diambil |
1873| `skipped` | boolean | `true` | Ditetapkan untuk perintah Git yang memindahkan working tree, seperti `git checkout` atau `git stash`, sehingga Claude Code tidak mengambil diff |1899| `skipped` | boolean | `true` | Ditetapkan untuk perintah Git yang memindahkan working tree, seperti `git checkout` atau `git stash`, sehingga Claude Code tidak mengambil diff |
1874| `shared` | boolean | `true` | Ditetapkan saat panggilan tool Bash lain, seperti milik subagent, berjalan di repositori yang sama pada saat yang sama, sehingga beberapa perubahan yang dicantumkan mungkin berasal dari perintah tersebut |1900| `shared` | boolean | `true` | Ditetapkan saat panggilan tool Bash lain, seperti milik subagent, berjalan di repositori yang sama pada saat yang sama, sehingga beberapa perubahan yang tercantum mungkin berasal dari perintah tersebut |
1875 1901
1876<a id="powershell" />1902<a id="powershell" />
1877 1903
1881 1907
1882Menjalankan perintah PowerShell. Lihat [tool PowerShell](/docs/id/tools-reference#powershell-tool) untuk ketersediaan berdasarkan platform.1908Menjalankan perintah PowerShell. Lihat [tool PowerShell](/docs/id/tools-reference#powershell-tool) untuk ketersediaan berdasarkan platform.
1883 1909
1884Field-nya sama dengan tool Bash, dengan string perintah di `command`:1910Kolomnya sama dengan tool Bash, dengan string perintah di `command`:
1885 1911
1886| Field | Tipe | Contoh | Deskripsi |1912| Kolom | Tipe | Contoh | Deskripsi |
1887| :- | :- | :- | :- |1913| :- | :- | :- | :- |
1888| `command` | string | `"Get-ChildItem -Recurse"` | Perintah PowerShell yang akan dijalankan |1914| `command` | string | `"Get-ChildItem -Recurse"` | Perintah PowerShell yang akan dijalankan |
1889| `description` | string | `"List files recursively"` | Deskripsi opsional tentang apa yang dilakukan perintah |1915| `description` | string | `"List files recursively"` | Deskripsi opsional tentang apa yang dilakukan perintah |
1890| `timeout` | number | `120000` | Timeout opsional dalam milidetik |1916| `timeout` | number | `120000` | Timeout opsional dalam milidetik |
1891| `run_in_background` | boolean | `false` | Apakah perintah dijalankan di latar belakang |1917| `run_in_background` | boolean | `false` | Apakah perintah dijalankan di latar belakang |
1892 1918
1893Cocokkan `Bash|PowerShell` dalam hook yang memeriksa perintah shell, sehingga hook tersebut mencakup kedua tool:1919Cocokkan `Bash|PowerShell` di hook yang memeriksa perintah shell, agar mencakup kedua tool:
1894 1920
1895* Di Windows, di mana pun tool PowerShell diaktifkan, Claude memperlakukan PowerShell sebagai shell utama dan mengarahkan perintah shell melaluinya.1921* Di Windows, di mana pun tool PowerShell diaktifkan, Claude memperlakukan PowerShell sebagai shell utama dan mengarahkan perintah shell melaluinya.
1896* Di Windows tanpa Git Bash, tool ini diaktifkan secara otomatis dan Claude Code sama sekali tidak mendaftarkan tool Bash.1922* Di Windows tanpa Git Bash, tool tersebut diaktifkan secara otomatis dan Claude Code sama sekali tidak mendaftarkan tool Bash.
1897* Hook yang hanya mencocokkan `Bash` tidak pernah dipicu di sana.1923* Hook yang hanya cocok dengan `Bash` tidak pernah dipicu di sana.
1898 1924
1899<h5 id="write">1925<h5 id="write">
1900 Write1926 Write
1902 1928
1903Membuat atau menimpa file.1929Membuat atau menimpa file.
1904 1930
1905| Field | Tipe | Contoh | Deskripsi |1931| Kolom | Tipe | Contoh | Deskripsi |
1906| :- | :- | :- | :- |1932| :- | :- | :- | :- |
1907| `file_path` | string | `"/path/to/file.txt"` | Path absolut ke file yang akan ditulis |1933| `file_path` | string | `"/path/to/file.txt"` | Path absolut ke file yang akan ditulis |
1908| `content` | string | `"file content"` | Konten yang akan ditulis ke file |1934| `content` | string | `"file content"` | Konten yang akan ditulis ke file |
1911 Edit1937 Edit
1912</h5>1938</h5>
1913 1939
1914Mengganti string dalam file yang sudah ada.1940Mengganti string di file yang sudah ada.
1915 1941
1916| Field | Tipe | Contoh | Deskripsi |1942| Kolom | Tipe | Contoh | Deskripsi |
1917| :- | :- | :- | :- |1943| :- | :- | :- | :- |
1918| `file_path` | string | `"/path/to/file.txt"` | Path absolut ke file yang akan diedit |1944| `file_path` | string | `"/path/to/file.txt"` | Path absolut ke file yang akan diedit |
1919| `old_string` | string | `"original text"` | Teks yang akan dicari dan diganti |1945| `old_string` | string | `"original text"` | Teks yang akan dicari dan diganti |
1924 Read1950 Read
1925</h5>1951</h5>
1926 1952
1927Membaca konten file.1953Membaca isi file.
1928 1954
1929| Field | Tipe | Contoh | Deskripsi |1955| Kolom | Tipe | Contoh | Deskripsi |
1930| :- | :- | :- | :- |1956| :- | :- | :- | :- |
1931| `file_path` | string | `"/path/to/file.txt"` | Path absolut ke file yang akan dibaca |1957| `file_path` | string | `"/path/to/file.txt"` | Path absolut ke file yang akan dibaca |
1932| `offset` | number | `10` | Nomor baris opsional untuk mulai membaca |1958| `offset` | number | `10` | Nomor baris opsional untuk mulai membaca |
1938 1964
1939Menemukan file yang cocok dengan pola glob.1965Menemukan file yang cocok dengan pola glob.
1940 1966
1941| Field | Tipe | Contoh | Deskripsi |1967| Kolom | Tipe | Contoh | Deskripsi |
1942| :- | :- | :- | :- |1968| :- | :- | :- | :- |
1943| `pattern` | string | `"**/*.ts"` | Pola glob untuk mencocokkan file |1969| `pattern` | string | `"**/*.ts"` | Pola glob untuk mencocokkan file |
1944| `path` | string | `"/path/to/dir"` | Direktori opsional tempat pencarian. Default-nya adalah direktori kerja saat ini |1970| `path` | string | `"/path/to/dir"` | Direktori opsional untuk pencarian. Default-nya adalah direktori kerja saat ini |
1945 1971
1946<h5 id="grep">1972<h5 id="grep">
1947 Grep1973 Grep
1948</h5>1974</h5>
1949 1975
1950Mencari konten file dengan ekspresi reguler.1976Mencari isi file dengan ekspresi reguler.
1951 1977
1952| Field | Tipe | Contoh | Deskripsi |1978| Kolom | Tipe | Contoh | Deskripsi |
1953| :- | :- | :- | :- |1979| :- | :- | :- | :- |
1954| `pattern` | string | `"TODO.*fix"` | Pola ekspresi reguler yang akan dicari |1980| `pattern` | string | `"TODO.*fix"` | Pola ekspresi reguler yang dicari |
1955| `path` | string | `"/path/to/dir"` | File atau direktori opsional tempat pencarian |1981| `path` | string | `"/path/to/dir"` | File atau direktori opsional untuk pencarian |
1956| `glob` | string | `"*.ts"` | Pola glob opsional untuk memfilter file |1982| `glob` | string | `"*.ts"` | Pola glob opsional untuk memfilter file |
1957| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"`, atau `"count"`. Default-nya adalah `"files_with_matches"` |1983| `output_mode` | string | `"content"` | `"content"`, `"files_with_matches"`, atau `"count"`. Default-nya adalah `"files_with_matches"` |
1958| `-i` | boolean | `true` | Pencarian tanpa membedakan huruf besar/kecil |1984| `-i` | boolean | `true` | Pencarian tanpa membedakan huruf besar/kecil |
1964 1990
1965Mengambil dan memproses konten web.1991Mengambil dan memproses konten web.
1966 1992
1967| Field | Tipe | Contoh | Deskripsi |1993| Kolom | Tipe | Contoh | Deskripsi |
1968| :- | :- | :- | :- |1994| :- | :- | :- | :- |
1969| `url` | string | `"https://example.com/api"` | URL tempat konten diambil |1995| `url` | string | `"https://example.com/api"` | URL untuk mengambil konten |
1970| `prompt` | string | `"Extract the API endpoints"` | Prompt yang dijalankan pada konten yang diambil |1996| `prompt` | string | `"Extract the API endpoints"` | Prompt yang dijalankan pada konten yang diambil |
1971| `offset` | number | `100000` | Jumlah karakter opsional yang dilewati dari awal halaman. Claude menetapkannya untuk terus membaca halaman yang panjang. Memerlukan Claude Code v2.1.290 atau yang lebih baru |1997| `offset` | number | `100000` | Jumlah karakter opsional yang dilewati dari awal halaman. Claude menetapkannya untuk melanjutkan membaca halaman yang panjang. Memerlukan Claude Code v2.1.290 atau lebih baru |
1972 1998
1973<h5 id="websearch">1999<h5 id="websearch">
1974 WebSearch2000 WebSearch
1976 2002
1977Mencari di web.2003Mencari di web.
1978 2004
1979| Field | Tipe | Contoh | Deskripsi |2005| Kolom | Tipe | Contoh | Deskripsi |
1980| :- | :- | :- | :- |2006| :- | :- | :- | :- |
1981| `query` | string | `"react hooks best practices"` | Kueri pencarian |2007| `query` | string | `"react hooks best practices"` | Kueri pencarian |
1982| `allowed_domains` | array | `["docs.example.com"]` | Opsional: hanya sertakan hasil dari domain ini |2008| `allowed_domains` | array | `["docs.example.com"]` | Opsional: hanya sertakan hasil dari domain-domain ini |
1983| `blocked_domains` | array | `["spam.example.com"]` | Opsional: kecualikan hasil dari domain ini |2009| `blocked_domains` | array | `["spam.example.com"]` | Opsional: kecualikan hasil dari domain-domain ini |
1984 2010
1985<h5 id="agent">2011<h5 id="agent">
1986 Agent2012 Agent
1988 2014
1989Memunculkan [subagent](/docs/id/sub-agents).2015Memunculkan [subagent](/docs/id/sub-agents).
1990 2016
1991| Field | Tipe | Contoh | Deskripsi |2017| Kolom | Tipe | Contoh | Deskripsi |
1992| :- | :- | :- | :- |2018| :- | :- | :- | :- |
1993| `prompt` | string | `"Find all API endpoints"` | Tugas yang akan dilakukan agent |2019| `prompt` | string | `"Find all API endpoints"` | Tugas yang akan dikerjakan agent |
1994| `description` | string | `"Find API endpoints"` | Deskripsi singkat tugas |2020| `description` | string | `"Find API endpoints"` | Deskripsi singkat tugas |
1995| `subagent_type` | string | `"Explore"` | Jenis agent khusus yang akan digunakan |2021| `subagent_type` | string | `"Explore"` | Tipe agent khusus yang digunakan |
1996| `model` | string | `"sonnet"` | Alias model opsional untuk menimpa default |2022| `model` | string | `"sonnet"` | Alias model opsional untuk menimpa default |
1997 2023
1998Saat panggilan Agent di latar depan selesai, [hook PostToolUse](#posttooluse) Anda menerima hasil subagent dan telemetri run di `tool_response`. Baca field ini untuk memeriksa run; untuk rekapitulasi token dan biaya di seluruh subagent, gunakan [penghitung token dan biaya](/docs/id/monitoring-usage#token-counter) yang difilter ke `query_source` `"subagent"`, karena `totalTokens` dan `usage` hanya mencakup permintaan terakhir:2024Saat panggilan Agent latar depan selesai, [hook PostToolUse](#posttooluse) Anda menerima hasil subagent dan telemetri eksekusi dalam `tool_response`. Baca kolom-kolom ini untuk memeriksa eksekusi; untuk rekapitulasi token dan biaya di seluruh subagent, gunakan [penghitung token dan biaya](/docs/id/monitoring-usage#token-counter) yang difilter ke `query_source` `"subagent"`, karena `totalTokens` dan `usage` hanya mencakup permintaan terakhir:
1999 2025
2000| Field | Tipe | Contoh | Deskripsi |2026| Kolom | Tipe | Contoh | Deskripsi |
2001| :- | :- | :- | :- |2027| :- | :- | :- | :- |
2002| `status` | string | `"completed"` | `"completed"` untuk subagent latar depan, `"async_launched"` untuk subagent latar belakang. Subagent berjalan di latar belakang secara default, sehingga panggilan Agent yang menghilangkan `run_in_background` juga menghasilkan `"async_launched"` |2028| `status` | string | `"completed"` | `"completed"` untuk subagent latar depan, `"async_launched"` untuk subagent latar belakang. Subagent berjalan di latar belakang secara default, sehingga panggilan Agent yang tidak menyertakan `run_in_background` juga menghasilkan `"async_launched"` |
2003| `agentId` | string | `"a4d2c8f1e0b3a297"` | Pengenal untuk run subagent |2029| `agentId` | string | `"a4d2c8f1e0b3a297"` | Pengidentifikasi untuk eksekusi subagent |
2004| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Blok teks akhir subagent, atau, untuk subagent yang laporannya melalui `SubagentHandback`, catatan singkat tentang penyerahan tersebut sebagai gantinya |2030| `content` | array | `[{"type": "text", "text": "Found 12 endpoints..."}]` | Blok teks terakhir subagent, atau, untuk subagent yang laporannya melalui `SubagentHandback`, catatan singkat tentang penyerahan tersebut sebagai gantinya |
2005| `resolvedModel` | string | `"claude-sonnet-4-5"` | Model tempat subagent dimulai, yang mungkin berbeda dari model yang diminta |2031| `resolvedModel` | string | `"claude-sonnet-4-5"` | Model yang digunakan subagent saat mulai, yang mungkin berbeda dari model yang diminta |
2006| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | Model yang digunakan secara berurutan, dengan pengulangan berturut-turut diciutkan; hanya ditetapkan saat model ditukar di tengah run. Memerlukan Claude Code v2.1.212 atau yang lebih baru |2032| `modelsUsed` | array | `["claude-sonnet-4-5", "claude-haiku-4-5"]` | Model yang digunakan secara berurutan, dengan pengulangan berturut-turut digabungkan; hanya ditetapkan saat model ditukar di tengah eksekusi. Memerlukan Claude Code v2.1.212 atau lebih baru |
2007| `totalTokens` | number | `12450` | Jumlah token dari permintaan API terakhir subagent: token input, output, dan cache digabungkan. Ini bukan total di seluruh run |2033| `totalTokens` | number | `12450` | Jumlah token dari permintaan API terakhir subagent: gabungan token input, output, dan cache. Ini bukan total di seluruh eksekusi |
2008| `totalDurationMs` | number | `48211` | Durasi waktu nyata run subagent |2034| `totalDurationMs` | number | `48211` | Durasi waktu nyata eksekusi subagent |
2009| `totalToolUseCount` | number | `7` | Jumlah panggilan tool yang dilakukan subagent |2035| `totalToolUseCount` | number | `7` | Jumlah panggilan tool yang dilakukan subagent |
2010| `usage` | object | `{"input_tokens": 8320, ...}` | Rincian token per jenis dari permintaan API terakhir: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |2036| `usage` | object | `{"input_tokens": 8320, ...}` | Rincian token per tipe dari permintaan API terakhir: `input_tokens`, `output_tokens`, `cache_creation_input_tokens`, `cache_read_input_tokens` |
2011 2037
2012Pada Claude Code v2.1.271 atau yang lebih baru, subagent yang berjalan dengan tool [`SubagentHandback`](/docs/id/tools-reference), yang disediakan Claude Code dalam [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode), mengirimkan laporannya melalui tool tersebut alih-alih mengembalikannya sebagai teks. Field `content` dari hasil `completed`-nya kemudian membawa catatan singkat tentang penyerahan tersebut, bukan laporan itu sendiri. Untuk membaca laporan, cocokkan hook `PreToolUse` atau `PostToolUse` pada `SubagentHandback` dan baca `tool_input.message`.2038Di Claude Code v2.1.271 atau lebih baru, subagent yang berjalan dengan tool [`SubagentHandback`](/docs/id/tools-reference), yang disediakan Claude Code di [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode), menyampaikan laporannya melalui tool tersebut alih-alih mengembalikannya sebagai teks. Kolom `content` dari hasil `completed`-nya kemudian membawa catatan singkat tentang penyerahan tersebut, bukan laporannya sendiri. Untuk membaca laporan, cocokkan hook `PreToolUse` atau `PostToolUse` pada `SubagentHandback` dan baca `tool_input.message`.
2013 2039
2014Untuk subagent latar belakang, tool kembali saat tugas berpindah ke latar belakang, sehingga `tool_response` tidak membawa field penggunaan: peluncuran latar belakang langsung kembali, dan tugas latar depan yang dipindahkan Claude Code ke latar belakang di tengah run kembali pada transisi tersebut. Respons ini memiliki `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile`, dan `resolvedModel`.2040Untuk subagent latar belakang, tool kembali saat tugas berpindah ke latar belakang, sehingga `tool_response` tidak membawa kolom penggunaan: peluncuran latar belakang langsung kembali, dan tugas latar depan yang dipindahkan Claude Code ke latar belakang di tengah eksekusi kembali pada transisi tersebut. Respons tersebut memiliki `status: "async_launched"`, `agentId`, `description`, `prompt`, `outputFile`, dan `resolvedModel`.
2015 2041
2016Pada respons `completed`, `resolvedModel` menyebutkan model tempat subagent dimulai, yang dapat berbeda dari nilai `model` di `tool_input`, seperti saat `availableModels` atau override lain berlaku. Pada respons `async_launched`, `resolvedModel` menyebutkan model yang digunakan saat agent berpindah ke latar belakang, sehingga penukaran yang terjadi sebelum dipindahkan ke latar belakang tercermin di sana. `modelsUsed` dan perilaku `resolvedModel` pada saat pemindahan ke latar belakang memerlukan Claude Code v2.1.212 atau yang lebih baru.2042Pada respons `completed`, `resolvedModel` menyebutkan model yang digunakan subagent saat mulai, yang dapat berbeda dari nilai `model` di `tool_input`, misalnya saat `availableModels` atau override lain berlaku. Pada respons `async_launched`, `resolvedModel` menyebutkan model yang digunakan saat agent berpindah ke latar belakang, sehingga pertukaran yang terjadi sebelum pemindahan ke latar belakang tercermin di sana. `modelsUsed` dan perilaku `resolvedModel` pada saat pemindahan ke latar belakang memerlukan Claude Code v2.1.212 atau lebih baru.
2017 2043
2018<a id="askuserquestion" />2044<a id="askuserquestion" />
2019 2045
2023 2049
2024Mengajukan satu hingga empat pertanyaan pilihan ganda kepada pengguna.2050Mengajukan satu hingga empat pertanyaan pilihan ganda kepada pengguna.
2025 2051
2026| Field | Tipe | Contoh | Deskripsi |2052| Kolom | Tipe | Contoh | Deskripsi |
2027| :- | :- | :- | :- |2053| :- | :- | :- | :- |
2028| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | Pertanyaan yang akan disajikan, masing-masing dengan string `question`, `header` singkat, array `options`, dan flag `multiSelect` opsional |2054| `questions` | array | `[{"question": "Which framework?", "header": "Framework", "options": [{"label": "React", "description": "Component library"}, {"label": "Vue", "description": "Progressive framework"}], "multiSelect": false}]` | Pertanyaan yang akan ditampilkan, masing-masing dengan string `question`, `header` singkat, array `options`, dan flag `multiSelect` opsional |
2029| `answers` | object | `{"Which framework?": "React"}` | Opsional. Memetakan teks pertanyaan ke label opsi yang dipilih. Jawaban multi-pilihan menggabungkan label dengan koma. Claude tidak menetapkan field ini; berikan melalui `updatedInput` untuk menjawab secara terprogram |2055| `answers` | object | `{"Which framework?": "React"}` | Opsional. Memetakan teks pertanyaan ke label opsi yang dipilih. Jawaban pilihan ganda menggabungkan label dengan koma. Claude tidak menetapkan kolom ini; berikan melalui `updatedInput` untuk menjawab secara terprogram |
2030 2056
2031<h5 id="exitplanmode">2057<h5 id="exitplanmode">
2032 ExitPlanMode2058 ExitPlanMode
2033</h5>2059</h5>
2034 2060
2035Menyajikan rencana dan meminta pengguna untuk menyetujuinya sebelum Claude meninggalkan [plan mode](/docs/id/permission-modes#analyze-before-you-edit-with-plan-mode). Claude menulis rencana ke file di disk sebelum memanggil tool, sehingga `tool_input` literal dari model biasanya kosong. Claude Code menyisipkan konten rencana dan path file sebelum meneruskan input ke hook.2061Menampilkan rencana dan meminta pengguna untuk menyetujuinya sebelum Claude meninggalkan [plan mode](/docs/id/permission-modes#analyze-before-you-edit-with-plan-mode). Claude menulis rencana ke file di disk sebelum memanggil tool, sehingga `tool_input` literal dari model biasanya kosong. Claude Code menyisipkan isi rencana dan path file sebelum meneruskan input ke hook.
2036 2062
2037| Field | Tipe | Contoh | Deskripsi |2063| Kolom | Tipe | Contoh | Deskripsi |
2038| :- | :- | :- | :- |2064| :- | :- | :- | :- |
2039| `plan` | string | `"## Refactor auth\n1. Extract..."` | Konten rencana dalam Markdown. Disisipkan dari file rencana di disk |2065| `plan` | string | `"## Refactor auth\n1. Extract..."` | Isi rencana dalam Markdown. Disisipkan dari file rencana di disk |
2040| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Path ke file rencana. Disisipkan |2066| `planFilePath` | string | `"/Users/.../plans/refactor-auth.md"` | Path ke file rencana. Disisipkan |
2041| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Deprecated. Claude Code menerima field ini tetapi mengabaikannya. Sebelum v2.1.205, field ini membawa izin berbasis prompt yang diminta Claude untuk mengimplementasikan rencana |2067| `allowedPrompts` | array | `[{"tool": "Bash", "prompt": "run tests"}]` | Deprecated. Claude Code menerima kolom ini tetapi mengabaikannya. Sebelum v2.1.205, kolom ini membawa izin berbasis prompt yang diminta Claude untuk mengimplementasikan rencana |
2042 2068
2043Di `PostToolUse`, `tool_response` adalah objek dengan field `plan` dan `filePath` yang berisi rencana yang disetujui, ditambah flag status internal. Baca `tool_response.plan` untuk konten rencana alih-alih membaca ulang file dari disk.2069Di `PostToolUse`, `tool_response` adalah objek dengan kolom `plan` dan `filePath` yang berisi rencana yang disetujui, ditambah flag status internal. Baca `tool_response.plan` untuk isi rencana alih-alih membaca ulang file dari disk.
2044 2070
2045<h4 id="pretooluse-decision-control">2071<h4 id="pretooluse-decision-control">
2046 Kontrol keputusan PreToolUse2072 Kontrol keputusan PreToolUse
2047</h4>2073</h4>
2048 2074
2049Hook `PreToolUse` dapat mengontrol apakah panggilan tool berlanjut. Tidak seperti hook lain yang menggunakan field `decision` tingkat atas, PreToolUse mengembalikan keputusannya di dalam objek `hookSpecificOutput`. Ini memberinya kontrol yang lebih kaya: empat hasil (allow, deny, ask, atau defer) ditambah kemampuan untuk memodifikasi input tool sebelum eksekusi.2075Hook `PreToolUse` dapat mengontrol apakah panggilan tool dilanjutkan. Tidak seperti hook lain yang menggunakan kolom `decision` tingkat atas, PreToolUse mengembalikan keputusannya di dalam objek `hookSpecificOutput`. Ini memberinya kontrol yang lebih kaya: empat hasil (allow, deny, ask, atau defer) ditambah kemampuan untuk mengubah input tool sebelum eksekusi.
2050 2076
2051| Field | Deskripsi |2077| Kolom | Deskripsi |
2052| :- | :- |2078| :- | :- |
2053| `permissionDecision` | `"allow"` melewati permintaan izin, kecuali untuk [tindakan yang tidak disetujui otomatis oleh mode mana pun](/docs/id/permission-modes#actions-no-mode-auto-approves), untuk [pembacaan dari path jaringan](/docs/id/permissions#network-paths), dan untuk `AskUserQuestion` dan `ExitPlanMode`, yang memerlukan [`updatedInput` yang dipasangkan dengannya](#allow-with-updatedinput). `"deny"` mencegah panggilan tool. `"ask"` meminta pengguna untuk mengonfirmasi. `"defer"` keluar dengan baik sehingga tool dapat dilanjutkan nanti. [Aturan deny dan ask](/docs/id/permissions#manage-permissions) tetap dievaluasi terlepas dari apa yang dikembalikan hook |2079| `permissionDecision` | `"allow"` melewati permintaan izin, kecuali untuk [tindakan yang tidak disetujui otomatis oleh mode mana pun](/docs/id/permission-modes#actions-no-mode-auto-approves), untuk [pembacaan dari path jaringan](/docs/id/permissions#network-paths), dan untuk `AskUserQuestion` serta `ExitPlanMode`, yang memerlukan [`updatedInput` yang dipasangkan dengannya](#allow-with-updatedinput). `"deny"` mencegah panggilan tool. `"ask"` meminta pengguna untuk mengonfirmasi. `"defer"` keluar dengan baik sehingga tool dapat dilanjutkan nanti. [Aturan deny dan ask](/docs/id/permissions#manage-permissions) tetap dievaluasi apa pun yang dikembalikan hook |
2054| `permissionDecisionReason` | Untuk `"ask"`, ditampilkan kepada pengguna dalam permintaan izin. Saat Claude Code [menolak panggilan](/docs/id/headless#turn-off-permission-prompts-in-unattended-runs) dalam run `-p` tempat tidak ada yang dapat menjawab permintaan tersebut, Claude membaca alasan tersebut di hasil tool sebagai gantinya. Untuk `"deny"`, ditampilkan kepada Claude. Untuk `"allow"` dan `"defer"`, hanya ditulis ke [log debug](#debug-hooks) |2080| `permissionDecisionReason` | Untuk `"ask"`, ditampilkan kepada pengguna dalam permintaan izin. Saat Claude Code [menolak panggilan](/docs/id/headless#turn-off-permission-prompts-in-unattended-runs) dalam eksekusi `-p` tempat tidak ada yang dapat menjawab permintaan tersebut, Claude membaca alasannya di hasil tool sebagai gantinya. Untuk `"deny"`, ditampilkan kepada Claude. Untuk `"allow"` dan `"defer"`, hanya ditulis ke [debug log](#debug-hooks) |
2055| `updatedInput` | Memodifikasi parameter input tool sebelum eksekusi. Menggantikan seluruh objek input, jadi sertakan field yang tidak berubah bersama field yang dimodifikasi. Claude Code mengevaluasi aturan izin dan [kelayakan latar belakang otomatis](/docs/id/tools-reference#foreground-commands-that-move-to-the-background) perintah Bash terhadap input yang dikembalikan hook Anda, bukan input yang dikirim Claude. Gabungkan dengan `"allow"` untuk menyetujui secara otomatis, atau `"ask"` untuk menampilkan input yang dimodifikasi kepada pengguna. Untuk `"defer"`, diabaikan |2081| `updatedInput` | Mengubah parameter input tool sebelum eksekusi. Menggantikan seluruh objek input, jadi sertakan kolom yang tidak berubah bersama kolom yang diubah. Claude Code mengevaluasi aturan izin dan [kelayakan auto-background](/docs/id/tools-reference#foreground-commands-that-move-to-the-background) perintah Bash terhadap input yang dikembalikan hook Anda, bukan input yang dikirim Claude. Kombinasikan dengan `"allow"` untuk menyetujui otomatis, atau `"ask"` untuk menampilkan input yang diubah kepada pengguna. Untuk `"defer"`, diabaikan |
2056| `additionalContext` | String yang ditambahkan ke konteks Claude bersama hasil tool. Diabaikan saat `permissionDecision` bernilai `"defer"`. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |2082| `additionalContext` | String yang ditambahkan ke konteks Claude bersama hasil tool. Diabaikan saat `permissionDecision` bernilai `"defer"`. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |
2057 2083
2058Saat beberapa hook PreToolUse mengembalikan keputusan yang berbeda, urutan prioritasnya adalah `deny` > `defer` > `ask` > `allow`.2084Saat beberapa hook PreToolUse mengembalikan keputusan yang berbeda, urutan prioritasnya adalah `deny` > `defer` > `ask` > `allow`.
2059 2085
2060Hook yang memblokir dengan keluar menggunakan 2 diarahkan dengan cara yang sama seperti `"deny"`: Claude melihat pesan stderr sebagai alasan penolakan.2086Hook yang memblokir dengan keluar menggunakan kode 2 diarahkan dengan cara yang sama seperti `"deny"`: Claude melihat pesan stderr sebagai alasan penolakan.
2061 2087
2062Saat hook mengembalikan `"ask"`, permintaan izin yang ditampilkan kepada pengguna menyertakan label yang mengidentifikasi asal hook: `[settings]` untuk hook dari file pengaturan mana pun atau dari frontmatter agent, `[plugin:<name>]` untuk hook plugin, atau `[skill]` untuk hook dari frontmatter skill. Ini membantu pengguna memahami sumber konfigurasi mana yang meminta konfirmasi.2088Saat hook mengembalikan `"ask"`, permintaan izin yang ditampilkan kepada pengguna menyertakan label yang mengidentifikasi asal hook: `[settings]` untuk hook dari file pengaturan mana pun atau dari frontmatter agent, `[plugin:<name>]` untuk hook plugin, atau `[skill]` untuk hook dari frontmatter skill. Ini membantu pengguna memahami sumber konfigurasi mana yang meminta konfirmasi.
2063 2089
2064`"ask"` dari hook juga memaksa permintaan izin dalam [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode): pengklasifikasi tetap dapat menolak panggilan tool, tetapi tidak dapat menyetujuinya secara diam-diam. Sebelum v2.1.211, pengklasifikasi dapat menyetujui perintah Bash yang berjalan di luar [sandbox](/docs/id/sandboxing) tanpa menampilkan permintaan yang diminta hook; pengklasifikasi tetap menerapkan aturan keamanannya sendiri pada perintah tersebut, dan `"deny"` dari hook selalu dihormati.2090`"ask"` dari hook juga memaksa permintaan izin di [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode): pengklasifikasi tetap dapat menolak panggilan tool, tetapi tidak dapat menyetujui panggilan tersebut secara diam-diam. Sebelum v2.1.211, pengklasifikasi dapat menyetujui perintah Bash yang berjalan di luar [sandbox](/docs/id/sandboxing) tanpa menampilkan permintaan yang diminta hook; pengklasifikasi tetap menerapkan aturan keamanannya sendiri pada perintah tersebut, dan `"deny"` dari hook selalu dipatuhi.
2065 2091
2066```json theme={null}2092```json theme={null}
2067{2093{
2078```2104```
2079 2105
2080<Note>2106<Note>
2081 PreToolUse sebelumnya menggunakan field `decision` dan `reason` tingkat atas, tetapi field tersebut sudah deprecated untuk event ini. Gunakan `hookSpecificOutput.permissionDecision` dan `hookSpecificOutput.permissionDecisionReason` sebagai gantinya. Nilai deprecated `"approve"` dan `"block"` masing-masing dipetakan ke `"allow"` dan `"deny"`. Event lain seperti PostToolUse dan Stop tetap menggunakan `decision` dan `reason` tingkat atas sebagai format saat ini.2107 PreToolUse sebelumnya menggunakan kolom `decision` dan `reason` tingkat atas, tetapi kolom tersebut sudah deprecated untuk event ini. Gunakan `hookSpecificOutput.permissionDecision` dan `hookSpecificOutput.permissionDecisionReason` sebagai gantinya. Nilai deprecated `"approve"` dan `"block"` masing-masing dipetakan ke `"allow"` dan `"deny"`. Event lain seperti PostToolUse dan Stop tetap menggunakan `decision` dan `reason` tingkat atas sebagai format saat ini.
2082</Note>2108</Note>
2083 2109
2084<h4 id="allow-with-updatedinput">2110<h4 id="allow-with-updatedinput">
2085 Tool yang memerlukan interaksi pengguna2111 Tool yang memerlukan interaksi pengguna
2086</h4>2112</h4>
2087 2113
2088`AskUserQuestion` dan `ExitPlanMode` memerlukan interaksi pengguna. Dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`, Claude Code hanya menawarkannya saat run memiliki [host izin](/docs/id/headless#turn-off-permission-prompts-in-unattended-runs) untuk menerima permintaan, seperti callback `canUseTool` Agent SDK.2114`AskUserQuestion` dan `ExitPlanMode` memerlukan interaksi pengguna. Dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`, Claude Code hanya menawarkannya saat eksekusi memiliki [host izin](/docs/id/headless#turn-off-permission-prompts-in-unattended-runs) untuk menerima permintaan, seperti callback `canUseTool` Agent SDK.
2089 2115
2090Hook `PreToolUse` memenuhi persyaratan tersebut saat melakukan hal berikut:2116Hook `PreToolUse` memenuhi persyaratan tersebut jika melakukan hal berikut:
2091 2117
20921. Membaca input tool dari stdin21181. Membaca input tool dari stdin
20932. Mengumpulkan jawaban melalui UI Anda sendiri21192. Mengumpulkan jawaban melalui UI Anda sendiri
20943. Mengembalikan `permissionDecision: "allow"` bersama `updatedInput` yang berisi jawaban, sehingga tool berjalan tanpa meminta21203. Mengembalikan `permissionDecision: "allow"` bersama `updatedInput` yang berisi jawaban, sehingga tool berjalan tanpa permintaan
2095 2121
2096Mengembalikan `"allow"` saja tidak cukup untuk tool ini.2122Mengembalikan `"allow"` saja tidak cukup untuk tool-tool ini.
2097 2123
2098Untuk `AskUserQuestion`, kembalikan array `questions` asli dan tambahkan objek [`answers`](#askuserquestion) yang memetakan teks setiap pertanyaan ke jawaban yang dipilih. Output ini menjawab satu pertanyaan dengan `React`:2124Untuk `AskUserQuestion`, kembalikan array `questions` asli dan tambahkan objek [`answers`](#askuserquestion) yang memetakan teks setiap pertanyaan ke jawaban yang dipilih. Output ini menjawab satu pertanyaan dengan `React`:
2099 2125
2117}2143}
2118```2144```
2119 2145
2120Tool MCP yang ditandai server-nya dengan [`_meta["anthropic/requiresUserInteraction"]`](/docs/id/mcp#require-approval-for-a-specific-tool) lebih ketat: hook tidak dapat melewati permintaan persetujuannya dengan `"allow"`, dengan atau tanpa `updatedInput`, karena Claude Code tidak dapat memastikan bahwa hook telah mengumpulkan interaksi yang dibutuhkan tool.2146Tool MCP yang ditandai oleh server-nya dengan [`_meta["anthropic/requiresUserInteraction"]`](/docs/id/mcp#require-approval-for-a-specific-tool) lebih ketat: hook tidak dapat melewati permintaan persetujuannya dengan `"allow"`, dengan atau tanpa `updatedInput`, karena Claude Code tidak dapat memastikan bahwa hook telah mengumpulkan interaksi yang dibutuhkan tool tersebut.
2121 2147
2122<h4 id="defer-a-tool-call-for-later">2148<h4 id="defer-a-tool-call-for-later">
2123 Menangguhkan panggilan tool untuk nanti2149 Menangguhkan panggilan tool untuk nanti
2124</h4>2150</h4>
2125 2151
2126`"defer"` ditujukan untuk integrasi yang menjalankan `claude -p` sebagai subproses dan membaca output JSON-nya, seperti aplikasi Agent SDK atau UI kustom yang dibangun di atas Claude Code. Ini memungkinkan proses pemanggil tersebut menjeda Claude pada panggilan tool, mengumpulkan input melalui antarmukanya sendiri, dan melanjutkan dari titik terakhir. Claude Code hanya menghormati nilai ini dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`. Dalam sesi interaktif, Claude Code mencatat peringatan dan mengabaikan hasil hook.2152`"defer"` ditujukan untuk integrasi yang menjalankan `claude -p` sebagai subproses dan membaca output JSON-nya, seperti aplikasi Agent SDK atau UI kustom yang dibangun di atas Claude Code. Nilai ini memungkinkan proses pemanggil tersebut menjeda Claude pada panggilan tool, mengumpulkan input melalui antarmukanya sendiri, dan melanjutkan dari titik terakhir. Claude Code hanya mematuhi nilai ini dalam [mode non-interaktif](/docs/id/headless) dengan flag `-p`. Dalam sesi interaktif, Claude Code mencatat peringatan dan mengabaikan hasil hook.
2127 2153
2128Tool `AskUserQuestion` adalah kasus yang umum: Claude ingin menanyakan sesuatu kepada pengguna, tetapi tidak ada terminal untuk menjawabnya. Run `-p` hanya menawarkan `AskUserQuestion` saat memiliki [host izin](/docs/id/headless#turn-off-permission-prompts-in-unattended-runs), seperti tool MCP yang Anda teruskan dengan `--permission-prompt-tool`, jadi mulai run dengan salah satunya. Perjalanan bolak-baliknya bekerja seperti ini:2154Tool `AskUserQuestion` adalah kasus yang umum: Claude ingin menanyakan sesuatu kepada pengguna, tetapi tidak ada terminal untuk menjawabnya. Eksekusi `-p` hanya menawarkan `AskUserQuestion` saat memiliki [host izin](/docs/id/headless#turn-off-permission-prompts-in-unattended-runs), seperti tool MCP yang Anda berikan dengan `--permission-prompt-tool`, jadi mulailah eksekusi dengan salah satunya. Alur bolak-baliknya berjalan seperti ini:
2129 2155
21301. Claude memanggil `AskUserQuestion`. Hook `PreToolUse` dipicu.21561. Claude memanggil `AskUserQuestion`. Hook `PreToolUse` dipicu.
21312. Hook mengembalikan `permissionDecision: "defer"`. Tool tidak dieksekusi. Proses keluar dengan `stop_reason: "tool_deferred"` dan panggilan tool yang tertunda dipertahankan dalam transkrip.21572. Hook mengembalikan `permissionDecision: "defer"`. Tool tidak dieksekusi. Proses keluar dengan `stop_reason: "tool_deferred"` dan panggilan tool yang tertunda dipertahankan dalam transkrip.
21334. Proses pemanggil menjalankan `claude -p --resume <session-id>` dengan host izin yang sama. Panggilan tool yang sama memicu `PreToolUse` lagi.21594. Proses pemanggil menjalankan `claude -p --resume <session-id>` dengan host izin yang sama. Panggilan tool yang sama memicu `PreToolUse` lagi.
21345. Hook mengembalikan `permissionDecision: "allow"` dengan jawaban di `updatedInput`. Tool dieksekusi dan Claude melanjutkan.21605. Hook mengembalikan `permissionDecision: "allow"` dengan jawaban di `updatedInput`. Tool dieksekusi dan Claude melanjutkan.
2135 2161
2136Field `deferred_tool_use` membawa `id`, `name`, dan `input` tool. `input` adalah parameter yang dihasilkan Claude untuk panggilan tool, yang ditangkap sebelum eksekusi:2162Kolom `deferred_tool_use` membawa `id`, `name`, dan `input` dari tool. `input` adalah parameter yang dihasilkan Claude untuk panggilan tool, yang ditangkap sebelum eksekusi:
2137 2163
2138```json theme={null}2164```json theme={null}
2139{2165{
2149}2175}
2150```2176```
2151 2177
2152Tidak ada timeout atau batas retry. Sesi tetap berada di disk hingga Anda melanjutkannya, dengan tunduk pada pembersihan retensi [`cleanupPeriodDays`](/docs/id/settings-reference#cleanupperioddays), yang menghapus file sesi setelah 30 hari secara default, mengikuti [aturan pembersihan retensi](/docs/id/claude-directory#cleaned-up-automatically). Jika jawaban belum siap saat Anda melanjutkan, hook dapat mengembalikan `"defer"` lagi dan proses keluar dengan cara yang sama. Proses pemanggil mengontrol kapan memutus loop dengan akhirnya mengembalikan `"allow"` atau `"deny"` dari hook.2178Tidak ada timeout atau batas retry. Sesi tetap berada di disk hingga Anda melanjutkannya, dengan tunduk pada pembersihan retensi [`cleanupPeriodDays`](/docs/id/settings-reference#cleanupperioddays), yang menghapus file sesi setelah 30 hari secara default, mengikuti [aturan pembersihan retensi](/docs/id/claude-directory#cleaned-up-automatically). Jika jawaban belum siap saat Anda melanjutkan, hook dapat mengembalikan `"defer"` lagi dan proses keluar dengan cara yang sama. Proses pemanggil mengontrol kapan memutus perulangan dengan pada akhirnya mengembalikan `"allow"` atau `"deny"` dari hook.
2153 2179
2154`"defer"` hanya berfungsi saat Claude melakukan satu panggilan tool dalam giliran tersebut. Jika Claude melakukan beberapa panggilan tool sekaligus, `"defer"` diabaikan dengan peringatan dan tool berlanjut melalui alur izin normal. Batasan ini ada karena resume hanya dapat menjalankan ulang satu tool: tidak ada cara untuk menangguhkan satu panggilan dari sekelompok panggilan tanpa membiarkan yang lain tidak terselesaikan.2180`"defer"` hanya berfungsi saat Claude melakukan satu panggilan tool dalam giliran tersebut. Jika Claude melakukan beberapa panggilan tool sekaligus, `"defer"` diabaikan dengan peringatan dan tool berlanjut melalui alur izin normal. Batasan ini ada karena resume hanya dapat menjalankan ulang satu tool: tidak ada cara untuk menangguhkan satu panggilan dari sekumpulan panggilan tanpa membiarkan yang lain tidak terselesaikan.
2155 2181
2156Jika tool yang ditangguhkan tidak lagi tersedia saat Anda melanjutkan, proses keluar dengan `stop_reason: "tool_deferred_unavailable"` dan `is_error: true` sebelum hook dipicu. Ini terjadi saat server MCP yang menyediakan tool tidak terhubung untuk sesi yang dilanjutkan. Payload `deferred_tool_use` tetap disertakan sehingga Anda dapat mengidentifikasi tool mana yang hilang.2182Jika tool yang ditangguhkan tidak lagi tersedia saat Anda melanjutkan, proses keluar dengan `stop_reason: "tool_deferred_unavailable"` dan `is_error: true` sebelum hook dipicu. Ini terjadi saat server MCP yang menyediakan tool tersebut tidak terhubung untuk sesi yang dilanjutkan. Payload `deferred_tool_use` tetap disertakan sehingga Anda dapat mengidentifikasi tool mana yang hilang.
2157 2183
2158<Note>2184<Note>
2159 Untuk melanjutkan sesi yang ditangguhkan dalam plan mode, berikan [`--permission-prompt-tool`](/docs/id/cli-reference#cli-flags) bersama `--resume` agar Claude Code dapat menyajikan rencana untuk disetujui. Untuk kondisi lainnya, lihat [Melanjutkan dalam plan mode dengan `-p`](/docs/id/sessions#resume-in-plan-mode-with-p). Memerlukan Claude Code v2.1.246 atau yang lebih baru.2185 Untuk melanjutkan sesi yang ditangguhkan dalam plan mode, berikan [`--permission-prompt-tool`](/docs/id/cli-reference#cli-flags) bersama `--resume` agar Claude Code dapat menampilkan rencana untuk disetujui. Untuk kondisi lainnya, lihat [Melanjutkan dalam plan mode dengan `-p`](/docs/id/sessions#resume-in-plan-mode-with-p). Memerlukan Claude Code v2.1.246 atau lebih baru.
2160 2186
2161 Saat Anda melanjutkan dengan `-p`, Claude Code tidak memulihkan mode izin tersimpan lainnya. Claude Code memulai run dalam mode izin yang akan digunakan oleh run `claude -p` baru, jadi teruskan `--permission-mode` atau `--dangerously-skip-permissions` lagi jika sesi yang ditangguhkan menggunakannya. Saat Anda melanjutkan dengan `claude --resume <session-id>` tanpa `-p`, Claude Code memulihkan mode izin yang tersimpan, dengan pengecualian yang tercantum di [mode izin saat resume](/docs/id/sessions#permission-mode-on-resume).2187 Saat Anda melanjutkan dengan `-p`, Claude Code tidak memulihkan mode izin tersimpan lainnya. Claude Code memulai eksekusi dalam mode izin yang akan digunakan oleh eksekusi `claude -p` baru, jadi berikan `--permission-mode` atau `--dangerously-skip-permissions` lagi jika sesi yang ditangguhkan menggunakannya. Saat Anda melanjutkan dengan `claude --resume <session-id>` tanpa `-p`, Claude Code memulihkan mode izin yang tersimpan, dengan pengecualian yang tercantum di [mode izin saat resume](/docs/id/sessions#permission-mode-on-resume).
2162</Note>2188</Note>
2163 2189
2164<h3 id="permissionrequest">2190<h3 id="permissionrequest">
2165 PermissionRequest2191 PermissionRequest
2166</h3>2192</h3>
2167 2193
2168Berjalan saat Claude Code akan meminta izin Anda untuk menggunakan tool. Dalam sesi yang tidak dapat menampilkan permintaan, seperti subagent latar belakang dalam [mode non-interaktif](/docs/id/headless), Claude Code tetap menjalankan hook ini, dan jika tidak ada hook yang mengembalikan keputusan, Claude Code menolak panggilan tool. Untuk panggilan yang mencapai `--permission-prompt-tool` atau [callback `canUseTool`](/docs/id/agent-sdk/permissions) Agent SDK, hook berjalan bersama host Anda, dan mana pun yang memutuskan lebih dulu yang berlaku.2194Berjalan saat Claude Code akan meminta izin Anda untuk menggunakan tool. Dalam sesi yang tidak dapat menampilkan permintaan, seperti subagent latar belakang dalam [mode non-interaktif](/docs/id/headless), Claude Code tetap menjalankan hook ini, dan jika tidak ada hook yang mengembalikan keputusan, Claude Code menolak panggilan tool tersebut. Untuk panggilan yang mencapai `--permission-prompt-tool` atau [callback `canUseTool`](/docs/id/agent-sdk/permissions) Agent SDK, hook berjalan bersamaan dengan host Anda, dan mana pun yang memutuskan lebih dulu yang berlaku.
2169Gunakan [kontrol keputusan PermissionRequest](#permissionrequest-decision-control) untuk mengizinkan atau menolak atas nama pengguna.2195Gunakan [kontrol keputusan PermissionRequest](#permissionrequest-decision-control) untuk mengizinkan atau menolak atas nama pengguna.
2170 2196
2171Gunakan event ini saat Anda memerlukan sinyal tepat ketika Claude meminta izin untuk menggunakan tool. Claude Code menjalankan hook [Notification](#notification) dengan jenis `permission_prompt` hanya setelah permintaan menunggu sekitar enam detik.2197Gunakan event ini saat Anda memerlukan sinyal tepat ketika Claude meminta izin untuk menggunakan tool. Claude Code menjalankan hook [Notification](#notification) dengan tipe `permission_prompt` hanya setelah permintaan menunggu sekitar enam detik.
2172 2198
2173Claude Code tidak menjalankan hook PermissionRequest untuk [permintaan jaringan](/docs/id/sandboxing#network-isolation) dari perintah yang berjalan di sandbox. Untuk mendapatkan sinyal bagi permintaan tersebut, gunakan jenis notifikasi `permission_prompt`.2199Claude Code tidak menjalankan hook PermissionRequest untuk [permintaan jaringan](/docs/id/sandboxing#network-isolation) dari perintah yang berjalan dalam sandbox. Untuk mendapatkan sinyal bagi permintaan izin tersebut, gunakan tipe notifikasi `permission_prompt`.
2174 2200
2175Dicocokkan pada nama tool, dengan nilai yang sama seperti PreToolUse.2201Dicocokkan pada nama tool, dengan nilai yang sama seperti PreToolUse.
2176 2202
2180 2206
2181Hook PermissionRequest menerima field `tool_name` dan `tool_input` seperti hook PreToolUse, tetapi tanpa `tool_use_id`. Untuk tool MCP, hook ini juga menerima objek [`mcp_server`](#pretooluse-input). Array `permission_suggestions` opsional berisi [pembaruan izin](#permission-update-entries) yang disarankan Claude Code untuk permintaan ini, seperti menambahkan aturan allow atau mengubah mode izin.2207Hook PermissionRequest menerima field `tool_name` dan `tool_input` seperti hook PreToolUse, tetapi tanpa `tool_use_id`. Untuk tool MCP, hook ini juga menerima objek [`mcp_server`](#pretooluse-input). Array `permission_suggestions` opsional berisi [pembaruan izin](#permission-update-entries) yang disarankan Claude Code untuk permintaan ini, seperti menambahkan aturan allow atau mengubah mode izin.
2182 2208
2183Array `permission_suggestions` bukan daftar persis dari opsi yang Anda lihat, karena setiap dialog izin membangun opsinya sendiri. Beberapa dialog, seperti dialog untuk pengeditan file, sama sekali tidak membaca array tersebut dan menurunkan opsinya dari permintaan itu sendiri. Dialog yang membacanya tetap dapat menahan opsi yang sarannya tetap ada di array, misalnya saat [`allowManagedPermissionRulesOnly`](/docs/id/settings-reference#allowmanagedpermissionrulesonly) menyembunyikan opsi penyimpanan aturan. Dialog juga dapat menawarkan opsi yang tidak memiliki entri saran, seperti [**Yes, and switch to auto mode**](/docs/id/permission-modes#switch-permission-modes), yang mengubah mode izin secara langsung alih-alih melalui pembaruan izin.2209Array `permission_suggestions` bukan daftar persis dari opsi yang Anda lihat, karena setiap dialog izin membangun opsinya sendiri. Beberapa dialog, seperti dialog untuk pengeditan file, sama sekali tidak membaca array tersebut dan menurunkan opsinya dari permintaan itu sendiri. Dialog yang membacanya tetap dapat menahan opsi yang sarannya tetap ada di array, misalnya ketika [`allowManagedPermissionRulesOnly`](/docs/id/settings-reference#allowmanagedpermissionrulesonly) menyembunyikan opsi penyimpanan aturan. Dialog tersebut juga dapat menawarkan opsi yang tidak memiliki entri saran, seperti [**Yes, and switch to auto mode**](/docs/id/permission-modes#switch-permission-modes), yang mengubah mode izin secara langsung, bukan melalui pembaruan izin.
2184 2210
2185Hook PreToolUse berjalan sebelum setiap panggilan tool, terlepas dari apakah panggilan tersebut memerlukan izin. Hook PermissionRequest hanya berjalan saat Claude Code akan meminta izin Anda, atau saat Claude Code jika tidak demikian akan menolak otomatis panggilan yang tidak dapat menampilkan permintaan. Tidak satu pun event ini dipicu untuk [`EndConversation`](/docs/id/tools-reference#endconversation-tool-behavior).2211Hook PreToolUse berjalan sebelum setiap panggilan tool, baik panggilan tersebut memerlukan izin maupun tidak. Hook PermissionRequest hanya berjalan ketika Claude Code akan meminta izin kepada Anda, atau ketika Claude Code akan menolak secara otomatis panggilan yang tidak dapat menampilkan permintaan izin. Kedua event ini tidak dipicu untuk [`EndConversation`](/docs/id/tools-reference#endconversation-tool-behavior).
2186 2212
2187```json theme={null}2213```json theme={null}
2188{2214{
2241 Entri pembaruan izin2267 Entri pembaruan izin
2242</h4>2268</h4>
2243 2269
2244Field output `updatedPermissions` dan [field input `permission_suggestions`](#permissionrequest-input) sama-sama menggunakan array objek entri yang sama. Setiap entri memiliki `type` yang menentukan field lainnya, serta `destination` yang mengontrol ke mana perubahan ditulis.2270Field output `updatedPermissions` dan [field input `permission_suggestions`](#permissionrequest-input) sama-sama menggunakan array objek entri yang sama. Setiap entri memiliki `type` yang menentukan field lainnya, dan `destination` yang mengontrol ke mana perubahan ditulis.
2245 2271
2246| `type` | Field | Efek |2272| `type` | Field | Efek |
2247| :- | :- | :- |2273| :- | :- | :- |
2248| `addRules` | `rules`, `behavior`, `destination` | Menambahkan aturan izin. `rules` adalah array objek `{toolName, ruleContent?}`. Hilangkan `ruleContent` untuk mencocokkan seluruh tool. `behavior` adalah `"allow"`, `"deny"`, atau `"ask"` |2274| `addRules` | `rules`, `behavior`, `destination` | Menambahkan aturan izin. `rules` adalah array objek `{toolName, ruleContent?}`. Hilangkan `ruleContent` untuk mencocokkan seluruh tool. `behavior` adalah `"allow"`, `"deny"`, atau `"ask"` |
2249| `replaceRules` | `rules`, `behavior`, `destination` | Mengganti semua aturan dengan `behavior` yang diberikan di `destination` dengan `rules` yang disediakan |2275| `replaceRules` | `rules`, `behavior`, `destination` | Menggantikan semua aturan dengan `behavior` tertentu di `destination` dengan `rules` yang diberikan |
2250| `removeRules` | `rules`, `behavior`, `destination` | Menghapus aturan yang cocok dengan `behavior` yang diberikan |2276| `removeRules` | `rules`, `behavior`, `destination` | Menghapus aturan yang cocok dengan `behavior` tertentu |
2251| `setMode` | `mode`, `destination` | Mengubah mode izin. Mode yang valid adalah `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan`, dan `manual` sebagai alias untuk `default` |2277| `setMode` | `mode`, `destination` | Mengubah mode izin. Mode yang valid adalah `default`, `auto`, `acceptEdits`, `dontAsk`, `bypassPermissions`, `plan`, dan `manual` sebagai alias untuk `default` |
2252| `addDirectories` | `directories`, `destination` | Menambahkan direktori kerja. `directories` adalah array string path |2278| `addDirectories` | `directories`, `destination` | Menambahkan direktori kerja. `directories` adalah array string path |
2253| `removeDirectories` | `directories`, `destination` | Menghapus direktori kerja |2279| `removeDirectories` | `directories`, `destination` | Menghapus direktori kerja |
2254 2280
2255<Note>2281<Note>
2256 `setMode` dengan `bypassPermissions` hanya berlaku jika Anda meluncurkan sesi dengan mode bypass yang sudah tersedia: `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions`, atau `permissions.defaultMode: "bypassPermissions"` di [pengaturan pengguna, `--settings`, atau pengaturan terkelola](/docs/id/settings-reference#permissions-defaultmode). Jika tidak, pembaruan tidak berpengaruh apa pun. Pembaruan juga tidak berpengaruh ketika [`permissions.disableBypassPermissionsMode`](/docs/id/permissions#managed-settings) menonaktifkan mode tersebut, atau ketika sesi dimulai dalam [mode terbatas](/docs/id/cli-reference#cli-flags).2282 `setMode` dengan `bypassPermissions` hanya berlaku jika Anda meluncurkan sesi dengan mode bypass yang sudah tersedia: `--dangerously-skip-permissions`, `--permission-mode bypassPermissions`, `--allow-dangerously-skip-permissions`, atau `permissions.defaultMode: "bypassPermissions"` di [pengaturan pengguna, `--settings`, atau pengaturan terkelola](/docs/id/settings-reference#permissions-defaultmode). Jika tidak, pembaruan tersebut tidak berpengaruh. Pembaruan juga tidak berpengaruh ketika [`permissions.disableBypassPermissionsMode`](/docs/id/permissions#managed-settings) menonaktifkan mode tersebut, atau ketika sesi dimulai dalam [restricted mode](/docs/id/cli-reference#cli-flags).
2257 2283
2258 `bypassPermissions` tidak pernah disimpan sebagai `defaultMode` terlepas dari `destination`.2284 `bypassPermissions` tidak pernah disimpan sebagai `defaultMode` terlepas dari `destination`.
2259</Note>2285</Note>
2260 2286
2261Field `destination` pada setiap entri menentukan apakah perubahan tetap berada di memori atau disimpan ke file pengaturan.2287Field `destination` pada setiap entri menentukan apakah perubahan tetap di memori atau disimpan ke file pengaturan.
2262 2288
2263| `destination` | Menulis ke |2289| `destination` | Menulis ke |
2264| :- | :- |2290| :- | :- |
2265| `session` | hanya di memori, dibuang saat sesi berakhir |2291| `session` | hanya di memori, dibuang ketika sesi berakhir |
2266| `localSettings` | `.claude/settings.local.json` |2292| `localSettings` | `.claude/settings.local.json` |
2267| `projectSettings` | `.claude/settings.json` |2293| `projectSettings` | `.claude/settings.json` |
2268| `userSettings` | `~/.claude/settings.json` |2294| `userSettings` | `~/.claude/settings.json` |
2269 2295
2270Sebuah hook dapat mengembalikan salah satu `permission_suggestions` yang diterimanya sebagai output `updatedPermissions` miliknya sendiri.2296Hook dapat mengembalikan salah satu `permission_suggestions` yang diterimanya sebagai output `updatedPermissions`-nya sendiri.
2271 2297
2272<h3 id="posttooluse">2298<h3 id="posttooluse">
2273 PostToolUse2299 PostToolUse
2274</h3>2300</h3>
2275 2301
2276Berjalan segera setelah sebuah tool selesai dengan sukses.2302Berjalan segera setelah tool berhasil diselesaikan.
2277 2303
2278Mencocokkan nama tool, dengan nilai yang sama seperti PreToolUse.2304Mencocokkan berdasarkan nama tool, dengan nilai yang sama seperti PreToolUse.
2279 2305
2280Gunakan pencocokan yang lebih luas ketika nama tool bukan filter yang tepat:2306Cocokkan secara lebih luas ketika nama tool bukan filter yang tepat:
2281 2307
2282* Untuk menjalankan hook setelah tool apa pun selesai dengan sukses, hilangkan `matcher` atau setel ke `"*"`. Hook Anda kemudian dapat menemukan sendiri apa yang berubah, misalnya dengan menjalankan `git status --porcelain`, yang juga mencantumkan file yang tidak terlacak yang terlewat oleh `git diff`. Untuk panggilan tool yang gagal, tambahkan hook yang sama di bawah [PostToolUseFailure](#posttoolusefailure).2308* Untuk menjalankan hook setelah tool apa pun berhasil diselesaikan, hilangkan `matcher` atau atur ke `"*"`. Hook Anda kemudian dapat menemukan sendiri apa yang berubah, misalnya dengan menjalankan `git status --porcelain`, yang juga mencantumkan file yang tidak terlacak yang terlewat oleh `git diff`. Untuk panggilan tool yang gagal, tambahkan hook yang sama di bawah [PostToolUseFailure](#posttoolusefailure).
2283* Untuk menjalankan hook ketika file tertentu berubah di disk, apa pun yang menulisnya, gunakan [FileChanged](#filechanged). Claude Code tidak menjalankan hook `PostToolUse` yang mencocokkan `Edit|Write` ketika perintah `Bash` atau proses di luar Claude Code menulis ulang file yang sama.2309* Untuk menjalankan hook ketika file tertentu berubah di disk, apa pun yang menulisnya, gunakan [FileChanged](#filechanged). Claude Code tidak menjalankan hook `PostToolUse` yang mencocokkan `Edit|Write` ketika perintah `Bash` atau proses di luar Claude Code menulis ulang file yang sama.
2284 2310
2285<h4 id="posttooluse-input">2311<h4 id="posttooluse-input">
2286 Input PostToolUse2312 Input PostToolUse
2287</h4>2313</h4>
2288 2314
2289Hook `PostToolUse` dipicu setelah sebuah tool berhasil dieksekusi. Input mencakup `tool_input`, yaitu argumen yang dikirim ke tool, dan `tool_response`, yaitu hasil yang dikembalikannya. Skema persis untuk keduanya bergantung pada tool. Path `tool_input` untuk tool file tiba dalam format yang sama seperti untuk [PreToolUse](#pretooluse-input): selalu absolut, dengan pemisah bawaan platform, sehingga menggunakan backslash di Windows. Untuk tool MCP, input juga membawa objek [`mcp_server`](#pretooluse-input).2315Hook `PostToolUse` dipicu setelah tool berhasil dieksekusi. Input mencakup `tool_input`, yaitu argumen yang dikirim ke tool, dan `tool_response`, yaitu hasil yang dikembalikannya. Skema persis untuk keduanya bergantung pada tool. Path `tool_input` pada tool file tiba dalam format yang sama seperti untuk [PreToolUse](#pretooluse-input): selalu absolut, dengan separator native platform, jadi backslash di Windows. Untuk tool MCP, input juga membawa objek [`mcp_server`](#pretooluse-input).
2290 2316
2291```json theme={null}2317```json theme={null}
2292{2318{
2325| `reason` | Penjelasan yang ditampilkan kepada Claude ketika `decision` adalah `"block"` |2351| `reason` | Penjelasan yang ditampilkan kepada Claude ketika `decision` adalah `"block"` |
2326| `additionalContext` | String yang ditambahkan ke konteks Claude bersama hasil tool. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |2352| `additionalContext` | String yang ditambahkan ke konteks Claude bersama hasil tool. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |
2327| `classifierContext` | Catatan singkat tentang hasil panggilan ini untuk pengklasifikasi [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode), bukan untuk Claude. Lihat [Menganotasi hasil untuk pengklasifikasi auto mode](#annotate-a-result-for-the-auto-mode-classifier). Memerlukan Claude Code v2.1.236 atau lebih baru |2353| `classifierContext` | Catatan singkat tentang hasil panggilan ini untuk pengklasifikasi [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode), bukan untuk Claude. Lihat [Menganotasi hasil untuk pengklasifikasi auto mode](#annotate-a-result-for-the-auto-mode-classifier). Memerlukan Claude Code v2.1.236 atau lebih baru |
2328| `updatedToolOutput` | Mengganti output tool dengan nilai yang diberikan sebelum dikirim ke Claude. Nilai harus sesuai dengan bentuk output tool |2354| `updatedToolOutput` | Menggantikan output tool dengan nilai yang diberikan sebelum dikirim ke Claude. Nilai harus sesuai dengan bentuk output tool |
2329| `updatedMCPToolOutput` | Mengganti output hanya untuk [tool MCP](#match-mcp-tools). Sebaiknya gunakan `updatedToolOutput`, yang berfungsi untuk semua tool |2355| `updatedMCPToolOutput` | Menggantikan output hanya untuk [tool MCP](#match-mcp-tools). Utamakan `updatedToolOutput`, yang berfungsi untuk semua tool |
2330 2356
2331Contoh di bawah ini mengganti output dari panggilan `Bash`. Nilai pengganti sesuai dengan bentuk output tool `Bash`:2357Contoh di bawah ini menggantikan output dari panggilan `Bash`. Nilai pengganti sesuai dengan bentuk output tool `Bash`:
2332 2358
2333```json theme={null}2359```json theme={null}
2334{2360{
2346```2372```
2347 2373
2348<Warning>2374<Warning>
2349 `updatedToolOutput` hanya mengubah apa yang dilihat Claude. Tool sudah berjalan pada saat hook dipicu, sehingga file apa pun yang ditulis, perintah yang dieksekusi, atau permintaan jaringan yang dikirim sudah berlaku. Telemetri seperti span tool OpenTelemetry dan event analitik juga menangkap output asli sebelum hook berjalan. Untuk mencegah atau memodifikasi panggilan tool sebelum dijalankan, gunakan hook [PreToolUse](#pretooluse).2375 `updatedToolOutput` hanya mengubah apa yang dilihat Claude. Tool sudah berjalan pada saat hook dipicu, sehingga file apa pun yang ditulis, perintah yang dieksekusi, atau permintaan jaringan yang dikirim sudah berlaku. Telemetri seperti span tool OpenTelemetry dan event analitik juga menangkap output asli sebelum hook berjalan. Untuk mencegah atau memodifikasi panggilan tool sebelum berjalan, gunakan hook [PreToolUse](#pretooluse) sebagai gantinya.
2350 2376
2351 Nilai pengganti harus sesuai dengan bentuk output tool. Tool bawaan mengembalikan objek terstruktur, bukan string biasa. Misalnya, `Bash` mengembalikan objek dengan field `stdout`, `stderr`, `interrupted`, dan `isImage`. Untuk tool bawaan, nilai yang tidak sesuai dengan skema output tool akan diabaikan dan output asli yang digunakan. Output tool MCP diteruskan tanpa validasi skema. Menghapus detail error yang dibutuhkan Claude dapat menyebabkannya melanjutkan berdasarkan asumsi yang salah.2377 Nilai pengganti harus sesuai dengan bentuk output tool. Tool bawaan mengembalikan objek terstruktur, bukan string biasa. Misalnya, `Bash` mengembalikan objek dengan field `stdout`, `stderr`, `interrupted`, dan `isImage`. Untuk tool bawaan, nilai yang tidak sesuai dengan skema output tool akan diabaikan dan output asli yang digunakan. Output tool MCP diteruskan tanpa validasi skema. Menghapus detail error yang dibutuhkan Claude dapat menyebabkannya melanjutkan berdasarkan asumsi yang salah.
2352</Warning>2378</Warning>
2355 Menganotasi hasil untuk pengklasifikasi auto mode2381 Menganotasi hasil untuk pengklasifikasi auto mode
2356</h4>2382</h4>
2357 2383
2358Kembalikan `classifierContext` untuk mengirim catatan singkat tentang hasil panggilan tool ke pengklasifikasi [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode), bukan ke Claude. Pengklasifikasi [tidak pernah menerima hasil tool itu sendiri](/docs/id/permission-modes#how-the-classifier-evaluates-actions), sehingga field ini adalah cara yang didukung untuk memberi tahu pengklasifikasi sesuatu tentang apa yang dikembalikan oleh sebuah panggilan sebelum meninjau tindakan berikutnya. Field ini memerlukan Claude Code v2.1.236 atau lebih baru.2384Kembalikan `classifierContext` untuk mengirim catatan singkat tentang hasil panggilan tool ke pengklasifikasi [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode), bukan ke Claude. Pengklasifikasi [tidak pernah menerima hasil tool itu sendiri](/docs/id/permission-modes#how-the-classifier-evaluates-actions), sehingga field ini adalah cara yang didukung untuk memberi tahunya sesuatu tentang apa yang dikembalikan oleh panggilan sebelum pengklasifikasi meninjau tindakan selanjutnya. Field ini memerlukan Claude Code v2.1.236 atau lebih baru.
2359 2385
2360Contoh di bawah ini memberi tahu pengklasifikasi dari mana output sebuah query berasal:2386Contoh di bawah ini memberi tahu pengklasifikasi dari mana output kueri berasal:
2361 2387
2362```json theme={null}2388```json theme={null}
2363{2389{
2368}2394}
2369```2395```
2370 2396
2371Seberapa besar bobot yang diberikan pengklasifikasi pada catatan tersebut bergantung pada di mana Anda mengonfigurasi hook:2397Seberapa besar bobot yang diberikan pengklasifikasi pada catatan tersebut bergantung pada tempat Anda mengonfigurasi hook:
2372 2398
2373* **Hook yang dikonfigurasi di Claude Code**: untuk hook dari file pengaturan, plugin, skill, dan frontmatter agent, pengklasifikasi memperlakukan catatan sebagai konteks yang disediakan aplikasi dan belum diverifikasi. Catatan tersebut tidak pernah menetapkan niat pengguna, dan jika catatan mengklaim bahwa Anda menyetujui atau meminta sesuatu, pengklasifikasi memeriksa klaim tersebut terhadap pesan Anda sendiri dalam percakapan2399* **Hook yang dikonfigurasi di Claude Code**: untuk hook dari file pengaturan, plugin, skill, dan frontmatter agent, pengklasifikasi memperlakukan catatan sebagai konteks yang tidak terverifikasi dan disediakan oleh aplikasi. Catatan tidak pernah menetapkan niat pengguna, dan jika catatan mengklaim bahwa Anda menyetujui atau meminta sesuatu, pengklasifikasi memeriksa klaim tersebut terhadap pesan Anda sendiri dalam percakapan
2374* **Callback Agent SDK dalam proses**: ketika aplikasi yang menyematkan Claude Code mendaftarkan hook sebagai [callback TypeScript SDK](/docs/id/agent-sdk/hooks) dan mengembalikan catatan selama sesi aktif, pengklasifikasi dapat menimbang pernyataan pengguna yang diteruskan dalam catatan sebagai niat pengguna. Pernyataan semacam itu dapat memenuhi persyaratan persetujuan yang akan diterima pengklasifikasi dari pesan yang Anda kirim, tetapi tidak pernah mencabut blokir yang juga tidak dapat dicabut oleh pesan Anda sendiri. Setelah sesi dilanjutkan, Claude Code memperlakukan catatan yang dipulihkan sebagai konteks yang belum diverifikasi. Ketika hook dari kedua kelompok menganotasi panggilan yang sama, pengklasifikasi memperlakukan catatan gabungan sebagai belum diverifikasi2400* **Callback Agent SDK in-process**: ketika aplikasi yang menyematkan Claude Code mendaftarkan hook sebagai [callback TypeScript SDK](/docs/id/agent-sdk/hooks) dan mengembalikan catatan selama sesi aktif, pengklasifikasi dapat menimbang pernyataan pengguna yang diteruskan dalam catatan sebagai niat pengguna. Pernyataan semacam itu dapat memenuhi persyaratan persetujuan yang akan diterima pengklasifikasi dari pesan yang Anda kirim, tetapi tidak pernah mencabut blokir yang juga tidak dapat dicabut oleh pesan Anda sendiri. Setelah sesi dilanjutkan, Claude Code memperlakukan catatan yang dipulihkan sebagai konteks yang tidak terverifikasi. Ketika hook dari kedua kelompok menganotasi panggilan yang sama, pengklasifikasi memperlakukan catatan gabungan sebagai tidak terverifikasi
2375 2401
2376Claude Code menerapkan batasan berikut saat menyampaikan catatan:2402Claude Code menerapkan batasan berikut saat mengirimkan catatan:
2377 2403
2378* **Panjang**: Claude Code membatasi catatan untuk satu panggilan tool hingga 2.000 karakter dan memotong sisanya. Batas ini dibagi di antara setiap hook yang merespons panggilan tersebut2404* **Panjang**: Claude Code membatasi catatan untuk satu panggilan tool hingga 2.000 karakter dan memotong sisanya. Batas ini dibagi di antara setiap hook yang merespons panggilan tersebut
2379* **Hanya respons sinkron**: Claude Code mengabaikan field ini dalam respons hook yang [berjalan di latar belakang](#run-hooks-in-the-background), karena respons tersebut tiba setelah Claude Code mencatat hasil tool2405* **Hanya respons sinkron**: Claude Code mengabaikan field ini dalam respons hook yang [berjalan di latar belakang](#run-hooks-in-the-background), karena respons tersebut tiba setelah Claude Code mencatat hasil tool
2380* **Panggilan yang tidak dicatat pengklasifikasi**: transkrip pengklasifikasi menghilangkan pencarian read-only seperti pembacaan file dan pencarian. Claude Code membuang catatan yang dilampirkan pada salah satu panggilan tersebut2406* **Panggilan yang tidak dicatat pengklasifikasi**: transkrip pengklasifikasi menghilangkan pencarian read-only seperti pembacaan file dan pencarian. Claude Code membuang catatan yang dilampirkan pada salah satu panggilan tersebut
2381* **Interaksi dengan penulisan ulang**: ketika catatan menjelaskan output yang Anda ganti dengan `updatedToolOutput`, kembalikan kedua field dalam respons hook yang sama. Claude Code membuang catatan jika penulisan ulang tersebut ditolak atau penulisan ulang dari hook lain menggantikannya. Claude Code menyampaikan catatan yang Anda kembalikan tanpa penulisan ulang meskipun hook lain menulis ulang output2407* **Interaksi dengan penulisan ulang**: ketika catatan mendeskripsikan output yang Anda ganti dengan `updatedToolOutput`, kembalikan kedua field dalam respons hook yang sama. Claude Code membuang catatan jika penulisan ulang tersebut ditolak atau penulisan ulang dari hook lain menggantikannya. Claude Code mengirimkan catatan yang Anda kembalikan tanpa penulisan ulang bahkan ketika hook lain menulis ulang output
2382 2408
2383<Warning>2409<Warning>
2384 Pengklasifikasi membaca konten yang Anda tempatkan di `classifierContext` sebagai informasi dari aplikasi yang meng-host sesi, jadi jangan salin output tool yang tidak tepercaya atau teks pihak ketiga ke dalamnya. Batasi catatan pada pernyataan singkat tentang satu panggilan ini, seperti fakta tentang asalnya atau pernyataan pengguna tentangnya; jangan gunakan field ini untuk menyampaikan pesan yang tidak terkait atau serangkaian event.2410 Pengklasifikasi membaca konten yang Anda tempatkan di `classifierContext` sebagai informasi dari aplikasi yang menghosting sesi, jadi jangan menyalin output tool yang tidak tepercaya atau teks pihak ketiga ke dalamnya. Batasi catatan pada pernyataan singkat tentang satu panggilan ini, seperti fakta tentang asalnya atau pernyataan pengguna tentangnya; jangan gunakan field ini untuk mengirimkan pesan yang tidak terkait atau aliran event.
2385</Warning>2411</Warning>
2386 2412
2387<h3 id="posttoolusefailure">2413<h3 id="posttoolusefailure">
2390 2416
2391Berjalan ketika tool yang mulai dieksekusi gagal: tool melempar error, atau tool MCP mengembalikan hasil error. Gunakan ini untuk mencatat kegagalan, mengirim peringatan, atau memberikan umpan balik korektif kepada Claude.2417Berjalan ketika tool yang mulai dieksekusi gagal: tool melempar error, atau tool MCP mengembalikan hasil error. Gunakan ini untuk mencatat kegagalan, mengirim peringatan, atau memberikan umpan balik korektif kepada Claude.
2392 2418
2393Mencocokkan nama tool, dengan nilai yang sama seperti PreToolUse.2419Mencocokkan berdasarkan nama tool, dengan nilai yang sama seperti PreToolUse.
2394 2420
2395<Note>2421<Note>
2396 Event ini tidak dipicu untuk panggilan tool yang ditolak sebelum eksekusi: nama tool yang tidak dikenal, input yang gagal validasi skema atau validasi khusus tool, atau penolakan izin. Penolakan validasi dikembalikan sebagai hasil `tool_use_error` dan terjadi sebelum hook berjalan, sehingga tidak memicu `PreToolUse` maupun `PostToolUseFailure`. Penolakan izin memicu `PreToolUse` tetapi tidak memicu event ini; lihat [PermissionDenied](#permissiondenied).2422 Event ini tidak dipicu untuk panggilan tool yang ditolak sebelum eksekusi: nama tool yang tidak dikenal, input yang gagal dalam validasi skema atau validasi khusus tool, atau penolakan izin. Penolakan validasi dikembalikan sebagai hasil `tool_use_error` dan terjadi sebelum hook berjalan, sehingga tidak memicu `PreToolUse` maupun `PostToolUseFailure`. Penolakan izin memicu `PreToolUse` tetapi tidak memicu event ini; lihat [PermissionDenied](#permissiondenied).
2397</Note>2423</Note>
2398 2424
2399<h4 id="posttoolusefailure-input">2425<h4 id="posttoolusefailure-input">
2400 Input PostToolUseFailure2426 Input PostToolUseFailure
2401</h4>2427</h4>
2402 2428
2403Hook PostToolUseFailure menerima field `tool_name` dan `tool_input` yang sama seperti PostToolUse, beserta informasi error sebagai field tingkat atas. Untuk tool MCP, hook juga menerima objek [`mcp_server`](#pretooluse-input). Misalnya, perintah `npm test` yang gagal mungkin mengirimkan:2429Hook PostToolUseFailure menerima field `tool_name` dan `tool_input` yang sama seperti PostToolUse, bersama dengan informasi error sebagai field tingkat atas. Untuk tool MCP, hook ini juga menerima objek [`mcp_server`](#pretooluse-input). Misalnya, perintah `npm test` yang gagal mungkin mengirimkan:
2404 2430
2405```json theme={null}2431```json theme={null}
2406{2432{
2423 2449
2424| Field | Deskripsi |2450| Field | Deskripsi |
2425| :- | :- |2451| :- | :- |
2426| `error` | String yang menjelaskan apa yang salah. Formatnya bergantung pada tool yang gagal |2452| `error` | String yang mendeskripsikan apa yang salah. Formatnya bergantung pada tool yang gagal |
2427| `is_interrupt` | Boolean opsional. True ketika kegagalan mencapai Claude Code sebagai pembatalan (abort), bukan sebagai error yang dilaporkan tool. Membatalkan tool yang sedang berjalan tidak memicu hook ini; hasil tool membawa pesan interupsi sebagai gantinya |2453| `is_interrupt` | Boolean opsional. True ketika kegagalan mencapai Claude Code sebagai pembatalan (abort), bukan sebagai error yang dilaporkan tool. Membatalkan tool yang sedang berjalan tidak memicu hook ini; hasil tool membawa pesan interupsi sebagai gantinya |
2428| `duration_ms` | Opsional. Waktu eksekusi tool dalam milidetik. Tidak termasuk waktu yang dihabiskan dalam permintaan izin dan hook PreToolUse |2454| `duration_ms` | Opsional. Waktu eksekusi tool dalam milidetik. Tidak termasuk waktu yang dihabiskan dalam permintaan izin dan hook PreToolUse |
2429 2455
2456 PostToolBatch2482 PostToolBatch
2457</h3>2483</h3>
2458 2484
2459Berjalan sekali setelah setiap panggilan tool dalam satu batch selesai, sebelum Claude Code mengirim permintaan berikutnya ke model. `PostToolUse` dipicu sekali per tool, yang berarti dipicu secara bersamaan ketika Claude melakukan panggilan tool paralel. `PostToolBatch` dipicu tepat sekali dengan batch lengkap, sehingga ini adalah tempat yang tepat untuk menyuntikkan konteks yang bergantung pada kumpulan tool yang berjalan, bukan pada satu tool tertentu. Tidak ada matcher untuk event ini.2485Berjalan sekali setelah setiap panggilan tool dalam satu batch telah diselesaikan, sebelum Claude Code mengirim permintaan berikutnya ke model. `PostToolUse` dipicu sekali per tool, yang berarti dipicu secara bersamaan ketika Claude melakukan panggilan tool paralel. `PostToolBatch` dipicu tepat sekali dengan batch lengkap, sehingga menjadi tempat yang tepat untuk menyisipkan konteks yang bergantung pada kumpulan tool yang berjalan, bukan pada satu tool tertentu. Tidak ada matcher untuk event ini.
2460 2486
2461<h4 id="posttoolbatch-input">2487<h4 id="posttoolbatch-input">
2462 Input PostToolBatch2488 Input PostToolBatch
2463</h4>2489</h4>
2464 2490
2465Selain [field input umum](#common-input-fields), hook PostToolBatch menerima `tool_calls`, sebuah array yang menjelaskan setiap panggilan tool dalam batch:2491Selain [field input umum](#common-input-fields), hook PostToolBatch menerima `tool_calls`, yaitu array yang mendeskripsikan setiap panggilan tool dalam batch:
2466 2492
2467```json theme={null}2493```json theme={null}
2468{2494{
2488}2514}
2489```2515```
2490 2516
2491`tool_response` berisi konten yang sama yang diterima model dalam blok `tool_result` yang bersesuaian. Nilainya adalah string terserialisasi atau array content-block, persis seperti yang dikeluarkan tool. Untuk `Read`, artinya teks yang diawali nomor baris, bukan konten file mentah. Respons bisa berukuran besar, jadi parse hanya field yang Anda butuhkan.2517`tool_response` berisi konten yang sama yang diterima model dalam blok `tool_result` yang bersangkutan. Nilainya adalah string yang diserialisasi atau array content-block, persis seperti yang dikeluarkan tool. Untuk `Read`, itu berarti teks dengan awalan nomor baris, bukan konten file mentah. Respons bisa berukuran besar, jadi parse hanya field yang Anda butuhkan.
2492 2518
2493<Note>2519<Note>
2494 Bentuk `tool_response` berbeda dari milik `PostToolUse`. `PostToolUse` meneruskan objek `Output` terstruktur milik tool, seperti `{filePath: "...", type: "create"}` untuk `Write`; `PostToolBatch` meneruskan konten `tool_result` terserialisasi yang dilihat model.2520 Bentuk `tool_response` berbeda dari milik `PostToolUse`. `PostToolUse` meneruskan objek `Output` terstruktur dari tool, seperti `{filePath: "...", type: "create"}` untuk `Write`; `PostToolBatch` meneruskan konten `tool_result` terserialisasi yang dilihat model.
2495</Note>2521</Note>
2496 2522
2497<h4 id="posttoolbatch-decision-control">2523<h4 id="posttoolbatch-decision-control">
2498 Kontrol keputusan PostToolBatch2524 Kontrol keputusan PostToolBatch
2499</h4>2525</h4>
2500 2526
2501Hook `PostToolBatch` dapat menyuntikkan konteks untuk Claude. Selain [field output JSON](#json-output) yang tersedia untuk semua hook, skrip hook Anda dapat mengembalikan field khusus event berikut:2527Hook `PostToolBatch` dapat menyisipkan konteks untuk Claude. Selain [field output JSON](#json-output) yang tersedia untuk semua hook, skrip hook Anda dapat mengembalikan field khusus event berikut:
2502 2528
2503| Field | Deskripsi |2529| Field | Deskripsi |
2504| :- | :- |2530| :- | :- |
2505| `additionalContext` | String konteks yang disuntikkan sekali sebelum panggilan model berikutnya. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) untuk detail penyampaian, apa yang harus dimasukkan, dan bagaimana sesi yang dilanjutkan menangani nilai sebelumnya |2531| `additionalContext` | String konteks yang disisipkan sekali sebelum panggilan model berikutnya. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) untuk detail pengiriman, apa yang perlu dimasukkan, dan bagaimana sesi yang dilanjutkan menangani nilai sebelumnya |
2506 2532
2507```json theme={null}2533```json theme={null}
2508{2534{
2513}2539}
2514```2540```
2515 2541
2516Mengembalikan `decision: "block"` atau `continue: false` menghentikan agentic loop sebelum panggilan model berikutnya. Pesan pemblokiran berasal dari `reason` atau `stopReason` JSON, atau dari stderr pada exit 2. Anda melihatnya sebagai peringatan di transkrip, dan pesan tersebut tetap berada dalam percakapan, sehingga Claude melihatnya ketika percakapan berlanjut.2542Mengembalikan `decision: "block"` atau `continue: false` menghentikan agentic loop sebelum panggilan model berikutnya. Pesan pemblokiran berasal dari `reason` atau `stopReason` JSON, atau dari stderr pada exit 2. Anda melihatnya sebagai peringatan di transkrip, dan pesan tersebut tetap ada dalam percakapan, sehingga Claude melihatnya ketika percakapan berlanjut.
2517 2543
2518<h3 id="permissiondenied">2544<h3 id="permissiondenied">
2519 PermissionDenied2545 PermissionDenied
2520</h3>2546</h3>
2521 2547
2522Berjalan ketika [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode) menolak panggilan tool, termasuk ketika menolak tanpa putusan pengklasifikasi karena [pemeriksaan keamanan yang terpisah dari auto mode menolak permintaan pengklasifikasi itu sendiri](/docs/id/errors#auto-mode-cannot-determine-the-safety-of-an-action) atau responsnya tidak dapat di-parse. Hook ini hanya dipicu dalam auto mode: hook ini tidak berjalan ketika Anda menolak dialog izin secara manual, ketika hook `PreToolUse` memblokir panggilan, atau ketika aturan `deny` cocok. Gunakan untuk mencatat penolakan, menyesuaikan konfigurasi, atau memberi tahu model bahwa ia boleh mencoba ulang panggilan tool.2548Berjalan ketika [auto mode](/docs/id/permission-modes#eliminate-prompts-with-auto-mode) menolak panggilan tool, termasuk ketika menolak tanpa putusan pengklasifikasi karena [pemeriksaan keamanan yang terpisah dari auto mode menolak permintaan pengklasifikasi itu sendiri](/docs/id/errors#auto-mode-cannot-determine-the-safety-of-an-action) atau responsnya tidak dapat di-parse. Hook ini hanya dipicu dalam auto mode: hook ini tidak berjalan ketika Anda menolak dialog izin secara manual, ketika hook `PreToolUse` memblokir panggilan, atau ketika aturan `deny` cocok. Gunakan ini untuk mencatat penolakan, menyesuaikan konfigurasi, atau memberi tahu model bahwa model dapat mencoba ulang panggilan tool.
2523 2549
2524Mencocokkan nama tool, dengan nilai yang sama seperti PreToolUse.2550Mencocokkan berdasarkan nama tool, dengan nilai yang sama seperti PreToolUse.
2525 2551
2526<h4 id="permissiondenied-input">2552<h4 id="permissiondenied-input">
2527 Input PermissionDenied2553 Input PermissionDenied
2528</h4>2554</h4>
2529 2555
2530Selain [field input umum](#common-input-fields), hook PermissionDenied menerima `tool_name`, `tool_input`, `tool_use_id`, dan `reason`. Untuk tool MCP, hook juga menerima objek [`mcp_server`](#pretooluse-input).2556Selain [field input umum](#common-input-fields), hook PermissionDenied menerima `tool_name`, `tool_input`, `tool_use_id`, dan `reason`. Untuk tool MCP, hook ini juga menerima objek [`mcp_server`](#pretooluse-input).
2531 2557
2532```json theme={null}2558```json theme={null}
2533{2559{
2548 2574
2549| Field | Deskripsi |2575| Field | Deskripsi |
2550| :- | :- |2576| :- | :- |
2551| `reason` | Alasan penolakan. Untuk putusan pengklasifikasi, di sebagian besar sesi berisi nama aturan yang cocok dalam kurung siku, seperti `[Data Exfiltration]`; lihat [Meninjau penolakan](/docs/id/auto-mode-config#review-denials) untuk bentuk lainnya. Untuk [penolakan tanpa putusan](#permissiondenied-decision-control), diawali dengan `Auto mode could not evaluate this action and is blocking it for safety`. Untuk penolakan karena model pengklasifikasi tidak tersedia, berisi teks tetap `Classifier unavailable` |2577| `reason` | Alasan penolakan. Untuk putusan pengklasifikasi, di sebagian besar sesi alasan ini menyebutkan aturan yang cocok dalam tanda kurung siku, seperti `[Data Exfiltration]`; lihat [Meninjau penolakan](/docs/id/auto-mode-config#review-denials) untuk bentuk lainnya. Untuk [penolakan tanpa putusan](#permissiondenied-decision-control), alasan dimulai dengan `Auto mode could not evaluate this action and is blocking it for safety`. Untuk penolakan karena model pengklasifikasi tidak tersedia, alasannya adalah teks tetap `Classifier unavailable` |
2552 2578
2553<h4 id="permissiondenied-decision-control">2579<h4 id="permissiondenied-decision-control">
2554 Kontrol keputusan PermissionDenied2580 Kontrol keputusan PermissionDenied
2555</h4>2581</h4>
2556 2582
2557Hook PermissionDenied dapat memberi tahu model bahwa ia boleh mencoba ulang panggilan tool yang ditolak. Kembalikan objek JSON dengan `hookSpecificOutput.retry` disetel ke `true`:2583Hook PermissionDenied dapat memberi tahu model bahwa model dapat mencoba ulang panggilan tool yang ditolak. Kembalikan objek JSON dengan `hookSpecificOutput.retry` diatur ke `true`:
2558 2584
2559```json theme={null}2585```json theme={null}
2560{2586{
2565}2591}
2566```2592```
2567 2593
2568Ketika `retry` bernilai `true`, Claude Code menambahkan pesan ke percakapan yang memberi tahu model bahwa ia boleh mencoba ulang panggilan tool. Claude Code tidak membatalkan penolakan itu sendiri. Jika hook Anda tidak mengembalikan JSON, atau mengembalikan `retry: false`, penolakan tetap berlaku dan model menerima pesan penolakan asli.2594Ketika `retry` bernilai `true`, Claude Code menambahkan pesan ke percakapan yang memberi tahu model bahwa model dapat mencoba ulang panggilan tool. Claude Code tidak membatalkan penolakan itu sendiri. Jika hook Anda tidak mengembalikan JSON, atau mengembalikan `retry: false`, penolakan tetap berlaku dan model menerima pesan penolakan asli.
2569 2595
2570Claude Code mengabaikan `retry: true` ketika pengklasifikasi [tidak menghasilkan putusan atas tindakan tersebut](/docs/id/errors#auto-mode-cannot-determine-the-safety-of-an-action): responsnya tidak dapat di-parse, atau pemeriksaan keamanan yang terpisah dari auto mode menolak permintaan pengklasifikasi itu sendiri. Untuk penolakan tersebut, Claude Code sudah memberi tahu model dalam pesan penolakan apakah harus mencoba ulang nanti atau melanjutkan.2596Claude Code mengabaikan `retry: true` ketika pengklasifikasi tidak menghasilkan [putusan atas tindakan tersebut](/docs/id/errors#auto-mode-cannot-determine-the-safety-of-an-action): responsnya tidak dapat di-parse, atau pemeriksaan keamanan yang terpisah dari auto mode menolak permintaan pengklasifikasi itu sendiri. Untuk penolakan tersebut, Claude Code sudah memberi tahu model dalam pesan penolakan apakah harus mencoba ulang nanti atau melanjutkan.
2571 2597
2572<h3 id="notification">2598<h3 id="notification">
2573 Notification2599 Notification
2574</h3>2600</h3>
2575 2601
2576Berjalan ketika Claude Code mengirim notifikasi. Mencocokkan jenis notifikasi. Hilangkan matcher untuk menjalankan hook untuk semua jenis notifikasi.2602Berjalan ketika Claude Code mengirim notifikasi. Mencocokkan berdasarkan jenis notifikasi. Hilangkan matcher untuk menjalankan hook untuk semua jenis notifikasi.
2577 2603
2578Anda menerima event hook ini bahkan ketika notifikasi desktop dimatikan: pengaturan `preferredNotifChannel`, termasuk `notifications_disabled`, hanya mengubah cara Anda diberi peringatan, bukan apakah hook Anda berjalan.2604Anda menerima event hook ini bahkan ketika notifikasi desktop dimatikan: pengaturan `preferredNotifChannel`, termasuk `notifications_disabled`, hanya mengubah cara Anda diberi peringatan, bukan apakah hook Anda berjalan.
2579 2605
2588| `elicitation_response` | Respons elicitation MCP dikirim kembali ke server |2614| `elicitation_response` | Respons elicitation MCP dikirim kembali ke server |
2589| `agent_needs_input` | Sesi latar belakang mulai menunggu input Anda saat [agent view](/docs/id/agent-view) terbuka di terminal. Juga dipicu ketika sesi terminal menampilkan kepada Anda [pertanyaan penyiapan terminal dari rekan tim agent](/docs/id/agent-teams#choose-a-display-mode) atau pemberitahuan auto mode tentang [biaya permintaan pengklasifikasi](/docs/id/auto-mode-classifier-billing) dan Anda belum mengetik selama sekitar enam detik |2615| `agent_needs_input` | Sesi latar belakang mulai menunggu input Anda saat [agent view](/docs/id/agent-view) terbuka di terminal. Juga dipicu ketika sesi terminal menampilkan kepada Anda [pertanyaan penyiapan terminal dari rekan tim agent](/docs/id/agent-teams#choose-a-display-mode) atau pemberitahuan auto mode tentang [biaya permintaan pengklasifikasi](/docs/id/auto-mode-classifier-billing) dan Anda belum mengetik selama sekitar enam detik |
2590| `agent_completed` | Sesi latar belakang selesai atau gagal. Hanya dipicu saat [agent view](/docs/id/agent-view) terbuka di terminal |2616| `agent_completed` | Sesi latar belakang selesai atau gagal. Hanya dipicu saat [agent view](/docs/id/agent-view) terbuka di terminal |
2591| `quota_auto_resume_fired` | Claude Code melanjutkan tugas Anda setelah batas penggunaan claude.ai menjedanya: pada saat reset, atau lebih cepat ketika sesuatu yang Anda lakukan di Claude Code selama menunggu, seperti menambahkan kredit penggunaan, meningkatkan paket Anda, atau berpindah model, membuat penggunaan tersedia kembali, dengan [pengecualian pengaturan model](/docs/id/interactive-mode#wait-for-a-usage-limit-to-reset) |2617| `quota_auto_resume_fired` | Claude Code melanjutkan tugas Anda setelah batas penggunaan claude.ai menjedanya: pada saat reset, atau lebih cepat ketika sesuatu yang Anda lakukan di Claude Code selama menunggu, seperti menambahkan kredit penggunaan, meningkatkan paket Anda, atau beralih model, membuat penggunaan tersedia kembali, dengan [pengecualian pengaturan model](/docs/id/interactive-mode#wait-for-a-usage-limit-to-reset) |
2592| `quota_auto_resume_stale` | Batas penggunaan claude.ai di-reset saat komputer Anda dalam mode tidur selama lebih dari sekitar 30 menit. Claude Code menunggu Anda menekan `Enter` alih-alih melanjutkan. Setelah tidur yang lebih singkat, Claude Code melanjutkan dan memicu `quota_auto_resume_fired` sebagai gantinya |2618| `quota_auto_resume_stale` | Batas penggunaan claude.ai di-reset saat komputer Anda dalam mode tidur selama lebih dari sekitar 30 menit. Claude Code menunggu Anda menekan `Enter` alih-alih melanjutkan. Setelah tidur yang lebih singkat, Claude Code melanjutkan dan memicu `quota_auto_resume_fired` sebagai gantinya |
2593| `quota_auto_resume_disabled` | Claude Code mengakhiri penantiannya atas batas penggunaan claude.ai tanpa melanjutkan tugas Anda: [`autoContinueAtUsageLimit`](/docs/id/settings-reference#autocontinueatusagelimit) dimatikan atau reset bergeser lebih dari 24 jam ke depan selama penantian yang dimulai Claude Code sendiri, tugas yang dilanjutkan terus mencapai batas, atau kelanjutan diblokir sebelum mencapai model. Tidak dipicu ketika Anda menekan `Esc` atau `Ctrl+C`, atau memilih **Don't continue automatically** |2619| `quota_auto_resume_disabled` | Claude Code mengakhiri penantiannya untuk batas penggunaan claude.ai tanpa melanjutkan tugas Anda: [`autoContinueAtUsageLimit`](/docs/id/settings-reference#autocontinueatusagelimit) dimatikan atau reset bergeser lebih dari 24 jam selama penantian yang dimulai Claude Code sendiri, tugas yang dilanjutkan terus mencapai batas, atau kelanjutan diblokir sebelum mencapai model. Tidak dipicu ketika Anda menekan `Esc` atau `Ctrl+C`, atau memilih **Don't continue automatically** |
2594 2620
2595Jenis `quota_auto_resume_fired`, `quota_auto_resume_stale`, dan `quota_auto_resume_disabled` memerlukan Claude Code v2.1.234 atau lebih baru.2621Jenis `quota_auto_resume_fired`, `quota_auto_resume_stale`, dan `quota_auto_resume_disabled` memerlukan Claude Code v2.1.234 atau lebih baru.
2596 2622
2599`agent_needs_input` untuk pertanyaan penyiapan terminal dari rekan tim memerlukan Claude Code v2.1.248 atau lebih baru.2625`agent_needs_input` untuk pertanyaan penyiapan terminal dari rekan tim memerlukan Claude Code v2.1.248 atau lebih baru.
2600 2626
2601<Note>2627<Note>
2602 Jenis `permission_prompt`, `idle_prompt`, `elicitation_dialog`, dan `elicitation_url_dialog` berbagi waktu yang sama dengan notifikasi desktop, sehingga dalam sesi terminal Anda hanya melihatnya ketika Anda tampak sedang tidak berada di terminal:2628 Jenis `permission_prompt`, `idle_prompt`, `elicitation_dialog`, dan `elicitation_url_dialog` berbagi pengaturan waktu dengan notifikasi desktop, sehingga dalam sesi terminal Anda hanya melihatnya ketika Anda tampak jauh dari terminal:
2603 2629
2604 * Harapkan `permission_prompt` setelah Anda tidak mengetik selama sekitar enam detik. Timer dimulai saat permintaan izin muncul, dan setiap penekanan tombol menundanya. Untuk menjalankan hook segera ketika Claude meminta izin untuk menggunakan tool, gunakan [PermissionRequest](#permissionrequest) sebagai gantinya.2630 * Harapkan `permission_prompt` setelah Anda tidak mengetik selama sekitar enam detik. Timer dimulai ketika permintaan izin muncul, dan setiap penekanan tombol menundanya. Untuk menjalankan hook segera ketika Claude meminta izin untuk menggunakan tool, gunakan [PermissionRequest](#permissionrequest) sebagai gantinya.
2605 * Harapkan `idle_prompt` sekitar 60 detik setelah Claude selesai merespons, dan hanya jika Anda belum mengetik sejak itu dan tidak ada agent latar belakang, seperti [subagent](/docs/id/sub-agents) latar belakang, yang masih berjalan. Claude Code tidak mengirim `idle_prompt` saat menunggu batas penggunaan claude.ai di-reset. Ketika penantian berakhir dengan sendirinya, salah satu jenis `quota_auto_resume_*` dipicu sebagai gantinya.2631 * Harapkan `idle_prompt` sekitar 60 detik setelah Claude selesai merespons, dan hanya jika Anda belum mengetik sejak itu dan tidak ada agent latar belakang, seperti [subagent](/docs/id/sub-agents) latar belakang, yang masih berjalan. Claude Code tidak mengirim `idle_prompt` saat menunggu batas penggunaan claude.ai di-reset. Ketika penantian berakhir dengan sendirinya, salah satu jenis `quota_auto_resume_*` dipicu sebagai gantinya.
2606 * Harapkan `elicitation_dialog` untuk formulir elicitation, atau `elicitation_url_dialog` untuk permintaan URL browser, setelah Anda tidak mengetik selama sekitar enam detik. Keduanya berbagi batas enam detik yang sama dengan `permission_prompt`: timer dimulai saat dialog muncul, dan setiap penekanan tombol menundanya.2632 * Harapkan `elicitation_dialog` untuk formulir elicitation, atau `elicitation_url_dialog` untuk permintaan URL browser, setelah Anda tidak mengetik selama sekitar enam detik. Keduanya berbagi gerbang enam detik yang sama dengan `permission_prompt`: timer dimulai ketika dialog muncul, dan setiap penekanan tombol menundanya.
2607 2633
2608 Permintaan izin atau elicitation yang tiba saat dialog lain sedang tampil di layar tetap menggunakan batas enam detik yang sama, dihitung sejak permintaan tiba. Notifikasinya dapat sampai kepada Anda saat permintaan tersebut masih menunggu di belakang dialog yang terbuka.2634 Permintaan izin atau elicitation yang tiba saat dialog lain sedang ditampilkan di layar tetap menggunakan gerbang enam detik yang sama, dihitung sejak permintaan tiba. Notifikasinya dapat mencapai Anda saat permintaan masih menunggu di belakang dialog yang terbuka.
2609</Note>2635</Note>
2610 2636
2611Claude Code mengatur waktu `permission_prompt` secara berbeda dalam sesi di mana Claude Code mengirim permintaan izin ke [callback `canUseTool`](/docs/id/agent-sdk/user-input) milik Agent SDK, yaitu cara Claude Desktop dan ekstensi VS Code meng-host Claude Code:2637Claude Code mengatur waktu `permission_prompt` secara berbeda dalam sesi di mana Claude Code mengirim permintaan izin ke [callback `canUseTool`](/docs/id/agent-sdk/user-input) milik Agent SDK, yang merupakan cara Claude Desktop dan ekstensi VS Code menghosting Claude Code:
2612 2638
2613* Harapkan `permission_prompt` sekitar enam detik setelah Claude meminta izin. Claude Code tidak menundanya saat Anda mengetik.2639* Harapkan `permission_prompt` sekitar enam detik setelah Claude meminta izin. Claude Code tidak menundanya saat Anda mengetik.
2614* Jika Anda atau hook [PermissionRequest](#permissionrequest) menjawab lebih cepat, Claude Code tidak menjalankan `permission_prompt`.2640* Jika Anda atau hook [PermissionRequest](#permissionrequest) menjawab lebih cepat, Claude Code tidak menjalankan `permission_prompt`.
2615* Setel [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/id/env-vars) ke `1` untuk mematikan `permission_prompt` dalam sesi-sesi ini.2641* Atur [`CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS`](/docs/id/env-vars) ke `1` untuk mematikan `permission_prompt` dalam sesi ini.
2616 2642
2617Sebelum v2.1.233, `permission_prompt` tidak dipicu dalam sesi-sesi ini.2643Sebelum v2.1.233, `permission_prompt` tidak dipicu dalam sesi ini.
2618 2644
2619Gunakan matcher terpisah untuk menjalankan handler yang berbeda tergantung pada jenis notifikasi. Konfigurasi ini memicu skrip peringatan khusus izin ketika Claude membutuhkan persetujuan izin dan notifikasi berbeda ketika Claude menganggur:2645Gunakan matcher terpisah untuk menjalankan handler yang berbeda tergantung pada jenis notifikasi. Konfigurasi ini memicu skrip peringatan khusus izin ketika Claude membutuhkan persetujuan izin dan notifikasi yang berbeda ketika Claude sedang idle:
2620 2646
2621```json theme={null}2647```json theme={null}
2622{2648{
2649 Input Notification2675 Input Notification
2650</h4>2676</h4>
2651 2677
2652Selain [field input umum](#common-input-fields), hook Notification menerima `message` berisi teks notifikasi, `title` opsional, dan `notification_type` yang menunjukkan jenis mana yang dipicu.2678Selain [field input umum](#common-input-fields), hook Notification menerima `message` dengan teks notifikasi, `title` opsional, dan `notification_type` yang menunjukkan jenis mana yang dipicu.
2653 2679
2654```json theme={null}2680```json theme={null}
2655{2681{
2663}2689}
2664```2690```
2665 2691
2666Hook Notification tidak dapat memblokir atau memodifikasi notifikasi. Claude Code membuang field `systemMessage` dan `continue` miliknya tetapi tetap mengeluarkan [`terminalSequence`](#emit-terminal-notifications), yang menjadi andalan contoh notifikasi desktop. Hook Notification ditujukan untuk efek samping seperti meneruskan notifikasi ke layanan eksternal.2692Hook Notification tidak dapat memblokir atau memodifikasi notifikasi. Claude Code membuang field `systemMessage` dan `continue` mereka tetapi tetap mengeluarkan [`terminalSequence`](#emit-terminal-notifications), yang menjadi andalan contoh notifikasi desktop. Hook Notification ditujukan untuk efek samping seperti meneruskan notifikasi ke layanan eksternal.
2667 2693
2668<h3 id="subagentstart">2694<h3 id="subagentstart">
2669 SubagentStart2695 SubagentStart
2670</h3>2696</h3>
2671 2697
2672Berjalan ketika Claude memunculkan subagent dengan tool Agent, ketika Claude [melanjutkan subagent](/docs/id/sub-agents#resume-subagents), dan setiap kali rekan tim [tim agent](/docs/id/agent-teams) dalam proses menangani pesan baru. Mendukung matcher untuk memfilter berdasarkan nama jenis agent. Untuk agent bawaan, ini adalah nama agent seperti `general-purpose`, `Explore`, atau `Plan`. Untuk [subagent kustom](/docs/id/sub-agents), ini adalah field `name` dari frontmatter agent, bukan nama file.2698Berjalan ketika Claude memunculkan subagent dengan tool Agent, ketika Claude [melanjutkan subagent](/docs/id/sub-agents#resume-subagents), dan setiap kali rekan tim [tim agent](/docs/id/agent-teams) in-process menangani pesan baru. Mendukung matcher untuk memfilter berdasarkan nama jenis agent. Untuk agent bawaan, ini adalah nama agent seperti `general-purpose`, `Explore`, atau `Plan`. Untuk [subagent kustom](/docs/id/sub-agents), ini adalah field `name` dari frontmatter agent, bukan nama file.
2673 2699
2674Untuk subagent yang disertakan oleh [plugin](/docs/id/plugins/overview), jenis agent adalah pengenal dengan cakupan plugin seperti `my-plugin:reviewer`, bukan nama frontmatter polos. Titik dua menempatkan nama dengan cakupan plugin pada jalur regular expression, jadi jangkarkan matcher dengan `^` dan `$` untuk pencocokan persis: `^my-plugin:reviewer$`.2700Untuk subagent yang dikirimkan oleh [plugin](/docs/id/plugins/overview), jenis agent adalah pengidentifikasi dengan cakupan plugin seperti `my-plugin:reviewer`, bukan nama frontmatter polos. Titik dua menempatkan nama dengan cakupan plugin pada jalur ekspresi reguler, jadi jangkarkan matcher dengan `^` dan `$` untuk kecocokan persis: `^my-plugin:reviewer$`.
2675 2701
2676<h4 id="subagentstart-input">2702<h4 id="subagentstart-input">
2677 Input SubagentStart2703 Input SubagentStart
2678</h4>2704</h4>
2679 2705
2680Selain [field input umum](#common-input-fields), hook SubagentStart menerima `agent_id` berisi pengenal unik untuk subagent dan `agent_type` berisi nama agent yang difilter oleh matcher.2706Selain [field input umum](#common-input-fields), hook SubagentStart menerima `agent_id` dengan pengidentifikasi unik untuk subagent dan `agent_type` dengan nama agent yang difilter oleh matcher.
2681 2707
2682```json theme={null}2708```json theme={null}
2683{2709{
2690}2716}
2691```2717```
2692 2718
2693Hook SubagentStart tidak dapat memblokir pembuatan subagent, tetapi dapat menyuntikkan konteks ke dalam subagent. Selain [field output JSON](#json-output) yang tersedia untuk semua hook, Anda dapat mengembalikan:2719Hook SubagentStart tidak dapat memblokir pembuatan subagent, tetapi dapat menyisipkan konteks ke dalam subagent. Selain [field output JSON](#json-output) yang tersedia untuk semua hook, Anda dapat mengembalikan:
2694 2720
2695| Field | Deskripsi |2721| Field | Deskripsi |
2696| :- | :- |2722| :- | :- |
2705}2731}
2706```2732```
2707 2733
2708Ketika hook berjalan lagi untuk subagent yang sama, Claude Code menyuntikkan konteks yang dikembalikan hanya jika konteks subagent belum memuat salinan dari eksekusi sebelumnya. Salinan yang disuntikkan saat peluncuran tetap di tempatnya, sehingga [prompt cache](/docs/id/prompt-caching#subagents-and-the-cache) subagent tetap utuh. Setelah [auto-compaction](/docs/id/sub-agents#auto-compaction) membuang salinan tersebut, Claude Code menyuntikkan konteks dari eksekusi berikutnya lagi.2734Ketika hook berjalan lagi untuk subagent yang sama, Claude Code menyisipkan konteks yang dikembalikan hanya ketika konteks subagent belum memuat salinan dari eksekusi sebelumnya. Salinan yang disisipkan saat peluncuran tetap di tempatnya, sehingga [prompt cache](/docs/id/prompt-caching#subagents-and-the-cache) subagent tetap utuh. Setelah [auto-compaction](/docs/id/sub-agents#auto-compaction) membuang salinan tersebut, Claude Code menyisipkan konteks dari eksekusi berikutnya lagi.
2709 2735
2710<h3 id="subagentstop">2736<h3 id="subagentstop">
2711 SubagentStop2737 SubagentStop
2712</h3>2738</h3>
2713 2739
2714Berjalan ketika subagent Claude Code selesai merespons. Mencocokkan jenis agent, dengan nilai yang sama seperti SubagentStart.2740Berjalan ketika subagent Claude Code selesai merespons. Mencocokkan berdasarkan jenis agent, dengan nilai yang sama seperti SubagentStart.
2715 2741
2716<h4 id="subagentstop-input">2742<h4 id="subagentstop-input">
2717 Input SubagentStop2743 Input SubagentStop
2718</h4>2744</h4>
2719 2745
2720Selain [field input umum](#common-input-fields), hook SubagentStop menerima `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path`, dan `last_assistant_message`. Field `agent_type` adalah nilai yang digunakan untuk pemfilteran matcher. `transcript_path` adalah transkrip sesi utama, sedangkan `agent_transcript_path` adalah transkrip milik subagent sendiri yang disimpan dalam folder `subagents/` bersarang. Field `last_assistant_message` berisi konten teks dari respons akhir subagent, sehingga hook dapat mengaksesnya tanpa mem-parse file transkrip.2746Selain [field input umum](#common-input-fields), hook SubagentStop menerima `stop_hook_active`, `agent_id`, `agent_type`, `agent_transcript_path`, dan `last_assistant_message`. Field `agent_type` adalah nilai yang digunakan untuk pemfilteran matcher. `transcript_path` adalah transkrip sesi utama, sedangkan `agent_transcript_path` adalah transkrip milik subagent itu sendiri yang disimpan dalam folder `subagents/` bersarang. Field `last_assistant_message` berisi konten teks dari respons akhir subagent, sehingga hook dapat mengaksesnya tanpa mem-parse file transkrip.
2721 2747
2722Tidak setiap event SubagentStop berasal dari subagent yang dimunculkan Claude. Claude Code juga menjalankan agent internal untuk beberapa fiturnya sendiri, seperti [saran prompt](/docs/id/interactive-mode#prompt-suggestions) dan [pertanyaan sampingan `/btw`](/docs/id/interactive-mode#side-questions-with-%2Fbtw), dan SubagentStop juga dipicu ketika salah satunya selesai. Untuk event tersebut, `agent_type` adalah nama agent yang dijalankan oleh sesi itu sendiri, seperti yang disetel dengan [`--agent`](/docs/id/cli-reference#cli-flags) atau [pengaturan `agent`](/docs/id/settings-reference#agent), dan berupa string kosong ketika sesi berjalan tanpa agent tersebut.2748Tidak setiap event SubagentStop berasal dari subagent yang dimunculkan Claude. Claude Code juga menjalankan agent internal untuk beberapa fiturnya sendiri, seperti [saran prompt](/docs/id/interactive-mode#prompt-suggestions) dan [pertanyaan sampingan `/btw`](/docs/id/interactive-mode#side-questions-with-%2Fbtw), dan SubagentStop juga dipicu ketika salah satu dari agent tersebut selesai. Untuk event tersebut, `agent_type` adalah nama agent yang dijalankan oleh sesi itu sendiri, seperti yang diatur dengan [`--agent`](/docs/id/cli-reference#cli-flags) atau [pengaturan `agent`](/docs/id/settings-reference#agent), dan string kosong ketika sesi berjalan tanpanya.
2723 2749
2724`matcher` yang menyebutkan jenis agent tidak cocok dengan `agent_type` kosong. Hook yang matcher-nya dihilangkan, `""`, atau `"*"`, atau berupa regular expression yang cocok dengan string kosong, juga berjalan untuk event dengan `agent_type` kosong.2750`matcher` yang menyebutkan jenis agent tidak mencocokkan `agent_type` yang kosong. Hook yang matcher-nya dihilangkan, `""`, atau `"*"`, atau merupakan ekspresi reguler yang cocok dengan string kosong, juga berjalan untuk event dengan `agent_type` kosong.
2725 2751
2726Pada Claude Code v2.1.271 atau lebih baru, subagent yang berjalan dengan tool [`SubagentHandback`](/docs/id/tools-reference) menyampaikan laporannya melalui tool tersebut sebelum berhenti. Field `last_assistant_message` kemudian berisi teks penutup subagent, jika ada, yang bukan laporan yang disampaikan. Laporan tersebut adalah input `message` dari panggilan itu, yang diterima sebagai `tool_input.message` oleh hook `PreToolUse` atau `PostToolUse` yang dicocokkan pada `SubagentHandback`.2752Pada Claude Code v2.1.271 atau lebih baru, subagent yang berjalan dengan tool [`SubagentHandback`](/docs/id/tools-reference) mengirimkan laporannya melalui tool tersebut sebelum berhenti. Field `last_assistant_message` kemudian memuat teks penutup subagent, jika ada, yang bukan merupakan laporan yang dikirimkan. Laporan tersebut adalah input `message` dari panggilan itu, yang diterima oleh hook `PreToolUse` atau `PostToolUse` yang mencocokkan `SubagentHandback` sebagai `tool_input.message`.
2727 2753
2728Hook SubagentStop juga menerima array `background_tasks` dan `session_crons` yang dijelaskan di bagian [Input Stop](#stop-input). Kedua array memiliki cakupan sesi induk, bukan subagent.2754Hook SubagentStop juga menerima array `background_tasks` dan `session_crons` yang dijelaskan di bawah [Input Stop](#stop-input). Kedua array tersebut dicakup ke sesi induk, bukan subagent.
2729 2755
2730```json theme={null}2756```json theme={null}
2731{2757{
2744}2770}
2745```2771```
2746 2772
2747Hook SubagentStop menggunakan format kontrol keputusan yang sama seperti [hook Stop](#stop-decision-control), termasuk `hookSpecificOutput.additionalContext` dengan `hookEventName` disetel ke `"SubagentStop"`, untuk umpan balik non-error yang membuat subagent tetap berjalan. Mengembalikan `decision: "block"` dengan `reason` membuat subagent tetap berjalan dan menyampaikan `reason` kepada subagent sebagai instruksi berikutnya. Hook yang memblokir dengan exit 2 menyampaikan pesan stderr-nya dengan cara yang sama. Untuk menyuntikkan konteks ke sesi induk setelah subagent kembali, gunakan hook [`PostToolUse`](#posttooluse) pada tool `Agent` sebagai gantinya.2773Hook SubagentStop menggunakan format kontrol keputusan yang sama dengan [hook Stop](#stop-decision-control), termasuk `hookSpecificOutput.additionalContext` dengan `hookEventName` diatur ke `"SubagentStop"`, untuk umpan balik non-error yang membuat subagent tetap berjalan. Mengembalikan `decision: "block"` dengan `reason` membuat subagent tetap berjalan dan mengirimkan `reason` ke subagent sebagai instruksi berikutnya. Hook yang memblokir dengan keluar dengan kode 2 mengirimkan pesan stderr-nya dengan cara yang sama. Untuk menyisipkan konteks ke sesi induk setelah subagent kembali, gunakan hook [`PostToolUse`](#posttooluse) pada tool `Agent` sebagai gantinya.
2748 2774
2749<h3 id="taskcreated">2775<h3 id="taskcreated">
2750 TaskCreated2776 TaskCreated
2751</h3>2777</h3>
2752 2778
2753Berjalan ketika tugas sedang dibuat melalui tool `TaskCreate`. Gunakan untuk menegakkan konvensi penamaan, mewajibkan deskripsi tugas, atau mencegah tugas tertentu dibuat. Dalam [sesi tanpa tool Task](/docs/id/tools-reference#task-tool-availability), event ini tidak dipicu.2779Berjalan ketika tugas sedang dibuat melalui tool `TaskCreate`. Gunakan ini untuk menegakkan konvensi penamaan, mewajibkan deskripsi tugas, atau mencegah tugas tertentu dibuat. Dalam [sesi tanpa tool Task](/docs/id/tools-reference#task-tool-availability), event ini tidak dipicu.
2754 2780
2755Hook TaskCreated tidak mendukung matcher dan dipicu pada setiap kejadian.2781Hook TaskCreated tidak mendukung matcher dan dipicu pada setiap kejadian.
2756 2782
2776 2802
2777| Field | Deskripsi |2803| Field | Deskripsi |
2778| :- | :- |2804| :- | :- |
2779| `task_id` | Pengenal tugas yang sedang dibuat |2805| `task_id` | Pengidentifikasi tugas yang sedang dibuat |
2780| `task_subject` | Judul tugas |2806| `task_subject` | Judul tugas |
2781| `task_description` | Deskripsi rinci tugas. Mungkin tidak ada |2807| `task_description` | Deskripsi terperinci tentang tugas. Mungkin tidak ada |
2782| `teammate_name` | Nama rekan tim yang membuat tugas. Mungkin tidak ada |2808| `teammate_name` | Nama rekan tim yang membuat tugas. Mungkin tidak ada |
2783| `team_name` | Deprecated. Nama tim yang diturunkan dari sesi; akan dihapus dalam rilis mendatang |2809| `team_name` | Deprecated. Nama tim yang diturunkan dari sesi; akan dihapus dalam rilis mendatang |
2784| `agent_id` | Pada event ini, [field input umum](#common-input-fields) ini mengidentifikasi subagent atau [rekan tim dalam proses](/docs/id/agent-teams#choose-a-display-mode) yang membuat tugas. Mungkin tidak ada. Memerlukan Claude Code v2.1.290 atau lebih baru |2810| `agent_id` | Pada event ini, [field input umum](#common-input-fields) ini mengidentifikasi subagent atau [rekan tim in-process](/docs/id/agent-teams#choose-a-display-mode) yang membuat tugas. Mungkin tidak ada. Memerlukan Claude Code v2.1.290 atau lebih baru |
2785 2811
2786<h4 id="taskcreated-decision-control">2812<h4 id="taskcreated-decision-control">
2787 Kontrol keputusan TaskCreated2813 Kontrol keputusan TaskCreated
2788</h4>2814</h4>
2789 2815
2790Hook TaskCreated dapat memblokir pembuatan dengan exit code 2 atau dengan keputusan JSON. Apa pun caranya, Claude Code menghapus tugas dan mengembalikan pesan Anda kepada Claude sebagai error tool. Claude Code mengabaikan `continue: false` dari event ini dan Claude terus bekerja.2816Hook TaskCreated dapat memblokir pembuatan dengan exit code 2 atau dengan keputusan JSON. Dengan cara mana pun, Claude Code menghapus tugas dan mengembalikan pesan Anda kepada Claude sebagai error tool. Claude Code mengabaikan `continue: false` dari event ini dan Claude terus bekerja.
2791 2817
2792* **Exit code 2**: Claude Code mengembalikan teks stderr sebagai pesan.2818* **Exit code 2**: Claude Code mengembalikan teks stderr sebagai pesan.
2793* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code mengembalikan `reason` sebagai pesan.2819* **JSON `{"decision": "block", "reason": "..."}`**: Claude Code mengembalikan `reason` sebagai pesan.
2811 TaskCompleted2837 TaskCompleted
2812</h3>2838</h3>
2813 2839
2814Berjalan ketika tugas sedang ditandai sebagai selesai. Ini dipicu dalam dua situasi: ketika agent mana pun secara eksplisit menandai tugas sebagai selesai melalui tool TaskUpdate, atau ketika rekan tim [tim agent](/docs/id/agent-teams) menyelesaikan gilirannya dengan tugas yang sedang berlangsung. Gunakan untuk menegakkan kriteria penyelesaian seperti lolos pengujian atau pemeriksaan lint sebelum tugas dapat ditutup.2840Berjalan ketika tugas sedang ditandai sebagai selesai. Ini dipicu dalam dua situasi: ketika agent mana pun secara eksplisit menandai tugas sebagai selesai melalui tool TaskUpdate, atau ketika rekan tim [tim agent](/docs/id/agent-teams) menyelesaikan gilirannya dengan tugas yang sedang berlangsung. Gunakan ini untuk menegakkan kriteria penyelesaian seperti lulus pengujian atau pemeriksaan lint sebelum tugas dapat ditutup.
2815 2841
2816Hook TaskCompleted tidak mendukung matcher dan dipicu pada setiap kejadian.2842Hook TaskCompleted tidak mendukung matcher dan dipicu pada setiap kejadian.
2817 2843
2838 2864
2839| Field | Deskripsi |2865| Field | Deskripsi |
2840| :- | :- |2866| :- | :- |
2841| `task_id` | Pengenal tugas yang sedang diselesaikan |2867| `task_id` | Pengidentifikasi tugas yang sedang diselesaikan |
2842| `task_subject` | Judul tugas |2868| `task_subject` | Judul tugas |
2843| `task_description` | Deskripsi rinci tugas. Mungkin tidak ada |2869| `task_description` | Deskripsi terperinci tentang tugas. Mungkin tidak ada |
2844| `teammate_name` | Nama rekan tim yang menyelesaikan tugas. Mungkin tidak ada |2870| `teammate_name` | Nama rekan tim yang menyelesaikan tugas. Mungkin tidak ada |
2845| `team_name` | Deprecated. Nama tim yang diturunkan dari sesi; akan dihapus dalam rilis mendatang |2871| `team_name` | Deprecated. Nama tim yang diturunkan dari sesi; akan dihapus dalam rilis mendatang |
2846| `agent_id` | Pada event ini, [field input umum](#common-input-fields) ini mengidentifikasi subagent atau [rekan tim dalam proses](/docs/id/agent-teams#choose-a-display-mode) yang menyelesaikan tugas. Mungkin tidak ada. Memerlukan Claude Code v2.1.290 atau lebih baru |2872| `agent_id` | Pada event ini, [field input umum](#common-input-fields) ini mengidentifikasi subagent atau [rekan tim in-process](/docs/id/agent-teams#choose-a-display-mode) yang menyelesaikan tugas. Mungkin tidak ada. Memerlukan Claude Code v2.1.290 atau lebih baru |
2847 2873
2848<h4 id="taskcompleted-decision-control">2874<h4 id="taskcompleted-decision-control">
2849 Kontrol keputusan TaskCompleted2875 Kontrol keputusan TaskCompleted
2852Hook TaskCompleted mendukung dua cara untuk mengontrol penyelesaian tugas:2878Hook TaskCompleted mendukung dua cara untuk mengontrol penyelesaian tugas:
2853 2879
2854* **Exit code 2**: tugas tidak ditandai sebagai selesai dan pesan stderr diumpankan kembali ke model sebagai umpan balik.2880* **Exit code 2**: tugas tidak ditandai sebagai selesai dan pesan stderr diumpankan kembali ke model sebagai umpan balik.
2855* **JSON `{"continue": false, "stopReason": "..."}`**: ketika rekan tim yang menyelesaikan gilirannya memicu event, ini menghentikan rekan tim sepenuhnya, sesuai dengan perilaku hook `Stop`. `stopReason` ditampilkan kepada pengguna. Ketika tool `TaskUpdate` memicu event, Claude Code mengabaikan `continue: false`; exit code 2 tetap memblokir penyelesaian.2881* **JSON `{"continue": false, "stopReason": "..."}`**: ketika rekan tim yang menyelesaikan gilirannya memicu event, menghentikan rekan tim sepenuhnya, sesuai dengan perilaku hook `Stop`. `stopReason` ditampilkan kepada pengguna. Ketika tool `TaskUpdate` memicu event, Claude Code mengabaikan `continue: false`; exit code 2 tetap memblokir penyelesaian.
2856 2882
2857Contoh ini menjalankan pengujian dan memblokir penyelesaian tugas jika pengujian gagal:2883Contoh ini menjalankan pengujian dan memblokir penyelesaian tugas jika pengujian gagal:
2858 2884
2879[StopFailure](#stopfailure) sebagai gantinya.2905[StopFailure](#stopfailure) sebagai gantinya.
2880 2906
2881<Tip>2907<Tip>
2882 Perintah [`/goal`](/docs/id/goal) adalah pintasan bawaan untuk hook Stop berbasis prompt dengan cakupan sesi. Gunakan ketika Anda ingin Claude terus bekerja menuju suatu kondisi tanpa menulis konfigurasi hook.2908 Perintah [`/goal`](/docs/id/goal) adalah pintasan bawaan untuk hook Stop berbasis prompt dengan cakupan sesi. Gunakan ini ketika Anda ingin Claude terus bekerja menuju suatu kondisi tanpa menulis konfigurasi hook.
2883</Tip>2909</Tip>
2884 2910
2885<h4 id="stop-input">2911<h4 id="stop-input">
2886 Input Stop2912 Input Stop
2887</h4>2913</h4>
2888 2914
2889Selain [field input umum](#common-input-fields), hook Stop menerima `stop_hook_active`, `last_assistant_message`, `background_tasks`, dan `session_crons`. Field `stop_hook_active` bernilai `true` ketika Claude Code sudah melanjutkan sebagai akibat dari stop hook. Periksa nilai ini atau proses transkrip untuk menghindari pemblokiran pada kondisi yang tidak akan pernah terselesaikan.2915Selain [field input umum](#common-input-fields), hook Stop menerima `stop_hook_active`, `last_assistant_message`, `background_tasks`, dan `session_crons`. Field `stop_hook_active` bernilai `true` ketika Claude Code sudah melanjutkan sebagai akibat dari hook stop. Periksa nilai ini atau proses transkrip untuk menghindari pemblokiran pada kondisi yang tidak akan pernah terselesaikan.
2890 2916
2891Claude Code menerapkan batas 8 kelanjutan berturut-turut: setelah stop hook melanjutkan giliran delapan kali berturut-turut, Claude Code menimpa blokir berikutnya dan mengakhiri giliran. Hitungan kelanjutan berturut-turut di-reset setiap kali Claude memanggil tool. Untuk menaikkan batas, setel [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/id/env-vars).2917Claude Code menerapkan batas 8 kelanjutan berturut-turut: setelah hook stop melanjutkan giliran delapan kali berturut-turut, Claude Code menimpa blokir berikutnya dan mengakhiri giliran. Hitungan kelanjutan berturut-turut di-reset setiap kali Claude memanggil tool. Untuk menaikkan batas, atur [`CLAUDE_CODE_STOP_HOOK_BLOCK_CAP`](/docs/id/env-vars).
2892 2918
2893Field `last_assistant_message` berisi konten teks dari respons akhir Claude, sehingga hook dapat mengaksesnya tanpa mem-parse file transkrip. Untuk hook yang bertindak pada giliran yang baru selesai, seperti hook pembacaan nyaring atau notifikasi, gunakan field ini alih-alih membaca `transcript_path`: file transkrip tidak dijamin menyertakan pesan akhir pada saat Stop di semua versi.2919Field `last_assistant_message` berisi konten teks dari respons akhir Claude, sehingga hook dapat mengaksesnya tanpa mem-parse file transkrip. Untuk hook yang bertindak pada giliran yang baru saja selesai, seperti hook pembacaan nyaring atau notifikasi, gunakan field ini alih-alih membaca `transcript_path`: file transkrip tidak dijamin menyertakan pesan akhir pada saat Stop di semua versi.
2894 2920
2895Array `background_tasks` dan `session_crons` memungkinkan hook membedakan "sesi sudah selesai" dari "sesi dijeda menunggu pekerjaan latar belakang untuk membangunkannya kembali". Kedua array ada ketika registri tugas dapat dijangkau dan kosong ketika tidak ada yang sedang berjalan atau dijadwalkan.2921Array `background_tasks` dan `session_crons` memungkinkan hook membedakan "sesi telah selesai" dari "sesi dijeda menunggu pekerjaan latar belakang untuk membangunkannya kembali". Kedua array ada ketika registri tugas dapat dijangkau dan kosong ketika tidak ada yang sedang berjalan atau dijadwalkan.
2896 2922
2897Setiap entri dalam `background_tasks` menjelaskan satu tugas yang sedang berjalan dan menggunakan field berikut:2923Setiap entri dalam `background_tasks` mendeskripsikan satu tugas yang sedang berjalan dan menggunakan field berikut:
2898 2924
2899| Field | Deskripsi |2925| Field | Deskripsi |
2900| :- | :- |2926| :- | :- |
2901| `id` | Pengenal tugas |2927| `id` | Pengidentifikasi tugas |
2902| `type` | Label jenis tugas yang mudah dibaca seperti `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session`, atau `MCP task`. Setiap label mengidentifikasi fitur Claude Code mana yang membuat tugas tersebut. Kembali ke diskriminan mentah untuk jenis yang tidak dikenali |2928| `type` | Label jenis tugas yang mudah dibaca seperti `shell`, `subagent`, `monitor`, `workflow`, `teammate`, `cloud session`, atau `MCP task`. Setiap label mengidentifikasi fitur Claude Code mana yang membuat tugas. Kembali ke diskriminan mentah untuk jenis yang tidak dikenali |
2903| `status` | Status tugas saat ini |2929| `status` | Status tugas saat ini |
2904| `description` | Deskripsi teks bebas, dibatasi 1000 karakter dengan penanda `… [+N chars]` di dalam string ketika dipotong |2930| `description` | Deskripsi teks bebas, dibatasi hingga 1000 karakter dengan penanda `… [+N chars]` di dalam string ketika dipotong |
2905| `command` | Baris perintah shell, dibatasi 1000 karakter. Hanya ada untuk tugas `shell` |2931| `command` | Baris perintah shell, dibatasi hingga 1000 karakter. Hanya ada untuk tugas `shell` |
2906| `agent_type` | Nama jenis subagent. Hanya ada untuk tugas `subagent` |2932| `agent_type` | Nama jenis subagent. Hanya ada untuk tugas `subagent` |
2907| `server` | Nama server MCP. Hanya ada untuk tugas `monitor` dan `MCP task` |2933| `server` | Nama server MCP. Hanya ada untuk tugas `monitor` dan `MCP task` |
2908| `tool` | Nama tool MCP. Hanya ada untuk tugas `monitor` dan `MCP task` |2934| `tool` | Nama tool MCP. Hanya ada untuk tugas `monitor` dan `MCP task` |
2909| `name` | Nama workflow. Hanya ada untuk tugas `workflow` |2935| `name` | Nama workflow. Hanya ada untuk tugas `workflow` |
2910 2936
2911Setiap entri dalam `session_crons` menjelaskan satu wakeup terjadwal dengan cakupan sesi, yang bersumber dari `CronCreate`, `ScheduleWakeup`, dan `/loop`:2937Setiap entri dalam `session_crons` mendeskripsikan satu wakeup terjadwal dengan cakupan sesi, yang bersumber dari `CronCreate`, `ScheduleWakeup`, dan `/loop`:
2912 2938
2913| Field | Deskripsi |2939| Field | Deskripsi |
2914| :- | :- |2940| :- | :- |
2915| `id` | Pengenal tugas cron |2941| `id` | Pengidentifikasi tugas cron |
2916| `schedule` | Ekspresi cron, misalnya `0 9 * * 1-5` |2942| `schedule` | Ekspresi cron, misalnya `0 9 * * 1-5` |
2917| `recurring` | `false` untuk wakeup sekali jalan yang jadwalnya mengodekan satu waktu pemicuan, `true` untuk tugas yang dipicu ulang pada setiap kecocokan |2943| `recurring` | `false` untuk wakeup sekali jalan yang jadwalnya mengodekan satu waktu pemicuan, `true` untuk tugas yang dipicu ulang pada setiap kecocokan |
2918| `prompt` | Prompt yang dikirim ketika cron dipicu, dibatasi 1000 karakter dengan penanda `… [+N chars]` yang sama |2944| `prompt` | Prompt yang dikirimkan ketika cron dipicu, dibatasi hingga 1000 karakter dengan penanda `… [+N chars]` yang sama |
2919 2945
2920Contoh ini menunjukkan input Stop dengan satu tugas shell yang sedang berjalan dan satu cron berulang:2946Contoh ini menunjukkan input Stop dengan satu tugas shell yang sedang berjalan dan satu cron berulang:
2921 2947
2957| Field | Deskripsi |2983| Field | Deskripsi |
2958| :- | :- |2984| :- | :- |
2959| `decision` | `"block"` mencegah Claude berhenti. Hilangkan untuk mengizinkan Claude berhenti |2985| `decision` | `"block"` mencegah Claude berhenti. Hilangkan untuk mengizinkan Claude berhenti |
2960| `reason` | Wajib ketika `decision` adalah `"block"`. Memberi tahu Claude mengapa ia harus melanjutkan |2986| `reason` | Wajib ketika `decision` adalah `"block"`. Memberi tahu Claude mengapa harus melanjutkan |
2961| `hookSpecificOutput.additionalContext` | Umpan balik non-error untuk Claude. Percakapan berlanjut sehingga Claude dapat menindaklanjutinya, tetapi tidak seperti `decision: "block"`, ini ditampilkan di transkrip sebagai umpan balik hook, bukan error hook |2987| `hookSpecificOutput.additionalContext` | Umpan balik non-error untuk Claude. Percakapan berlanjut sehingga Claude dapat menindaklanjutinya, tetapi tidak seperti `decision: "block"`, ini ditampilkan di transkrip sebagai umpan balik hook, bukan error hook |
2962 2988
2963Hook yang memblokir dengan exit 2 diarahkan dengan cara yang sama seperti `reason`: Claude menerima pesan stderr sebagai penjelasan mengapa ia harus melanjutkan.2989Hook yang memblokir dengan keluar dengan kode 2 dirutekan dengan cara yang sama seperti `reason`: Claude menerima pesan stderr sebagai penjelasan mengapa harus melanjutkan.
2964 2990
2965```json theme={null}2991```json theme={null}
2966{2992{
2969}2995}
2970```2996```
2971 2997
2972Gunakan `additionalContext` ketika hook bekerja sesuai rancangan dan memberikan panduan kepada Claude, seperti "jalankan rangkaian pengujian sebelum selesai". Ini membuat percakapan terus berjalan melalui perlindungan loop yang sama seperti `decision: "block"`, yaitu input `stop_hook_active` dan batas 8 kelanjutan berturut-turut, tetapi transkrip melabelinya `Stop hook feedback` dan tidak ada notifikasi error hook yang ditampilkan:2998Gunakan `additionalContext` ketika hook bekerja sesuai rancangan dan memberikan panduan kepada Claude, seperti "jalankan test suite sebelum selesai". Ini membuat percakapan terus berjalan melalui perlindungan loop yang sama seperti `decision: "block"`, yaitu input `stop_hook_active` dan batas 8 kelanjutan berturut-turut, tetapi transkrip melabelinya `Stop hook feedback` dan tidak ada notifikasi error hook yang ditampilkan:
2973 2999
2974```json theme={null}3000```json theme={null}
2975{3001{
2984 StopFailure3010 StopFailure
2985</h3>3011</h3>
2986 3012
2987Berjalan sebagai pengganti [Stop](#stop) ketika giliran berakhir karena error API. Claude Code mengabaikan output dan exit code hook, kecuali [`terminalSequence`](#emit-terminal-notifications). Gunakan untuk mencatat kegagalan, mengirim peringatan, atau mengambil tindakan pemulihan ketika Claude tidak dapat menyelesaikan respons karena rate limit, masalah autentikasi, atau error API lainnya.3013Berjalan alih-alih [Stop](#stop) ketika giliran berakhir karena error API. Claude Code mengabaikan output dan exit code hook, kecuali [`terminalSequence`](#emit-terminal-notifications). Gunakan ini untuk mencatat kegagalan, mengirim peringatan, atau mengambil tindakan pemulihan ketika Claude tidak dapat menyelesaikan respons karena rate limit, masalah autentikasi, atau error API lainnya.
2988 3014
2989<h4 id="stopfailure-input">3015<h4 id="stopfailure-input">
2990 Input StopFailure3016 Input StopFailure
2996| :- | :- |3022| :- | :- |
2997| `error` | Jenis error: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error`, atau `unknown` |3023| `error` | Jenis error: `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error`, atau `unknown` |
2998| `error_details` | Detail tambahan tentang error, jika tersedia |3024| `error_details` | Detail tambahan tentang error, jika tersedia |
2999| `last_assistant_message` | Teks error yang dirender dan ditampilkan dalam percakapan. Tidak seperti `Stop` dan `SubagentStop`, di mana field ini berisi output percakapan Claude, untuk `StopFailure` field ini berisi string error API itu sendiri, seperti `"API Error: Rate limit reached"` |3025| `last_assistant_message` | Teks error yang dirender yang ditampilkan dalam percakapan. Tidak seperti `Stop` dan `SubagentStop`, di mana field ini memuat output percakapan Claude, untuk `StopFailure` field ini berisi string error API itu sendiri, seperti `"API Error: Rate limit reached"` |
3000 3026
3001```json theme={null}3027```json theme={null}
3002{3028{
3010}3036}
3011```3037```
3012 3038
3013Hook StopFailure tidak memiliki kontrol keputusan. Hook ini hanya berjalan untuk keperluan notifikasi dan logging.3039Hook StopFailure tidak memiliki kontrol keputusan. Hook ini hanya berjalan untuk tujuan notifikasi dan pencatatan log.
3014 3040
3015<h3 id="teammateidle">3041<h3 id="teammateidle">
3016 TeammateIdle3042 TeammateIdle
3017</h3>3043</h3>
3018 3044
3019Berjalan ketika rekan tim [tim agent](/docs/id/agent-teams) akan menganggur setelah menyelesaikan gilirannya. Gunakan untuk menegakkan gerbang kualitas sebelum rekan tim berhenti bekerja, seperti mewajibkan pemeriksaan lint yang lolos atau memverifikasi bahwa file output ada.3045Berjalan ketika rekan tim [tim agent](/docs/id/agent-teams) akan menjadi idle setelah menyelesaikan gilirannya. Gunakan ini untuk menegakkan gerbang kualitas sebelum rekan tim berhenti bekerja, seperti mewajibkan lulus pemeriksaan lint atau memverifikasi bahwa file output ada.
3020 3046
3021Hook TeammateIdle tidak mendukung matcher dan dipicu pada setiap kejadian.3047Hook TeammateIdle tidak mendukung matcher dan dipicu pada setiap kejadian.
3022 3048
3040 3066
3041| Field | Deskripsi |3067| Field | Deskripsi |
3042| :- | :- |3068| :- | :- |
3043| `teammate_name` | Nama rekan tim yang akan menganggur |3069| `teammate_name` | Nama rekan tim yang akan menjadi idle |
3044| `team_name` | Deprecated. Nama tim yang diturunkan dari sesi; akan dihapus dalam rilis mendatang |3070| `team_name` | Deprecated. Nama tim yang diturunkan dari sesi; akan dihapus dalam rilis mendatang |
3045| `agent_id` | Pada event ini, [field input umum](#common-input-fields) ini mengidentifikasi [rekan tim dalam proses](/docs/id/agent-teams#choose-a-display-mode) yang akan menganggur. Mungkin tidak ada. Memerlukan Claude Code v2.1.290 atau lebih baru |3071| `agent_id` | Pada event ini, [field input umum](#common-input-fields) ini mengidentifikasi [rekan tim in-process](/docs/id/agent-teams#choose-a-display-mode) yang akan menjadi idle. Mungkin tidak ada. Memerlukan Claude Code v2.1.290 atau lebih baru |
3046 3072
3047<h4 id="teammateidle-decision-control">3073<h4 id="teammateidle-decision-control">
3048 Kontrol keputusan TeammateIdle3074 Kontrol keputusan TeammateIdle
3050 3076
3051Hook TeammateIdle mendukung dua cara untuk mengontrol perilaku rekan tim:3077Hook TeammateIdle mendukung dua cara untuk mengontrol perilaku rekan tim:
3052 3078
3053* **Exit code 2**: rekan tim menerima pesan stderr sebagai umpan balik dan terus bekerja alih-alih menganggur.3079* **Exit code 2**: rekan tim menerima pesan stderr sebagai umpan balik dan terus bekerja alih-alih menjadi idle.
3054* **JSON `{"continue": false, "stopReason": "..."}`**: menghentikan rekan tim sepenuhnya, sesuai dengan perilaku hook `Stop`. `stopReason` ditampilkan kepada pengguna.3080* **JSON `{"continue": false, "stopReason": "..."}`**: menghentikan rekan tim sepenuhnya, sesuai dengan perilaku hook `Stop`. `stopReason` ditampilkan kepada pengguna.
3055 3081
3056Contoh ini memeriksa bahwa artefak build ada sebelum mengizinkan rekan tim menganggur:3082Contoh ini memeriksa bahwa artefak build ada sebelum mengizinkan rekan tim menjadi idle:
3057 3083
3058```bash theme={null}3084```bash theme={null}
3059#!/bin/bash3085#!/bin/bash
3070 ConfigChange3096 ConfigChange
3071</h3>3097</h3>
3072 3098
3073Berjalan ketika file konfigurasi berubah selama sesi. Gunakan untuk mengaudit perubahan pengaturan, menegakkan kebijakan keamanan, atau memblokir modifikasi tidak sah pada file konfigurasi.3099Berjalan ketika file konfigurasi berubah selama sesi. Gunakan ini untuk mengaudit perubahan pengaturan, menegakkan kebijakan keamanan, atau memblokir modifikasi yang tidak sah pada file konfigurasi.
3074 3100
3075Claude Code menjalankan hook ConfigChange ketika file pengaturan, file kebijakan terkelola, atau file skill berubah. Untuk kebijakan terkelola, Claude Code menjalankannya hanya ketika `managed-settings.json` atau file di `managed-settings.d/` berubah. Claude Code menerapkan [pengaturan yang dikelola server](/docs/id/server-managed-settings) dan perubahan pada preferensi terkelola macOS atau kebijakan registri Windows tanpa menjalankannya. Di WSL dengan [`wslInheritsWindowsSettings`](/docs/id/settings-reference#wslinheritswindowssettings), Claude Code juga menerapkan file pengaturan terkelola sisi Windows yang berubah pada polling kebijakannya tanpa menjalankannya.3101Claude Code menjalankan hook ConfigChange ketika file pengaturan, file kebijakan terkelola, atau file skill berubah. Untuk kebijakan terkelola, Claude Code menjalankannya hanya ketika `managed-settings.json` atau file di `managed-settings.d/` berubah. Claude Code menerapkan [pengaturan yang dikelola server](/docs/id/server-managed-settings) dan perubahan pada preferensi terkelola macOS atau kebijakan registri Windows tanpa menjalankannya. Di WSL dengan [`wslInheritsWindowsSettings`](/docs/id/settings-reference#wslinheritswindowssettings), Claude Code juga menerapkan file pengaturan terkelola sisi Windows yang berubah pada polling kebijakannya tanpa menjalankannya.
3076 3102
3139}3165}
3140```3166```
3141 3167
3142Perubahan `policy_settings` tidak dapat diblokir. Hook tetap dipicu untuk sumber `policy_settings` ketika file pengaturan terkelola di mesin berubah, sehingga Anda dapat menggunakannya untuk mencatat pengeditan tersebut, tetapi keputusan pemblokiran apa pun diabaikan. Ini memastikan pengaturan yang dikelola perusahaan selalu berlaku. Claude Code tidak menjalankan hook `ConfigChange` ketika [pengaturan yang dikelola server](/docs/id/server-managed-settings) tiba atau diperbarui.3168Perubahan `policy_settings` tidak dapat diblokir. Hook tetap dipicu untuk sumber `policy_settings` ketika file pengaturan terkelola di mesin berubah, sehingga Anda dapat menggunakannya untuk mencatat pengeditan tersebut, tetapi setiap keputusan pemblokiran diabaikan. Ini memastikan pengaturan yang dikelola perusahaan selalu berlaku. Claude Code tidak menjalankan hook `ConfigChange` ketika [pengaturan yang dikelola server](/docs/id/server-managed-settings) tiba atau diperbarui.
3143 3169
3144Claude Code bertindak berdasarkan keputusan pemblokiran dari output JSON hook ConfigChange dan membuang `systemMessage` dan `continue`. Perubahan yang diblokir tidak menampilkan pesan apa pun kepada Anda atau kepada Claude, baik Anda memblokir dengan `reason` maupun dengan stderr pada exit 2. Claude Code hanya menulis satu baris ke log debug.3170Claude Code bertindak berdasarkan keputusan pemblokiran dari output JSON hook ConfigChange dan membuang `systemMessage` dan `continue`. Perubahan yang diblokir tidak menampilkan pesan apa pun kepada Anda atau kepada Claude, baik Anda memblokir dengan `reason` maupun dengan stderr pada exit 2. Claude Code hanya menulis satu baris ke log debug.
3145 3171
3147 CwdChanged3173 CwdChanged
3148</h3>3174</h3>
3149 3175
3150Berjalan ketika perintah shell dalam percakapan utama mengubah direktori kerja, misalnya ketika Claude mengeksekusi perintah `cd`. Gunakan untuk bereaksi terhadap perubahan direktori: memuat ulang environment variable, mengaktifkan toolchain khusus proyek, atau menjalankan skrip penyiapan secara otomatis. Berpasangan dengan [FileChanged](#filechanged) untuk alat seperti [direnv](https://direnv.net/) yang mengelola environment per direktori.3176Berjalan ketika perintah shell dalam percakapan utama mengubah direktori kerja, misalnya ketika Claude mengeksekusi perintah `cd`. Gunakan ini untuk bereaksi terhadap perubahan direktori: memuat ulang environment variable, mengaktifkan toolchain khusus proyek, atau menjalankan skrip penyiapan secara otomatis. Berpasangan dengan [FileChanged](#filechanged) untuk alat seperti [direnv](https://direnv.net/) yang mengelola lingkungan per direktori.
3151 3177
3152Hook CwdChanged memiliki akses ke [`CLAUDE_ENV_FILE`](#persist-environment-variables). Variabel yang ditulis ke file tersebut bertahan ke perintah Bash berikutnya hingga event CwdChanged berikutnya, saat Claude Code menghapusnya.3178Hook CwdChanged memiliki akses ke [`CLAUDE_ENV_FILE`](#persist-environment-variables). Variabel yang ditulis ke file tersebut bertahan ke perintah Bash berikutnya hingga event CwdChanged berikutnya, ketika Claude Code menghapusnya.
3153 3179
3154CwdChanged tidak mendukung matcher dan dipicu pada setiap kejadian.3180CwdChanged tidak mendukung matcher dan dipicu pada setiap kejadian.
3155 3181
3174 Output CwdChanged3200 Output CwdChanged
3175</h4>3201</h4>
3176 3202
3177Selain [field output JSON](#json-output) yang tersedia untuk semua hook, hook CwdChanged dapat mengembalikan `watchPaths` untuk secara dinamis menetapkan path file mana yang dipantau oleh [FileChanged](#filechanged):3203Selain [field output JSON](#json-output) yang tersedia untuk semua hook, hook CwdChanged dapat mengembalikan `watchPaths` untuk mengatur secara dinamis path file mana yang dipantau oleh [FileChanged](#filechanged):
3178 3204
3179| Field | Deskripsi |3205| Field | Deskripsi |
3180| :- | :- |3206| :- | :- |
3181| `watchPaths` | Array path absolut. Menggantikan daftar pantau dinamis saat ini. Path dari konfigurasi `matcher` Anda selalu dipantau. Mengembalikan array kosong akan mengosongkan daftar dinamis, yang umum dilakukan saat memasuki direktori baru |3207| `watchPaths` | Array path absolut. Menggantikan daftar pantauan dinamis saat ini. Path dari konfigurasi `matcher` Anda selalu dipantau. Mengembalikan array kosong akan mengosongkan daftar dinamis, yang umum dilakukan saat memasuki direktori baru |
3182 3208
3183Hook CwdChanged tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir perubahan direktori.3209Hook CwdChanged tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir perubahan direktori.
3184 3210
3185Claude Code membaca `watchPaths` dan `systemMessage` dari output JSON-nya dan membuang `continue`. Dalam sesi interaktif, Claude Code menampilkan `systemMessage` sebagai notifikasi terminal singkat. Pesan tersebut tidak mencapai aliran pesan SDK.3211Claude Code membaca `watchPaths` dan `systemMessage` dari output JSON mereka dan membuang `continue`. Dalam sesi interaktif, Claude Code menampilkan `systemMessage` sebagai notifikasi terminal singkat. Pesan tersebut tidak mencapai aliran pesan SDK.
3186 3212
3187<h3 id="directoryadded">3213<h3 id="directoryadded">
3188 DirectoryAdded3214 DirectoryAdded
3189</h3>3215</h3>
3190 3216
3191Berjalan setelah Anda menambahkan direktori kerja di tengah sesi dengan perintah `/add-dir`, atau setelah klien SDK menambahkannya dengan permintaan kontrol `register_repo_root`. Gunakan untuk menyiapkan repositori yang baru ditambahkan, misalnya dengan menginstal dependensinya.3217Berjalan setelah Anda menambahkan direktori kerja di tengah sesi dengan perintah `/add-dir`, atau setelah klien SDK menambahkannya dengan permintaan kontrol `register_repo_root`. Gunakan ini untuk menyiapkan repositori yang baru ditambahkan, misalnya dengan menginstal dependensinya.
3192 3218
3193Claude Code tidak memicu event ini ketika:3219Claude Code tidak memicu event ini ketika:
3194 3220
3195* Anda meneruskan direktori dengan flag startup `--add-dir`; [SessionStart](#sessionstart) mencakup direktori tersebut3221* Anda meneruskan direktori dengan flag startup `--add-dir`; [SessionStart](#sessionstart) mencakup direktori tersebut
3196* Anda menambahkan direktori pada tab Workspace di `/permissions`3222* Anda menambahkan direktori di tab Workspace `/permissions`
3197* Anda menambahkan direktori yang sudah merupakan direktori kerja atau berada di dalamnya3223* Anda menambahkan direktori yang sudah menjadi direktori kerja atau berada di dalamnya
3198 3224
3199Claude Code memicu DirectoryAdded setelah memperbarui status sandbox dan izin, sehingga tool yang di-sandbox sudah melihat direktori baru saat hook Anda berjalan. Perintah hook sendiri berjalan tanpa sandbox.3225Claude Code memicu DirectoryAdded setelah menyegarkan status sandbox dan izin, sehingga tool yang di-sandbox sudah melihat direktori baru ketika hook Anda berjalan. Perintah hook itu sendiri berjalan tanpa sandbox.
3200 3226
3201Claude Code tidak menunggu hook: penambahan selesai segera, dan hook berjalan di latar belakang dengan timeout default 600 detik.3227Claude Code tidak menunggu hook: penambahan selesai segera, dan hook berjalan di latar belakang dengan timeout default 600 detik.
3202 3228
3215 3241
3216| Field | Deskripsi |3242| Field | Deskripsi |
3217| :- | :- |3243| :- | :- |
3218| `directory` | Path absolut direktori yang ditambahkan |3244| `directory` | Path absolut dari direktori yang ditambahkan |
3219| `source` | Cara direktori ditambahkan, `"slash_command"` untuk `/add-dir` atau `"register_repo_root"` untuk permintaan kontrol SDK |3245| `source` | Cara direktori ditambahkan, `"slash_command"` untuk `/add-dir` atau `"register_repo_root"` untuk permintaan kontrol SDK |
3220 3246
3221```json theme={null}3247```json theme={null}
3229}3255}
3230```3256```
3231 3257
3232Hook DirectoryAdded tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir penambahan, yang sudah selesai saat hook berjalan. Claude Code membuang field `continue` dari output JSON-nya dan menampilkan sisanya secara berbeda per sumber:3258Hook DirectoryAdded tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir penambahan, yang sudah selesai ketika hook berjalan. Claude Code membuang field `continue` dari output JSON mereka dan menampilkan sisanya secara berbeda per sumber:
3233 3259
3234* `slash_command`: Claude Code menyampaikan `systemMessage` hook kepada Claude sebagai konteks pada giliran percakapan berikutnya, alih-alih menampilkannya kepada Anda. Jumlah hook yang gagal muncul di transkrip. Output kegagalan lengkap masuk ke log debug3260* `slash_command`: Claude Code mengirimkan `systemMessage` hook kepada Claude sebagai konteks pada giliran percakapan berikutnya, alih-alih menampilkannya kepada Anda. Jumlah hook yang gagal muncul di transkrip. Output kegagalan lengkap masuk ke log debug
3235* `register_repo_root`: Claude Code menulis output `systemMessage` dan output kegagalan hanya ke log debug3261* `register_repo_root`: Claude Code menulis output `systemMessage` dan output kegagalan hanya ke log debug
3236 3262
3237<h3 id="filechanged">3263<h3 id="filechanged">
3238 FileChanged3264 FileChanged
3239</h3>3265</h3>
3240 3266
3241Berjalan ketika file yang dipantau berubah di disk. Claude Code mendeteksi perubahan dengan pemantau sistem file, bukan dengan memeriksa panggilan tool, sehingga Claude Code menjalankan hook apa pun yang mengubah file: panggilan tool `Edit` atau `Write`, skrip yang dijalankan Claude dengan `Bash`, atau proses yang sepenuhnya di luar Claude Code. Penggunaan umum adalah memuat ulang environment variable ketika file konfigurasi proyek berubah.3267Berjalan ketika file yang dipantau berubah di disk. Claude Code mendeteksi perubahan dengan filesystem watcher, bukan dengan memeriksa panggilan tool, sehingga hook dijalankan apa pun yang mengubah file tersebut: panggilan tool `Edit` atau `Write`, skrip yang dijalankan Claude dengan `Bash`, atau proses yang sepenuhnya berada di luar Claude Code. Penggunaan umumnya adalah memuat ulang environment variable ketika file konfigurasi proyek berubah.
3242 3268
3243`matcher` untuk event ini memiliki dua peran:3269`matcher` untuk event ini memiliki dua peran:
3244 3270
3245* **Membangun daftar pantau**: nilai dipisah pada `|` dan setiap segmen didaftarkan sebagai nama file literal di direktori kerja, sehingga `".envrc|.env"` memantau tepat kedua file tersebut. Pola regex tidak berguna di sini: nilai seperti `^\.env` akan memantau file yang secara literal bernama `^\.env`.3271* **Membangun daftar pantauan**: nilainya dipisahkan pada `|` dan setiap segmen didaftarkan sebagai nama file literal di direktori kerja, sehingga `".envrc|.env"` memantau tepat kedua file tersebut. Pola regex tidak berguna di sini: nilai seperti `^\.env` akan memantau file yang secara literal bernama `^\.env`.
3246* **Memfilter hook mana yang berjalan**: ketika file yang dipantau berubah, nilai yang sama memfilter grup hook mana yang berjalan menggunakan [aturan matcher](#matcher-patterns) standar terhadap nama dasar file yang berubah.3272* **Memfilter hook mana yang berjalan**: ketika file yang dipantau berubah, nilai yang sama memfilter grup hook mana yang berjalan menggunakan [aturan matcher](#matcher-patterns) standar terhadap basename file yang berubah.
3247 3273
3248Contoh ini menormalkan akhir baris di `data.csv` setelah setiap perubahan, termasuk perintah `Bash` atau skrip eksternal yang menulis ulang file:3274Contoh ini menormalkan akhir baris di `data.csv` setelah perubahan apa pun, termasuk perintah `Bash` atau skrip eksternal yang menulis ulang file tersebut:
3249 3275
3250```json theme={null}3276```json theme={null}
3251{3277{
3265}3291}
3266```3292```
3267 3293
3268Hook membaca path absolut file yang berubah dari field `file_path` pada [input JSON](#filechanged-input) di stdin. Penjaga `grep`-nya menguji hal yang sama yang dihapus oleh `perl`, yaitu CR di akhir baris, sehingga eksekusi setelah normalisasi keluar tanpa menyentuh file. Penjaga yang lebih longgar akan berulang tanpa henti, karena `perl -i` menulis ulang file bahkan ketika tidak mengganti apa pun dan Claude Code menjalankan hook lagi setelah setiap penulisan ulang. Simpan skrip ini di `/path/to/normalize-line-endings.sh` dan buat agar dapat dieksekusi:3294Hook membaca path absolut file yang berubah dari field `file_path` pada [input JSON](#filechanged-input) di stdin. Pemeriksaan `grep`-nya menguji hal yang sama dengan yang dihapus oleh `perl`, yaitu CR di akhir baris, sehingga eksekusi setelah normalisasi keluar tanpa menyentuh file. Pemeriksaan yang lebih longgar akan berulang tanpa henti, karena `perl -i` menulis ulang file bahkan ketika tidak mengganti apa pun dan Claude Code menjalankan hook lagi setelah setiap penulisan ulang. Simpan skrip ini di `/path/to/normalize-line-endings.sh` dan jadikan dapat dieksekusi:
3269 3295
3270```bash theme={null}3296```bash theme={null}
3271#!/bin/bash3297#!/bin/bash
3275fi3301fi
3276```3302```
3277 3303
3278Untuk memastikan hook berfungsi, minta Claude menambahkan baris CRLF ke `data.csv` dengan perintah `Bash`. Claude Code menjalankan hook dan file berakhir dengan akhir baris LF.3304Untuk memastikan hook berfungsi, minta Claude menambahkan baris CRLF ke `data.csv` dengan perintah `Bash`. Claude Code menjalankan hook dan file akhirnya memiliki akhir baris LF.
3279 3305
3280Untuk memantau file yang tidak dapat Anda sebutkan di awal, kembalikan [`watchPaths`](#filechanged-output) dari hook untuk memperbarui daftar pantau secara dinamis. Claude Code memulai pemantau hanya ketika sesuatu menyebutkan file untuk dipantau, jadi isi daftar awal dengan grup FileChanged yang matcher-nya menyebutkan setidaknya satu file, atau dengan hook [SessionStart](#sessionstart-decision-control) atau [CwdChanged](#cwdchanged) yang mengembalikan `watchPaths`. Matcher tetap memfilter grup hook mana yang berjalan ketika file yang dipantau berubah, jadi berikan grup yang menangani path dinamis matcher yang dihilangkan, yang cocok dengan setiap file yang dipantau dan tidak menambahkan apa pun ke daftar pantau. Matcher `"*"` juga cocok dengan setiap file, tetapi Claude Code mendaftarkannya di daftar pantau seperti nilai lainnya, sebagai file literal bernama `*`.3306Untuk memantau file yang tidak dapat Anda sebutkan di awal, kembalikan [`watchPaths`](#filechanged-output) dari hook untuk memperbarui daftar pantauan secara dinamis. Claude Code memulai watcher hanya ketika ada sesuatu yang menyebutkan file untuk dipantau, jadi isi daftar awal dengan grup FileChanged yang matcher-nya menyebutkan setidaknya satu file, atau dengan hook [SessionStart](#sessionstart-decision-control) atau [CwdChanged](#cwdchanged) yang mengembalikan `watchPaths`. Matcher tetap memfilter grup hook mana yang berjalan ketika file yang dipantau berubah, jadi berikan grup yang menangani path dinamis matcher yang dihilangkan, yang cocok dengan setiap file yang dipantau dan tidak menambahkan apa pun ke daftar pantauan. Matcher `"*"` juga cocok dengan setiap file, tetapi Claude Code mendaftarkannya di daftar pantauan seperti nilai lainnya, sebagai file literal bernama `*`.
3281 3307
3282Hook FileChanged memiliki akses ke [`CLAUDE_ENV_FILE`](#persist-environment-variables). Variabel yang ditulis ke file tersebut bertahan ke perintah Bash berikutnya hingga event [CwdChanged](#cwdchanged) berikutnya, saat Claude Code menghapusnya.3308Hook FileChanged memiliki akses ke [`CLAUDE_ENV_FILE`](#persist-environment-variables). Variabel yang ditulis ke file tersebut bertahan ke perintah Bash berikutnya hingga event [CwdChanged](#cwdchanged) berikutnya, saat Claude Code menghapusnya.
3283 3309
3307 Output FileChanged3333 Output FileChanged
3308</h4>3334</h4>
3309 3335
3310Selain [field output JSON](#json-output) yang tersedia untuk semua hook, hook FileChanged dapat mengembalikan `watchPaths` untuk secara dinamis memperbarui path file mana yang dipantau:3336Selain [field output JSON](#json-output) yang tersedia untuk semua hook, hook FileChanged dapat mengembalikan `watchPaths` untuk memperbarui secara dinamis path file mana yang dipantau:
3311 3337
3312| Field | Deskripsi |3338| Field | Deskripsi |
3313| :- | :- |3339| :- | :- |
3314| `watchPaths` | Array path absolut. Menggantikan daftar pantau dinamis saat ini. Path dari konfigurasi `matcher` Anda selalu dipantau. Gunakan ini ketika skrip hook Anda menemukan file tambahan untuk dipantau berdasarkan file yang berubah |3340| `watchPaths` | Array path absolut. Menggantikan daftar pantauan dinamis saat ini. Path dari konfigurasi `matcher` Anda selalu dipantau. Gunakan ini ketika skrip hook Anda menemukan file tambahan untuk dipantau berdasarkan file yang berubah |
3315 3341
3316Hook FileChanged tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir terjadinya perubahan file.3342Hook FileChanged tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir terjadinya perubahan file.
3317 3343
3336 3362
3337Karena hook menggantikan perilaku default sepenuhnya, [`.worktreeinclude`](/docs/id/worktrees#copy-gitignored-files-into-worktrees) tidak diproses. Jika Anda perlu menyalin file konfigurasi lokal seperti `.env` ke worktree baru, lakukan di dalam skrip hook Anda.3363Karena hook menggantikan perilaku default sepenuhnya, [`.worktreeinclude`](/docs/id/worktrees#copy-gitignored-files-into-worktrees) tidak diproses. Jika Anda perlu menyalin file konfigurasi lokal seperti `.env` ke worktree baru, lakukan di dalam skrip hook Anda.
3338 3364
3339Hook harus mengembalikan path ke direktori worktree yang dibuat. Claude Code menggunakan path ini sebagai direktori kerja untuk sesi terisolasi. Lihat [Output WorktreeCreate](#worktreecreate-output) untuk mengetahui cara setiap jenis hook mengembalikan path.3365Hook harus mengembalikan path ke direktori worktree yang dibuat. Claude Code menggunakan path ini sebagai direktori kerja untuk sesi terisolasi. Lihat [output WorktreeCreate](#worktreecreate-output) untuk cara setiap jenis hook mengembalikan path.
3340 3366
3341Claude Code bertindak berdasarkan keberhasilan hook dan path yang dikembalikan, serta membuang `systemMessage` dan `continue`.3367Claude Code bertindak berdasarkan keberhasilan hook dan path yang dikembalikan, serta membuang `systemMessage` dan `continue`.
3342 3368
3359}3385}
3360```3386```
3361 3387
3362Hook membaca `name` worktree dari input JSON di stdin, melakukan checkout salinan baru ke direktori baru, lalu mencetak path direktori tersebut. `echo` pada baris terakhir adalah yang dibaca Claude Code sebagai path worktree. Alihkan output lainnya ke stderr agar tidak mengganggu path.3388Hook membaca `name` worktree dari input JSON di stdin, melakukan checkout salinan baru ke direktori baru, dan mencetak path direktori tersebut. `echo` pada baris terakhir adalah yang dibaca Claude Code sebagai path worktree. Alihkan output lain ke stderr agar tidak mengganggu path.
3363 3389
3364<h4 id="worktreecreate-input">3390<h4 id="worktreecreate-input">
3365 Input WorktreeCreate3391 Input WorktreeCreate
3366</h4>3392</h4>
3367 3393
3368Selain [kolom input umum](#common-input-fields), hook WorktreeCreate menerima kolom `name`. Ini adalah pengidentifikasi slug untuk worktree baru, baik yang ditentukan oleh pengguna maupun yang dibuat otomatis, misalnya `bold-oak-a3f2`.3394Selain [field input umum](#common-input-fields), hook WorktreeCreate menerima field `name`. Ini adalah pengidentifikasi slug untuk worktree baru, baik yang ditentukan oleh pengguna maupun yang dibuat otomatis, misalnya `bold-oak-a3f2`.
3369 3395
3370```json theme={null}3396```json theme={null}
3371{3397{
3381 Output WorktreeCreate3407 Output WorktreeCreate
3382</h4>3408</h4>
3383 3409
3384Hook WorktreeCreate tidak menggunakan model keputusan allow/block standar. Sebagai gantinya, keberhasilan atau kegagalan hook menentukan hasilnya. Hook harus mengembalikan path ke direktori worktree yang dibuat:3410Hook WorktreeCreate tidak menggunakan model keputusan allow/block standar. Sebaliknya, keberhasilan atau kegagalan hook menentukan hasilnya. Hook harus mengembalikan path ke direktori worktree yang dibuat:
3385 3411
3386* **Hook perintah** (`type: "command"`): cetak path sebagai baris tidak kosong terakhir dari stdout. Claude Code menghapus kode escape ANSI sebelum membaca baris tersebut, sehingga banner startup shell yang dicetak sebelum `echo` Anda diabaikan. Alihkan output hook lainnya ke stderr.3412* **Hook command** (`type: "command"`): cetak path sebagai baris tidak kosong terakhir dari stdout. Claude Code menghapus kode escape ANSI sebelum membaca baris tersebut, sehingga banner startup shell yang dicetak sebelum `echo` Anda diabaikan. Alihkan output hook lainnya ke stderr.
3387* **Hook HTTP** (`type: "http"`): kembalikan `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` di badan respons.3413* **Hook HTTP** (`type: "http"`): kembalikan `{ "hookSpecificOutput": { "hookEventName": "WorktreeCreate", "worktreePath": "/absolute/path" } }` di body respons.
3388 3414
3389Jika hook gagal atau tidak menghasilkan path, pembuatan worktree gagal dengan error.3415Jika hook gagal atau tidak menghasilkan path, pembuatan worktree gagal dengan error.
3390 3416
3391Claude Code menyelesaikan path relatif terhadap direktori tempat hook dijalankan, dengan meringkas segmen `.` atau `..` di dalamnya. Jika path yang dihasilkan bukan direktori yang dapat dimasuki Claude Code, sesi mencetak error yang menyebutkan path tersebut dan keluar dengan kode 1.3417Claude Code me-resolve path relatif terhadap direktori tempat hook dijalankan, dengan meringkas segmen `.` atau `..` di dalamnya. Jika path yang dihasilkan bukan direktori yang dapat dimasuki Claude Code, sesi mencetak error yang menyebutkan path tersebut dan keluar dengan kode 1.
3392 3418
3393Claude Code menolak path absolut yang berisi segmen `.` atau `..`, serta path apa pun yang melewati symlink di bawah root repositori, karena symlink yang di-commit ke repositori dapat mengalihkan worktree ke luar repositori. Error tersebut menyebutkan komponen yang ditolak. Kembalikan path yang dinormalisasi dan tidak melewati symlink di dalam repositori. Sebelum v2.1.216, pembuatan worktree mengikuti path dari hook tanpa penyaringan ini.3419Claude Code menolak path absolut yang berisi segmen `.` atau `..`, dan path apa pun yang melewati symlink di bawah root repositori, karena symlink yang di-commit ke repositori dapat mengalihkan worktree ke luar repositori. Error tersebut menyebutkan komponen yang ditolak. Kembalikan path yang sudah dinormalisasi dan tidak melewati symlink di dalam repositori. Sebelum v2.1.216, pembuatan worktree mengikuti path dari hook tanpa pemeriksaan ini.
3394 3420
3395<h3 id="worktreeremove">3421<h3 id="worktreeremove">
3396 WorktreeRemove3422 WorktreeRemove
3397</h3>3423</h3>
3398 3424
3399Berjalan saat Claude Code membersihkan worktree yang dibuat oleh hook [`WorktreeCreate`](#worktreecreate) Anda. Event ini dipicu ketika:3425Berjalan ketika Claude Code membersihkan worktree yang dibuat oleh hook [`WorktreeCreate`](#worktreecreate) Anda. Event ini terpicu ketika:
3400 3426
3401* Anda keluar dari [sesi worktree](/docs/id/worktrees#start-claude-in-a-worktree) interaktif dan memilih untuk menghapus worktree saat Claude Code meminta Anda3427* Anda keluar dari [sesi worktree](/docs/id/worktrees#start-claude-in-a-worktree) interaktif dan memilih untuk menghapus worktree ketika Claude Code meminta Anda
3402* Anda keluar dari sesi worktree interaktif yang belum Anda [beri nama](/docs/id/sessions#name-your-sessions), Claude Code tidak menemukan file yang berubah atau tidak terlacak, dan menghapus worktree tanpa meminta Anda3428* Anda keluar dari sesi worktree interaktif yang belum Anda [beri nama](/docs/id/sessions#name-your-sessions), Claude Code tidak menemukan file yang berubah atau tidak terlacak, dan Claude Code menghapus worktree tanpa meminta konfirmasi Anda
3403* Anda menghapus [sesi latar belakang](/docs/id/agent-view#what-deleting-a-session-removes) yang berjalan di worktree tersebut3429* Anda menghapus [sesi latar belakang](/docs/id/agent-view#what-deleting-a-session-removes) yang berjalan di worktree tersebut
3404* Anda meminta Claude untuk keluar dan menghapus worktree selama sesi, dan Claude menghapusnya dengan tool [`ExitWorktree`](/docs/id/tools-reference)3430* Anda meminta Claude untuk keluar dan menghapus worktree selama sesi, dan Claude menghapusnya dengan tool [`ExitWorktree`](/docs/id/tools-reference)
3405* Sesi yang dimulai oleh [`claude remote-control`](/docs/id/remote-control#start-a-remote-control-session) dalam mode `worktree` berakhir tanpa crash, dan Claude Code tidak menemukan file yang berubah atau tidak terlacak serta tidak ada commit baru di worktree-nya3431* Sesi yang dimulai oleh [`claude remote-control`](/docs/id/remote-control#start-a-remote-control-session) dalam mode `worktree` berakhir tanpa crash, dan Claude Code tidak menemukan file yang berubah atau tidak terlacak serta tidak ada commit baru di worktree-nya
3406* Anda menghentikan `claude remote-control` saat sesi yang dimulainya dalam mode `worktree` masih berjalan, dan Claude Code tidak menemukan file yang berubah atau tidak terlacak serta tidak ada commit baru di worktree-nya3432* Anda menghentikan `claude remote-control` saat sesi yang dimulainya dalam mode `worktree` masih berjalan, dan Claude Code tidak menemukan file yang berubah atau tidak terlacak serta tidak ada commit baru di worktree-nya
3407 3433
3408Ketika subagent atau agent workflow selesai, Claude Code mempertahankan worktree yang dibuat hook WorktreeCreate Anda untuknya dan tidak menjalankan hook WorktreeRemove Anda. Hapus sendiri worktree tersebut ketika pekerjaan selesai.3434Ketika subagent atau agent workflow selesai, Claude Code menyimpan worktree yang dibuat oleh hook WorktreeCreate Anda untuknya dan tidak menjalankan hook WorktreeRemove Anda. Hapus sendiri worktree tersebut ketika pekerjaan selesai.
3409 3435
3410Claude Code tidak meminta konfirmasi Anda sebelum hook Anda berjalan untuk panggilan `ExitWorktree` atau pembersihan `claude remote-control`. `ExitWorktree` menolak menghapus worktree yang dibuat hook kecuali panggilan tersebut meneruskan [`discard_changes: true`](/docs/id/agent-sdk/typescript#exitworktree), yang menjadikan hook Anda pemeriksaan terakhir pada jalur tersebut.3436Claude Code tidak meminta konfirmasi Anda sebelum hook Anda berjalan untuk panggilan `ExitWorktree` atau pembersihan `claude remote-control`. `ExitWorktree` menolak menghapus worktree yang dibuat hook kecuali panggilan tersebut menyertakan [`discard_changes: true`](/docs/id/agent-sdk/typescript#exitworktree), yang menjadikan hook Anda sebagai pemeriksaan terakhir pada jalur tersebut.
3411 3437
3412Claude Code menggunakan git untuk mencari file yang berubah atau tidak terlacak, sehingga tidak menemukan apa pun di worktree yang bukan checkout git atau tidak berada di dalamnya, meskipun direktori tersebut berisi pekerjaan yang belum di-commit. Periksa pekerjaan tersebut di hook WorktreeRemove Anda sebelum hook menghapus apa pun.3438Claude Code menggunakan git untuk mencari file yang berubah atau tidak terlacak, sehingga tidak menemukan apa pun di worktree yang bukan checkout git atau tidak berada di dalamnya, bahkan ketika direktori tersebut berisi pekerjaan yang belum di-commit. Periksa pekerjaan tersebut di hook WorktreeRemove Anda sebelum hook menghapus apa pun.
3413 3439
3414Untuk worktree berbasis git, Claude Code menangani pembersihan secara otomatis dengan `git worktree remove`. Jika Anda mengonfigurasi hook WorktreeCreate, pasangkan dengan hook WorktreeRemove untuk mengontrol pembersihan:3440Untuk worktree berbasis git, Claude Code menangani pembersihan secara otomatis dengan `git worktree remove`. Jika Anda mengonfigurasi hook WorktreeCreate, pasangkan dengan hook WorktreeRemove untuk mengontrol pembersihan:
3415 3441
3416* **Tanpa hook WorktreeRemove**: Claude Code beralih ke git sebagai fallback untuk penghapusan saat keluar atau melalui `ExitWorktree`, dan mempertahankan worktree saat `claude remote-control` melakukan pembersihan:3442* **Tanpa hook WorktreeRemove**: Claude Code melakukan fallback ke git untuk penghapusan saat keluar atau melalui `ExitWorktree`, dan menyimpan worktree ketika `claude remote-control` melakukan pembersihan:
3417 * **Anda keluar dari sesi worktree, atau Claude memanggil `ExitWorktree`**: Claude Code menghapus path yang dikembalikan hook WorktreeCreate Anda seperti yang dilakukan `git worktree remove --force`, sehingga worktree yang dikenali git akan dihapus. Worktree yang tidak dikenali git, misalnya yang dibuat hook Anda dengan sistem kontrol versi non-git, tetap ada di disk.3443 * **Anda keluar dari sesi worktree, atau Claude memanggil `ExitWorktree`**: Claude Code menghapus path yang dikembalikan oleh hook WorktreeCreate Anda seperti yang dilakukan `git worktree remove --force`, sehingga worktree yang dikenali git akan dihapus. Worktree yang tidak dikenali git, misalnya yang dibuat hook Anda dengan sistem kontrol versi non-git, tetap ada di disk.
3418 * **`claude remote-control` membersihkan worktree sebuah sesi**: worktree tetap ada di disk, dan terminal yang menjalankan `claude remote-control` menampilkan `worktree removal failed, kept: <path>`.3444 * **`claude remote-control` membersihkan worktree sesi**: worktree tetap ada di disk, dan terminal yang menjalankan `claude remote-control` menampilkan `worktree removal failed, kept: <path>`.
3419 * **Anda menghapus sesi latar belakang**: lihat [Apa yang dihapus saat menghapus sesi](/docs/id/agent-view#what-deleting-a-session-removes).3445 * **Anda menghapus sesi latar belakang**: lihat [Apa yang dihapus saat menghapus sesi](/docs/id/agent-view#what-deleting-a-session-removes).
3420* **Hook keluar dengan 0**: worktree dianggap telah dihapus. Claude Code tidak membaca apa pun lagi dari hook, jadi pastikan hook Anda telah menghapus direktori tersebut.3446* **Hook keluar dengan 0**: worktree dianggap telah dihapus. Claude Code tidak membaca apa pun lagi dari hook, jadi pastikan hook Anda telah menghapus direktori tersebut.
3421* **Hook keluar dengan non-zero**: penghapusan gagal jika direktori di `worktree_path` masih ada setelahnya, dan worktree tetap ada di disk tanpa fallback git. Hook yang telah menghapus direktori sebelum keluar dengan non-zero dianggap telah menghapus. Untuk cara kegagalan dilaporkan, lihat [Input WorktreeRemove](#worktreeremove-input).3447* **Hook keluar dengan non-zero**: penghapusan gagal jika direktori di `worktree_path` masih ada setelahnya, dan worktree tetap ada di disk tanpa fallback git. Hook yang menghapus direktori sebelum keluar dengan non-zero dianggap telah menghapus. Untuk cara kegagalan dilaporkan, lihat [input WorktreeRemove](#worktreeremove-input).
3422 3448
3423Claude Code tidak pernah menghapus branch milik worktree yang dibuat hook, karena Claude Code hanya mengetahui path yang dikembalikan hook WorktreeCreate Anda. Jika hook WorktreeCreate Anda membuat branch, hapus branch tersebut di hook WorktreeRemove Anda.3449Claude Code tidak pernah menghapus branch milik worktree yang dibuat hook, karena Claude Code hanya mengetahui path yang dikembalikan oleh hook WorktreeCreate Anda. Jika hook WorktreeCreate Anda membuat branch, hapus branch tersebut di hook WorktreeRemove Anda.
3424 3450
3425Claude Code membuang [kolom output JSON](#json-output) dari hook WorktreeRemove, seperti `systemMessage` dan `continue`.3451Claude Code membuang [field output JSON](#json-output) hook WorktreeRemove, seperti `systemMessage` dan `continue`.
3426 3452
3427Untuk penghapusan sesi latar belakang, Claude Code memverifikasi path worktree yang tersimpan sebelum menjalankan hook dan menolak path yang merupakan symlink atau melewati symlink di bawah root repositori. Pada jalur tersebut, hook berjalan untuk worktree yang masih berisi file hanya ketika Anda mengonfirmasi penghapusan di [agent view](/docs/id/agent-view#what-deleting-a-session-removes); untuk worktree seperti itu, [`claude rm`](/docs/id/agent-view#manage-sessions-from-the-shell) justru mempertahankan sesi dan worktree. Sebelum v2.1.216, hook berjalan pada path yang tersimpan tanpa pemeriksaan ini.3453Untuk penghapusan sesi latar belakang, Claude Code memverifikasi path worktree yang tersimpan sebelum menjalankan hook dan menolak path yang merupakan symlink atau melewati symlink di bawah root repositori. Pada jalur tersebut, hook berjalan untuk worktree yang masih berisi file hanya ketika Anda mengonfirmasi penghapusan di [agent view](/docs/id/agent-view#what-deleting-a-session-removes); untuk worktree seperti itu, [`claude rm`](/docs/id/agent-view#manage-sessions-from-the-shell) justru menyimpan sesi dan worktree. Sebelum v2.1.216, hook berjalan pada path yang tersimpan tanpa pemeriksaan ini.
3428 3454
3429Claude Code meneruskan path yang dikembalikan oleh WorktreeCreate sebagai `worktree_path` dalam input hook. Contoh ini membaca path tersebut dan menghapus direktorinya:3455Claude Code meneruskan path yang dikembalikan oleh WorktreeCreate sebagai `worktree_path` dalam input hook. Contoh ini membaca path tersebut dan menghapus direktorinya:
3430 3456
3449 Input WorktreeRemove3475 Input WorktreeRemove
3450</h4>3476</h4>
3451 3477
3452Selain [kolom input umum](#common-input-fields), hook WorktreeRemove menerima kolom `worktree_path`, yaitu path absolut ke worktree yang sedang dihapus.3478Selain [field input umum](#common-input-fields), hook WorktreeRemove menerima field `worktree_path`, yaitu path absolut ke worktree yang sedang dihapus.
3453 3479
3454```json theme={null}3480```json theme={null}
3455{3481{
3465 3491
3466* Worktree tetap ada di disk, dan perintah serta stderr hook dikirim ke [log debug](#debug-hooks).3492* Worktree tetap ada di disk, dan perintah serta stderr hook dikirim ke [log debug](#debug-hooks).
3467* Jika Anda sedang menghapus sesi latar belakang, sesi tersebut juga tetap ada. Pesan penolakan di [agent view](/docs/id/agent-view#what-deleting-a-session-removes) melaporkan bagaimana hook berakhir, seperti `exited 1`, mengutip awal stderr-nya, dan menyatakan apakah menghapus sesi lagi tetap akan menghapus direktori tersebut.3493* Jika Anda sedang menghapus sesi latar belakang, sesi tersebut juga tetap ada. Pesan penolakan di [agent view](/docs/id/agent-view#what-deleting-a-session-removes) melaporkan bagaimana hook berakhir, seperti `exited 1`, mengutip awal stderr-nya, dan menyatakan apakah menghapus sesi lagi tetap akan menghapus direktori tersebut.
3468* Jika `claude remote-control` sedang membersihkan worktree sebuah sesi, terminal yang menjalankannya menampilkan `worktree removal failed, kept: <path>`.3494* Jika `claude remote-control` sedang membersihkan worktree sesi, terminal yang menjalankannya menampilkan `worktree removal failed, kept: <path>`.
3469 3495
3470<h3 id="precompact">3496<h3 id="precompact">
3471 PreCompact3497 PreCompact
3475 3501
3476Nilai matcher menunjukkan apakah compaction dipicu secara manual atau otomatis:3502Nilai matcher menunjukkan apakah compaction dipicu secara manual atau otomatis:
3477 3503
3478| Matcher | Kapan dipicu |3504| Matcher | Kapan terpicu |
3479| :- | :- |3505| :- | :- |
3480| `manual` | `/compact` |3506| `manual` | `/compact` |
3481| `auto` | Auto-compact saat percakapan mencapai [jendela auto-compact](/docs/id/model-config#set-the-auto-compact-window) |3507| `auto` | Auto-compact ketika percakapan mencapai [jendela auto-compact](/docs/id/model-config#set-the-auto-compact-window), dan [idle compaction](/docs/id/settings-reference#idlecompaction) |
3482 3508
3483Keluar dengan kode 2 untuk memblokir compaction. Untuk `/compact` manual, pesan stderr ditampilkan kepada pengguna. Anda juga dapat memblokir dengan mengembalikan JSON dengan `"decision": "block"`.3509Keluar dengan kode 2 untuk memblokir compaction. Untuk `/compact` manual, pesan stderr ditampilkan kepada pengguna. Anda juga dapat memblokir dengan mengembalikan JSON dengan `"decision": "block"`.
3484 3510
3485Memblokir compaction otomatis memiliki efek berbeda tergantung kapan dipicu. Jika compaction dipicu secara proaktif sebelum batas konteks, Claude Code melewatinya dan percakapan berlanjut tanpa di-compact. Jika compaction dipicu untuk pulih dari error batas konteks yang sudah dikembalikan oleh API, error yang mendasarinya muncul dan permintaan saat ini gagal.3511Memblokir compaction otomatis memiliki efek berbeda tergantung kapan terpicu. Jika compaction dipicu secara proaktif sebelum batas konteks, Claude Code melewatinya dan percakapan berlanjut tanpa di-compact. Jika compaction dipicu untuk memulihkan dari error batas konteks yang sudah dikembalikan oleh API, error yang mendasarinya muncul dan permintaan saat ini gagal.
3486 3512
3487Claude Code membuang kolom `systemMessage` dan `continue` dari hook PreCompact.3513Claude Code membuang field `systemMessage` dan `continue` dari hook PreCompact.
3488 3514
3489<h4 id="precompact-input">3515<h4 id="precompact-input">
3490 Input PreCompact3516 Input PreCompact
3491</h4>3517</h4>
3492 3518
3493Selain [kolom input umum](#common-input-fields), hook PreCompact menerima `trigger` dan `custom_instructions`. Untuk `manual`, `custom_instructions` berisi apa yang diteruskan pengguna ke `/compact` dan bernilai `null` ketika pengguna tidak meneruskan apa pun. Untuk `auto`, `custom_instructions` bernilai `null`.3519Selain [field input umum](#common-input-fields), hook PreCompact menerima `trigger` dan `custom_instructions`. Untuk `manual`, `custom_instructions` berisi apa yang diteruskan pengguna ke `/compact` dan bernilai `null` ketika mereka tidak meneruskan apa pun. Untuk `auto`, `custom_instructions` bernilai `null`.
3494 3520
3495```json theme={null}3521```json theme={null}
3496{3522{
3507 PostCompact3533 PostCompact
3508</h3>3534</h3>
3509 3535
3510Berjalan setelah Claude Code menyelesaikan operasi compact. Gunakan event ini untuk bereaksi terhadap status baru hasil compact, misalnya untuk mencatat ringkasan yang dihasilkan atau memperbarui status eksternal. Claude Code membuang kolom `systemMessage` dan `continue` dari hook PostCompact.3536Berjalan setelah Claude Code menyelesaikan operasi compact. Gunakan event ini untuk bereaksi terhadap state baru yang sudah di-compact, misalnya untuk mencatat ringkasan yang dihasilkan atau memperbarui state eksternal. Claude Code membuang field `systemMessage` dan `continue` dari hook PostCompact.
3511 3537
3512Nilai matcher yang sama berlaku seperti untuk `PreCompact`:3538Nilai matcher yang sama berlaku seperti untuk `PreCompact`:
3513 3539
3514| Matcher | Kapan dipicu |3540| Matcher | Kapan terpicu |
3515| :- | :- |3541| :- | :- |
3516| `manual` | Setelah `/compact` |3542| `manual` | Setelah `/compact` |
3517| `auto` | Setelah auto-compact saat percakapan mencapai [jendela auto-compact](/docs/id/model-config#set-the-auto-compact-window) |3543| `auto` | Setelah auto-compact ketika percakapan mencapai [jendela auto-compact](/docs/id/model-config#set-the-auto-compact-window), dan setelah [idle compaction](/docs/id/settings-reference#idlecompaction) |
3518 3544
3519<h4 id="postcompact-input">3545<h4 id="postcompact-input">
3520 Input PostCompact3546 Input PostCompact
3521</h4>3547</h4>
3522 3548
3523Selain [kolom input umum](#common-input-fields), hook PostCompact menerima `trigger` dan `compact_summary`. Kolom `compact_summary` berisi ringkasan percakapan yang dihasilkan oleh operasi compact.3549Selain [field input umum](#common-input-fields), hook PostCompact menerima `trigger` dan `compact_summary`. Field `compact_summary` berisi ringkasan percakapan yang dihasilkan oleh operasi compact.
3524 3550
3525```json theme={null}3551```json theme={null}
3526{3552{
3539 PreModelSwitch3565 PreModelSwitch
3540</h3>3566</h3>
3541 3567
3542Berjalan sebelum Claude Code menerapkan peralihan model yang diminta oleh Anda atau klien. Gunakan untuk memblokir peralihan, meminta konfirmasi, atau menampilkan biaya peralihan sebelum terjadi.3568Berjalan sebelum Claude Code menerapkan pergantian model yang diminta oleh Anda atau klien. Gunakan untuk memblokir pergantian, meminta konfirmasi, atau menampilkan biaya pergantian sebelum terjadi.
3543 3569
3544PreModelSwitch memerlukan Claude Code v2.1.251 atau lebih baru. Claude Code menjalankannya untuk permintaan berikut:3570PreModelSwitch memerlukan Claude Code v2.1.251 atau yang lebih baru. Claude Code menjalankannya untuk permintaan berikut:
3545 3571
3546* `/model <name>` dan pemilih `/model`3572* `/model <name>` dan pemilih `/model`
3547* Pemilih model `Option+P` atau `Alt+P`3573* Pemilih model `Option+P` atau `Alt+P`
3549* Mengaktifkan [fast mode](/docs/id/fast-mode) ketika hal itu mengubah model sesi3575* Mengaktifkan [fast mode](/docs/id/fast-mode) ketika hal itu mengubah model sesi
3550* Permintaan `set_model`, atau perubahan model dalam permintaan `apply_flag_settings`, dari host [Agent SDK](/docs/id/agent-sdk/typescript#query-object) atau [Remote Control](/docs/id/remote-control)3576* Permintaan `set_model`, atau perubahan model dalam permintaan `apply_flag_settings`, dari host [Agent SDK](/docs/id/agent-sdk/typescript#query-object) atau [Remote Control](/docs/id/remote-control)
3551 3577
3552Claude Code tidak menjalankan hook PreModelSwitch untuk peralihan yang dilakukannya sendiri, seperti [fallback model otomatis](/docs/id/model-config#automatic-model-fallback) atau memulihkan model saat Anda melanjutkan sesi. Perubahan tersebut hanya mencapai [PostModelSwitch](#postmodelswitch).3578Claude Code tidak menjalankan hook PreModelSwitch untuk pergantian yang dilakukannya sendiri, seperti [fallback model otomatis](/docs/id/model-config#automatic-model-fallback) atau memulihkan model ketika Anda melanjutkan sesi. Perubahan tersebut hanya mencapai [PostModelSwitch](#postmodelswitch).
3553 3579
3554Claude Code membandingkan matcher dengan nama kanonis model yang menjadi tujuan peralihan sesi, dengan mengabaikan sufiks `[1m]` apa pun. Alias seperti `opus`, ID model bertanggal, dan ID khusus penyedia seperti ID model Amazon Bedrock semuanya cocok dengan satu nama kanonis yang dituju, sehingga `claude-opus-5` mencakup setiap penulisan Opus 5.3580Claude Code membandingkan matcher dengan nama kanonis model yang menjadi tujuan pergantian sesi, dengan mengabaikan sufiks `[1m]` apa pun. Alias seperti `opus`, ID model bertanggal, dan ID khusus penyedia seperti ID model Amazon Bedrock semuanya cocok dengan satu nama kanonis yang menjadi hasil resolusinya, sehingga `claude-opus-5` mencakup setiap penulisan Opus 5.
3555 3581
3556Ketika Claude Code tidak dapat menentukan nama kanonis untuk target, misalnya ID model kustom yang hanya diketahui oleh [LLM gateway](/docs/id/llm-gateway) Anda, Claude Code menjalankan setiap hook PreModelSwitch terlepas dari matcher. Oleh karena itu, hook yang memblokir harus memeriksa `to_model` dari inputnya alih-alih hanya mengandalkan matcher.3582Ketika Claude Code tidak dapat menentukan nama kanonis untuk target, misalnya ID model kustom yang hanya diketahui oleh [LLM gateway](/docs/id/llm-gateway) Anda, Claude Code menjalankan setiap hook PreModelSwitch terlepas dari matcher-nya. Oleh karena itu, hook yang memblokir harus memeriksa `to_model` dari input-nya alih-alih hanya mengandalkan matcher.
3557 3583
3558Tulis matcher sebagai nama persis, daftar yang dipisahkan `|` seperti `claude-opus-4-6|claude-opus-5`, atau ekspresi reguler seperti `.*opus.*`. Contoh ini menggunakan matcher nama persis dan juga memeriksa `to_model` dari input hook, sehingga menolak peralihan ke Opus 4.6 dengan keluar menggunakan kode 2 dan membiarkan target lainnya lolos:3584Tulis matcher sebagai nama persis, daftar yang dipisahkan `|` seperti `claude-opus-4-6|claude-opus-5`, atau ekspresi reguler seperti `.*opus.*`. Contoh ini menggunakan matcher nama persis dan juga memeriksa `to_model` dari input hook, sehingga menolak pergantian ke Opus 4.6 dengan keluar menggunakan kode 2 dan membiarkan target lain lolos:
3559 3585
3560<Tabs>3586<Tabs>
3561 <Tab title="macOS/Linux">3587 <Tab title="macOS/Linux">
3581 </Tab>3607 </Tab>
3582 3608
3583 <Tab title="Windows (PowerShell)">3609 <Tab title="Windows (PowerShell)">
3584 Daftarkan hook perintah yang menjalankan skrip melalui PowerShell:3610 Daftarkan hook command yang menjalankan skrip melalui PowerShell:
3585 3611
3586 ```json theme={null}3612 ```json theme={null}
3587 {3613 {
3621 </Tab>3647 </Tab>
3622</Tabs>3648</Tabs>
3623 3649
3624Untuk memastikan hook berfungsi, jalankan `/model claude-opus-4-6` dari sesi yang menjalankan model lain. Claude Code mempertahankan model saat ini dan melaporkan bahwa hook PreModelSwitch memblokir peralihan, dengan pesan Anda sebagai alasannya.3650Untuk memastikan hook berfungsi, jalankan `/model claude-opus-4-6` dari sesi yang menjalankan model lain. Claude Code mempertahankan model saat ini dan melaporkan bahwa hook PreModelSwitch memblokir pergantian, dengan pesan Anda sebagai alasannya.
3625 3651
3626<h4 id="premodelswitch-input">3652<h4 id="premodelswitch-input">
3627 Input PreModelSwitch3653 Input PreModelSwitch
3628</h4>3654</h4>
3629 3655
3630Selain [kolom input umum](#common-input-fields), hook PreModelSwitch menerima kolom-kolom dalam tabel ini. Lima kolom terakhir menjelaskan biaya pengiriman ulang percakapan ke model baru, sehingga hook dapat menampilkan angka tersebut sebelum peralihan terjadi.3656Selain [field input umum](#common-input-fields), hook PreModelSwitch menerima field dalam tabel ini. Lima field terakhir menjelaskan biaya pengiriman ulang percakapan ke model baru, sehingga hook dapat menampilkan angka tersebut sebelum pergantian terjadi.
3631 3657
3632| Kolom | Tipe | Deskripsi |3658| Field | Tipe | Deskripsi |
3633| :- | :- | :- |3659| :- | :- | :- |
3634| `from_model` | string | ID model asal peralihan |3660| `from_model` | string | ID model asal pergantian |
3635| `to_model` | string | ID model tujuan peralihan. Matcher membandingkan dengan nama kanonis model ini |3661| `to_model` | string | ID model tujuan pergantian. Matcher membandingkan dengan nama kanonis model ini |
3636| `requested_model` | string atau `null` | Model yang disebutkan dalam permintaan: alias seperti `opus`, ID model lengkap, atau `null` ketika permintaan ditujukan untuk model default |3662| `requested_model` | string atau `null` | Model yang disebutkan dalam permintaan: alias seperti `opus`, ID model lengkap, atau `null` ketika permintaan ditujukan untuk model default |
3637| `source` | string | Asal permintaan: `"command"` untuk `/model <name>`, pengaturan Model di `/config`, atau mengaktifkan fast mode; `"picker"` untuk pemilih model; `"sdk"` untuk permintaan `set_model`, atau perubahan model dalam permintaan `apply_flag_settings`, dari host Agent SDK atau Remote Control |3663| `source` | string | Asal permintaan: `"command"` untuk `/model <name>`, pengaturan Model di `/config`, atau mengaktifkan fast mode; `"picker"` untuk pemilih model; `"sdk"` untuk permintaan `set_model`, atau perubahan model dalam permintaan `apply_flag_settings`, dari host Agent SDK atau Remote Control |
3638| `context_tokens` | number | Token yang dikirim ulang oleh permintaan berikutnya sebagai prompt-nya: gabungan token input, cache read, cache creation, dan output dari respons terakhir dalam percakapan utama. `0` sebelum respons pertama |3664| `context_tokens` | number | Token yang dikirim ulang oleh permintaan berikutnya sebagai prompt-nya: gabungan token input, cache read, cache creation, dan output dari respons terakhir di percakapan utama. `0` sebelum respons pertama |
3639| `prompt_cache_warm` | boolean | Apakah cache prompt model saat ini kemungkinan masih hangat, yang berarti peralihan akan mengorbankannya |3665| `prompt_cache_warm` | boolean | Apakah prompt cache model saat ini kemungkinan masih hangat, yang berarti pergantian akan mengorbankannya |
3640| `cache_ttl` | string | [Masa berlaku cache prompt](/docs/id/prompt-caching#cache-lifetime) yang diminta Claude Code untuk sesi ini: `"5m"` atau `"1h"` |3666| `cache_ttl` | string | [Masa berlaku prompt cache](/docs/id/prompt-caching#cache-lifetime) yang diminta Claude Code untuk sesi ini: `"5m"` atau `"1h"` |
3641| `estimated_cache_write_usd` | number | Perkiraan biaya dalam dolar AS untuk menulis `context_tokens` ke cache prompt pada `to_model` dengan tarif `cache_ttl`, tidak termasuk respons berikutnya. Server mungkin tidak perlu melakukan cache ulang seluruh konteks, jadi perlakukan angka ini sebagai perkiraan |3667| `estimated_cache_write_usd` | number | Estimasi biaya dalam dolar AS untuk menulis `context_tokens` ke prompt cache pada `to_model` dengan tarif `cache_ttl`, tidak termasuk respons berikutnya. Server mungkin tidak perlu melakukan cache ulang seluruh konteks, jadi anggap ini sebagai estimasi |
3642| `pricing` | string | Cara Claude Code menghitung harga `estimated_cache_write_usd`: `"configured"` dengan tarif milik organisasi Anda sendiri jika organisasi telah mengonfigurasinya, `"catalog"` dengan harga daftar, atau `"default"` ketika `to_model` tidak memiliki harga yang diketahui dan Claude Code mengasumsikan tarif default |3668| `pricing` | string | Cara Claude Code menghitung harga `estimated_cache_write_usd`: `"configured"` dengan tarif organisasi Anda sendiri ketika organisasi telah mengonfigurasinya, `"catalog"` dengan harga daftar, atau `"default"` ketika `to_model` tidak memiliki harga yang diketahui dan Claude Code mengasumsikan tarif default |
3643 3669
3644Contoh ini menunjukkan input untuk `/model opus` dalam sesi yang menjalankan Sonnet 5:3670Contoh ini menunjukkan input untuk `/model opus` dalam sesi yang menjalankan Sonnet 5:
3645 3671
3665 Kontrol keputusan PreModelSwitch3691 Kontrol keputusan PreModelSwitch
3666</h4>3692</h4>
3667 3693
3668Hook `PreModelSwitch` dapat membatalkan peralihan, meminta pengguna untuk mengonfirmasinya, atau membiarkannya berlanjut. Exit code 2 atau `decision: "block"` tingkat atas membatalkan peralihan.3694Hook `PreModelSwitch` dapat membatalkan pergantian, meminta pengguna untuk mengonfirmasinya, atau membiarkannya berlanjut. Exit code 2 atau `decision: "block"` tingkat atas membatalkan pergantian.
3669 3695
3670Untuk kontrol yang lebih rinci, kembalikan `permissionDecision` dan `permissionDecisionReason` dalam objek `hookSpecificOutput`, seperti pada [PreToolUse](#pretooluse-decision-control). `PreModelSwitch` menerima `"allow"`, `"deny"`, dan `"ask"`. Hook ini tidak menerima `"defer"`, `updatedInput`, atau `additionalContext`. Tabel di bawah menjelaskan kedua kolom:3696Untuk kontrol yang lebih rinci, kembalikan `permissionDecision` dan `permissionDecisionReason` dalam objek `hookSpecificOutput`, seperti pada [PreToolUse](#pretooluse-decision-control). `PreModelSwitch` menerima `"allow"`, `"deny"`, dan `"ask"`. Hook ini tidak menerima `"defer"`, `updatedInput`, atau `additionalContext`. Tabel di bawah menjelaskan kedua field tersebut:
3671 3697
3672| Kolom | Deskripsi |3698| Field | Deskripsi |
3673| :- | :- |3699| :- | :- |
3674| `permissionDecision` | `"allow"` melanjutkan dan melewati [konfirmasi yang ditampilkan Claude Code selama cache prompt masih hangat](/docs/id/prompt-caching#switching-models). `"deny"` membatalkan peralihan. `"ask"` meminta pengguna untuk mengonfirmasinya |3700| `permissionDecision` | `"allow"` melanjutkan dan melewati [konfirmasi yang ditampilkan Claude Code saat prompt cache masih hangat](/docs/id/prompt-caching#switching-models). `"deny"` membatalkan pergantian. `"ask"` meminta pengguna untuk mengonfirmasinya |
3675| `permissionDecisionReason` | Untuk `"deny"`, ditampilkan kepada pengguna sebagai alasan peralihan diblokir, atau dikembalikan sebagai error untuk permintaan `set_model`. Untuk `"ask"`, ditampilkan dalam dialog konfirmasi. Diabaikan untuk `"allow"` |3701| `permissionDecisionReason` | Untuk `"deny"`, ditampilkan kepada pengguna sebagai alasan pergantian diblokir, atau dikembalikan sebagai error untuk permintaan `set_model`. Untuk `"ask"`, ditampilkan di dialog konfirmasi. Diabaikan untuk `"allow"` |
3676 3702
3677Hanya `/model` dalam sesi interaktif yang dapat menampilkan dialog `"ask"`. Pada setiap surface lainnya, termasuk mode non-interaktif dengan flag `-p`, `/config`, dan permintaan `set_model`, Claude Code memperlakukan `"ask"` sebagai penolakan.3703Hanya `/model` dalam sesi interaktif yang dapat menampilkan dialog `"ask"`. Pada setiap surface lain, termasuk mode non-interaktif dengan flag `-p`, `/config`, dan permintaan `set_model`, Claude Code memperlakukan `"ask"` sebagai penolakan.
3678 3704
3679Contoh ini meminta pengguna untuk mengonfirmasi dan mengutip jumlah token dari `context_tokens`:3705Contoh ini meminta pengguna untuk mengonfirmasi dan mengutip jumlah token dari `context_tokens`:
3680 3706
3688}3714}
3689```3715```
3690 3716
3691Ketika beberapa hook PreModelSwitch mengembalikan keputusan yang berbeda, urutan prioritasnya adalah `deny` > `ask` > `allow`.3717Ketika beberapa hook PreModelSwitch mengembalikan keputusan berbeda, urutan prioritasnya adalah `deny` > `ask` > `allow`.
3692 3718
3693Claude Code menampilkan kepada pengguna `systemMessage` apa pun yang dikembalikan hook Anda terlepas dari keputusannya, sehingga hook pelaporan biaya dapat mengembalikan `{"systemMessage": "..."}` dan keluar dengan 0.3719Claude Code menampilkan kepada pengguna setiap `systemMessage` yang dikembalikan hook Anda terlepas dari keputusannya, sehingga hook pelaporan biaya dapat mengembalikan `{"systemMessage": "..."}` dan keluar dengan 0.
3694 3720
3695Hook PreModelSwitch yang tidak merespons sebelum timeout-nya akan memblokir pergantian. Untuk apa yang dilakukan timeout pada event lain, lihat [Timeout](#timeouts). Timeout default untuk event ini adalah 30 detik. `PreModelSwitch` hanya menjalankan hook `command`, `http`, dan `mcp_tool`, sehingga default `prompt` dan `agent` tidak berlaku.3721Hook PreModelSwitch yang tidak merespons sebelum timeout-nya akan memblokir pergantian. Untuk efek timeout pada event lain, lihat [Timeouts](#timeouts). Timeout default untuk event ini adalah 30 detik. `PreModelSwitch` hanya menjalankan hook `command`, `http`, dan `mcp_tool`, sehingga default `prompt` dan `agent` tidak berlaku.
3696 3722
3697Hook yang keluar dengan kode selain 0 atau 2 dan tidak mencetak keputusan JSON merupakan error yang tidak memblokir, seperti yang dijelaskan di [Exit code lainnya](#other-exit-codes).3723Hook yang keluar dengan kode selain 0 atau 2 dan tidak mencetak keputusan JSON merupakan error non-blocking, seperti dijelaskan di [Exit code lainnya](#other-exit-codes).
3698 3724
3699<h3 id="postmodelswitch">3725<h3 id="postmodelswitch">
3700 PostModelSwitch3726 PostModelSwitch
3701</h3>3727</h3>
3702 3728
3703Berjalan setelah model sesi berubah. Gunakan untuk memberi Claude panduan khusus model tanpa mengedit setiap CLAUDE.md, misalnya instruksi tingkat organisasi yang berlaku pada model tertentu.3729Berjalan setelah model sesi berubah. Gunakan untuk memberikan panduan khusus model kepada Claude tanpa mengedit setiap CLAUDE.md, misalnya instruksi tingkat organisasi yang berlaku pada model tertentu.
3704 3730
3705PostModelSwitch memerlukan Claude Code v2.1.251 atau lebih baru. Hook ini tidak dapat memblokir, karena model sudah berubah. Claude Code menjalankan hook PostModelSwitch setelah salah satu perubahan berikut:3731PostModelSwitch memerlukan Claude Code v2.1.251 atau yang lebih baru. Hook ini tidak dapat memblokir, karena model sudah berubah. Claude Code menjalankan hook PostModelSwitch setelah salah satu perubahan berikut:
3706 3732
3707* Peralihan yang diminta oleh Anda atau klien3733* Pergantian yang diminta oleh Anda atau klien
3708* [Fallback model otomatis](/docs/id/model-config#automatic-model-fallback), yang mengubah model sesi3734* [Fallback model otomatis](/docs/id/model-config#automatic-model-fallback), yang mengubah model sesi
3709* Pengaturan seperti [`opusplan`](/docs/id/model-config#opusplan-model-setting) yang masuk atau keluar dari plan mode3735* Pengaturan seperti [`opusplan`](/docs/id/model-config#opusplan-model-setting) yang masuk atau keluar dari plan mode
3710* Claude Code memulihkan model saat Anda melanjutkan sesi3736* Claude Code memulihkan model ketika Anda melanjutkan sesi
3711 3737
3712Claude Code tidak menjalankan hook PostModelSwitch ketika model dari [rantai model fallback](/docs/id/model-config#fallback-model-chains) melayani satu giliran, karena substitusi tersebut hanya berlangsung satu giliran dan tidak mengubah model sesi.3738Claude Code tidak menjalankan hook PostModelSwitch ketika model dari [rantai model fallback](/docs/id/model-config#fallback-model-chains) melayani suatu giliran, karena penggantian tersebut hanya berlangsung satu giliran dan tidak mengubah model sesi.
3713 3739
3714Matcher mengikuti aturan yang sama seperti [PreModelSwitch](#premodelswitch): Claude Code membandingkannya dengan nama kanonis model yang menjadi tujuan peralihan sesi.3740Matcher mengikuti aturan yang sama seperti [PreModelSwitch](#premodelswitch): Claude Code membandingkannya dengan nama kanonis model yang menjadi tujuan pergantian sesi.
3715 3741
3716Contoh ini menambahkan panduan setiap kali model sesi berubah ke model Opus mana pun:3742Contoh ini menambahkan panduan setiap kali model sesi berubah ke model Opus apa pun:
3717 3743
3718```json theme={null}3744```json theme={null}
3719{3745{
3739 Input PostModelSwitch3765 Input PostModelSwitch
3740</h4>3766</h4>
3741 3767
3742Hook PostModelSwitch menerima kolom yang sama seperti [PreModelSwitch](#premodelswitch-input), dengan `hook_event_name` diatur ke `"PostModelSwitch"` dan dua nilai `source` tambahan: `"auto"` untuk fallback otomatis atau perubahan lain yang dilakukan Claude Code sendiri, dan `"resume"` untuk model yang dipulihkan saat Anda melanjutkan sesi.3768Hook PostModelSwitch menerima field yang sama seperti [PreModelSwitch](#premodelswitch-input), dengan `hook_event_name` diatur ke `"PostModelSwitch"` dan dua nilai `source` tambahan: `"auto"` untuk fallback otomatis atau perubahan lain yang dilakukan Claude Code sendiri, dan `"resume"` untuk model yang dipulihkan ketika Anda melanjutkan sesi.
3743 3769
3744`requested_model` bernilai `null` ketika `source` adalah `"auto"`. Ketika `source` adalah `"resume"`, nilainya adalah pengaturan model tersimpan yang dipulihkan Claude Code.3770`requested_model` bernilai `null` ketika `source` adalah `"auto"`. Ketika `source` adalah `"resume"`, nilainya adalah pengaturan model tersimpan yang dipulihkan Claude Code.
3745 3771
3747 Kontrol keputusan PostModelSwitch3773 Kontrol keputusan PostModelSwitch
3748</h4>3774</h4>
3749 3775
3750Claude Code mengambil [stdout teks biasa](#exit-code-0) hook Anda saat keluar dengan 0, atau `additionalContext` dari output JSON, dan menyampaikannya kepada Claude bersama permintaan berikutnya setelah peralihan. Selain [kolom output JSON](#json-output) yang tersedia untuk semua hook, Anda dapat mengembalikan:3776Claude Code mengambil [stdout teks biasa](#exit-code-0) hook Anda saat keluar dengan 0, atau `additionalContext` dari output JSON, dan mengirimkannya ke Claude bersama permintaan berikutnya setelah pergantian. Selain [field output JSON](#json-output) yang tersedia untuk semua hook, Anda dapat mengembalikan:
3751 3777
3752| Kolom | Deskripsi |3778| Field | Deskripsi |
3753| :- | :- |3779| :- | :- |
3754| `additionalContext` | String yang ditambahkan ke konteks Claude bersama permintaan berikutnya. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |3780| `additionalContext` | String yang ditambahkan ke konteks Claude bersama permintaan berikutnya. Lihat [Menambahkan konteks untuk Claude](#add-context-for-claude) |
3755 3781
3756Jika hook belum selesai dalam lima detik setelah Anda mengirim prompt berikutnya, Claude Code mengirim permintaan tersebut tanpa output dan melampirkannya ke permintaan setelahnya. Jika model berubah beberapa kali sebelum permintaan berikutnya, Claude Code hanya menyampaikan output untuk model tujuan peralihan terakhir.3782Jika hook belum selesai dalam lima detik setelah Anda mengirim prompt berikutnya, Claude Code mengirim permintaan tersebut tanpa output dan melampirkannya ke permintaan berikutnya. Jika model berubah beberapa kali sebelum permintaan berikutnya, Claude Code hanya mengirimkan output untuk model target pergantian terakhir.
3757 3783
3758<h3 id="sessionend">3784<h3 id="sessionend">
3759 SessionEnd3785 SessionEnd
3760</h3>3786</h3>
3761 3787
3762Berjalan saat sesi Claude Code berakhir. Berguna untuk tugas pembersihan, mencatat statistik3788Berjalan ketika sesi Claude Code berakhir. Berguna untuk tugas pembersihan, mencatat statistik
3763sesi, atau menyimpan status sesi. Mendukung matcher untuk memfilter berdasarkan alasan keluar.3789sesi, atau menyimpan state sesi. Mendukung matcher untuk memfilter berdasarkan alasan keluar.
3764 3790
3765Kolom `reason` dalam input hook menunjukkan mengapa sesi berakhir:3791Field `reason` dalam input hook menunjukkan mengapa sesi berakhir:
3766 3792
3767| Alasan | Deskripsi |3793| Reason | Deskripsi |
3768| :- | :- |3794| :- | :- |
3769| `clear` | Sesi dibersihkan dengan perintah `/clear` |3795| `clear` | Sesi dibersihkan dengan perintah `/clear` |
3770| `resume` | Sesi dialihkan melalui `/resume` interaktif |3796| `resume` | Sesi dialihkan melalui `/resume` interaktif |
3771| `logout` | Pengguna keluar (log out) |3797| `logout` | Pengguna keluar (log out) |
3772| `prompt_input_exit` | Pengguna keluar saat input prompt terlihat |3798| `prompt_input_exit` | Pengguna keluar saat input prompt sedang terlihat |
3773| `other` | Alasan keluar lainnya |3799| `other` | Alasan keluar lainnya |
3774| `bypass_permissions_disabled` | Dihapus di v2.1.234; Claude Code tidak mengirimkannya. Hapus dari matcher `SessionEnd` Anda |3800| `bypass_permissions_disabled` | Dihapus di v2.1.234; Claude Code tidak mengirimkannya. Hapus dari matcher `SessionEnd` Anda |
3775 3801
3777 Input SessionEnd3803 Input SessionEnd
3778</h4>3804</h4>
3779 3805
3780Selain [kolom input umum](#common-input-fields), hook SessionEnd menerima kolom `reason` yang menunjukkan mengapa sesi berakhir. Lihat [tabel alasan](#sessionend) di atas untuk semua nilai.3806Selain [field input umum](#common-input-fields), hook SessionEnd menerima field `reason` yang menunjukkan mengapa sesi berakhir. Lihat [tabel reason](#sessionend) di atas untuk semua nilai.
3781 3807
3782```json theme={null}3808```json theme={null}
3783{3809{
3789}3815}
3790```3816```
3791 3817
3792Hook SessionEnd tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir penghentian sesi tetapi dapat melakukan tugas pembersihan. Claude Code membuang [kolom output JSON](#json-output) mereka, seperti `systemMessage`.3818Hook SessionEnd tidak memiliki kontrol keputusan. Hook ini tidak dapat memblokir penghentian sesi tetapi dapat melakukan tugas pembersihan. Claude Code membuang [field output JSON](#json-output)-nya, seperti `systemMessage`.
3793 3819
3794Hook SessionEnd memiliki timeout default 1,5 detik. Timeout ini berlaku saat Anda keluar, menjalankan `/clear`, atau beralih sesi dengan `/resume` interaktif. Anda dapat memberi hook lebih banyak waktu dengan dua cara:3820Hook SessionEnd memiliki timeout default 1,5 detik. Ini berlaku ketika Anda keluar, menjalankan `/clear`, atau beralih sesi dengan `/resume` interaktif. Anda dapat memberi hook lebih banyak waktu dengan dua cara:
3795 3821
3796* **`timeout` per hook**: atur `timeout` dalam konfigurasi hook tersebut. Anggaran keseluruhan naik secara otomatis agar sesuai dengan `timeout` per hook tertinggi di file pengaturan Anda, hingga 60 detik. Jika Anda menaikkan anggaran dengan cara ini, hook tanpa `timeout`-nya sendiri tetap menggunakan default. Timeout yang diatur pada hook yang disediakan plugin tidak menaikkan anggaran.3822* **`timeout` per hook**: atur `timeout` dalam konfigurasi hook tersebut. Anggaran keseluruhan naik secara otomatis untuk menyamai `timeout` per hook tertinggi di file pengaturan Anda, hingga 60 detik. Jika Anda menaikkan anggaran dengan cara ini, hook tanpa `timeout` sendiri tetap menggunakan default. Timeout yang diatur pada hook yang disediakan plugin tidak menaikkan anggaran.
3797* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: atur environment variable ini dalam milidetik untuk menimpa anggaran secara eksplisit. Nilai yang Anda atur juga menjadi timeout untuk setiap hook tanpa `timeout`-nya sendiri.3823* **`CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS`**: atur environment variable ini dalam milidetik untuk menimpa anggaran secara eksplisit. Nilai yang Anda atur juga menjadi timeout untuk setiap hook tanpa `timeout` sendiri.
3798 3824
3799Contoh ini mengatur anggaran menjadi 5 detik:3825Contoh ini mengatur anggaran menjadi 5 detik:
3800 3826
3802CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude3828CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude
3803```3829```
3804 3830
3805Sebelum v2.1.268, `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` hanya menaikkan anggaran keseluruhan, dan hook tanpa `timeout`-nya sendiri tetap dibatalkan setelah 1,5 detik.3831Sebelum v2.1.268, `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` hanya menaikkan anggaran keseluruhan, dan hook tanpa `timeout` sendiri tetap dibatalkan setelah 1,5 detik.
3806 3832
3807<h3 id="elicitation">3833<h3 id="elicitation">
3808 Elicitation3834 Elicitation
3809</h3>3835</h3>
3810 3836
3811Berjalan saat server MCP meminta input pengguna di tengah tugas. Secara default, Claude Code menampilkan dialog interaktif agar pengguna merespons. Hook dapat mencegat permintaan ini dan merespons secara terprogram, sehingga melewati dialog sepenuhnya.3837Berjalan ketika server MCP meminta input pengguna di tengah tugas. Secara default, Claude Code menampilkan dialog interaktif agar pengguna merespons. Hook dapat mencegat permintaan ini dan merespons secara terprogram, melewati dialog sepenuhnya.
3812 3838
3813Untuk hook lengkap beserta entri pengaturan dan skripnya, lihat [Menjawab permintaan formulir dari skrip](#answer-a-form-request-from-a-script).3839Untuk hook lengkap beserta entri pengaturan dan skripnya, lihat [Menjawab permintaan formulir dari skrip](#answer-a-form-request-from-a-script).
3814 3840
3815Kolom matcher dicocokkan dengan nama server MCP.3841Field matcher dicocokkan dengan nama server MCP.
3816 3842
3817<h4 id="elicitation-input">3843<h4 id="elicitation-input">
3818 Input Elicitation3844 Input Elicitation
3819</h4>3845</h4>
3820 3846
3821Selain [kolom input umum](#common-input-fields), hook Elicitation menerima `mcp_server_name`, `message`, serta kolom opsional `mode`, `url`, `elicitation_id`, dan `requested_schema`.3847Selain [field input umum](#common-input-fields), hook Elicitation menerima `mcp_server_name`, `message`, serta field opsional `mode`, `url`, `elicitation_id`, dan `requested_schema`.
3822 3848
3823Untuk elicitation mode formulir, kasus yang paling umum:3849Untuk elicitation mode formulir, kasus yang paling umum:
3824 3850
3859 Output Elicitation3885 Output Elicitation
3860</h4>3886</h4>
3861 3887
3862Hook Elicitation dapat menjawab permintaan atas nama pengguna, menolak atau membatalkannya, atau menyerahkannya ke dialog. Untuk menjawab, menolak, atau membatalkan, keluar dengan 0 dan cetak objek `hookSpecificOutput` dengan `action`. Server mendapatkan jawaban Anda dan tidak ada dialog yang muncul. Setiap baris tabel ini menunjukkan apa yang harus dikembalikan untuk satu hasil dan apa yang diterima server MCP:3888Hook Elicitation dapat menjawab permintaan atas nama pengguna, menolak atau membatalkannya, atau menyerahkannya ke dialog. Untuk menjawab, menolak, atau membatalkan, keluar dengan 0 dan cetak objek `hookSpecificOutput` dengan `action`. Server menerima jawaban Anda dan tidak ada dialog yang muncul. Setiap baris tabel ini menunjukkan apa yang dikembalikan untuk satu hasil dan apa yang diterima server MCP:
3863 3889
3864| Untuk | Kembalikan | Yang diterima server |3890| Untuk | Kembalikan | Server menerima |
3865| :- | :- | :- |3891| :- | :- | :- |
3866| Menjawab atas nama pengguna | `"action": "accept"`, dengan nilai kolom formulir di `content` | `accept` dengan `content` Anda |3892| Menjawab atas nama pengguna | `"action": "accept"`, dengan nilai field formulir di `content` | `accept` dengan `content` Anda |
3867| Menolak permintaan | `"action": "decline"` | `decline` |3893| Menolak permintaan | `"action": "decline"` | `decline` |
3868| Membatalkan permintaan | `"action": "cancel"` | `cancel` |3894| Membatalkan permintaan | `"action": "cancel"` | `cancel` |
3869| Menyerahkan permintaan kepada pengguna | Tanpa output, dengan exit code 0 | Jawaban pengguna dari [dialog](/docs/id/mcp#respond-to-mcp-elicitation-requests) |3895| Menyerahkan permintaan kepada pengguna | Tanpa output, dengan exit code 0 | Jawaban pengguna dari [dialog](/docs/id/mcp#respond-to-mcp-elicitation-requests) |
3870 3896
3871Output ini menjawab permintaan mode formulir yang ditampilkan di [Input Elicitation](#elicitation-input). Kunci di `content` adalah nama properti dari `requested_schema` permintaan tersebut:3897Output ini menjawab permintaan mode formulir yang ditampilkan di [Input Elicitation](#elicitation-input). Kunci dalam `content` adalah nama properti dari `requested_schema` permintaan tersebut:
3872 3898
3873```json theme={null}3899```json theme={null}
3874{3900{
3893}3919}
3894```3920```
3895 3921
3896Di dialog, memilih **Decline** mengirim `decline` dan menekan `Esc` mengirim `cancel`, jadi kembalikan yang ingin Anda tampilkan kepada server.3922Di dialog, memilih **Decline** mengirim `decline` dan menekan `Esc` mengirim `cancel`, jadi kembalikan yang ingin Anda tampilkan ke server.
3897 3923
3898Untuk permintaan mode URL, hook yang mengembalikan `accept` melewati dialog, sehingga URL tidak pernah dibuka.3924Untuk permintaan mode URL, hook yang mengembalikan `accept` melewati dialog, sehingga URL tidak pernah dibuka.
3899 3925
3903 Cara lain untuk menolak elicitation3929 Cara lain untuk menolak elicitation
3904</h4>3930</h4>
3905 3931
3906Hook Anda juga dapat menolak dengan cara-cara berikut. Server menerima `decline` yang sama seperti untuk `"action": "decline"`:3932Hook Anda juga dapat menolak dengan cara berikut. Server menerima `decline` yang sama seperti untuk `"action": "decline"`:
3907 3933
3908* **Keluar dengan kode 2**: Claude Code mengabaikan `hookSpecificOutput` yang dicetak oleh hook yang sama3934* **Keluar dengan kode 2**: Claude Code mengabaikan `hookSpecificOutput` yang dicetak oleh hook yang sama
3909* **Mencetak `"decision": "block"` tingkat atas**: blokir tersebut menimpa `action` dalam output yang sama3935* **Mencetak `"decision": "block"` tingkat atas**: block menimpa `action` dalam output yang sama
3910 3936
3911Ketika beberapa hook cocok dengan permintaan yang sama, penolakan dari salah satunya menimpa `accept` atau `cancel` dari yang lain.3937Ketika beberapa hook cocok dengan permintaan yang sama, penolakan dari salah satunya menimpa `accept` atau `cancel` dari hook lain.
3912 3938
3913Skrip ini menolak permintaan mode URL dan menyerahkan permintaan formulir ke dialog:3939Skrip ini menolak permintaan mode URL dan menyerahkan permintaan formulir ke dialog:
3914 3940
3927 Menjawab permintaan formulir dari skrip3953 Menjawab permintaan formulir dari skrip
3928</h4>3954</h4>
3929 3955
3930Contoh ini menjawab satu pertanyaan berulang atas nama pengguna. Server MCP bernama `issue-tracker` meminta kunci proyek dalam formulir, dan hook mengisi `DOCS`. Skrip menerima ketika `project_key` adalah satu-satunya kolom formulir. Untuk permintaan lainnya, skrip tidak mencetak apa pun, sehingga dialog muncul.3956Contoh ini menjawab satu pertanyaan berulang atas nama pengguna. Server MCP bernama `issue-tracker` meminta kunci proyek dalam formulir, dan hook mengisinya dengan `DOCS`. Skrip menerima ketika `project_key` adalah satu-satunya field formulir. Untuk permintaan lainnya, skrip tidak mencetak apa pun, sehingga dialog muncul.
3931 3957
3932<Tabs>3958<Tabs>
3933 <Tab title="macOS/Linux">3959 <Tab title="macOS/Linux">
3934 Daftarkan hook perintah untuk event tersebut di file pengaturan Anda, dengan nama server sebagai matcher:3960 Daftarkan hook command untuk event ini di file pengaturan Anda, dengan nama server sebagai matcher:
3935 3961
3936 ```json theme={null}3962 ```json theme={null}
3937 {3963 {
3966 </Tab>3992 </Tab>
3967 3993
3968 <Tab title="Windows (PowerShell)">3994 <Tab title="Windows (PowerShell)">
3969 Daftarkan hook perintah yang menjalankan skrip melalui PowerShell, dengan nama server sebagai matcher:3995 Daftarkan hook command yang menjalankan skrip melalui PowerShell, dengan nama server sebagai matcher:
3970 3996
3971 ```json theme={null}3997 ```json theme={null}
3972 {3998 {
4012 </Tab>4038 </Tab>
4013</Tabs>4039</Tabs>
4014 4040
4015Untuk memastikan hook berfungsi, jalankan Claude Code dengan `claude --debug` dan berikan Claude tugas yang membuat server meminta kunci proyek. Tidak ada dialog yang muncul, dan [log debug](#debug-hooks) memiliki baris yang diakhiri dengan `Elicitation resolved by hook: {"action":"accept","content":{"project_key":"DOCS"}}`.4041Untuk memastikan hook berfungsi, mulai Claude Code dengan `claude --debug` dan berikan Claude tugas yang membuat server meminta kunci proyek. Tidak ada dialog yang muncul, dan [log debug](#debug-hooks) memiliki baris yang diakhiri dengan `Elicitation resolved by hook: {"action":"accept","content":{"project_key":"DOCS"}}`.
4016 4042
4017<h3 id="elicitationresult">4043<h3 id="elicitationresult">
4018 ElicitationResult4044 ElicitationResult
4020 4046
4021Berjalan setelah pengguna merespons elicitation MCP. Hook dapat mengamati, memodifikasi, atau memblokir respons sebelum dikirim kembali ke server MCP.4047Berjalan setelah pengguna merespons elicitation MCP. Hook dapat mengamati, memodifikasi, atau memblokir respons sebelum dikirim kembali ke server MCP.
4022 4048
4023Ketika hook [Elicitation](#elicitation) menjawab permintaan, Claude Code mengirim jawaban tersebut ke server tanpa menjalankan hook ElicitationResult.4049Ketika hook [Elicitation](#elicitation) menjawab suatu permintaan, Claude Code mengirim jawaban tersebut ke server tanpa menjalankan hook ElicitationResult.
4024 4050
4025Kolom matcher dicocokkan dengan nama server MCP.4051Field matcher dicocokkan dengan nama server MCP.
4026 4052
4027<h4 id="elicitationresult-input">4053<h4 id="elicitationresult-input">
4028 Input ElicitationResult4054 Input ElicitationResult
4029</h4>4055</h4>
4030 4056
4031Selain [kolom input umum](#common-input-fields), hook ElicitationResult menerima `mcp_server_name`, `action`, serta kolom opsional `mode`, `elicitation_id`, dan `content`.4057Selain [field input umum](#common-input-fields), hook ElicitationResult menerima `mcp_server_name`, `action`, serta field opsional `mode`, `elicitation_id`, dan `content`.
4032 4058
4033```json theme={null}4059```json theme={null}
4034{4060{
4047 Output ElicitationResult4073 Output ElicitationResult
4048</h4>4074</h4>
4049 4075
4050Hook ElicitationResult dapat meloloskan respons pengguna, mengubah nilainya, atau memblokirnya. Untuk mengubah atau memblokir respons, keluar dengan 0 dan cetak objek `hookSpecificOutput` dengan `action`. Setiap baris tabel ini menunjukkan apa yang harus dikembalikan untuk satu hasil dan apa yang diterima server MCP:4076Hook ElicitationResult dapat meloloskan respons pengguna, mengubah nilainya, atau memblokirnya. Untuk mengubah atau memblokir respons, keluar dengan 0 dan cetak objek `hookSpecificOutput` dengan `action`. Setiap baris tabel ini menunjukkan apa yang dikembalikan untuk satu hasil dan apa yang diterima server MCP:
4051 4077
4052| Untuk | Kembalikan | Yang diterima server |4078| Untuk | Kembalikan | Server menerima |
4053| :- | :- | :- |4079| :- | :- | :- |
4054| Meloloskan respons | Tanpa output, dengan exit code 0 | Respons pengguna, tanpa perubahan |4080| Meloloskan respons | Tanpa output, dengan exit code 0 | Respons pengguna, tanpa perubahan |
4055| Mengubah nilai yang dikirim | `"action": "accept"`, dengan nilai baru di `content` | `accept` dengan `content` Anda sebagai pengganti nilai pengguna |4081| Mengubah nilai yang dikirimkan | `"action": "accept"`, dengan nilai baru di `content` | `accept` dengan `content` Anda sebagai pengganti nilai pengguna |
4056| Memblokir respons | `"action": "decline"` | `decline`, tanpa nilai pengguna |4082| Memblokir respons | `"action": "decline"` | `decline`, tanpa nilai pengguna |
4057| Membatalkan permintaan | `"action": "cancel"` | `cancel`, beserta nilai yang dikirim pengguna. Untuk menahannya, kembalikan `"decline"` |4083| Membatalkan permintaan | `"action": "cancel"` | `cancel`, beserta nilai yang dikirimkan pengguna. Untuk menahannya, kembalikan `"decline"` |
4058 4084
4059Output ini mengubah respons yang ditampilkan di [Input ElicitationResult](#elicitationresult-input), sehingga server menerima `alice@example.com` di tempat pengguna mengirim `alice`:4085Output ini mengubah respons yang ditampilkan di [Input ElicitationResult](#elicitationresult-input), sehingga server menerima `alice@example.com` padahal pengguna mengirimkan `alice`:
4060 4086
4061```json theme={null}4087```json theme={null}
4062{4088{
4070}4096}
4071```4097```
4072 4098
4073`content` Anda menggantikan seluruh objek `content` milik pengguna, jadi sertakan kolom yang tidak Anda ubah. Kembalikan `action` bersamanya, karena Claude Code mengabaikan `hookSpecificOutput` yang tidak memiliki `action`.4099`content` Anda menggantikan seluruh objek `content` pengguna, jadi sertakan field yang tidak Anda ubah. Kembalikan `action` bersamanya, karena Claude Code mengabaikan `hookSpecificOutput` yang tidak memiliki `action`.
4074 4100
4075Hook ElicitationResult juga berjalan ketika pengguna menolak atau membatalkan, dan `action` Anda menggantikan milik mereka. Periksa bahwa `action` pada input adalah `accept` sebelum Anda mengembalikan `accept`, atau hook Anda akan mengubah permintaan yang ditolak menjadi diterima. Skrip ini melakukan perubahan yang sama ketika pengguna menerima, mempertahankan kolom lainnya, dan tidak mencetak apa pun dalam kondisi lain:4101Hook ElicitationResult juga berjalan ketika pengguna menolak atau membatalkan, dan `action` Anda menggantikan milik mereka. Periksa bahwa `action` pada input adalah `accept` sebelum Anda mengembalikan `accept`, atau hook Anda akan mengubah permintaan yang ditolak menjadi diterima. Skrip ini melakukan perubahan yang sama ketika pengguna menerima, mempertahankan field lainnya, dan tidak mencetak apa pun dalam kasus lain:
4076 4102
4077```bash theme={null}4103```bash theme={null}
4078#!/bin/bash4104#!/bin/bash
4351* **Sendirian di stdout**: ketika respons adalah satu-satunya teks di stdout, respons tersebut dapat mencakup beberapa baris, seperti output `jq` yang diformat rapi. Mencakup beberapa baris memerlukan Claude Code v2.1.295 atau yang lebih baru.4377* **Sendirian di stdout**: ketika respons adalah satu-satunya teks di stdout, respons tersebut dapat mencakup beberapa baris, seperti output `jq` yang diformat rapi. Mencakup beberapa baris memerlukan Claude Code v2.1.295 atau yang lebih baru.
4352* **Pada satu barisnya sendiri**: async hook dapat mencetak teks lain ke stdout ketika respons muat dalam satu baris tersendiri, misalnya dengan `jq -c`.4378* **Pada satu barisnya sendiri**: async hook dapat mencetak teks lain ke stdout ketika respons muat dalam satu baris tersendiri, misalnya dengan `jq -c`.
4353 4379
4354Claude Code memvalidasi respons JSON tersebut terhadap [output schema](#json-output) yang sama seperti hooks sinkron, dan menghapus bidang apa pun yang nilainya memiliki tipe yang salah, seperti `systemMessage` yang bukan string, alih-alih menyampaikannya. Jalankan dengan `--debug` untuk melihat peringatan yang menyebutkan setiap bidang yang dihapus. Sebelum v2.1.202, output JSON yang tidak terbentuk dengan baik dari async hook dapat menghancurkan sesi, dan kerusakan terulang setiap kali sesi dilanjutkan.4380Claude Code memvalidasi respons JSON tersebut terhadap [skema output](#json-output) yang sama seperti hooks sinkron, dan menghapus bidang apa pun yang nilainya memiliki tipe yang salah, seperti `systemMessage` yang bukan string, alih-alih menyampaikannya. Jalankan dengan `--debug` untuk melihat peringatan yang menyebutkan setiap bidang yang dihapus.
4355 4381
4356Notifikasi penyelesaian async hook ditekan secara default. Untuk melihatnya, aktifkan mode verbose dengan `Ctrl+O` atau mulai Claude Code dengan `--verbose`.4382Notifikasi penyelesaian async hook ditekan secara default. Untuk melihatnya, aktifkan mode verbose dengan `Ctrl+O` atau mulai Claude Code dengan `--verbose`.
4357 4383