Hooks memungkinkan Anda menyisipkan logika kustom ke dalam alur eksekusi utama Agen pada titik-titik kunci di Qoder CN CLI tanpa harus terikat langsung ke CLI tersebut. Kasus penggunaan umum mencakup mencegat operasi berbahaya sebelum tool dijalankan, mengirim notifikasi desktop saat tugas selesai, atau menjalankan linter secara otomatis setelah menulis file.
Hooks didefinisikan dalam file konfigurasi JSON. Tidak diperlukan perubahan kode; cukup ubah file konfigurasi agar perubahan langsung berlaku.
Quick start
Contoh berikut menunjukkan cara menggunakan Hook untuk mencegat perintah berbahaya—secara otomatis memblokir Agen yang mencoba menjalankan rm -rf.
Langkah 1: Buat skrip
mkdir -p ~/.qoder-cn/hooks
cat > ~/.qoder-cn/hooks/block-rm.sh << 'EOF'
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command')
if echo "$command" | grep -q 'rm -rf'; then
echo "Perintah berbahaya diblokir: $command" >&2
exit 2
fi
exit 0
EOF
chmod +x ~/.qoder-cn/hooks/block-rm.shLangkah 2: Edit file konfigurasi
Pada ~/.qoder-cn/settings.json, tambahkan konfigurasi berikut:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.qoder-cn/hooks/block-rm.sh"
}
]
}
]
}
}Langkah 3: Verifikasi hasilnya
Jalankan Qoder CN CLI dan instruksikan Agen untuk mengeksekusi perintah yang mengandung rm -rf. Hook akan memblokir eksekusi dan memberi prompt kepada Agen.
Konfigurasi
Lokasi file konfigurasi
Konfigurasi Hook dimuat dari ketiga file berikut. Pengaturan dari ketiga level ini akan digabung dan dieksekusi:
~/.qoder-cn/settings.json # Level pengguna: berlaku untuk semua proyek.
${project}/.qoder/settings.json # Level proyek: berlaku untuk proyek saat ini. Dapat dikomit ke Git untuk dibagikan dengan tim Anda.
${project}/.qoder/settings.local.json # Level proyek (lokal): memiliki prioritas tertinggi. Disarankan ditambahkan ke .gitignore.Format konfigurasi
{
"hooks": {
"EventName": [
{
"matcher": "kondisi pencocokan",
"hooks": [
{
"type": "command",
"command": "perintah yang akan dijalankan",
"timeout": 60
}
]
}
]
}
}Deskripsi bidang:
Field | Wajib | Deskripsi |
| Ya | Harus diatur ke |
| Ya | Perintah shell yang akan dijalankan. |
| Tidak | Batas waktu dalam detik. Default: 60. |
| Tidak | Menentukan kondisi pencocokan. Jika dihilangkan, hook berlaku untuk semua instans. |
Anda dapat mengonfigurasi beberapa kelompok matcher di bawah satu event. Setiap kelompok dapat berisi beberapa perintah hook.
Aturan matcher
Bidang matcher menentukan kapan hook dipicu. Setiap event dicocokkan dengan bidang yang berbeda, seperti dijelaskan dalam deskripsinya.
Sintaks | Deskripsi | Contoh |
Dibiarkan kosong atau | Mencocokkan semua. | Dipicu untuk semua tool. |
Nilai eksak | Pencocokan eksak. |
|
Pembatas | Mencocokkan beberapa nilai. |
|
Ekspresi reguler | Pencocokan ekspresi reguler. |
|
Menulis skrip hook
Skrip hook menerima muatan JSON dari standard input (stdin) dan menggunakan kode keluar serta standard output (stdout) untuk mengontrol perilaku. Bagian ini menjelaskan format input dan output umum untuk semua event. Untuk bidang tambahan spesifik event, lihat Event yang Didukung.
Input
Skrip hook menerima data JSON melalui stdin. Input untuk semua event mencakup bidang umum berikut:
Field | Deskripsi |
| ID sesi saat ini. |
| Direktori kerja saat ini. |
| Nama event yang memicu hook. |
Event yang berbeda menambahkan bidang tambahan ke struktur ini (lihat deskripsi masing-masing event). Gunakan jq untuk mengurai input:
#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')Output
Hook mengontrol perilaku melalui kode keluar dan standard output (stdout). Kode keluar menentukan aksi utama: 0 untuk sukses, 2 untuk memblokir operasi (untuk event yang didukung), dan nilai bukan nol lainnya untuk error non-blokir. Untuk beberapa event, objek JSON pada stdout memberikan kontrol detail halus, tetapi hanya diurai jika kode keluar bernilai 0.
Variabel lingkungan
Variabel lingkungan berikut tersedia untuk skrip hook selama eksekusi:
Variabel | Deskripsi |
| Direktori kerja proyek saat ini. |
Event yang didukung
Qoder CN CLI mendukung event hook berikut, yang mencakup berbagai tahap siklus hidup sesi.
SessionStart
Dipicu saat sesi dimulai.
Bidang matcher: Sumber sesi
Nilai matcher | Skenario pemicu |
| Sesi baru dimulai. |
| Sesi yang sudah ada dilanjutkan. |
| Kompaksi konteks selesai. |
Bidang input tambahan:
{
"source": "startup",
"model": "Auto"
}SessionEnd
Dipicu saat sesi berakhir.
Bidang matcher: Alasan berakhir
Nilai matcher | Skenario pemicu |
| Pengguna menutup prompt (misalnya dengan menekan Ctrl+D). |
| Sesi berakhir karena alasan lain. |
Bidang input tambahan:
{
"reason": "prompt_input_exit"
}UserPromptSubmit
Dipicu setelah pengguna mengirimkan prompt tetapi sebelum Agen memprosesnya.
Bidang input tambahan:
{
"prompt": "Tulis fungsi pengurutan untuk saya"
}PreToolUse
Dipicu sebelum tool dijalankan. Hook ini dapat memblokir eksekusi tool.
matcher: Nama tool (seperti Bash, Write, Edit, Read, Glob, Grep, atau nama tool MCP seperti mcp__server__tool)
Bidang input tambahan:
{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf /tmp/build"},
"tool_use_id": "toolu_01ABC123"
}Blokir eksekusi tool: Keluar dengan kode 2. Konten apa pun pada stderr dikembalikan ke Agen sebagai pesan error. Untuk contoh lengkap, lihat bagian Quick start.
PostToolUse
Dipicu setelah tool berhasil dieksekusi.
Bidang matcher: Nama tool
Bidang input tambahan:
{
"tool_name": "Write",
"tool_input": {"file_path": "/path/to/file.ts", "content": "..."},
"tool_response": "File berhasil ditulis",
"tool_use_id": "toolu_01ABC123"
}PostToolUseFailure
Dipicu setelah tool gagal dieksekusi.
Bidang matcher: Nama tool
Bidang input tambahan:
{
"tool_name": "Bash",
"tool_input": {"command": "npm test"},
"tool_use_id": "toolu_01ABC123",
"error": "Perintah keluar dengan kode status bukan nol 1",
"is_interrupt": false
}Stop
Dipicu setelah Agen utama menyelesaikan responsnya dan tidak ada panggilan tool yang tertunda. Anda dapat menggunakan hook ini untuk mencegah Agen berhenti dan meminta Agen untuk terus bekerja.
Cegah Agen berhenti: Keluar dengan kode 2. Sistem kemudian menyisipkan konten apa pun dari stderr ke dalam percakapan sebagai pesan, sehingga meminta Agen untuk terus berjalan.
SubagentStart / SubagentStop
Dipicu saat Subagen dimulai atau dihentikan. Event SubagentStop mirip dengan Stop dan dapat mencegah Subagen berhenti.
Bidang matcher: Nama jenis Agen
Bidang input tambahan:
{
"agent_id": "a1b2c3d4",
"agent_type": "task"
}PreCompact
Dipicu sebelum kompaksi konteks.
Bidang matcher: Metode pemicu
Nilai matcher | Skenario pemicu |
| Pengguna menjalankan |
| Kompaksi dipicu secara otomatis saat jendela konteks penuh. |
Bidang input tambahan:
{
"trigger": "manual",
"custom_instructions": "Pertahankan semua hasil pemanggilan tool"
}Notification
Dipicu untuk event notifikasi, seperti permintaan izin atau penyelesaian tugas.
Bidang matcher: Jenis notifikasi
Nilai matcher | Skenario pemicu |
| Notifikasi permintaan izin. |
| Notifikasi untuk hasil yang dihasilkan oleh Agen. |
Bidang input tambahan:
{
"message": "Agen meminta izin untuk menjalankan: rm -rf node_modules",
"title": "Izin Diperlukan",
"notification_type": "permission"
}PermissionRequest
Dipicu saat tool memerlukan otorisasi pengguna untuk dijalankan.
Bidang matcher: Nama tool
Bidang input tambahan:
{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf node_modules"}
}Kasus penggunaan
Kirim notifikasi desktop
Skrip ini menampilkan notifikasi desktop saat Agen menyelesaikan tugas atau memerlukan otorisasi. Skrip berikut ditujukan untuk macOS dan berada di ~/.qoder-cn/hooks/notify.sh:
#!/bin/bash
input=$(cat)
message=$(echo "$input" | jq -r '.message')
if echo "$message" | grep -q "^Agent"; then
osascript -e 'display notification "Tugas selesai" with title "Qoder CN CLI"'
else
osascript -e 'display notification "Otorisasi diperlukan" with title "Qoder CN CLI"'
fi
exit 0Konfigurasi:
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "~/.qoder-cn/hooks/notify.sh"
}
]
}
]
}
}Lakukan lint otomatis pada file yang dimodifikasi
Skrip ini menjalankan pemeriksaan lint secara otomatis setiap kali Agen menulis atau mengedit file. Skrip berada di ${project}/.qoder-cn/hooks/auto-lint.sh:
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
# Periksa hanya file JS/TS
case "$file_path" in
*.js|*.ts|*.jsx|*.tsx)
npx eslint "$file_path" --fix 2>/dev/null
;;
esac
exit 0Konfigurasi: Atur event ke PostToolUse, matcher ke Write|Edit, dan command ke .qoder-cn/hooks/auto-lint.sh.
Pertahankan Agen tetap berjalan
Skrip ini memeriksa adanya tugas yang belum selesai saat Agen berhenti. Jika ditemukan, skrip menyisipkan pesan untuk meminta Agen melanjutkan pekerjaan. Skrip berada di ~/.qoder-cn/hooks/check-continue.sh:
#!/bin/bash
# Periksa perubahan Git yang belum dikomit
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
echo "Ditemukan perubahan yang belum dikomit. Harap komit perubahan Anda." >&2
exit 2
fi
exit 0Konfigurasi: Atur event ke Stop dan command ke ~/.qoder-cn/hooks/check-continue.sh.