מדריך קלוד קוד בעברית

פרק 8

הוקים: אוטומציה ואכיפת חוקים

מערכת ה-Hooks של קלוד קוד מריצה אוטומטית פקודות או הערכות בנקודות מוגדרות במחזור החיים שלו. הדבר מעניק שליטה דטרמיניסטית: פעולות מסוימות מתרחשות תמיד, במקום להסתמך על שיקול הדעת של מודל השפה. משתמשים בהוקים כדי לאכוף כללי פרויקט, לאוטמט משימות שגרתיות ולחבר את קלוד קוד לכלים קיימים.

קלוד קוד תומך בחמישה סוגי הוקים: פקודות מעטפת (type: "command"), נקודות קצה של HTTP (type: "http"), קריאות לכלי MCP שכבר מחוברים (type: "mcp_tool"), פרומפטים להערכה חד פעמית מבוססת מודל (type: "prompt"), וסוכנים המריצים בדיקות מרובות שלבים עם גישה לקריאת קבצים וחיפוש בקוד (type: "agent").

קלוד קוד מפעיל את אותם אירועי הוק בכל סביבה שבה הוא רץ: בטרמינל, בהרחבות ה-IDE, באפליקציית השולחן (Desktop), ובסשנים בענן (סביבת הדפדפן). האירועים מתחלקים לשלושה קצבים עיקריים:

  • פעם בכל סשן: SessionStart ו-SessionEnd.
  • פעם בכל תור שיחה: UserPromptSubmit, Stop, ו-StopFailure.
  • בכל קריאה לכלי בלולאת הסוכן: PreToolUse ו-PostToolUse (למעט קריאות לכלי EndConversation, שמדלגות על שניהם).

דרכים נוספות להרחבת קלוד קוד כוללות כישורים (skills) למתן הוראות נוספות ופקודות להרצה, סוכני משנה (subagents) להרצת משימות בהקשרים מבודדים, ותוספים (plugins) לשיתוף הרחבות בין פרויקטים שונים.

לפי התיעוד הרשמי, ספטמבר 2026.


#הגדרת ההוק הראשון שלך

כדי ליצור הוק, מוסיפים בלוק hooks לקובץ הגדרות. ההליך הבא מגדיר הוק להתראות שולחן עבודה, כדי לקבל התראה בכל פעם שקלוד ממתין לקלט במקום לצפות בטרמינל.

  1. הוספת ההוק להגדרות: פתחו את הקובץ ~/.claude/settings.json והוסיפו הוק עבור אירוע Notification. אם הקובץ אינו קיים, צרו אותו. הדוגמה הבאה משתמשת ב-osascript עבור macOS:
{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

אם קובץ ההגדרות כבר כולל מפתח hooks, הוסיפו את Notification לצד מפתחות האירועים הקיימים ולא במקומם. כל שם אירוע הוא מפתח בתוך אובייקט ה-hooks היחיד:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }]
      }
    ],
    "Notification": [
      {
        "matcher": "",
        "hooks": [{ "type": "command", "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'" }]
      }
    ]
  }
}

ניתן גם לבקש מקלוד לכתוב את ההוק על ידי תיאור הפעולה הרצויה ב-CLI.

  1. אימות ההגדרה: הקלידו /hooks כדי לפתוח את תפריט העיון בהוקים. יוצגו כל אירועי ההוק הזמינים, לצד מספר ההוקים המוגדרים לכל אירוע. התפריט מציג את כל חמשת הסוגים (command, prompt, agent, http, mcp_tool) עם קידומת המזהה את מקור ההגדרה: User Settings, Project Settings, Local Settings, Plugin Hooks, או Session Hooks. בחרו ב-Notification כדי לוודא שההוק החדש מופיע ברשימה. בחירת ההוק מציגה את פרטיו: האירוע, ה-matcher, הסוג, קובץ המקור והפקודה. תפריט /hooks הוא לקריאה בלבד. כדי להוסיף, לערוך או להסיר הוקים, יש לערוך את קובץ ה-JSON ישירות או לבקש מקלוד לבצע את השינוי. כדי להשבית זמנית את כל ההוקים בלי למחוק אותם, ניתן להגדיר "disableAllHooks": true בקובץ ההגדרות.

  2. בדיקת ההוק: לחצו על Esc כדי לחזור ל-CLI. לחצו על Shift+Tab עד ששורת המצב מציגה ⏸ manual mode on, בקשו מקלוד לבצע פעולה הדורשת הרשאה, ועברו לחלון אחר מחוץ לטרמינל. כעת אמורה להתקבל התראת שולחן עבודה.


#מה אפשר לאוטמט

הוקים מאפשרים להריץ קוד בנקודות מפתח במחזור החיים של קלוד קוד: עיצוב קבצים לאחר עריכה, חסימת פקודות לפני ביצוען, שליחת התראות כשקלוד זקוק לקלט, הזרקת הקשר בתחילת סשן, תגובה לשינויי תיקייה, אישור הרשאות אוטומטי, והרצת בדיקות ברקע.

#קבלת התראה כשקלוד זקוק לקלט

קבלת התראת שולחן עבודה בכל פעם שקלוד מסיים לעבוד וזקוק לקלט, כדי לעבור למשימות אחרות בלי לבדוק ברציפות את הטרמינל.

הוק זה משתמש באירוע Notification, הנורה כשקלוד ממתין לקלט או להרשאה. יש להוסיף את ההגדרה לקובץ ~/.claude/settings.json בהתאם למערכת ההפעלה:

macOS:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

אם לא מופיעה התראה: הפקודה osascript מנתבת התראות דרך האפליקציה המובנית Script Editor. אם אין לה הרשאת התראות, הפקודה נכשלת בשקט ומערכת macOS לא תבקש אישור. הריצו בטרמינל פעם אחת:

osascript -e 'display notification "test"'

דבר לא יופיע עדיין. פתחו את System Settings > Notifications, אתרו את Script Editor ברשימה, והפעילו את Allow Notifications. הריצו שוב את הפקודה כדי לוודא שהתראת הבדיקה מוצגת.

Linux:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
          }
        ]
      }
    ]
  }
}

אם לא מופיעה התראה: notify-send זקוק ל-daemon של התראות שולחן עבודה, אשר אינו קיים בשרתי headless, בסשנים של SSH וברוב הקונטיינרים. בדקו תחילה את הפקודה ישירות:

notify-send 'Claude Code' 'test'

אם הפקודה אינה נמצאת, התקינו את החבילה libnotify-bin ב-Debian וב-Ubuntu, או את המקבילה בהפצה שלכם.

Windows (PowerShell):

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
          }
        ]
      }
    ]
  }
}

אם לא מופיעה תיבת דו שיח: פקודה זו פותחת תיבת הודעה ולא התראה בפינת המסך, ולכן היא עשויה להיפתח מאחורי חלון הטרמינל. בדקו את הפקודה תחילה ישירות ב-PowerShell. אם מריצים את קלוד קוד בתוך WSL, הקובץ powershell.exe חייב להיות זמין ב-PATH דרך מנגנון התאימות של Windows.

ערך matcher ריק מפעיל את ההוק בכל סוגי ההתראות. כדי להפעיל את ההוק רק באירועים מסוימים, מגדירים אחד מהערכים הבאים:

Matcherמתי זה מופעל
permission_promptקלוד זקוק לאישור לשימוש בכלי או לבקשת רשת של פקודה בסנדבוקס, והבקשה המתינה כ-6 שניות
idle_promptקלוד סיים להגיב לפני כ-60 שניות ולא הוקלד דבר מאז. אינו נשלח בזמן המתנה לאיפוס מגבלת שימוש
auth_successתהליך האימות הושלם
elicitation_dialogשרת MCP פותח טופס elicitation ולא הוקלד דבר במשך כ-6 שניות
elicitation_url_dialogשרת MCP מבקש לפתוח כתובת דפדפן ולא הוקלד דבר במשך כ-6 שניות
elicitation_completeשרת MCP מדווח שהליך elicitation במצב URL הושלם
elicitation_responseתשובת elicitation של MCP נשלחת בחזרה לשרת
agent_needs_inputסשן רקע ממתין לקלט בזמן ש-agent view פתוח בטרמינל, או שהסשן הנוכחי שואל שאלת הגדרת טרמינל עבור חבר צוות סוכנים ולא הוקלד דבר במשך כ-6 שניות
agent_completedסשן רקע מסתיים או נכשל. נורה רק כש-agent view פתוח בטרמינל
quota_auto_resume_firedקלוד קוד ממשיך את המשימה לאחר שהושהתה עקב מגבלת שימוש ב-claude.ai: במועד האיפוס, או מוקדם יותר כאשר פעולה מצדכם (הוספת קרדיטים, שדרוג תוכנית, החלפת מודל) מאפשרת שימוש מחדש, בכפוף לחריג הגדרת מודל
quota_auto_resume_staleמגבלת שימוש ב-claude.ai התאפסה בזמן שהמחשב היה במצב שינה מעל כ-30 דקות. קלוד קוד ממתין ללחיצה על Enter במקום להמשיך. בשינה קצרה יותר המשימה ממשיכה ונורה quota_auto_resume_fired
quota_auto_resume_disabledקלוד קוד מסיים את ההמתנה למגבלת שימוש בלי להמשיך את המשימה: autoContinueAtUsageLimit כבוי, האיפוס נדחה מעבר ל-24 שעות במהלך המתנה שקלוד קוד התחיל בעצמו, המשימה שהומשכה נתקלת שוב במגבלה, או שהמשך הפעולה נחסם לפני הפנייה למודל. אינו נורה בלחיצה על Esc או Ctrl+C, או בבחירה לא להמשיך אוטומטית

מלכודות:

  • אירועי הוק של Notification מופעלים גם כאשר התראות שולחן עבודה כבויות בהגדרות (preferredNotifChannel, כולל notifications_disabled, משנה רק את אופן ההתרעה למשתמש, ולא את הפעלת ההוק).
  • תזמון בטרמינל: הערכים permission_prompt, idle_prompt, elicitation_dialog ו-elicitation_url_dialog מופעלים רק כאשר המשתמש אינו מול הטרמינל (טיימר של כ-6 שניות שנדחה בכל הקשה). בקשת אישור שמגיעה בזמן שתיבת דו שיח אחרת פתוחה שומרת על טיימר של 6 שניות ממועד הגעתה, ולכן ההתראה יכולה להגיע בזמן שהבקשה ממתינה מאחורי התיבה הפתוחה. כדי להגיב מיד כשקלוד מבקש אישור לשימוש בכלי, יש להשתמש בהוק PermissionRequest.
  • הוקי Notification אינם יכולים לחסום או לשנות התראות. קלוד קוד מתעלם מכל שדות systemMessage או continue שמוחזרים מהם. עם זאת, ניתן להחזיר בפלט ה-JSON את השדה terminalSequence (מוגבל לרצפי OSC 0, 1, 2, 9, 99, 777 ו-BEL), וקלוד קוד ישדר אותם ישירות אל הטרמינל.

דרישות גרסה עבור ערכי ה-matcher:

  • הערכים agent_needs_input ו-agent_completed דורשים גרסה v2.1.198 ומעלה.
  • בסשנים המשתמשים ב-Agent SDK (כגון Claude Desktop והרחבת VS Code), אירוע permission_prompt נורה כ-6 שניות לאחר הבקשה בלי להמתין להפסקת הקלדה. אם המשתמש או הוק PermissionRequest עונים קודם, ההוק אינו נורה. ניתן לבטל זאת עם משתנה הסביבה CLAUDE_CODE_DISABLE_PERMISSION_PROMPT_NOTIFY_HOOKS=1 (לפני גרסה v2.1.233 האירוע לא נורה בסשנים אלה).
  • הערכים quota_auto_resume_fired, quota_auto_resume_stale ו-quota_auto_resume_disabled דורשים גרסה v2.1.234 ומעלה.
  • בסשנים של טרמינל, permission_prompt עבור בקשת רשת של פקודה בסנדבוקס דורש גרסה v2.1.246 ומעלה.
  • הערך agent_needs_input עבור שאלת הגדרת טרמינל של חבר צוות סוכנים דורש גרסה v2.1.248 ומעלה.

#עיצוב קוד אוטומטי אחרי עריכות

הרצה אוטומטית של Prettier על כל קובץ שקלוד עורך, לשמירה על עיצוב עקבי בלי פעולה ידנית.

הוק זה משתמש באירוע PostToolUse עם ה-matcher Edit|Write, ולכן רץ רק אחרי כלי עריכת קבצים. החל מגרסה v2.1.191, פסיק משמש להפרדה באותו אופן, כך ש-Edit, Write שקול לחלוטין. הפקודה מחלצת את נתיב הקובץ באמצעות jq ומעבירה אותו ל-Prettier. יש להוסיף לקובץ .claude/settings.json בשורש הפרויקט:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

לבדיקת ההוק, בקשו מקלוד להוסיף שורה עם מחרוזות במירכאות בודדות לקובץ JavaScript ולאחר מכן פתחו את הקובץ: בהגדרות ברירת המחדל של Prettier, ההוק ישכתב אותן למירכאות כפולות. כשההוק מצליח, קלוד קוד אינו מציג דבר בשיחה. כדי לעצב מחדש קובץ מסוים בכל אופן שבו הוא משתנה, כולל כאשר פקודת Bash או תהליך חיצוני משכתבים אותו, יש להשתמש בהוק FileChanged. דוגמאות Bash במדריך משתמשות ב-jq לפענוח JSON. התקנה: brew install jq ב-macOS, או apt-get install jq ב-Debian וב-Ubuntu.

באירועי כלי קבצים, השדה tool_input.file_path מגיע תמיד כנתיב מוחלט. ב-Windows הוא מגיע עם לוכסנים הפוכים (\). החל מגרסה v2.1.269, כאשר פקודת Bash משנה קבצים במאגר Git, הוק PostToolUse יכול לקבל את רשימת הקבצים שהשתנו בשדה tool_response.bashEditDiff אם ההגדרה bashEditDiffEnabled מופעלת, או במצבי auto ו-bypassPermissions (בבטא ציבורית, אינו כולל קבצים ש-Git מתעלם מהם או תת מודולים). בנוסף, הוק PostToolUse יכול להחזיר בפלט ה-JSON שדות ייעודיים: additionalContext להוספת הקשר לקלוד לצד התוצאה, updatedToolOutput להחלפת הפלט שמוצג לקלוד (למשל לצנזור מידע רגיש), או classifierContext (החל מגרסה v2.1.236) להעברת הערה קצרה של עד 2,000 תווים עבור מסווג ה-auto mode.

#חסימת עריכות בקבצים מוגנים

מניעת עריכה של קבצים רגישים כמו .env, package-lock.json, או כל קובץ בתוך .git/. קלוד מקבל משוב שמסביר מדוע העריכה נחסמה, כדי שיוכל להתאים את גישתו.

דוגמה זו נעזרת בסקריפט חיצוני שההוק מפעיל. הסקריפט בודק את נתיב הקובץ מול רשימת תבניות מוגנות ויוצא עם קוד 2 כדי לחסום את העריכה:

  1. יצירת סקריפט ההוק: שמרו את הקוד הבא בקובץ .claude/hooks/protect-files.sh:
#!/bin/bash
# protect-files.sh

INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

# Normalize Windows backslash separators so the patterns below match
FILE_PATH="${FILE_PATH//\\//}"

PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/")

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == *"$pattern"* ]]; then
    echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
    exit 2
  fi
done

exit 0
  1. הפיכת הסקריפט לבר הרצה ב-macOS וב-Linux: סקריפטים של הוקים חייבים להיות בעלי הרשאת הרצה כדי שקלוד קוד יוכל להפעיל אותם:
chmod +x .claude/hooks/protect-files.sh
  1. רישום ההוק: הוסיפו הוק PreToolUse לקובץ .claude/settings.json, המריץ את הסקריפט לפני כל קריאה לכלי Edit או Write:
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PROJECT_DIR}\"/.claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}
  1. בדיקת ההוק: בקשו מקלוד להוסיף הערה לקובץ ה-.env. קלוד קוד חוסם את העריכה לפני ביצועה ומעביר לקלוד את הודעת ה-Blocked: של הסקריפט כמשוב.

מלכודות חשובות:

  • קוד יציאה 2 חוסם את הקריאה לכלי ומציג לקלוד את תוכן ה-stderr כסיבת החסימה. קוד יציאה 1 נחשב שגיאה לא חוסמת, וקלוד קוד ימשיך בביצוע הכלי למרות השגיאה.
  • במקום יציאה בקוד 2, ניתן להחזיר בפלט JSON מבנה מסוג hookSpecificOutput המכיל permissionDecision: "deny" ו-permissionDecisionReason. סדר הקדימויות בין החלטות שונות של מספר הוקים הוא deny ואז defer, ask, ולבסוף allow. השדות הישנים decision ו-reason ברמה העליונה אינם מומלצים עוד (deprecated) עבור PreToolUse.
  • PreToolUse אינו מופעל על קבצים שמשתמש מאזכר ישירות באמצעות @ בפרומפט (הם מוזרקים להקשר ישירות ללא שימוש בכלי; יש להשתמש בכלל deny עבור הכלי Read בהרשאות), ואינו מופעל עבור הכלי EndConversation.
  • ניתן לסנן הפעלה באופן ממוקד באמצעות שדה if המקבל כלל הרשאה (כגון "Edit(*.env*)"), וכך למנוע הרצה של סקריפטים כשאין התאמה.
  • עבור כלי MCP (החל מגרסה v2.1.274), קלט ההוק כולל אובייקט mcp_server המכיל את שם השרת (name) ומקור ההגדרה (source: כגון plugin, sdk, user, project). החלטות אמון והרשאה יש לבסס על source ולא על שם הכלי או שם השרת.

#הזרקה מחדש של הקשר אחרי דחיסה

כאשר חלון ההקשר של קלוד מתמלא, פעולת הדחיסה (compaction) מתמצתת את השיחה כדי לפנות מקום. פעולה זו עלולה להשמיט פרטים חשובים. שימוש בהוק SessionStart עם ה-matcher compact מאפשר להזריק מחדש הקשר קריטי לאחר כל דחיסה.

קלוד קוד מוסיף להקשר של קלוד טקסט רגיל שהפקודה כותבת ל-stdout. דוגמה זו מזכירה לקלוד מוסכמות פרויקט ומשימות נוכחיות. יש להוסיף לקובץ .claude/settings.json בשורש הפרויקט:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "compact",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Reminder: use Bun, not npm. Run bun test before committing. Current sprint: auth refactor.'"
          }
        ]
      }
    ]
  }
}

ערכי ה-matcher האפשריים עבור SessionStart:

  • startup: סשן חדש.
  • resume: המשך סשן קיים דרך --resume, --continue או /resume.
  • clear: איפוס שיחה עם פקודת /clear.
  • compact: לאחר דחיסת שיחה ידנית או אוטומטית.
  • fork: פיצול סשן דרך --fork-session עם --resume או --continue, פקודת /fork ברקע, או /branch (החל מגרסה v2.1.214; בגרסאות קודמות דווח כ-resume).

התנהגות ואירועים קשורים:

  • אירוע SessionStart תומך רק בהוקים מסוג command ו-mcp_tool. בסשנים אינטראקטיביים, בהמשך שיחה בהפעלה או לאחר /clear, הוקים אלה רצים ברקע וניתן להקליד מיד, אך התגובה הראשונה של קלוד תמתין להשלמתם כדי לקבל את ההקשר. לחיצה על Esc מחזירה את הפרומפט לשורת הקלט בלי לשלוח אותו, וההוקים ממשיכים לרוץ.
  • בהפעלת סשן חדש (startup, כולל --continue או --resume), הוקי mcp_tool נדלגים באירוע SessionStart מכיוון ששרתי ה-MCP אינם זמינים עדיין בשלב זה. אולם לאחר /clear או לאחר דחיסה, השרתים כבר מחוברים והוקי mcp_tool פועלים כרגיל. לפעולות הנדרשות מתחילת הסשן השתמשו בהוק command.
  • עבור בקרה על עצם פעולת הדחיסה, קיימים האירועים PreCompact (הנורה לפני הדחיסה ומאפשר לחסום אותה בקוד יציאה 2 או ב-JSON עם decision: "block") ו-PostCompact (הנורה בסיום הדחיסה ומקבל את compact_summary, ללא יכולת חסימה).
  • החל מגרסה v2.1.251, כאשר source הוא resume או fork והיומן כולל לפחות תגובה אחת מקלוד, ההוק מקבל גם נתוני עלות אסימונים של השיחה: seconds_since_last_response, context_tokens, prompt_cache_likely_expired, ו-estimated_cache_write_usd.
  • פלט ה-JSON של SessionStart יכול להחזיר שדות ייעודיים: additionalContext להזרקת הקשר, initialUserMessage לשליחת הודעה ראשונה במצב -p, sessionTitle להגדרת שם הסשן (במקורות startup, resume, fork), watchPaths לרשימת קבצים למעקב עבור אירוע FileChanged, ו-reloadSkills: true לסריקה מחדש של תיקיות הכישורים בתחילת הסשן.
  • משתני סביבה שנכתבים לנתיב שבמשתנה CLAUDE_ENV_FILE נשמרים עבור פקודות Bash הבאות בסשן. להזרקת הקשר סטטי בתחילת סשן מומלץ להשתמש ב-CLAUDE.md.

#ביקורת על שינויי הגדרות

מעקב אחר שינויים בקובצי הגדרות או כישורים במהלך סשן. האירוע ConfigChange נורה כאשר תהליך חיצוני או עורך קוד משנה קובץ הגדרות, וכך ניתן לתעד שינויים לצורכי תאימות או לחסום שינויים לא מורשים.

הדוגמה הבאה מוסיפה כל שינוי ליומן ביקורת. יש להוסיף ל-~/.claude/settings.json:

{
  "hooks": {
    "ConfigChange": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{timestamp: now | todate, source: .source, file: .file_path}' >> ~/claude-config-audit.log"
          }
        ]
      }
    ]
  }
}

ה-matcher מסנן לפי סוג ההגדרה: user_settings, project_settings, local_settings, policy_settings, או skills.

מלכודות:

  • קלוד קוד מפעיל הוקי ConfigChange כאשר משתנה קובץ הגדרות, קובץ כישורים, או קובץ מדיניות מנוהלת מקומי (managed-settings.json או קובץ בתוך managed-settings.d/). הוא אינו מפעיל הוקים אלה עבור הגדרות מנוהלות מהשרת (server-managed settings), שינויי מדיניות ב-macOS או ב-Windows registry, וכן בעת דגימת שינויים מ-Windows בתוך WSL עם wslInheritsWindowsSettings.
  • כדי למנוע משינוי בהגדרות משתמש, פרויקט, הגדרות מקומיות או כישורים להיכנס לתוקף, יוצאים עם קוד יציאה 2 או מחזירים {"decision": "block", "reason": "..."}.
  • שינויים במדיניות ארגונית מנוהלת (policy_settings) אינם ניתנים לחסימה: ההוק אמנם יופעל לצורכי תיעוד, אך הוראת החסימה תתעלם כדי להבטיח שמדיניות ארגונית תיאכף תמיד.
  • חסימת שינוי אינה מציגה הודעה למשתמש או לקלוד (גם אם מציינים reason או כותבים ל-stderr עם קוד יציאה 2), וקלוד קוד מתעלם משדות systemMessage ו-continue. שורת אזהרה נרשמת ביומן ה-debug בלבד.

#טעינה מחדש של הסביבה כאשר תיקייה או קבצים משתנים

בפרויקטים מסוימים מוגדרים משתני סביבה שונים בהתאם לתיקייה שבה נמצאים. כלים כגון direnv מבצעים זאת אוטומטית במעטפת, אך כלי ה-Bash של קלוד אינו קולט שינויים אלה בעצמו.

שילוב הוק SessionStart עם הוק CwdChanged פותר בעיה זו: SessionStart טוען את המשתנים עבור תיקיית ההפעלה של הסשן, ו-CwdChanged טוען אותם מחדש בכל פעם שקלוד משנה תיקייה. שני ההוקים כותבים אל CLAUDE_ENV_FILE, שקלוד קוד מריץ כהקדמה לפני כל פקודת Bash. יש להוסיף ל-~/.claude/settings.json:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
          }
        ]
      }
    ],
    "CwdChanged": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
          }
        ]
      }
    ]
  }
}

יש להריץ direnv allow פעם אחת בכל תיקייה המכילה .envrc כדי לאשר ל-direnv לטעון אותו. אם אתם משתמשים ב-devbox או ב-nix במקום direnv, אותו דפוס עובד עם devbox shellenv או devbox global shellenv במקום direnv export bash.

כדי להגיב לשינויים בקבצים מסוימים במקום בכל שינוי תיקייה, משתמשים בהוק FileChanged עם matcher המפרט את שמות הקבצים למעקב, מופרדים בקו אנכי (|). בעת בניית רשימת המעקב, קלוד קוד מפרק ערך זה לשמות קבצים מדויקים ולא כביטוי רגולרי. לדוגמה, למעקב אחר .envrc ו-.env בתיקיית העבודה:

{
  "hooks": {
    "FileChanged": [
      {
        "matcher": ".envrc|.env",
        "hooks": [
          {
            "type": "command",
            "command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
          }
        ]
      }
    ]
  }
}

הוקי CwdChanged ו-FileChanged יכולים להחזיר בפלט ה-JSON מערך בשם watchPaths כדי לעדכן דינמית את רשימת הנתיבים המוחלטים שבהם מתבצע מעקב. אם מתווספת תיקיית עבודה נוספת במהלך הסשן באמצעות /add-dir או בקשת בקרה של ה-SDK מסוג register_repo_root, נורה האירוע DirectoryAdded.

#אישור אוטומטי של בקשות הרשאה מסוימות

דילוג על תיבת האישור עבור קריאות לכלים שאתם מאשרים תמיד. דוגמה זו מאשרת אוטומטית את הכלי ExitPlanMode, שקלוד קורא לו כשהוא מסיים להציג תוכנית ומבקש לעבור לביצוע, כדי שלא תישאלו על כך בכל פעם מחדש.

שלא כמו הדוגמאות הקודמות המבוססות על קודי יציאה, אישור אוטומטי דורש מההוק לכתוב החלטת JSON ל-stdout. קלוד קוד מריץ הוקי PermissionRequest כאשר הוא עומד לבקש מכם הרשאה, ואם ההוק מחזיר "behavior": "allow", קלוד קוד משיב לבקשה בשמכם.

ה-matcher מגביל את ההוק ל-ExitPlanMode בלבד, כך שבקשות אחרות אינן מושפעות. יש להוסיף ל-~/.claude/settings.json:

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "ExitPlanMode",
        "hooks": [
          {
            "type": "command",
            "command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"PermissionRequest\", \"decision\": {\"behavior\": \"allow\"}}}'"
          }
        ]
      }
    ]
  }
}

כשההוק מאשר, קלוד קוד יוצא ממצב תוכנית ומשחזר את מצב ההרשאות שהיה פעיל לפני הכניסה אליו. ביומן השיחה מוצג "Allowed by PermissionRequest hook" במקום תיבת הדו שיח. נתיב ההוק שומר תמיד על השיחה הנוכחית: הוא אינו יכול לאפס את ההקשר ולהתחיל סשן ביצוע נקי כפי שמאפשרת תיבת הדו שיח.

כדי להגדיר מצב הרשאות מסוים במקום זאת, פלט ההוק יכול לכלול מערך updatedPermissions עם רשומת setMode. הערך של mode יכול להיות default, auto, acceptEdits, dontAsk, bypassPermissions, plan, או manual (החל מגרסה v2.1.200 ככינוי ל-default), עם destination: "session" כדי להחיל אותו על הסשן הנוכחי בלבד:

{
  "hookSpecificOutput": {
    "hookEventName": "PermissionRequest",
    "decision": {
      "behavior": "allow",
      "updatedPermissions": [
        { "type": "setMode", "mode": "acceptEdits", "destination": "session" }
      ]
    }
  }
}

בנוסף ל-setMode, המערך updatedPermissions תומך בפעולות addRules, replaceRules, removeRules, addDirectories, ו-removeDirectories, עם יעדי שמירה שונים: session, localSettings, projectSettings, או userSettings.

מלכודות חשובות:

  • מצב bypassPermissions מופעל רק אם הסשן נפתח כאשר מצב עקיפה כבר זמין מראש: עם --dangerously-skip-permissions, עם --permission-mode bypassPermissions, עם --allow-dangerously-skip-permissions, או עם הגדרת permissions.defaultMode: "bypassPermissions" בהגדרות משתמש, דגל --settings, או מדיניות ארגון. הוא אינו מופעל אם המצב בוטל על ידי מדיניות ארגונית (permissions.disableBypassPermissionsMode) או אם הסשן הופעל במצב מוגבל (restricted mode). קלוד קוד לעולם אינו שומר אותו כ-defaultMode.
  • הוק PermissionRequest שיוצא בקוד 2 ללא אובייקט decision אינו משפיע על בקשת ההרשאה, והודעת ה-stderr שלו נזרקת. רק אובייקט decision ב-JSON יכול לאשר או לדחות את הבקשה.
  • שמרו על ה-matcher ממוקד ככל האפשר. התאמה על .* או השארת matcher ריק תאשר אוטומטית כל בקשת הרשאה, כולל פקודות מעטפת ומחיקת קבצים.

#כיצד הוקים פועלים

קלוד קוד מפעיל אירועי הוק בנקודות מוגדרות במחזור החיים שלו. כאשר אירוע נורה, כל ההוקים התואמים רצים במקביל.

אירועמתי זה מופעל
SessionStartבתחילת סשן או בעת חידושו
Setupבהרצה עם --init-only, או עם --init או --maintenance במצב -p. להכנה חד פעמית ב-CI או בסקריפטים
UserPromptSubmitבעת שליחת פרומפט, לפני שקלוד מעבד אותו
UserPromptExpansionכאשר פקודה מוקלדת מתרחבת לפרומפט, לפני הגעתה לקלוד. מאפשר לחסום את ההרחבה
PreToolUseלפני ביצוע קריאה לכלי. מאפשר לחסום אותה או לשנות את הקלט
PermissionRequestכאשר קריאה לכלי זקוקה להכרעת הרשאה
PermissionDeniedכאשר מצב אוטומטי (auto mode) דוחה קריאה לכלי. ניתן להחזיר hookSpecificOutput.retry: true כדי לאפשר למודל לנסות שוב
PostToolUseלאחר שקריאה לכלי הצליחה
PostToolUseFailureלאחר שקריאה לכלי נכשלה
PostToolBatchלאחר שסדרת קריאות מקבילות לכלים הושלמה, לפני הפנייה הבאה למודל
Notificationכאשר קלוד קוד שולח התראה
MessageDisplayתוך כדי הזרמת טקסט של הודעת מודל לתצוגה. מאפשר להחליף את הטקסט המוצג במסך
SubagentStartכאשר סוכן משנה מופעל או מחודש
SubagentStopכאשר סוכן משנה מסיים את פעולתו
TaskCreatedכאשר נוצרת משימה באמצעות TaskCreate
TaskCompletedכאשר משימה מסומנת כהושלמה באמצעות TaskUpdate או בסיום תור של חבר צוות
Stopכאשר קלוד מסיים להגיב
StopFailureכאשר תור השיחה מסתיים עקב שגיאת API
TeammateIdleכאשר חבר צוות סוכנים עומד לעבור למצב סרק
InstructionsLoadedכאשר קובץ CLAUDE.md או כלל נטענים להקשר. נורה בתחילת סשן ובטעינה עצלה
ConfigChangeכאשר קובץ הגדרות משתנה במהלך סשן
CwdChangedכאשר תיקיית העבודה משתנה, למשל עקב פקודת cd
DirectoryAddedכאשר תיקיית עבודה מתווספת במהלך סשן דרך /add-dir או בקרת SDK
FileChangedכאשר קובץ שנמצא במעקב משתנה בדיסק
WorktreeCreateבעת יצירת worktree דרך --worktree, בידוד סביבה או סשן רקע. מחליף את ברירת המחדל של Git ומחזיר נתיב
WorktreeRemoveבעת הסרת worktree בסיום סשן, בסיום סוכן משנה או במחיקת סשן רקע
PreCompactלפני דחיסת ההקשר. מאפשר לחסום את הדחיסה
PostCompactלאחר סיום דחיסת ההקשר
PreModelSwitchלפני החלפת מודל לפי בקשת משתמש או לקוח. מאפשר לחסום את ההחלפה (דורש v2.1.251 ומעלה)
PostModelSwitchלאחר שהמודל של הסשן הוחלף (דורש v2.1.251 ומעלה)
Elicitationכאשר שרת MCP מבקש קלט מהמשתמש במהלך קריאה לכלי
ElicitationResultלאחר שהמשתמש הגיב לבקשת MCP, לפני שהתשובה נשלחת חזרה לשרת
SessionEndבעת סיום הסשן

לכל הוק יש type שקובע כיצד הוא מופעל:

  • type: "command": הרצת פקודת מעטפת מקומית.
  • type: "http": שליחת נתוני האירוע ב-POST אל כתובת URL.
  • type: "mcp_tool": קריאה לכלי בשרת MCP שכבר מחובר.
  • type: "prompt": הערכה חד פעמית באמצעות מודל קלוד.
  • type: "agent": אימות רב שלבי באמצעות סוכן משנה בעל גישה לקריאת קבצים והרצת כלים (ניסיוני).

13 אירועים תומכים בכל חמשת הסוגים: PermissionDenied, PermissionRequest, PostToolBatch, PostToolUse, PostToolUseFailure, PreToolUse, Stop, SubagentStop, TaskCompleted, TaskCreated, TeammateIdle, UserPromptExpansion, ו-UserPromptSubmit. 18 אירועים תומכים ב-command, http ו-mcp_tool בלבד: ConfigChange, CwdChanged, DirectoryAdded, Elicitation, ElicitationResult, FileChanged, InstructionsLoaded, MessageDisplay, Notification, PostCompact, PostModelSwitch, PreCompact, PreModelSwitch, SessionEnd, StopFailure, SubagentStart, WorktreeCreate, ו-WorktreeRemove. שני אירועים, SessionStart ו-Setup, תומכים ב-command וב-mcp_tool בלבד.

#שילוב תוצאות ממספר הוקים

כאשר מספר הוקים מתאימים לאותו אירוע, כל פקודות ההוק רצות במקביל ומגיעות לסיומן לפני שקלוד קוד ממזג את התוצאות. החזרה של deny מהוק אחד אינה עוצרת את ההוקים המקבילים. אין להסתמך על deny כדי למנוע תופעות לוואי בהוק אחר.

בסיום כל ההוקים, קלוד קוד ממזג את הפלטים:

  • בהחלטות הרשאה של PreToolUse ו-PreModelSwitch, התשובה המגבילה ביותר קובעת לפי הסדר הבא: deny גובר על defer (ב-PreToolUse), שגובר על ask, שגובר על allow.
  • מחרוזות מ-additionalContext נאספות מכל ההוקים ומועברות יחד אל קלוד.

לדוגמה, הגדרת שני הוקים עבור Bash: הראשון מתעד כל פקודה ליומן ויוצא ב-0, והשני בודק פקודות הרסניות ויוצא ב-2 אם הפקודה מכילה rm -rf:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r .tool_input.command >> ~/.claude/bash.log"
          },
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-rm-rf.sh"
          }
        ]
      }
    ]
  }
}

אם קלוד ינסה להריץ rm -rf /tmp/build, שני ההוקים ירוצו במקביל: הוק התיעוד ירשום את הפקודה ליומן, והוק האבטחה ייצא ב-2 ויחסום את הביצוע. הפקודה תיחסם, אך הרישום ביומן יתבצע בכל מקרה כי שני ההוקים רצו.

#קריאת קלט והחזרת פלט

הוקים מתקשרים עם קלוד קוד באמצעות stdin, stdout, stderr וקודי יציאה.

#קלט ההוק

קלוד קוד מעביר נתוני JSON ל-stdin של ההוק (או בגוף ה-POST בהוקי HTTP). שדות משותפים לכל האירועים כוללים:

  • session_id: מזהה ייחודי של הסשן.
  • cwd: תיקיית העבודה בעת הפעלת ההוק.
  • hook_event_name: שם האירוע שהפעיל את ההוק.
  • transcript_path: נתיב לקובץ ה-JSONL של יומן השיחה.
  • prompt_id: מזהה ייחודי של הפרומפט הנוכחי שמעובד (דורש גרסה v2.1.196 ומעלה).
  • scratchpad_dir: נתיב לתיקיית הקבצים הזמניים של הסשן (דורש גרסה v2.1.257 ומעלה).
  • permission_mode: מצב ההרשאות הנוכחי (default, plan, acceptEdits, auto, dontAsk, bypassPermissions).
  • effort: אובייקט עם שדה level המציין את רמת המאמץ הנוכחית (low, medium, high, xhigh, max). זמין גם כמשתנה סביבה $CLAUDE_EFFORT.

כאשר קלוד רץ עם --agent או בתוך סוכן משנה, מתווספים שני שדות נוספים:

  • agent_id: מזהה ייחודי של סוכן המשנה.
  • agent_type: שם סוכן המשנה (למשל Explore או security-reviewer).

בסביבות ענן מרוחקות, משתנה הסביבה $CLAUDE_CODE_REMOTE מוגדר כ-"true". בסשן עם חיבור פעיל של Remote Control, משתנה הסביבה $CLAUDE_CODE_BRIDGE_SESSION_ID מכיל את מזהה הסשן (החל מגרסה v2.1.199).

בנוסף, כל אירוע מספק שדות ייעודיים. לדוגמה, באירוע PreToolUse מועברים tool_name, tool_input (שבפקודות מעטפת מכיל את command), ו-tool_use_id. עבור כלי MCP (החל מגרסה v2.1.274), הקלט כולל בנוסף את האובייקט mcp_server, המכיל את שם השרת (name) ואת מקור ההגדרה שלו (source: כגון plugin, sdk, user, project). מומלץ לבסס החלטות אמון על source ולא על שם הכלי.

#פלט קודי יציאה

ההוק קובע את הפעולה הבאה לפי קוד היציאה:

  • קוד יציאה 0: הצלחה. אין התנגדות מצד ההוק ותהליך ההרשאות הרגיל נמשך. באירועים UserPromptSubmit, UserPromptExpansion, SessionStart ו-PostModelSwitch, טקסט רגיל שנכתב ל-stdout מתווסף להקשר של קלוד.
  • קוד יציאה 2: שגיאה חוסמת. באירועים הניתנים לחסימה, קוד 2 עוצר את הפעולה מיד, גם אם נכתב פלט JSON המציין allow. הסיבה נלקחת מ-stderr או מתוך שדה הסיבה ב-JSON. אירועים שאינם ניתנים לחסימה (כמו PostToolUse או SessionStart) מציגים את stderr לקלוד או למשתמש וממשיכים.
  • כל קוד יציאה אחר: נחשב כשגיאה לא חוסמת, והפעולה נמשכת (למעט WorktreeCreate, שבו כל קוד שאינו 0 מבטל את היצירה). ביומן השיחה מופיעה הודעת שגיאה עם השורה הראשונה מ-stderr. אולם אם ההוק הדפיס ל-stdout אובייקט JSON תקין שעובר אימות מבנה, קלוד קוד מתעלם מקוד היציאה וה-JSON קובע את התוצאה.

התנהגות קוד יציאה 2 לפי סוג האירוע:

  • אירועים שניתנים לחסימה בקוד 2: PreToolUse (חוסם את הקריאה לכלי), UserPromptSubmit (חוסם את הפרומפט ומוחק אותו), UserPromptExpansion (חוסם את ההרחבה), Stop (מונע עצירה וממשיך בשיחה עם סיבת ה-stderr), SubagentStop (מונע מסוכן המשנה לעצור), TeammateIdle (מונע מחבר צוות לעבור למצב סרק), TaskCreated (מבטל את יצירת המשימה), TaskCompleted (מונע סימון משימה כהושלמה), ConfigChange (חוסם כניסת שינוי לתוקף, למעט מדיניות מנוהלת), PostToolBatch (עוצר את לולאת הסוכן לפני הפנייה הבאה למודל), PreCompact (חוסם דחיסה), PreModelSwitch (חוסם החלפת מודל ומציג stderr למשתמש), Elicitation (דוחה בקשת elicitation), ElicitationResult (משנה את הפעולה ל-decline), ו-WorktreeCreate (מכשיל יצירת worktree).
  • אירועים שאינם ניתנים לחסימה בקוד 2: PermissionRequest (קוד 2 אינו משפיע, ויש להשתמש באובייקט decision ב-JSON בלבד), PermissionDenied (הדחייה כבר התרחשה), PostToolUse ו-PostToolUseFailure (הכלי כבר הורץ או נכשל, stderr מוצג לקלוד), Notification, SubagentStart, SessionStart, Setup, SessionEnd, CwdChanged, DirectoryAdded, FileChanged, PostCompact, PostModelSwitch, InstructionsLoaded, MessageDisplay, ו-StopFailure.

#פלט JSON מובנה

עבור שליטה מדויקת, יוצאים בקוד 0 ומדפיסים אובייקט JSON ל-stdout:

  • שדות אוניברסליים:

    • continue: false: עוצר את עבודת קלוד לחלוטין לאחר ריצת ההוק. גובר על שדות החלטה אחרים.
    • stopReason: הודעה שתוצג למשתמש כאשר continue הוא false.
    • systemMessage: הודעת אזהרה שמוצגת למשתמש.
    • terminalSequence: רצף מילוט לשידור ישיר לטרמינל (תומך ב-OSC 0, 1, 2, 9, 99, 777, ובתו ה-BEL). עוקף את חוסר הזמינות של /dev/tty.
    • מחרוזות פלט של הוקים (כולל additionalContext, systemMessage, ו-stdout) מוגבלות לתקרה של 10,000 תווים. פלט ארוך יותר נשמר לקובץ ומוחלף בתצוגה מקדימה ונתיב.
  • החלטות ייעודיות לאירועים:

    • ב-PreToolUse: מחזירים hookSpecificOutput עם permissionDecision ("allow", "deny", "ask", או "defer" במצב -p), permissionDecisionReason, updatedInput להחלפת כלל הארגומנטים של הכלי, ו-additionalContext.
    • ב-PostToolUse: מחזירים ברמה העליונה decision: "block" עם reason, או משתמשים ב-updatedToolOutput כדי להחליף את הפלט שקלוד רואה, או ב-classifierContext (החל מגרסה v2.1.236) כדי לשלוח הערה לסיווג במצב auto.
    • ב-PermissionRequest: מחזירים hookSpecificOutput.decision עם behavior ("allow" או "deny"), updatedInput, או updatedPermissions.
    • ב-PermissionDenied: מחזירים hookSpecificOutput.retry: true כדי להודיע למודל שמותר לו לנסות שוב.
    • ב-Stop ו-SubagentStop: מחזירים ברמה העליונה decision: "block" עם reason, או מחזירים hookSpecificOutput.additionalContext למשוב שממשיך את השיחה כמשוב הוק רגיל במקום שגיאה.
    • ב-PreModelSwitch: מחזירים permissionDecision ("allow", "deny", "ask") או ברמה העליונה decision: "block".
    • ב-MessageDisplay: מחזירים hookSpecificOutput.displayContent כדי להחליף את הטקסט המוזרם במסך.
    • ב-UserPromptSubmit: מחזירים hookSpecificOutput.additionalContext להזרקת הקשר. השדה חייב להיות בתוך hookSpecificOutput.

#השהיית קריאה לכלי (Defer) במצב לא אינטראקטיבי

הערך "defer" בשדה permissionDecision של PreToolUse מיועד לשילובים המריצים את claude -p כתהליך בן (כגון ב-Agent SDK או בממשקים עצמאיים). הוא מאפשר להשהות את קלוד, לאסוף קלט בממשק שלכם ולהמשיך מאוחר יותר:

  1. קלוד קורא לכלי (כגון AskUserQuestion). הוק PreToolUse מופעל.
  2. ההוק מחזיר permissionDecision: "defer". הכלי אינו מתבצע, והתהליך יוצא עם stop_reason: "tool_deferred", תוך שמירת הקריאה הממתינה ביומן.
  3. התהליך המפעיל קורא את deferred_tool_use מתוצאת ה-SDK, מציג את השאלה למשתמש בממשק שלו וממתין למענה.
  4. התהליך מריץ מחדש claude -p --resume <session-id> עם אותו מארח הרשאות. אותו כלי מפעיל שוב את PreToolUse.
  5. ההוק מחזיר permissionDecision: "allow" יחד עם התשובות ב-updatedInput. הכלי מתבצע וקלוד ממשיך.

האפשרות "defer" נתמכת רק במצב -p וכאשר מתבצעת קריאה לכלי יחיד באותו תור. חידוש סשן שהושהה במצב תוכנית (plan mode) דורש העברת הדגל --permission-prompt-tool (החל מגרסה v2.1.246).

#סינון הוקים באמצעות Matchers והשדה if

ללא הגדרת matcher, ההוק מופעל בכל מופע של האירוע. ה-matcher מסנן לפי כללים מדויקים:

  • ערך ריק "", "*", או השמטת השדה: מפעיל את ההוק בכל מופע.
  • אותיות, ספרות, _, -, רווחים, פסיקים (,) וקווים אנכיים (|): מוערך כמחרוזת מדויקת או רשימת מחרוזות מופרדות בפסיק או קו אנכי (הפרדה בפסיקים דורשת v2.1.191+, מקפים דורשים v2.1.195+).
  • כל תו אחר: מוערך כביטוי רגולרי של JavaScript ללא עוגנים (RegExp.prototype.test).
  • האירועים FileChanged ו-StopFailure משתמשים בקבוצת תווים צרה יותר (אותיות, ספרות, _, ו-| בלבד). כל תו אחר מעביר אותם לנתיב ביטוי רגולרי.
אירועלפי מה ה-Matcher מסנןערכים לדוגמה
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDeniedשם הכליBash, Edit|Write, mcp__.*
SessionStartאופן תחילת הסשןstartup, resume, clear, compact, fork
Setupהדגל שהפעיל את ההכנהinit, maintenance
SessionEndסיבת סיום הסשןclear, resume, logout, prompt_input_exit, other (הערך bypass_permissions_disabled הוסר בגרסה v2.1.234)
Notificationסוג ההתראהpermission_prompt, idle_prompt, auth_success, agent_needs_input, ועוד
SubagentStart, SubagentStopסוג הסוכןgeneral-purpose, Explore, Plan, שמות סוכנים מותאמים, או שמות עם תחילית תוסף כמו ^my-plugin:reviewer$
PreCompact, PostCompactמה גרם לדחיסהmanual, auto
PreModelSwitch, PostModelSwitchהשם הקנוני של מודל היעדclaude-opus-5, claude-opus-4-6|claude-opus-5, .*opus.*
ConfigChangeמקור ההגדרהuser_settings, project_settings, local_settings, policy_settings, skills
DirectoryAddedאופן הוספת התיקייהslash_command, register_repo_root
StopFailureסוג השגיאהrate_limit, overloaded, authentication_failed, invalid_request, cloud_credential_error (החל מ-v2.1.267), ועוד
InstructionsLoadedסיבת טעינת ההוראותsession_start, nested_traversal, path_glob_match, include, compact
Elicitation, ElicitationResultשם שרת ה-MCPשמות שרתי ה-MCP המוגדרים שלכם
FileChangedשמות קבצים מדויקים למעקב.envrc|.env
UserPromptExpansionשם הפקודה או הכישורשמות הפקודות או הכישורים שהוגדרו

אירועים ללא תמיכה ב-matcher (נורים תמיד בכל מופע): UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, CwdChanged, ו-MessageDisplay.

כלי MCP משתמשים במבנה שמות ייחודי: mcp__<server>__<tool>. כדי להתאים לכל הכלים של שרת מסוים, חובה להוסיף .* בסוף: mcp__memory__.*. עבור כלים מתוספים המבנה כולל את שם התוסף: mcp__plugin_<plugin-name>_<server-name>__<tool>.

#סינון לפי שם כלי וארגומנטים באמצעות השדה if

השדה if מאפשר לסנן קריאות לכלים לפי שמם והארגומנטים שלהם יחד בתחביר של כללי הרשאות, עוד לפני שהתהליך של ההוק מופעל:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(git *)",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-git-policy.sh"
          }
        ]
      }
    ]
  }
}

התאמת השדה if מול פקודות מעטפת:

תבנית ifפקודת מעטפתהאם ההוק מופעל?הסבר
Bash(git *)FOO=bar git pushכןהשמות משתנים בהתחלה מוסרים לפני ההשוואה, ו-git push תואמת
Bash(git *)npm test && git pushכןנבדקת כל תת פקודה, ו-git push תואמת
Bash(rm *)echo $(rm -rf /)כןנבדקות פקודות בתוך $() ומירכאות נטויות, ו-rm -rf / תואמת
Bash(rm *)echo $(date)לאאף תת פקודה אינה תואמת לתבנית rm *
Bash(cat *)echo before $(date) afterלאהחלפה יכולה להופיע בכל ארגומנט, הפקודה כולה ו-date נבדקות ואינן תואמות
Bash(git *)$TOOL git pushכןקלוד קוד אינו יכול לחזות את ערך המשתנה, ולכן מפעיל את ההוק ליתר ביטחון
Bash(git push *)echo $(date)כןתבניות המפרטות מעבר לשם הפקודה מפעילות את ההוק בכל מופע של $(), מירכאות נטויות או משתנה סביבה

השדה if נתמך רק באירועי כלים: PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, ו-PermissionDenied. החל מגרסה v2.1.214, תבנית תיקייה בעלת מקטע יחיד כגון "Edit(src/**)" מתאימה רק לתיקיית src שבתור תיקיית העבודה ולא בעומק כלשהו. להתאמה בעומק כלשהו יש לכתוב "Edit(**/src/**)".

#הגדרת מיקום ההוקים וטווח פעולתם

המקום שבו מגדירים את ההוק קובע את טווח השפעתו:

מיקוםטווח פעולהשיתוף בצוות
~/.claude/settings.jsonכל הפרויקטים של המשתמשלא, מקומי למכונה
.claude/settings.jsonפרויקט יחידכן, נשמר ב-git
.claude/settings.local.jsonפרויקט יחידלא, נוסף אוטומטית ל-.gitignore
הגדרות מדיניות מנוהלת (Managed policy)כל הארגוןכן, בשליטת מנהל המערכת
קובץ hooks/hooks.json בתוסףכאשר התוסף מופעלכן, מופץ עם התוסף
כותרת קובץ כישור (Skill frontmatter)לשארית הסשן מרגע הפעלת הכישורכן, מוגדר בקובץ הכישור
כותרת קובץ סוכן משנה (Subagent frontmatter)בזמן ריצת סוכן המשנה בלבדכן (דורש אישור trust לתיקיית הפרויקט מגרסה v2.1.218)

בתוך כישורים (skills), ניתן להגדיר להוק את השדה once: true כדי שיוסר אוטומטית לאחר הפעלתו המוצלחת הראשונה. סביבות ענן (סביבת הדפדפן) אינן קוראות את ~/.claude/settings.json המקומי; ההוקים שם מגיעים מהמאגר ומהגדרות מנוהלות של הארגון. מנהלי מערכת בארגון יכולים להפעיל את allowManagedHooksOnly: true כדי לחסום הוקים מקומיים, של פרויקט, או של תוספים (למעט תוספים שהופעלו בכפייה בהגדרות המנוהלות). ניתן להגביל כתובות HTTP באמצעות allowedHttpHookUrls ומשתני סביבה בכותרות באמצעות httpHookAllowedEnvVars. כדי לבטל זמנית את כל ההוקים, מגדירים "disableAllHooks": true בקובץ ההגדרות, או מעבירים בדגל הפעלה: --settings '{"disableAllHooks": true}'.

#תצורת הפעלה: Exec form מול Shell form

עבור פקודות מעטפת (type: "command"):

  • Exec form: מופעל כאשר מגדירים מערך args. קלוד קוד מפעיל את קובץ ההרצה ישירות ללא מעטפת, כך שאין בעיות ציטוט ורווחים. משתני נתיב כגון ${CLAUDE_PROJECT_DIR}, ${CLAUDE_PLUGIN_ROOT}, ו-${CLAUDE_PLUGIN_DATA} מוחלפים כמחרוזות ישירות לתוך הפקודה והארגומנטים. כמו כן, בתוספים מוחלפים ערכי ${user_config.*} כמחרוזות ישירות. ב-Windows, מצב זה דורש קובץ הרצה אמיתי (כגון .exe), ועבור סקריפטים של Node.js יש להפעיל את node ישירות.
  • Shell form: מופעל כאשר משמיטים את args. הפקודה מועברת למעטפת (sh -c ב-macOS ו-Linux, או Git Bash/PowerShell ב-Windows). מתאים כאשר זקוקים לצינורות (|), שרשור פקודות (&&), או הפניות פלט. החל מגרסה v2.1.207, פקודת מעטפת בתוסף שמפנה ל-${user_config.*} נכשלת בשגיאה; יש לקרוא במקום זאת את משתנה הסביבה $CLAUDE_PLUGIN_OPTION_<KEY> או להשתמש ב-exec form. ב-Windows, קלוד קוד משכתב מצייני נתיב לפורמט ${env:NAME} ב-PowerShell מגרסה v2.1.198 ומעלה.

#הוקים מבוססי פרומפט

עבור החלטות הדורשות שיקול דעת ולא חוקים דטרמיניסטיים, משתמשים בהוקים מסוג type: "prompt". במקום להריץ פקודה, קלוד קוד שולח את הפרומפט ונתוני האירוע אל מודל קלוד (מודל מהיר כברירת מחדל, או מודל אחר המוגדר בשדה model) כדי לקבל החלטה.

שדות ההגדרה:

  • prompt: מחרוזת הפרומפט. המשתנה המיוחד $ARGUMENTS מוחלף בנתוני ה-JSON של האירוע. אם $ARGUMENTS מושמט, ה-JSON מתווסף בסוף הפרומפט.
  • model: המודל שיבצע את ההערכה (ברירת מחדל: מודל מהיר).
  • timeout: פסק זמן בשניות (ברירת מחדל: 30).
  • continueOnBlock: ברירת מחדל false. כאשר נקבע כ-true באירועים המתאימים, החזרת ok: false מעבירה את הסיבה לקלוד כמשוב וממשיכה את התור במקום לסיים אותו מיד.

המודל מחזיר אובייקט JSON במבנה הבא:

{
  "ok": true,
  "reason": "Explanation for the decision",
  "impossible": false
}

מה קורה כאשר המודל מחזיר ok: false:

  • ב-Stop וב-SubagentStop: ה-reason מוחזר לקלוד כהוראה הבאה והשיחה נמשכת, אלא אם המודל החזיר בנוסף "impossible": true, ואז העצירה מותרת והתור מסתיים.
  • ב-PreToolUse: הקריאה לכלי נדחית. כברירת מחדל התור מסתיים וסיבת הדחייה מופיעה כאזהרה בצ'אט. הגדרת continueOnBlock: true מחזירה את הסיבה לקלוד כשגיאת כלי כדי שיוכל לתקן ולהמשיך (שקול להחזרת permissionDecision: "deny").
  • ב-PostToolUse: כברירת מחדל התור מסתיים והסיבה מופיעה כאזהרה. הגדרת continueOnBlock: true מעבירה את הסיבה לקלוד וממשיכה את התור.
  • ב-PostToolBatch, UserPromptSubmit, ו-UserPromptExpansion: התור מסתיים והסיבה מוצגת כאזהרה.
  • ב-PostToolUseFailure ו-TaskCreated: הסיבה מוחזרת לקלוד כשגיאת כלי והתור נמשך תמיד.
  • ב-TaskCompleted: בעת סימון משימה כהושלמה במהלך תור, הסיבה מוחזרת כשגיאת כלי; בעת סיום תור של חבר צוות, חבר הצוות נעצר אלא אם הוגדר continueOnBlock: true.
  • ב-TeammateIdle: חבר הצוות נעצר אלא אם הוגדר continueOnBlock: true.
  • ב-PermissionRequest ו-PermissionDenied: להחזרת ok: false אין השפעה; יש להשתמש בהוק פקודה.

דוגמה לבדיקת השלמת משימות לפני עצירה:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "Evaluate if Claude should stop: $ARGUMENTS. Check if all tasks are complete. Respond with JSON: {\"ok\": true} to allow stopping, or {\"ok\": false, \"reason\": \"what remains to be done\"} to continue working.",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

#הוקים מבוססי סוכן

כאשר נדרש אימות שכולל בדיקת קבצים או הרצת פקודות בדיקה, משתמשים בהוקים מסוג type: "agent". הוק זה יוצר סוכן משנה ייעודי שיכול לקרוא קבצים, לחפש בקוד ולהפעיל כלים (כגון Read, Grep, ו-Glob) כדי לבדוק תנאים לפני מתן ההכרעה. תכונה זו מוגדרת ניסיונית (experimental) ועשויה להשתנות בעתיד.

הסוכן פועל לפי פורמט של { "ok": true } או { "ok": false, "reason": "..." }, עם פסק זמן ברירת מחדל של 60 שניות ועד 50 תורות שימוש בכלים. כאשר הוא מחזיר ok: false, ההתנהגות זהה להוק פרומפט עם continueOnBlock: true באותו אירוע. הוקי סוכן אינם תומכים בשדות impossible או continueOnBlock. המשתנה המיוחד $ARGUMENTS מוחלף אוטומטית בנתוני ה-JSON של האירוע.

דוגמה לאימות מעבר בדיקות לפני סיום:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "Verify that all unit tests pass. Run the test suite and check the results. $ARGUMENTS",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

#הוקי HTTP

הוקים מסוג type: "http" שולחים את נתוני האירוע בבקשת POST אל נקודת קצה מרוחקת עם Content-Type: application/json. השרת מקבל בגוף הבקשה את אותו מבנה JSON שמגיע ל-stdin של פקודת מעטפת, ומחזיר בגוף התשובה אובייקט JSON באותו מבנה פלט מובנה.

{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "http",
            "url": "http://localhost:8080/hooks/tool-use",
            "headers": {
              "Authorization": "Bearer $MY_TOKEN"
            },
            "allowedEnvVars": ["MY_TOKEN"],
            "timeout": 30
          }
        ]
      }
    ]
  }
}

בכותרות הבקשה ניתן לשלב משתני סביבה בתחביר $VAR_NAME או ${VAR_NAME}. מטעמי אבטחה, רק משתנים שצוינו במפורש במערך allowedEnvVars יפוענחו, ושאר המשתנים יישארו ריקים.

טיפול בתשובות HTTP:

  • סטטוס 2xx עם גוף ריק: הצלחה (שקול לקוד יציאה 0 ללא פלט).
  • סטטוס 2xx עם גוף JSON: מפוענח לפי אותם כללי פלט JSON של הוקי פקודה.
  • סטטוס 2xx עם טקסט רגיל: שגיאה לא חוסמת.
  • סטטוס שאינו 2xx או כשל בחיבור: שגיאה לא חוסמת, והביצוע נמשך.
  • קודי סטטוס HTTP לבדם אינם יכולים לחסום פעולות; כדי לחסום פעולה, יש להחזיר תשובת 2xx עם גוף JSON המכיל את שדות ההחלטה המתאימים.

#מגבלות ופתרון בעיות

#מגבלות ומצבי הרשאות

  • זמני ריצה (Timeouts): פסק זמן ברירת המחדל להוקי command, http ו-mcp_tool הוא 600 שניות (10 דקות). הוא מתקצר ל-30 שניות באירועים UserPromptSubmit, PreModelSwitch ו-PostModelSwitch, ול-10 שניות ב-MessageDisplay. להוקי prompt ברירת המחדל היא 30 שניות, ולהוקי agent 60 שניות. הוקי SessionEnd חולקים תקציב כולל של 1.5 שניות (ניתן להגדלה עד 60 שניות באמצעות הגדרת timeout פרטנית בהגדרות, או באמצעות המשתנה CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS). ניתן לדרוס את פסק הזמן לכל הוק באמצעות השדה timeout בשניות.
  • התנהגות פקיעת זמן (Timeout): באירוע PreModelSwitch, הוק שנכשל עקב פקיעת זמן חוסם את החלפת המודל. לעומת זאת, באירוע PreToolUse, הוק פקודה שפוקע זמנו אינו חוסם את הקריאה לכלי והיא ממשיכה לבדיקת הרשאות רגילה (אך בסוכני משנה של ה-Agent SDK, פקיעת זמן חוסמת את הכלי).
  • הרצת הוקים ברקע (Async Hooks): הוספת "async": true להוקי פקודה מריצה אותם ברקע בלי להמתין להם. הוקים אסינכרוניים אינם אוכפים מגבלת timeout, ואינם יכולים לחסום פעולות. הפלט שלהם (additionalContext ו-systemMessage) מועבר לקלוד בתור השיחה הבא. הגדרת "asyncRewake": true מריצה ברקע אך מעירה את קלוד מיד אם הפקודה יוצאת בקוד 2, כאשר הודעת ה-stderr מוצגת כתזכורת מערכת.
  • אי יכולת ביטול פעולות עבר: הוקי PostToolUse אינם יכולים לבטל פעולות, מאחר שהכלי כבר הורץ.
  • סוכני משנה ומסירת דוחות: החל מגרסה v2.1.271, סוכן משנה הפועל עם הכלי SubagentHandback (המסופק במצב auto) מוסר את הדוח שלו דרך הכלי ולא כטקסט חופשי. שדה content מכיל הערה קצרה בלבד; כדי לקרוא את הדוח המלא, יש להגדיר הוק PreToolUse או PostToolUse המותאם לכלי SubagentHandback ולקרוא את tool_input.message. בנוסף, באירוע SubagentStop, השדה last_assistant_message מכיל את דברי הסיום של הסוכן ולא את הדוח שנמסר.
  • עצירה בכל תור: הוקי Stop מופעלים בכל פעם שקלוד מסיים תור תגובה, ולא רק כשהמשימה כולה הושלמה.
  • יחסי גומלין עם מצבי הרשאות: הוקי PreToolUse רצים לפני כל בדיקת הרשאה, בכל מצבי ההרשאות כולל מצב dontAsk. הוק שמחזיר permissionDecision: "deny" חוסם את הכלי גם במצב bypassPermissions וגם עם הדגל --dangerously-skip-permissions. לעומת זאת, החזרת "allow" אינה עוקפת כללי deny מפורשים, ואינה מבטלת אישור חובה עבור כלי MCP המסומנים כדורשי אינטראקציה (requiresUserInteraction).

#מלכודות נפוצות ופתרון תקלות

  • ההוק אינו מופעל: ודאו באמצעות /hooks שההוק מופיע ברשימה תחת האירוע הנכון. שמות הכלים ב-matcher רגישים לאותיות גדולות וקטנות (case-sensitive).
  • שגיאת הוק בפלט: בדקו את הסקריפט ידנית על ידי הזרמת JSON דוגמה בטרמינל:
    echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh
    echo $?
    אם מופיעה שגיאת "command not found", השתמשו בנתיבים מוחלטים או ב-${CLAUDE_PROJECT_DIR}. כדי למנוע בעיות ציטוט במעטפת, הוסיפו "args": [] להגדרת ההוק כדי להפעילו ישירות ללא מעטפת (exec form). אם מופיעה שגיאה על jq, התקינו את הכלי או עברו לפענוח ב-Python או ב-Node.js. ודאו הרשאות הרצה עם chmod +x.
  • תפריט /hooks אינו מציג את ההוק: ודאו שקובץ ה-JSON תקין ושאין בו פסיקים מיותרים בסוף רשימות או הערות שאינן נתמכות. שינויים בקובץ נקלטים אוטומטית על ידי צופה הקבצים, אך אם הם לא מופיעים, הפעילו מחדש את הסשן.
  • הוק Stop נכנס ללולאת חסימות ומגיע לתקרה: קלוד קוד עוצר הוק Stop שחוסם 8 פעמים ברציפות ללא התקדמות ומסיים את התור באזהרה. כדי למנוע זאת, על הסקריפט לבדוק את השדה stop_hook_active בקלט ה-JSON ולצאת בקוד 0 אם ערכו true:
    #!/bin/bash
    INPUT=$(cat)
    if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
      exit 0
    fi
    במידת הצורך ניתן לשנות את התקרה באמצעות משתנה הסביבה CLAUDE_CODE_STOP_HOOK_BLOCK_CAP.
  • פלט ה-JSON אינו משפיע: אם פקודות בפרופיל המעטפת שלכם (כמו ~/.bashrc או ~/.zshrc) מדפיסות פלט טקסטואלי (כגון echo "ready"), הטקסט מתווסף לפני ה-JSON של ההוק ומונע מקלוד קוד לפענח אותו. עטפו פקודות אלו בפרופיל כך שירוצו רק במעטפת אינטראקטיבית:
    if [[ $- == *i* ]]; then
      echo "Shell ready"
    fi
    כמו כן, ודאו ששדות כמו permissionDecision מקוננים בתוך hookSpecificOutput ולא מוגדרים ברמה העליונה.
  • טכניקות ניפוי שגיאות: לחצו על Ctrl+O כדי להפעיל מצב verbose ביומן השיחה ולבדוק הודעות שגיאה של הוקים. להצגת פרטי ריצה מלאים של ההוקים (כולל stdin, stdout ו-stderr), הריצו את קלוד קוד עם claude --debug ובדקו את היומן בנתיב ~/.claude/debug/<session-id>.txt. לכתיבת יומן הדיבאג ישירות לקובץ מסוים, השתמשו בדגל claude --debug-file <path>. לפירוט מעמיק יותר של התאמת matchers, הגדירו CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose.