ویژگی پیشرفته

Hooks: گردش‌کار سفارشی خود را بسازید

در هر مرحله از فراخوانی‌های ابزار Claude Code منطق سفارشی تزریق کنید — قالب‌بندی خودکار، آزمون، بازبینی و ایمن‌سازی — همه به‌صورت خودکار

#Hooks #Automation #ClaudeCode #CI/CD

Hooks در Claude Code چیست؟

Hooks سیستم رویداد Claude Code است که به شما امکان می‌دهد پیش و پس از فراخوانی‌های ابزار، اسکریپت‌های shell سفارشی اجرا کنید. linterها را پس از ذخیره فایل به‌طور خودکار اجرا کنید، آزمون‌ها را پیش از commit اجرا کنید، یا هنگام دسترسی به فایل‌های حساس هشدار ایجاد کنید — همه بدون دخالت دستی.

پیکربندی سه سطح تودرتو دارد: رویداد، یک matcher که ابزارها را فیلتر می‌کند، و اسکریپت شما درون آرایه داخلی hooks. اسکریپت JSON این رویداد را از stdin می‌خواند و با کدهای خروج پاسخ می‌دهد: 0 یعنی مخالفتی نیست، 2 در رویدادهایی که اجازه می‌دهند فراخوانی را مسدود می‌کند. برای چهار رویداد زیر، یک هوک از نوع command در مهلت پیش‌فرض 600 ثانیه‌ای خود لغو می‌شود؛ این چهار مورد رایج‌اند، نه فهرست کامل رسمی (بررسی‌شده در 2026-09-22).

کاربر
یک prompt ارسال می‌کند
نقطه بازرسی هوک
پیش از اجرای ابزار بررسی می‌کند و می‌تواند مسدود کند
اجرای ابزار
تنها پس از آن ابزار اجرا می‌شود

انواع Hook توضیح داده شده

Hooks در Claude Code نقاط چرخه عمر ابزار، نشست و فشرده‌سازی را پوشش می‌دهند و کنترل‌کننده‌های command، HTTP و agent را دارند

PreToolUse: پیش از فراخوانی

پیش از اجرای ابزار فعال می‌شود — پارامترها را اعتبارسنجی کنید، مجوزها را بررسی کنید، به‌صورت خودکار تأیید یا رد کنید

"PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command" }] }]

PostToolUse: پس از فراخوانی

پس از اجرای ابزار فعال می‌شود — قالب‌بندی خودکار، اجرای آزمون‌ها، ارسال اعلان‌ها

"PostToolUse": [{ "matcher": "Edit|Write", "hooks": [{ "type": "command" }] }]

Notification: هنگام اعلان‌ها

هنگام اعلان‌های Claude Code فعال می‌شود — با Slack، ایمیل یا کانال‌های دیگر یکپارچه کنید

"Notification": [{ "matcher": "permission_prompt", "hooks": [{ "type": "command" }] }]

Stop: وقتی Claude کار را تمام می‌کند

وقتی Claude Code پاسخ‌دهی را تمام می‌کند فعال می‌شود — نتایج را ثبت کنید یا پاک‌سازی را اجرا کنید

"Stop": [{ "hooks": [{ "type": "command", "command": "~/scripts/on-stop.sh" }] }]

سه نمونه عملی خودکارسازی

سه مورد زیر یک ساختار مشترک دارند: رویداد را انتخاب کنید، آن را با matcher محدود کنید و اسکریپت را در آرایه داخلی hooks قرار دهید. قطعه‌کدها فقط قصد را نشان می‌دهند؛ بنابراین مرجع رسمی را منبع نام فیلدها و تودرتویی بدانید و هر چیزی را که اسکریپت‌تان باید بررسی کند از همان JSON روی stdin بخوانید.

1

قالب‌بندی پیش از کامیت

وقتی Claude در آستانه اجرای git commit است، PreToolUse ابتدا آرگومان‌ها را به اسکریپت شما می‌سپارد. اسکریپت دستور commit را تشخیص می‌دهد، قالب‌بند شما را اجرا می‌کند و با کد خروج پاسخ می‌دهد: 0 اجازه عبور فراخوانی را می‌دهد، 2 آن را مسدود می‌کند. همه این‌ها پیش از اجرا رخ می‌دهد، بنابراین commit مسدودشده درخت کاری را دست‌نخورده باقی می‌گذارد.

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "command": "if echo \"$TOOL_INPUT\" | grep -q 'git commit'; then npm run format; fi"
    }]
  }
}
2

اعلان پس از پایان تست‌ها

PostToolUse فقط پس از بازگشت موفق یک دستور فعال می‌شود؛ بنابراین اسکریپت شما می‌تواند pytest یا npm test را تشخیص دهد و یک اعلان دسکتاپ نمایش دهد. نمی‌تواند فراخوانی‌ای را که قبلاً اجرا شده خنثی کند و در خطاها ساکت می‌ماند؛ پس این اعلان یعنی نتایج آماده‌اند، نه اینکه تست‌ها موفق شده‌اند.

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash",
      "command": "if echo \"$TOOL_INPUT\" | grep -q 'pytest\\|npm test'; then notify-send 'Tests completed'; fi"
    }]
  }
}
3

رد ویرایش فایل‌های محرمانه

یک هوک PreToolUse روی Edit و Write قرار دهید: اسکریپت مسیر هدف را از stdin می‌گیرد و وقتی نام با .env، credentials یا مشابه آن مطابقت دارد با کد 2 خارج می‌شود. نوشتن پیش از رسیدن به دیسک رد می‌شود، بنابراین چیزی برای خنثی کردن وجود ندارد. matcher با مقدار Edit|Write هر دو ابزار را هم‌زمان پوشش می‌دهد.

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Edit|Write",
      "command": "if echo \"$TOOL_INPUT\" | grep -qE '\\.env|credentials|secrets'; then exit 2; fi"
    }]
  }
}

حالت headless و CI/CD

Claude Code را در خطوط لوله CI/CD با پرچم -p برای کارهای خودکارسازی بدون نظارت اجرا کنید

-p برای اجراهای غیرتعاملی

پرچم -p (یا --print) را به هر دستور claude اضافه کنید تا آن را به‌صورت غیرتعاملی اجرا کنید و پس از پایان نتیجه را چاپ کنید.

آن را به خط لوله CI وصل کنید

حالت غیرتعاملی از stdin می‌خواند و نتیجه را در stdout می‌نویسد؛ کد خروج 0 یعنی موفقیت، بنابراین اسکریپت‌های ساخت می‌توانند بر اساس آن شاخه‌بندی کنند.

خروجی ساختاریافته با JSON

برای انتخاب شکل پاسخ از --output-format استفاده کنید؛ json نتیجه را به‌همراه شناسه نشست و فراداده برمی‌گرداند تا آماده تجزیه توسط اسکریپت‌ها باشد.

فراخوانی غیرتعاملی در CI
# اجرای یک بازبینی به‌صورت غیرتعاملی: خروجی JSON، حداکثر 5 دور
claude -p "Review this PR and suggest improvements" \
  --output-format json \
  --max-turns 5

پیکربندی settings.json

Hooks خود را در .claude/settings.json تعریف کنید

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "command": "~/scripts/pre-bash-hook.sh"
      },
      {
        "matcher": "Edit|Write",
        "command": "~/scripts/protect-sensitive-files.sh"
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Bash",
        "command": "~/scripts/post-bash-hook.sh"
      }
    ],
    "Notification": [
      {
        "command": "~/scripts/send-notification.sh"
      }
    ],
    "Stop": [
      {
        "command": "~/scripts/on-stop.sh"
      }
    ]
  }
}

بهترین شیوه‌های Hooks

این چهار نکته از مرجع Hooks در Claude Code، از جمله یادداشت‌های امنیتی آن، پیروی می‌کنند که در 2026-09-22 بررسی شده است؛ آن‌ها نحوه نوشتن اسکریپت‌ها را پوشش می‌دهند، در حالی که ساختار پیکربندی در بخش settings.json بالا قرار دارد.

مسدودسازی با کد خروج 2

مرجع می‌گوید برای بیشتر رویدادهای hook، کد خروج 2 تنها کدی است که به‌تنهایی مسدود می‌کند؛ هر کد خروج دیگری خطایی غیرمسدودکننده است و اقدام ادامه می‌یابد. اسکریپتی که برای اعمال سیاست در نظر گرفته شده است باید با کد 2 خارج شود.

محرک‌ها را با matcher محدود کنید

فیلد matcher تعیین می‌کند Hooks چه زمانی فعال شوند. یک نام ابزار ساده دقیقاً مطابقت می‌کند، در حالی که مقداری با کاراکترهای دیگر به‌عنوان یک عبارت باقاعده JavaScript بدون لنگر ارزیابی می‌شود: Edit.* با هر دو Edit و NotebookEdit مطابقت می‌کند، بنابراین برای مطابقت کل رشته لنگر اضافه کنید.

پایان مهلت به معنای مسدودسازی نیست

Claude Code هر Hook را که به مهلت خود می‌رسد لغو می‌کند و خروجی را کنار می‌گذارد؛ بنابراین در بیشتر رویدادها، یک Hook با مهلت تمام‌شده هیچ تصمیمی ارائه نمی‌دهد. مستندات هشدار می‌دهند که در PreToolUse چنین Hook از نوع command فراخوانی را مسدود نمی‌کند، در حالی که در PreModelSwitch سوئیچ را مسدود می‌کند. گزارش‌های debug جزئیات اجرا را در خود دارند.

ورودی را غیرقابل‌اعتماد در نظر بگیرید

یادداشت‌های امنیتی چند عادت را فهرست می‌کنند: هرگز به داده‌های ورودی کورکورانه اعتماد نکنید، متغیرهای shell را همیشه در نقل‌قول بگذارید، مسیرهایی مانند ../ را از نظر path traversal بررسی کنید و از فایل‌های حساس مانند .env یا .git صرف‌نظر کنید. یک Hook یک payload JSON می‌خواند که فیلدهایش می‌توانند هر چیزی از بیرون را در خود جای دهند.

پرسش‌های متداول

اسکریپت Hook چگونه JSON ورودی را دریافت می‌کند؟

یک Hook از نوع command یک شیء JSON را روی stdin دریافت می‌کند. فیلدهای رایج شامل session_id، transcript_path، cwd و hook_event_name هستند؛ سپس هر رویداد فیلدهای خودش را اضافه می‌کند، بنابراین رویدادهای ابزار tool_name و tool_input را همراه دارند.

چگونه می‌توان کاری کرد که یک Hook فراخوانی ابزار را مسدود کند؟

اسکریپت را به PreToolUse متصل کنید و برای فراخوانی‌هایی که نباید اجرا شوند کد خروج 2 را برگردانید. جدول رویدادها PreToolUse را قابل‌مسدودسازی علامت می‌زند، بنابراین کد خروج 2 آن فراخوانی را متوقف می‌کند؛ برای تصمیم شرطی، به‌جای آن JSON را همراه با permissionDecision چاپ کنید. کد خروج 1 در بیشتر رویدادها هیچ چیزی را مسدود نمی‌کند.

وقتی مهلت یک Hook تمام می‌شود چه اتفاقی می‌افتد؟

هوکی که به پایان مهلت خود می‌رسد لغو می‌شود و خروجی‌اش دور ریخته می‌شود؛ در بیشتر رویدادها این یعنی هیچ تصمیمی گرفته نمی‌شود. PreModelSwitch موردی است که اتمام زمان، سوئیچ را مسدود می‌کند. مسیر اسکریپت با تایپ اشتباه نیز خطای غیرمسدودکننده است و مستندات به شما می‌گویند مراقب آن اعلان در نخستین اجرای یک هوک سیاستی باشید.

پیکربندی هوک‌ها در کدام فایل قرار دارد؟

دامنه از محل تعریف شما پیروی می‌کند: ~/.claude/settings.json همه پروژه‌های شما را پوشش می‌دهد و روی دستگاه شما می‌ماند؛ .claude/settings.json مخصوص هر پروژه است و می‌توان آن را کامیت کرد؛ .claude/settings.local.json مخصوص هر پروژه است و وقتی Claude Code تنظیمی را در آن ذخیره می‌کند، در gitignore قرار می‌گیرد.

خودکارسازی سازمانی با QCode.cc

پلتفرم توسعه‌دهندگان QCode.cc را با Hooks ترکیب کنید تا خطوط لوله کدنویسی با هوش مصنوعی در سطح سازمانی بسازید

دسترسی به دروازه از طریق ANTHROPIC_BASE_URL

مرجع رسمی متغیرهای محیطی Claude Code می‌گوید ANTHROPIC_BASE_URL می‌تواند نقطه پایانی API را به یک proxy یا gateway هدایت کند؛ QCode راهنمای راه‌اندازی این مسیر را در سایت منتشر می‌کند (بررسی‌شده در 2026-09-22).

ترمزها پیش از خودکارسازی

پیش از خودکارسازی ترمز بگذارید: مثال رسمی اسکریپتی را نشان می‌دهد که مسیر هدف را با الگوهای محافظت‌شده بررسی می‌کند و با کد 2 خارج می‌شود تا ویرایش فایل‌های حساس را مسدود کند.

یک پیکربندی برای کل تیم

جدول رسمی مکان‌های هوک می‌گوید .claude/settings.json را می‌توان در مخزن کامیت کرد؛ آن را با یک کلید QCode مشترک تیم جفت کنید تا هوک‌های همه یکسان رفتار کنند.

یک پلن، سه پلتفرم

QCode همچنین از OpenAI Codex / GPT-5.6 پشتیبانی می‌کند

سهمیه QCode شما در Claude Code و OpenAI Codex CLI کار می‌کند — یک موجودی مشترک، صفر هزینه تکراری.

گردش‌کار Claude Code خود را خودکار کنید

با Hooks + QCode.cc پتانسیل کامل کدنویسی با هوش مصنوعی را آزاد کنید

به‌روزرسانی شده 2026-11-14

مطمئن نیستید از کجا شروع کنید؟

یک هفته امتحان کنید

بسته کوچک: $4 برای $30 سهمیه، به مدت 7 روز معتبر

هر روز از آن استفاده کنید

Starter: $9.00/ماه با $5 سهمیه در هر روز — فقط $0.060 به‌ازای هر $1 سهمیه، در برابر حدود $0.113 برای بسته متوسط