Langsung ke konten utama
Claude Code hooks adalah perintah shell yang ditentukan pengguna yang dieksekusi pada berbagai titik dalam siklus hidup Claude Code. Hooks memberikan kontrol deterministik atas perilaku Claude Code, memastikan tindakan tertentu selalu terjadi daripada mengandalkan LLM untuk memilih menjalankannya.
Untuk dokumentasi referensi tentang hooks, lihat Hooks reference.
Contoh kasus penggunaan untuk hooks meliputi:
  • Notifikasi: Sesuaikan cara Anda mendapatkan pemberitahuan ketika Claude Code menunggu input atau izin Anda untuk menjalankan sesuatu.
  • Pemformatan otomatis: Jalankan prettier pada file .ts, gofmt pada file .go, dll. setelah setiap pengeditan file.
  • Logging: Lacak dan hitung semua perintah yang dieksekusi untuk kepatuhan atau debugging.
  • Umpan balik: Berikan umpan balik otomatis ketika Claude Code menghasilkan kode yang tidak mengikuti konvensi codebase Anda.
  • Izin khusus: Blokir modifikasi ke file produksi atau direktori sensitif.
Dengan mengkodekan aturan-aturan ini sebagai hooks daripada instruksi prompt, Anda mengubah saran menjadi kode tingkat aplikasi yang dieksekusi setiap kali diharapkan untuk berjalan.
Anda harus mempertimbangkan implikasi keamanan dari hooks saat menambahkannya, karena hooks berjalan secara otomatis selama loop agen dengan kredensial lingkungan Anda saat ini. Misalnya, kode hooks yang berbahaya dapat mengekstrak data Anda. Selalu tinjau implementasi hooks Anda sebelum mendaftarkannya.Untuk praktik keamanan terbaik lengkap, lihat Security Considerations dalam dokumentasi referensi hooks.

Ikhtisar Peristiwa Hook

Claude Code menyediakan beberapa peristiwa hook yang berjalan pada titik berbeda dalam alur kerja:
  • PreToolUse: Berjalan sebelum panggilan alat (dapat memblokir mereka)
  • PostToolUse: Berjalan setelah panggilan alat selesai
  • UserPromptSubmit: Berjalan ketika pengguna mengirimkan prompt, sebelum Claude memprosesnya
  • Notification: Berjalan ketika Claude Code mengirim notifikasi
  • Stop: Berjalan ketika Claude Code selesai merespons
  • SubagentStop: Berjalan ketika tugas subagen selesai
  • PreCompact: Berjalan sebelum Claude Code akan menjalankan operasi compact
  • SessionStart: Berjalan ketika Claude Code memulai sesi baru atau melanjutkan sesi yang ada
  • SessionEnd: Berjalan ketika sesi Claude Code berakhir
Setiap peristiwa menerima data berbeda dan dapat mengontrol perilaku Claude dengan cara yang berbeda.

Quickstart

Dalam quickstart ini, Anda akan menambahkan hook yang mencatat perintah shell yang dijalankan Claude Code.

Prasyarat

Instal jq untuk pemrosesan JSON di baris perintah.

Langkah 1: Buka konfigurasi hooks

Jalankan perintah /hooks slash command dan pilih peristiwa hook PreToolUse. Hook PreToolUse berjalan sebelum panggilan alat dan dapat memblokir mereka sambil memberikan umpan balik Claude tentang apa yang harus dilakukan berbeda.

Langkah 2: Tambahkan matcher

Pilih + Add new matcher… untuk menjalankan hook Anda hanya pada panggilan alat Bash. Ketik Bash untuk matcher.
Anda dapat menggunakan * untuk mencocokkan semua alat.

Langkah 3: Tambahkan hook

Pilih + Add new hook… dan masukkan perintah ini:
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt

Langkah 4: Simpan konfigurasi Anda

Untuk lokasi penyimpanan, pilih User settings karena Anda mencatat ke direktori home Anda. Hook ini kemudian akan berlaku untuk semua proyek, bukan hanya proyek Anda saat ini. Kemudian tekan Esc sampai Anda kembali ke REPL. Hook Anda sekarang terdaftar!

Langkah 5: Verifikasi hook Anda

Jalankan /hooks lagi atau periksa ~/.claude/settings.json untuk melihat konfigurasi Anda:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
          }
        ]
      }
    ]
  }
}

Langkah 6: Uji hook Anda

Minta Claude untuk menjalankan perintah sederhana seperti ls dan periksa file log Anda:
cat ~/.claude/bash-command-log.txt
Anda harus melihat entri seperti:
ls - Lists files and directories

Contoh Lainnya

Untuk implementasi contoh lengkap, lihat bash command validator example dalam codebase publik kami.

Hook Pemformatan Kode

Secara otomatis memformat file TypeScript setelah pengeditan:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }"
          }
        ]
      }
    ]
  }
}

Hook Pemformatan Markdown

Secara otomatis memperbaiki tag bahasa yang hilang dan masalah pemformatan dalam file markdown:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/markdown_formatter.py"
          }
        ]
      }
    ]
  }
}
Buat .claude/hooks/markdown_formatter.py dengan konten ini:
#!/usr/bin/env python3
"""
Markdown formatter for Claude Code output.
Fixes missing language tags and spacing issues while preserving code content.
"""
import json
import sys
import re
import os

def detect_language(code):
    """Best-effort language detection from code content."""
    s = code.strip()
    
    # JSON detection
    if re.search(r'^\s*[{\[]', s):
        try:
            json.loads(s)
            return 'json'
        except:
            pass
    
    # Python detection
    if re.search(r'^\s*def\s+\w+\s*\(', s, re.M) or \
       re.search(r'^\s*(import|from)\s+\w+', s, re.M):
        return 'python'
    
    # JavaScript detection  
    if re.search(r'\b(function\s+\w+\s*\(|const\s+\w+\s*=)', s) or \
       re.search(r'=>|console\.(log|error)', s):
        return 'javascript'
    
    # Bash detection
    if re.search(r'^#!.*\b(bash|sh)\b', s, re.M) or \
       re.search(r'\b(if|then|fi|for|in|do|done)\b', s):
        return 'bash'
    
    # SQL detection
    if re.search(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\s+', s, re.I):
        return 'sql'
        
    return 'text'

def format_markdown(content):
    """Format markdown content with language detection."""
    # Fix unlabeled code fences
    def add_lang_to_fence(match):
        indent, info, body, closing = match.groups()
        if not info.strip():
            lang = detect_language(body)
            return f"{indent}```{lang}\n{body}{closing}\n"
        return match.group(0)
    
    fence_pattern = r'(?ms)^([ \t]{0,3})```([^\n]*)\n(.*?)(\n\1```)\s*$'
    content = re.sub(fence_pattern, add_lang_to_fence, content)
    
    # Fix excessive blank lines (only outside code fences)
    content = re.sub(r'\n{3,}', '\n\n', content)
    
    return content.rstrip() + '\n'

# Main execution
try:
    input_data = json.load(sys.stdin)
    file_path = input_data.get('tool_input', {}).get('file_path', '')
    
    if not file_path.endswith(('.md', '.mdx')):
        sys.exit(0)  # Not a markdown file
    
    if os.path.exists(file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        formatted = format_markdown(content)
        
        if formatted != content:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(formatted)
            print(f"✓ Fixed markdown formatting in {file_path}")
    
except Exception as e:
    print(f"Error formatting markdown: {e}", file=sys.stderr)
    sys.exit(1)
Buat skrip dapat dieksekusi:
chmod +x .claude/hooks/markdown_formatter.py
Hook ini secara otomatis:
  • Mendeteksi bahasa pemrograman dalam blok kode tanpa label
  • Menambahkan tag bahasa yang sesuai untuk penyorotan sintaks
  • Memperbaiki baris kosong yang berlebihan sambil mempertahankan konten kode
  • Hanya memproses file markdown (.md, .mdx)

Hook Notifikasi Khusus

Dapatkan notifikasi desktop ketika Claude membutuhkan input:
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' 'Awaiting your input'"
          }
        ]
      }
    ]
  }
}

Hook Perlindungan File

Blokir pengeditan ke file sensitif:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 -c \"import json, sys; data=json.load(sys.stdin); path=data.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(p in path for p in ['.env', 'package-lock.json', '.git/']) else 0)\""
          }
        ]
      }
    ]
  }
}

Pelajari lebih lanjut

  • Untuk dokumentasi referensi tentang hooks, lihat Hooks reference.
  • Untuk praktik keamanan terbaik dan pedoman keselamatan yang komprehensif, lihat Security Considerations dalam dokumentasi referensi hooks.
  • Untuk langkah-langkah pemecahan masalah dan teknik debugging, lihat Debugging dalam dokumentasi referensi hooks.