הוק לקלוד עבור קומיט אחרי כל שינוי
אתמול בוובינר הראיתי איך להשתמש בגיט בעבודה עם סוכני קידוד ואחת ההמלצות החשובות היתה לא לפחד מקומיטים. כל פעם שיש שינוי קוד עושים קומיט ואחרי זה אם מתחרטים אפשר להשתמש ב git reset --hard כדי לחזור אחורה.
חלק מהמשתתפים העירו שאפשר לעשות את הקומיטים האלה אוטומטית ואז לא שוכחים. הלכתי לחקור את הרעיון ושמחתי לראות שזה עבד די בקלות. אם אתם בקלוד קוד אפשר ליצור קובץ .claude/settings.json בתיקיית הפרויקט עם התוכן הבא:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/auto-commit.sh",
"async": true,
"timeout": 30
}
]
}
]
}
}
ואז הסקריפט auto-commit.sh ירוץ כל פעם שקלוד מסיים לכתוב תשובה. את הסקריפט עצמו נתתי לקלוד לכתוב והוא נראה כך:
#!/usr/bin/env bash
# Stop hook: auto-commit Claude's changes using the last user prompt
# as the commit message.
set -uo pipefail
INPUT=$(cat)
read -r STOP_HOOK_ACTIVE TRANSCRIPT_PATH PROJECT_DIR < <(
printf '%s' "$INPUT" | jq -r '[.stop_hook_active // false, .transcript_path // "", .cwd // ""] | @tsv'
)
[ "$STOP_HOOK_ACTIVE" = "true" ] && exit 0
[ -n "$PROJECT_DIR" ] && cd "$PROJECT_DIR" 2>/dev/null || exit 0
git rev-parse --git-dir >/dev/null 2>&1 || exit 0
git add -A 2>/dev/null || exit 0
git diff --cached --quiet && exit 0
# Last user text message from this turn's transcript.
# Skips tool_result entries and slash-commands (which start with '<').
USER_PROMPT=""
if [ -f "$TRANSCRIPT_PATH" ]; then
USER_PROMPT=$(jq -r '
select(.type == "user") | .message.content
| if type == "string" then .
elif type == "array" then (map(select(.type == "text")) | .[0].text // "")
else "" end
| select(. != "" and (startswith("<") | not))
' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)
fi
# Use the user prompt as the commit message; first line as subject (capped at
# 72 chars), remaining lines as the body.
if [ -n "$USER_PROMPT" ]; then
SUBJECT=$(printf '%s' "$USER_PROMPT" | head -1 | cut -c1-72)
BODY=$(printf '%s' "$USER_PROMPT" | tail -n +2)
else
SUBJECT="checkpoint: $(date +%H:%M)"
BODY=""
fi
if [ -n "$BODY" ]; then
git commit --no-verify -m "$SUBJECT" -m "$BODY" >/dev/null 2>&1 || true
else
git commit --no-verify -m "$SUBJECT" >/dev/null 2>&1 || true
fi
exit 0
קלוד מפעיל את הסקריפט עם JSON של מידע על השיחה האחרונה. מה שמעניין אותנו מתוך ה JSON הזה הוא ההודעה של המשתמש, כי אני אוהב שהפרומפט שלי הופך להודעת הקומיט (אם צריך הודעה יותר מתוחכמת אפשר להשתמש ב git commit --amend כדי לתקן). ליתר בטחון קלוד הוסיף --no-verify לפקודת הקומיט כדי לדלג על קומיט הוקס. אני חושב שזה הוגן וממילא לא משתמש בקומיט הוקס. יש גם בדיקה בהתחלה שמדלגת על כל הסקריפט אם אנחנו לא בתוך ריפו.
סך הכל רעיון מעניין. שימו לב שאפשר להפעיל את ה hook או מקומית לפרויקט הנוכחי או באופן גלובאלי אם רושמים אותו ב settings של קלוד בתיקיית הבית. אני מתכנן להתחיל עם פרויקט אחד ולראות איך זה יעבוד לאורך זמן.