מערכת ה-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) לשיתוף הרחבות בין פרויקטים שונים.
כדי ליצור הוק, מוסיפים בלוק hooks לקובץ הגדרות. ההליך הבא מגדיר הוק להתראות שולחן עבודה, כדי לקבל התראה בכל פעם שקלוד ממתין לקלט במקום לצפות בטרמינל.
הוספת ההוק להגדרות:
פתחו את הקובץ ~/.claude/settings.json והוסיפו הוק עבור אירוע Notification. אם הקובץ אינו קיים, צרו אותו. הדוגמה הבאה משתמשת ב-osascript עבור macOS:
ניתן גם לבקש מקלוד לכתוב את ההוק על ידי תיאור הפעולה הרצויה ב-CLI.
אימות ההגדרה:
הקלידו /hooks כדי לפתוח את תפריט העיון בהוקים. יוצגו כל אירועי ההוק הזמינים, לצד מספר ההוקים המוגדרים לכל אירוע. התפריט מציג את כל חמשת הסוגים (command, prompt, agent, http, mcp_tool) עם קידומת המזהה את מקור ההגדרה: User Settings, Project Settings, Local Settings, Plugin Hooks, או Session Hooks. בחרו ב-Notification כדי לוודא שההוק החדש מופיע ברשימה. בחירת ההוק מציגה את פרטיו: האירוע, ה-matcher, הסוג, קובץ המקור והפקודה.
תפריט /hooks הוא לקריאה בלבד. כדי להוסיף, לערוך או להסיר הוקים, יש לערוך את קובץ ה-JSON ישירות או לבקש מקלוד לבצע את השינוי. כדי להשבית זמנית את כל ההוקים בלי למחוק אותם, ניתן להגדיר "disableAllHooks": true בקובץ ההגדרות.
בדיקת ההוק:
לחצו על Esc כדי לחזור ל-CLI. לחצו על Shift+Tab עד ששורת המצב מציגה ⏸ manual mode on, בקשו מקלוד לבצע פעולה הדורשת הרשאה, ועברו לחלון אחר מחוץ לטרמינל. כעת אמורה להתקבל התראת שולחן עבודה.
הוקים מאפשרים להריץ קוד בנקודות מפתח במחזור החיים של קלוד קוד: עיצוב קבצים לאחר עריכה, חסימת פקודות לפני ביצוען, שליחת התראות כשקלוד זקוק לקלט, הזרקת הקשר בתחילת סשן, תגובה לשינויי תיקייה, אישור הרשאות אוטומטי, והרצת בדיקות ברקע.
אם לא מופיעה התראה: הפקודה osascript מנתבת התראות דרך האפליקציה המובנית Script Editor. אם אין לה הרשאת התראות, הפקודה נכשלת בשקט ומערכת macOS לא תבקש אישור. הריצו בטרמינל פעם אחת:
osascript -e 'display notification "test"'
דבר לא יופיע עדיין. פתחו את System Settings > Notifications, אתרו את Script Editor ברשימה, והפעילו את Allow Notifications. הריצו שוב את הפקודה כדי לוודא שהתראת הבדיקה מוצגת.
אם לא מופיעה התראה: notify-send זקוק ל-daemon של התראות שולחן עבודה, אשר אינו קיים בשרתי headless, בסשנים של SSH וברוב הקונטיינרים. בדקו תחילה את הפקודה ישירות:
notify-send 'Claude Code' 'test'
אם הפקודה אינה נמצאת, התקינו את החבילה libnotify-bin ב-Debian וב-Ubuntu, או את המקבילה בהפצה שלכם.
אם לא מופיעה תיבת דו שיח: פקודה זו פותחת תיבת הודעה ולא התראה בפינת המסך, ולכן היא עשויה להיפתח מאחורי חלון הטרמינל. בדקו את הפקודה תחילה ישירות ב-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 בשורש הפרויקט:
לבדיקת ההוק, בקשו מקלוד להוסיף שורה עם מחרוזות במירכאות בודדות לקובץ 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. קלוד קוד חוסם את העריכה לפני ביצועה ומעביר לקלוד את הודעת ה-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:
ה-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:
יש להריץ direnv allow פעם אחת בכל תיקייה המכילה .envrc כדי לאשר ל-direnv לטעון אותו. אם אתם משתמשים ב-devbox או ב-nix במקום direnv, אותו דפוס עובד עם devbox shellenv או devbox global shellenv במקום direnv export bash.
כדי להגיב לשינויים בקבצים מסוימים במקום בכל שינוי תיקייה, משתמשים בהוק FileChanged עם matcher המפרט את שמות הקבצים למעקב, מופרדים בקו אנכי (|). בעת בניית רשימת המעקב, קלוד קוד מפרק ערך זה לשמות קבצים מדויקים ולא כביטוי רגולרי. לדוגמה, למעקב אחר .envrc ו-.env בתיקיית העבודה:
הוקי CwdChanged ו-FileChanged יכולים להחזיר בפלט ה-JSON מערך בשם watchPaths כדי לעדכן דינמית את רשימת הנתיבים המוחלטים שבהם מתבצע מעקב.
אם מתווספת תיקיית עבודה נוספת במהלך הסשן באמצעות /add-dir או בקשת בקרה של ה-SDK מסוג register_repo_root, נורה האירוע DirectoryAdded.
דילוג על תיבת האישור עבור קריאות לכלים שאתם מאשרים תמיד. דוגמה זו מאשרת אוטומטית את הכלי ExitPlanMode, שקלוד קורא לו כשהוא מסיים להציג תוכנית ומבקש לעבור לביצוע, כדי שלא תישאלו על כך בכל פעם מחדש.
שלא כמו הדוגמאות הקודמות המבוססות על קודי יציאה, אישור אוטומטי דורש מההוק לכתוב החלטת JSON ל-stdout. קלוד קוד מריץ הוקי PermissionRequest כאשר הוא עומד לבקש מכם הרשאה, ואם ההוק מחזיר "behavior": "allow", קלוד קוד משיב לבקשה בשמכם.
ה-matcher מגביל את ההוק ל-ExitPlanMode בלבד, כך שבקשות אחרות אינן מושפעות. יש להוסיף ל-~/.claude/settings.json:
כשההוק מאשר, קלוד קוד יוצא ממצב תוכנית ומשחזר את מצב ההרשאות שהיה פעיל לפני הכניסה אליו. ביומן השיחה מוצג "Allowed by PermissionRequest hook" במקום תיבת הדו שיח. נתיב ההוק שומר תמיד על השיחה הנוכחית: הוא אינו יכול לאפס את ההקשר ולהתחיל סשן ביצוע נקי כפי שמאפשרת תיבת הדו שיח.
כדי להגדיר מצב הרשאות מסוים במקום זאת, פלט ההוק יכול לכלול מערך updatedPermissions עם רשומת setMode. הערך של mode יכול להיות default, auto, acceptEdits, dontAsk, bypassPermissions, plan, או manual (החל מגרסה v2.1.200 ככינוי ל-default), עם 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 ריק תאשר אוטומטית כל בקשת הרשאה, כולל פקודות מעטפת ומחיקת קבצים.
כאשר מספר הוקים מתאימים לאותו אירוע, כל פקודות ההוק רצות במקביל ומגיעות לסיומן לפני שקלוד קוד ממזג את התוצאות. החזרה של deny מהוק אחד אינה עוצרת את ההוקים המקבילים. אין להסתמך על deny כדי למנוע תופעות לוואי בהוק אחר.
בסיום כל ההוקים, קלוד קוד ממזג את הפלטים:
בהחלטות הרשאה של PreToolUse ו-PreModelSwitch, התשובה המגבילה ביותר קובעת לפי הסדר הבא: deny גובר על defer (ב-PreToolUse), שגובר על ask, שגובר על allow.
מחרוזות מ-additionalContext נאספות מכל ההוקים ומועברות יחד אל קלוד.
לדוגמה, הגדרת שני הוקים עבור Bash: הראשון מתעד כל פקודה ליומן ויוצא ב-0, והשני בודק פקודות הרסניות ויוצא ב-2 אם הפקודה מכילה rm -rf:
אם קלוד ינסה להריץ rm -rf /tmp/build, שני ההוקים ירוצו במקביל: הוק התיעוד ירשום את הפקודה ליומן, והוק האבטחה ייצא ב-2 ויחסום את הביצוע. הפקודה תיחסם, אך הרישום ביומן יתבצע בכל מקרה כי שני ההוקים רצו.
קלוד קוד מעביר נתוני 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.
עבור שליטה מדויקת, יוצאים בקוד 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" בשדה permissionDecision של PreToolUse מיועד לשילובים המריצים את claude -p כתהליך בן (כגון ב-Agent SDK או בממשקים עצמאיים). הוא מאפשר להשהות את קלוד, לאסוף קלט בממשק שלכם ולהמשיך מאוחר יותר:
קלוד קורא לכלי (כגון AskUserQuestion). הוק PreToolUse מופעל.
ההוק מחזיר permissionDecision: "defer". הכלי אינו מתבצע, והתהליך יוצא עם stop_reason: "tool_deferred", תוך שמירת הקריאה הממתינה ביומן.
התהליך המפעיל קורא את deferred_tool_use מתוצאת ה-SDK, מציג את השאלה למשתמש בממשק שלו וממתין למענה.
התהליך מריץ מחדש claude -p --resume <session-id> עם אותו מארח הרשאות. אותו כלי מפעיל שוב את PreToolUse.
ההוק מחזיר permissionDecision: "allow" יחד עם התשובות ב-updatedInput. הכלי מתבצע וקלוד ממשיך.
האפשרות "defer" נתמכת רק במצב -p וכאשר מתבצעת קריאה לכלי יחיד באותו תור. חידוש סשן שהושהה במצב תוכנית (plan mode) דורש העברת הדגל --permission-prompt-tool (החל מגרסה v2.1.246).
אירועים ללא תמיכה ב-matcher (נורים תמיד בכל מופע): UserPromptSubmit, PostToolBatch, Stop, TeammateIdle, TaskCreated, TaskCompleted, WorktreeCreate, WorktreeRemove, CwdChanged, ו-MessageDisplay.
כלי MCP משתמשים במבנה שמות ייחודי: mcp__<server>__<tool>. כדי להתאים לכל הכלים של שרת מסוים, חובה להוסיף .* בסוף: mcp__memory__.*. עבור כלים מתוספים המבנה כולל את שם התוסף: mcp__plugin_<plugin-name>_<server-name>__<tool>.
השמות משתנים בהתחלה מוסרים לפני ההשוואה, ו-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/**)".
כן (דורש אישור trust לתיקיית הפרויקט מגרסה v2.1.218)
בתוך כישורים (skills), ניתן להגדיר להוק את השדה once: true כדי שיוסר אוטומטית לאחר הפעלתו המוצלחת הראשונה.
סביבות ענן (סביבת הדפדפן) אינן קוראות את ~/.claude/settings.json המקומי; ההוקים שם מגיעים מהמאגר ומהגדרות מנוהלות של הארגון.
מנהלי מערכת בארגון יכולים להפעיל את allowManagedHooksOnly: true כדי לחסום הוקים מקומיים, של פרויקט, או של תוספים (למעט תוספים שהופעלו בכפייה בהגדרות המנוהלות).
ניתן להגביל כתובות HTTP באמצעות allowedHttpHookUrls ומשתני סביבה בכותרות באמצעות httpHookAllowedEnvVars.
כדי לבטל זמנית את כל ההוקים, מגדירים "disableAllHooks": true בקובץ ההגדרות, או מעבירים בדגל הפעלה: --settings '{"disableAllHooks": true}'.
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 מעבירה את הסיבה לקלוד וממשיכה את התור.
ב-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
}
]
}
]
}
}
הוקים מסוג type: "http" שולחים את נתוני האירוע בבקשת POST אל נקודת קצה מרוחקת עם Content-Type: application/json. השרת מקבל בגוף הבקשה את אותו מבנה JSON שמגיע ל-stdin של פקודת מעטפת, ומחזיר בגוף התשובה אובייקט JSON באותו מבנה פלט מובנה.
בכותרות הבקשה ניתן לשלב משתני סביבה בתחביר $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).
אם מופיעה שגיאת "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.