Blog

Claude Code 2026 dagi hooklar: bosqichma-bosqich sozlash va foydalanishga tayyor 7 ta misol

Markdown

.claude/settings.json uchun nusxalash va joylashga tayyor 7 ta hook: .env himoyasi, prettier, main’ga force-push, uzun tirelar va dev-server. 4 ta handler turi va 31 ta hodisa.

Maqolani to‘liq o‘qish

Claude Code’dagi hooklar — Claude amaliyotidan oldin yoki keyin avtomatik ishlaydigan shell buyruqlari, HTTP chaqiruvlari yoki qisqa LLM tekshiruvlaridir. Ular aniq vosita hodisasiga tekshiruv, tahrirdan keyin formatlash va seans boshida kontekst qo‘shadi. Mos PreToolUse chaqiruvni rad etishi mumkin. Regex misollari qulay himoya, barcha fayl yoki Git yo‘liga xavfsizlik chegarasi emas. Quyida 4 ta handler turi, 31 ta hayotiy sikl hodisasi, “qachon qoida hookda bo‘lishi kerak” testi, .claude/settings.json uchun nusxalashga tayyor 7 ta hook va o‘zim duch kelgan 3 ta xato tahlil qilinadi.

Ailoot hujjatlari: API, kalitlar va sozlash.

Claude Code’da hooklar nima?

Asosiy xulosa

Hook — muayyan hayotiy sikl hodisasiga javoban Claude Code ishga tushiradigan shell buyrug‘i, HTTP chaqiruvi, qisqa LLM so‘rovi yoki subagent. CLAUDE.md dagi ko‘rsatmalardan farqli ravishda, model ularni e’tiborsiz qoldirishi yoki unutishi mumkin, hook esa har safar bir xil ishlaydi: bu kod, tavsiya emas.

Yarim yil davomida “.env faylini to‘g‘ridan-to‘g‘ri tahrirlamang” qoidasini CLAUDE.md ichida saqladim. Claude uni oyiga bir marta buzardi. Ataylab emas; uzoq sessiya oxiriga kelib shunchaki unutardi. Bir safar .env ichiga ortiqcha token tushib qoldi; boshqa safar esa nomi takrorlangan o‘zgaruvchi ishlatilayotgan qiymat ustidan yozib yubordi.

Mos bevosita tahrir vositasi .env yo‘lini berganda, sozlangan hook shu chaqiruvni rad etadi. Bash redirection, skript, MCP va boshqa yo‘lga alohida nazorat kerak. Misol faylni o‘zgarmas qilmaydi.

Hooklar — siz belgilaydigan va Claude Code hayotiy siklining muayyan nuqtalarida avtomatik ishlaydigan shell buyruqlari, HTTP endpointlari yoki LLM so‘rovlaridir.

— Anthropic, https://code.claude.com/docs/en/hooks

Boshqacha aytganda, hook — Claude Code muayyan hodisada ishga tushiradigan sizning buyrug‘ingiz. Har bir fayl tahriri, Bash ishga tushirilishi, sessiya boshlanishi yoki subagent yakunlanishi — hook biriktirish mumkin bo‘lgan hodisa.

Vibe coder uchun bu nega muhim:

  • Maxfiy ma’lumotli fayllarni tasodifiy tahrirlardan himoya qilish.
  • Har bir kod yaratishdan keyin prettier/eslint’ni avtomatik ishga tushirish.
  • Aniq ruxsatsiz git push --force buyrug‘ining main’ga yuborilishini bloklash.
  • Har bir sessiya boshida yangi kontekst kiritish.
  • Claude amallarini audit uchun qayd etish.

CLAUDE.md kontekstni boshqaradi. Hooklar amallarni boshqaradi. Bular ikki xil narsa, ularni chalkashtirish esa yangi boshlovchilarning asosiy xatosi.

Hooklar CLAUDE.md va skills’dan nimasi bilan farq qiladi?

Asosiy xulosa

CLAUDE.md — sessiya boshida model o‘qib, bajarishga urinadigan matn. Hook — modeldan mustaqil ravishda hodisaga javoban Claude Code jarayoni ishga tushiradigan shell buyrug‘i. Skill esa Claude Skill vositasi orqali chaqirishi mumkin bo‘lgan, funksiya kabi, nomlangan ko‘rsatmalar to‘plami. Uchalasi turli vazifalarni hal qiladi.

Anthropic hujjatlarida CLAUDE.md va hooklar o‘rtasidagi farq aniq tushuntirilgan:

CLAUDE.md mazmuni tizim so‘rovining bir qismi sifatida emas, tizim so‘rovidan keyin foydalanuvchi xabari sifatida uzatiladi. Claude uni o‘qiydi va bajarishga urinadi, ammo qat’iy rioya qilinishiga kafolat yo‘q.

— Anthropic, xotira hujjatlari, https://code.claude.com/docs/en/memory

Boshqacha aytganda, CLAUDE.md mazmuni Claude’ga tizim ko‘rsatmasi sifatida emas, foydalanuvchidan kelgan birinchi xabar sifatida yetib boradi. Model uni o‘qib, bajarishga urinadi. Ammo, ayniqsa kontekst kengayib, eski ko‘rsatmalar siqib chiqariladigan uzoq sessiya oxirida, hech qanday kafolat yo‘q.

Hook boshqacha ishlaydi. U settings.json faylida bo‘ladi, modelga bog‘liq emas va Claude Code jarayoni tomonidan muayyan hodisada ishga tushiriladi: PreToolUse, PostToolUse, SessionStart va boshqalar. Buyruq Claude natijani qabul qilishidan oldin ishlaydi va amalni jismonan bloklashi mumkin (exit 2) yoki tahrirdan keyin faylni o‘zgartirishi mumkin (exit 0).

Taqqoslash:

XususiyatCLAUDE.mdHookSkill
Qayerda joylashganLoyiha ildizidagi CLAUDE.md.claude/settings.json.claude/skills/ papkasi
Kim ishga tushiradiModel uni foydalanuvchi xabarining bir qismi sifatida o‘qiydiClaude Code jarayoni hodisa yuz bergandaModel Skill vositasi orqali
Bajarilish kafolatiYo‘q (eng yaxshi urinish)Sozlangan mos command hook kod bajaradi; xato va exit xulqi hodisaga bog‘liqModel chaqiruvi orqali (ruxsat bilan, lekin shell darajasida emas)
Nima uchunLoyiha konteksti, ohang, uslub, yo‘naltirishCheklovlar, formatlash, muayyan fayllar tekshiruviParametrlarga ega murakkab ko‘p bosqichli amallar
Qachon ishlaydiSessiyadagi har bir model xabaridaHayotiy sikl hodisasidaModel chaqirganida
Amalni bloklay oladimi?Yo‘qHa (exit 2)Yo‘q

To‘liq CLAUDE.md shabloni va uni doimiy ravishda yangilab borish uchun 6 qoida 2026-yilda CLAUDE.md’ni sozlash: tayyor shablon va 6 qoida qo‘llanmasida. Nomlangan imkoniyatlar sifatidagi skill’lar haqida Claude Code Skills: o‘z kutubxonangizni qanday yaratish maqolasidan bilib oling.

Hook — eng quyi daraja: modelsiz, talqinsiz, shunchaki shell.

Hooklar Plan Mode va /compact bilan bir qatorda kontekst muhandisligi vositalaridan biri.

4 ta hook turi: Command, HTTP, Prompt, Agent — qaysi birini tanlash kerak?

Asosiy xulosa

Claude Code’da 4 ta handler turi bor. Command — shell skripti, eng keng tarqalgan tur. HTTP URL’ingizga POST so‘rov yuboradi; jamoalar va integratsiyalar uchun. Prompt semantik tekshiruv uchun qisqa Haiku chaqiruvini amalga oshiradi. Agent chuqur tekshiruv uchun vositalardan foydalana oladigan subagent yaratadi. Yangi boshlovchilarga Command va Prompt kerak; ular vazifalarning 90% ini qamrab oladi.

TurNima qiladiQachon tanlash kerakMurakkablik
CommandShell buyrug‘ini ishga tushiradi, stdin orqali JSON oladi va chiqish kodi hamda stdout bilan javob beradiHolatlarning 90% ida: yo‘llarni tekshirish, formatlash, kontent bo‘yicha grep, lsof, git amallaripast
HTTPJSON tanasi bilan URL’ingizga POST so‘rov yuboradi va javobda JSON oladiQoida jamoa/CI doirasida bo‘lishi kerak bo‘lganda: markazlashgan tekshiruv, umumiy holat paneli, masofaviy audito‘rta (server talab qiladi)
PromptHaiku’ga (standart holatda) qisqa so‘rov yuboradi va semantik baho uchun ha/yo‘q javobini oladiGrep yetarli bo‘lmaganda: “bu matn korporativ uslubda eshitiladimi, bahola”past
AgentKo‘p bosqichli tekshiruvlar uchun Read/Grep/Glob ruxsatlariga ega subagent yaratadiChuqur tekshiruv: “barcha o‘zgargan fayllarni top va ularga mos testlar borligini tekshir”yuqori

Eng ko‘p uchraydigan xato — Prompt kerak bo‘lgan ishni Command bilan bajarishga urinish. Masalan, “.md fayllarida uzun tire ishlatma” — grep vazifasi, demak Command juda mos. Ammo “korporativ ohangda yozma” semantik masala, shuning uchun Prompt kerak.

Endi boshlayotgan bo‘lsangiz, Command’dan foydalaning. Quyidagi foydalanishga tayyor 7 ta hookning barchasi Command. HTTP/Prompt/Agent’ga keyin, tayyor bo‘lganingizda o‘tasiz.

settings.json qayerda va sozlamaning 4 darajasi qanday?

Asosiy xulosa

Claude Code konfiguratsiyani 4 joydan qidiradi: korporativ (MDM orqali joriy qilinadi), foydalanuvchi (~/.claude/settings.json), loyiha (repo ildizidagi .claude/settings.json) va mahalliy (.claude/settings.local.json, git’ga kirmaydi). Sessiya boshlanganda bu 4 fayl birlashtiriladi, bunda quyi daraja ustunlik qiladi.

DarajaYo‘lQachon amal qiladiGit’dami?
Korporativ/Library/Application Support/ClaudeCode/settings.json (Mac), /etc/claude-code/settings.json (Linux)MDM orqali butun jamoadayo‘q
Foydalanuvchi~/.claude/settings.jsonBitta foydalanuvchining barcha loyihalaridayo‘q
LoyihaRepo ildizidagi .claude/settings.jsonButun jamoa uchun shu loyihadaha
Mahalliy.claude/settings.local.jsonFaqat shu loyiha va faqat shu foydalanuvchi uchunyo‘q (.gitignore ichida)

Quyida bayon qilingan 7 ta hookni loyiha .claude/settings.json faylida saqlayman, shunda ular repo klonlanganda avtomatik qo‘shiladi va Claude yangi oynada ham bir xil qoidalarga amal qiladi. Shaxsiy tajriba hooklari jamoaga xalaqit bermasligi uchun .claude/settings.local.json fayliga joylanadi.

Sessiya boshlanganda 4 faylning barchasi birlashtiriladi. Qoidalar to‘qnashsa, quyi daraja ustunlik qiladi (mahalliy loyiha darajasidan, loyiha foydalanuvchi darajasidan ustun).

Birinchi hookni yaratishning eng tez yo‘li — Claude Code ichidagi interaktiv /hooks menyusi. Ro‘yxatdan hodisani tanlang, moslashtirgichni (masalan, Bash yoki Edit) belgilang va buyruqni kiriting. Claude Code siz uchun settings.json fayliga yaroqli JSON yozadi.

Hayotiy siklning 31 hodisasi: yangi boshlovchilarga qaysilari kerak?

Asosiy xulosa

Hozir Claude Code’da hayotiy siklning 31 hodisasi bor; ular 3 xil takrorlanish davriga bo‘lingan: har sessiyada bir marta (SessionStart/SessionEnd), har navbatda bir marta (UserPromptSubmit/Stop) va har bir vosita chaqiruvida (PreToolUse/PostToolUse). Yangi boshlovchilarga 31 hodisadan 4 tasi kerak: cheklovlar uchun PreToolUse, avtomatik tahrirlar uchun PostToolUse, kontekst uchun SessionStart va yakuniy tekshiruvlar uchun Stop.

Hodisalar uch chastotada yuz beradi: har sessiyada bir marta (SessionStart, SessionEnd), har navbatda bir marta (UserPromptSubmit, Stop, StopFailure) va agent siklidagi har bir vosita chaqiruvida (PreToolUse, PostToolUse).

— Anthropic, hooklar ma’lumotnomasi, https://code.claude.com/docs/en/hooks

Chalkashmaslik uchun uch takrorlanish davrini tushunish muhim:

  1. Har sessiyada bir marta - SessionStart, SessionEnd, Setup. Bular Claude Code ochilganda va yopilganda bir marta ishlaydi. Ulardan kontekstni boshlang‘ich holatga keltirish va vaqtinchalik fayllarni tozalash uchun foydalaning.
  2. Har navbatda bir marta - UserPromptSubmit, UserPromptExpansion, Stop, StopFailure. Bular har bir xabaringizda va model to‘xtagan har safar ishga tushadi. Ulardan suhbatni qayd etish va yakuniy natijani tekshirish uchun foydalaning.
  3. Har bir vosita chaqiruvida - PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest, PermissionDenied, PostToolBatch, SubagentStart, SubagentStop. Bular har bir fayl tahriri, Bash ishga tushirilishi, o‘qish yoki qidiruvda ishga tushadi. Bu cheklovlar, formatlash va tekshiruvlar joylashadigan eng faol qatlam.

31 hodisaning to‘liq ro‘yxatiga asinxron/reaktiv hodisalar ham kiradi: TeammateIdle, PreCompact, PostCompact, Elicitation, ElicitationResult, InstructionsLoaded, ConfigChange, CwdChanged, FileChanged, WorktreeCreate, WorktreeRemove, Notification. Bular ilg‘or holatlar uchun; hozircha ularni chetlab o‘ting.

Besh savolli test: qoida qachon hookda bo‘lishi kerak, qachon CLAUDE.md’da qoladi?

Asosiy xulosa

Agar qoida kontekstga emas, amalga tegishli bo‘lsa, xavfsizlik/pul/ma’lumotga taalluqli bo‘lsa, grep/regex orqali tekshirilsa, buzilsa ortga qaytarish qiyin bo‘lsa va Claude uni kamida bir marta buzgan bo‘lsa, u hookda bo‘lishi kerak. Bu besh javobdan uchtadan kami “ha” bo‘lsa, qoida CLAUDE.md’da qoladi. Testni 80 qatorimga qo‘lladim va 5 qoida hooklarga ko‘chdi.

Men uchun bu tavsiya emas, qonun kabi ishlaydi. CLAUDE.md va hook o‘rtasida tanlashni besh savolli sodda testga keltirdim. Kamida uchta javob “ha” bo‘lsa, qoida hookga o‘tadi. Uchtadan kami bo‘lsa, matnda qoladi.

“Qoida qachon hookda bo‘lishi kerak?” testi:

  1. Bu qoida kontekstga emas, amalga tegishlimi? (“rm -rf ni ishga tushirma” — amal; “menda TypeScript loyihasi bor” — kontekst.)
  2. Bu qoida xavfsizlik, pul yoki ma’lumotga taalluqlimi? (“.env ga tegma”, “kalitlarni e’lon qilma”.)
  3. Uni grep, regex yoki shell buyrug‘ining chiqish kodi bilan tekshirish mumkinmi? (“.md ni tahrirlagandan keyin uzun tire yo‘qligini tekshir.”)
  4. Qoida buzilsa, oqibatlarni ortga qaytarish og‘riqli bo‘ladimi? (“main’ga force-push”ni ortga qaytarish qiyin; “gap oxiriga nuqta qo‘yishni unutish” oson.)
  5. Claude bu qoidani hech bo‘lmaganda bir marta unutganini ko‘rganmisiz?

Misol: “Uzun tire ishlatma; faqat defis ishlat.” Amalmi? Ha. Xavfsizlikmi? Yo‘q. Grep bilan tekshiriladimi? Ha. Ortga qaytarish qiyinmi? Yo‘q. Buzilganini ko‘rganmisiz? Ha. 5 tadan 3 ta: hookga qo‘ying.

Qarama-qarshi misol: “Men dasturchilarni emas, vibe coderlarni nazarda tutyapman; jargon ishlatmay yoz.” Amalmi? Ko‘proq kontekstga o‘xshaydi. Xavfsizlikmi? Yo‘q. Regex bilan tekshirish mumkinmi? Juda qiyin. Ortga qaytarish qiyinmi? Yo‘q. Buzilganini ko‘rganmisiz? Ha. 5 tadan 1 ta: CLAUDE.md’da qoldiring.

Qoidalarimdan beshtasi testdan o‘tdi. Ular hooklarga ko‘chirildi. Qolgan 75% matnli faylda qoldi.

Nusxalashga tayyor 7 ta hook

Asosiy xulosa

Quyida .claude/settings.json uchun foydalanishga tayyor 7 ta hook: .env tahririni bloklash, prettier’ni avtomatik ishga tushirish, main’ga force-push’ning oldini olish, uzun tirelarni tekshirish, npm run dev dan oldin portni bo‘shatish, testlar muvaffaqiyatli o‘tgandan keyin avtomatik commit qilish va sessiya boshida yangi kontekst kiritish. Har birini faylga ko‘chiring, Claude Code’ni qayta ishga tushiring, shunda ishlaydi.

Barcha 7 hook loyiha ildizidagi bitta .claude/settings.json faylida saqlanadi. Har bir yozuvda hodisa turi, vosita filtri (matcher) va shell buyrug‘i bor. exit 2 mos PreToolUse’ni bajarishdan oldin rad etadi. PostToolUse’da amal allaqachon bo‘lgan: hook fikr bildiradi, uni qaytara olmaydi.

Ko‘pchilik hook hodisalarida faqat `exit 2` kodi amalni bloklaydi. Claude Code `exit 1` kodini bloklamaydigan xato sifatida ko‘rib, `1` Unix’da odatda muvaffaqiyatsizlikni anglatishiga qaramay, amalni davom ettiradi.

— Anthropic, hooklar ma’lumotnomasi, https://code.claude.com/docs/en/hooks

exit 0 muvaffaqiyatni anglatadi. exit 1 xatoni anglatadi, ammo Claude davom etadi (quyidagi birinchi noto‘g‘ri usul shu). exit 2 xulqi hodisaga xos: PreToolUse’ni bloklashi mumkin; PostToolUse allaqachon bajarilgan amalga faqat fikr bildiradi.

Hook 1. Bevosita .env tahririni tekshirish (PreToolUse, exit 2)

.env, .env.local, .env.production va shu kabilarga mos keluvchi istalgan faylni bevosita tahrirlashga urinishlarni bloklaydi.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(jq -r '.tool_input.file_path // empty'); [ -z \"$FILE\" ] && exit 0; echo \"$FILE\" | grep -qE '(^|/)\\.env(\\.|$)' && { echo 'Do not edit `.env` directly. Tell me which variable to add, and I’ll open the file myself.' >&2; exit 2; } || exit 0"
          }
        ]
      }
    ]
  }
}

Nima qiladi: Har bir Edit/Write/MultiEdit dan oldin fayl yo‘lini oladi, uning .env andozasiga mosligini grep orqali tekshiradi va mos kelsa, xabar bilan exit 2 qaytaradi. Claude stderr’ni ko‘rib, menga shunday deydi: “.env ni tahrirlashga urindim, ammo hook meni blokladi; qaysi o‘zgaruvchini qo‘shishimni ayting.”

Hook 2. Har bir kod tahriridan keyin prettier’ni avtomatik ishga tushirish (PostToolUse, exit 0)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(jq -r '.tool_input.file_path // empty'); [ -z \"$FILE\" ] && exit 0; echo \"$FILE\" | grep -qE '\\.(ts|tsx|js|jsx|json)$' && npx prettier --write \"$FILE\" 2>/dev/null & exit 0"
          }
        ]
      }
    ]
  }
}

Nima qiladi: Har bir Edit/Write dan keyin yo‘lni oladi va kengaytmasi .ts/.tsx/.js/.jsx/.json bo‘lsa, prettier’ni & bilan fonda ishga tushiradi. Bu formatlash, cheklov emas, shuning uchun har doim exit 0 bilan tugaydi. Prettier ishlamasa ham katta gap emas; fayl avvalgidek qoladi.

1-hookdan farqi asosiy: PreToolUse + exit 2 — amaldan oldingi qat’iy blok. PostToolUse + exit 0 — amaldan keyingi yumshoq tahrir. Bular turli vazifalar uchun ikki xil usul.

Hook 3. git push --force buyrug‘ining main branch’ga yuborilishini bloklash (PreToolUse, exit 2)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "CMD=$(jq -r '.tool_input.command // empty'); [ -z \"$CMD\" ] && exit 0; echo \"$CMD\" | grep -qE 'git[[:space:]]+push' && echo \"$CMD\" | grep -qE '(\\-\\-force|\\-\\-force-with-lease|[[:space:]]-f([[:space:]]|$))' && echo \"$CMD\" | grep -qE '([[:space:]/:])main([[:space:]/:]|$)' && { echo 'Force push to main is forbidden. Create a new branch or ask me to do it manually.' >&2; exit 2; } || exit 0"
          }
        ]
      }
    ]
  }
}

Nima qiladi: Har bir Bash ishga tushirilganda buyruqda push borligini, --force/--force-with-lease/-f ishlatilganini va main tilga olinganini tekshiradi. Uch shartning barchasi mos kelsa, aniq xabar bilan bloklaydi.

Ilgari bu qoida CLAUDE.md’da bosh harflar bilan yozilgan edi. Claude’ga “yomon commitimni bekor qilish uchun force-push qil” deb aytganimda ham, u taxminan ikki haftada bir marta qoidani buzardi. Hook ko‘rsatilgan literal yozilishlarni ushlaydi, lekin alias, skript, yashirin manzil branch’i yoki boshqa Git mijozi bu satr tekshiruvini chetlashi mumkin. Remote’da main himoyasini yoqing, agent credential’ini cheklang.

Hook 4. Matnli fayllarda uzun tirelarni bloklash (PostToolUse, exit 2)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(jq -r '.tool_input.file_path // empty'); [ -z \"$FILE\" ] && exit 0; echo \"$FILE\" | grep -qE '\\.(md|mdx|tsx?)$' && grep -q $'\\xe2\\x80\\x94' \"$FILE\" && { echo \"File $FILE contains an em dash (U+2014). Replace it with a regular hyphen (U+002D).\" >&2; exit 2; } || exit 0"
          }
        ]
      }
    ]
  }
}

Nima qiladi: PostToolUse’dagi exit 2 tahrirdan keyin Claude’ga tekshiruv xatosini bildiradi. Yozishni oldini olmaydi yoki qaytarmaydi. Claude faylni tahrirlab, uzun tireni qoldirsa, hook muvaffaqiyatsiz bo‘ladi, Claude javob oladi va yana urinadi. 2–3 sessiyadan so‘ng Claude bu belgini umuman kiritmay qo‘yadi.

E’tibor bering, grep $'\xe2\x80\x94' orqali aynan uzun tire belgisini (U+2014) qidiradi; bu Bash’da uni UTF-8 baytlari bilan yozish usuli. Shunchaki grep -q '-' deb yozsangiz, oddiy defislarni ham topadi va har bir faylda ishga tushadi. Ko‘rinmas belgi butun mantiqni buzadi.

Hook 5. npm run dev dan oldin 3000-portni bo‘shatish (PreToolUse, exit 0)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "CMD=$(jq -r '.tool_input.command // empty'); [ -z \"$CMD\" ] && exit 0; echo \"$CMD\" | grep -qE '(npm|pnpm|yarn)[[:space:]]+run[[:space:]]+dev' && { lsof -ti:3000 | xargs -r kill -9 2>/dev/null; echo 'Port 3000 freed before launch' >&2; }; exit 0"
          }
        ]
      }
    ]
  }
}

Nima qiladi: Har bir npm run dev (yoki pnpm/yarn) dan oldin 3000-portdagi jarayonni o‘chiradi. Bu tayyorgarlik, cheklov emas, shuning uchun doim exit 0 bilan tugaydi. Bu Claude “port band”ni ko‘rib, kodda muammo bor deb o‘ylab, aslida eski server ishlashda qolgan paytda boshqa narsalarni tuzata boshlaydigan muammolar sinfidan himoya qiladi.

Hook 6. Testlar muvaffaqiyatli o‘tgandan keyin avtomatik commit qilish (PostToolUse, exit 0)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "INPUT=$(cat); CMD=$(printf '%s' \"$INPUT\" | jq -r '.tool_input.command // empty') || exit 1; EXIT=$(printf '%s' \"$INPUT\" | jq -r '.tool_response.exit_code // empty') || exit 1; case \"$CMD\" in 'npm test'|'pnpm test'|'yarn test') ;; *) exit 0 ;; esac; [ \"$EXIT\" = \"0\" ] || exit 0; git diff --cached --quiet || { echo 'Existing staged changes: review manually' >&2; exit 0; }; git add -- src/orders.ts tests/orders.test.ts || exit 1; git diff --cached --quiet && exit 0; git commit -m 'tests: checkpoint after successful run'"
          }
        ]
      }
    ]
  }
}

Nima qiladi: JSON stdin’ni bir marta o‘qib, faqat ko‘rsatilgan oddiy test buyruqlarini qabul qiladi. Faqat tool_response.exit_code aniq nol bo‘lsa davom etadi; versiya bu maydonni bermasa, muvaffaqiyat taxmin qilmay commit’ni o‘tkazadi. src/orders.ts va tests/orders.test.ts ni vazifa egaligidagi aniq faylga almashtiring. Mavjud staged o‘zgarish retseptni to‘xtatadi. Add xatosi davom etmaydi, bo‘sh diff commit yaratmaydi, oddiy commit hook’lari yoqilgan qoladi. Yoqishdan oldin muvaffaqiyat, xato va yo‘q result kirishini oflayn sinang.

Noto‘g‘ri usul — har Edit’ga git commit --no-verify. Commit tekshiruvlarini yoqilgan tuting. Tekshiruv avtomatlashtirishni rekursiv chaqirsa, trigger’ni toraytiring yoki qayta tuzing; standart ravishda tekshiruvni chetlab o‘tmang. Auto-commit’dan oldin staged diff va vazifa egaligini ko‘ring.

Hook 7. Sessiya boshida yangi kontekst kiritish (additionalContext bilan SessionStart)

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo 'no-branch'); STATUS=$(git status --short 2>/dev/null | head -10); echo \"{\\\"additionalContext\\\":\\\"Current branch: $BRANCH. Uncommitted changes:\\n$STATUS\\\"}\""
          }
        ]
      }
    ]
  }
}

Nima qiladi: Sessiya boshlanganda joriy Git branch va commit qilinmagan o‘zgarishlar ro‘yxatini oladi, keyin additionalContext maydoni bo‘lgan JSON qaytaradi. Claude Code bu matnni birinchi tizim xabariga kiritadi, shunda Claude boshidanoq qayerdaligini va oldingi sessiyadan nimalar qolganini biladi.

Claude joriy muhit holati yoki hozirgina tugagan amal haqida bilishi kerak bo‘lgan ma’lumotlar uchun additionalContext’dan foydalaning: muhit holati (joriy branch, deploy maqsadi, faol feature flag’lar), shartli loyiha qoidalari (endi tahrirlangan faylga qaysi test buyrug‘i tegishli), tashqi ma’lumotlar (sizga biriktirilgan ochiq masalalar, so‘nggi CI natijalari).

— Anthropic, hooklar ma’lumotnomasi, https://code.claude.com/docs/en/hooks

Bu hookni kengaytirish yo‘llari: so‘nggi commit va uning tavsifini, GitHub Actions holatini, Linear/Jira’dagi faol sprintni va joriy repo uchun ochiq masalalarni olish.

Har ikkinchi odam duch keladigan hooklar bilan bog‘liq 3 ta muammo

Asosiy xulosa

Birinchi muammo: exit 1 bilan tugaydigan hook jimgina o‘tib ketadi va Claude xatoni e’tiborsiz qoldiradi. Ikkinchisi: hookdagi og‘ir ish 60 soniyalik taym-autdan keyin to‘xtatiladi. Uchinchisi: hook loyiha .env faylini emas, faqat ~/.zshrc dagi muhit o‘zgaruvchilarini ko‘radi. Har birini bir qatorda tuzatish mumkin, ammo bularni bilmasangiz, “hooklar ishlamayapti” degan taassurot paydo bo‘lishi mumkin.

Muammo 1. exit 1 bilan tugaydigan hook jimgina o‘tib ketadi

Eng xavflisi shu. Bir hafta davomida .env himoyachim ishlayapti deb o‘yladim, ammo hookda null’ni tekshirmasdan jq -r '.tool_input.file_path' ishlatgan ekanman. tool_input bo‘sh bo‘lganida, jq 1 kod bilan tugardi. Claude exit 1 ni “hook xatosi, davom et” deb qabul qildi va amalni bajardi. Nega .env ga hali ham tegilayotganini tushunolmadim. Sababni faqat hookni terminalda bo‘sh kirish bilan qo‘lda ishga tushirganimda ko‘rdim.

Tuzatish uchun bitta qoida: har bir hook boshida null qiymatini tekshiring va oxirida || exit 0 bilan yakunlang. Kutilmagan har qanday chiqish endi jimgina o‘tib ketish o‘rniga “xavfsiz” chiqishga olib keladi.

# Xavfsiz boshlash va yakunlash shabloni:
FILE=$(jq -r '.tool_input.file_path // empty')
[ -z "$FILE" ] && exit 0
# ... sizning mantiqingiz ...
exit 0   # yoki bir qatorda || exit 0

Muammo 2. Sekin hooklar taym-aut sababli to‘xtatiladi

Tahrirdan keyin butun fayl bo‘ylab eslint --fix ishlatadigan hookim bor edi. Katta fayllarni (1000+ qator) qayta ishlash 8–10 soniya olardi. Claude Code hook uchun standart taym-aut 60 soniya, shuning uchun chegaradan oshmayapman deb o‘yladim. Ammo bir daqiqada bir nechta Edit bajarilsa, hooklar yig‘ilib navbatga turadi, ayrimlari esa shunchaki o‘tkazib yuboriladi. Buni faqat jurnalda “hook timed out” yozuvini ko‘rganimdan keyin angladim.

Tuzatish: hook og‘ir ish talab qilsa, uni fonda ishga tushiring. Natijani kutmasdan eslint --fix "$FILE" & deb yozing. Shunda haqiqiy ish fonda davom etayotgan paytda hook millisekundlarda exit 0 qaytaradi.

# Og‘ir amalni fonda bajarish:
npx eslint --fix "$FILE" &
exit 0

Muammo 3. Hook loyiha muhit o‘zgaruvchilarini ko‘ra olmaydi

Hookdagi process.env Node.js ilovasidagidek mavjud bo‘ladi deb o‘ylagandim. Unday emas. Hook Claude Code ota-jarayoni yaratgan shell’da ishlaydi va faqat ~/.zshrc yoki ~/.bashrc dagi o‘zgaruvchilarni, shuningdek Claude Code aniq uzatadigan o‘zgaruvchilarni ko‘radi. Agar hook .env dagi OPENAI_API_KEY ga bog‘liq bo‘lsa, .env ni qo‘lda o‘qishingizga to‘g‘ri keladi.

Tuzatish: hook buyrug‘ida .env ni aniq o‘qing.

# Loyiha muhitini hookga uzatish:
cd "$PWD" && source .env && curl -H "Authorization: Bearer $OPENAI_API_KEY" ...
# Yoki dotenv bilan:
dotenv -e .env -- node my-validator.js

Bu monorepoda ayniqsa noqulay: turli paketlarning har birida o‘z .env fayli bo‘lishi mumkin. Buni PWD ni uzatib, buyruq boshida cd "$PWD" ni aniq ishga tushirish orqali hal qiling.

Commit qilishdan oldin hooklarni qanday sinash mumkin?

Asosiy xulosa

Hook — shell buyrug‘i. Uni terminalda stdin’ga soxta ma’lumot uzatib, chiqish kodi va stderr’ni tekshirgan holda qo‘lda ishga tushirish mumkin; bularning barchasini Claude Code ishga tushirishidan oldin bajarsa bo‘ladi. Bu bir necha soatlik nosozlik qidirishdan asraydi va o‘z ishini o‘zi bloklaydigan hooklardan himoya qiladi.

Asosiy sinov ssenariysi. JSON’dan hook buyrug‘ini oling, terminal oching va Claude Code yuborishi mumkin bo‘lgan JSON’ni unga uzating:

# 1-hookni sinash (.env himoyasi):
echo '{"tool_input":{"file_path":".env"}}' | bash -c '
FILE=$(jq -r ".tool_input.file_path // empty")
[ -z "$FILE" ] && exit 0
echo "$FILE" | grep -qE "(^|/)\.env(\.|$)" && {
  echo "BLOCKED" >&2
  exit 2
} || exit 0
'
echo "Exit code: $?"

stderr’da BLOCKED va Exit code: 2 ko‘rinishi kerak. Agar exit 0 chiqsa, regex’ingiz ishlamayapti; grep’ni tuzating.

Tekshiriladigan ssenariylar:

  1. Muvaffaqiyatli yo‘l - fayl bloklanishi kerak. 1-hook uchun .env, 3-hook uchun git push --force main.
  2. Salbiy yo‘l - fayl bloklanmasligi kerak. 1-hook uchun README.md, 3-hook uchun git push origin feature-branch.
  3. Chekka holatlar - bo‘sh kirish, null qiymatlar, kutilmagan belgilar. Hook exit 0 qaytarishi yoki aniq xato bilan tugashi kerak, jimgina o‘tib ketmasligi lozim.

Tajriba hooklarini qayerga qo‘yish kerak. .claude/settings.json ga emas, .claude/settings.local.json ga (git’ga kirmaydi). Yangi hooklarni u yerda PostToolUse ostiga haqiqiy amal o‘rniga echo bilan qo‘ying, ishga tushishini tekshiring, keyin ularni production settings.json ga ko‘chiring.

// settings.local.json da sinov - /tmp/hook-debug.log fayliga yozadi:
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"[hook fired] $(date) $(jq -r '.tool_input.file_path // \"?\"')\" >> /tmp/hook-debug.log"
          }
        ]
      }
    ]
  }
}

Claude Code’da 5–10 ta tahrirdan keyin /tmp/hook-debug.log faylini ochib, qaysi fayllar hookni ishga tushirganini ko‘ring. Bo‘sh bo‘lsa, moslashtirgich mos kelmayapti; regex’ni tuzating.

Keyingi qadam nima?

Asosiy xulosa

exit 0 bilan tugaydigan PostToolUse hooklaridan boshlang; ular eng xavfsiz va hech narsani bloklamaydi. Bir haftadan keyin .env ni himoya qilish yoki force-push’ning oldini olish uchun exit 2 bilan tugaydigan birinchi PreToolUse hookni qo‘shing. Ikki haftadan so‘ng CLAUDE.md 200 qatorli shartnomadan 50–80 qatorli qisqa kontekst tavsifiga qisqaradi, tanlangan hodisa tekshiruvlari hook’ga, qat’iy kirish limitlari esa alohida ruxsat, sandbox va remote himoyasiga o‘tadi.

Kelgusi hafta uchun 5 qadam:

  1. CLAUDE.md faylingizdan grep orqali qidiring: “hech qachon”, “taqiqlangan”, “har doim” va “shart” kabi so‘zlarni qidiring. Har bir shunday qoida hook uchun nomzod. Agar qoida buyruq-ohangida bo‘lsa, matnli fayl uni majburan bajartirmaydi.
  2. PostToolUse + exit 0 dan boshlang. Bular eng xavfsiz: o‘zgarish qiladi, ammo hech narsani bloklamaydi. Prettier (2-hook), dev-serverni o‘chirish (5-hook), testlardan keyin avtomatik commit (6-hook).
  3. Ishonch hosil qilganingizdagina birinchi PreToolUse + exit 2 hookni qo‘shing. Masalan, .env ni himoyalang (1-hook) yoki force-push’ning oldini oling (3-hook). Bu qat’iy blok va grep buyrug‘idagi xato sizning o‘zingizni ham bloklashi mumkin.
  4. Commit qilishdan oldin hooklarni qo‘lda sinang (yuqoridagi bo‘limga qarang). Bu bir necha soatlik nosozlik qidirishdan asraydi.
  5. Tajribalar uchun settings.local.json dan foydalaning. U yerga haqiqiy amal o‘rniga echo bilan yangi hooklarni qo‘ying.

Hooklarni sozlaganingizdan so‘ng, turkumdagi keyingi qadam — Claude Code’da o‘zgarishlarni qanday bekor qilish; bu hook xavfli biror narsani o‘tkazib yuborsa, kerak bo‘ladi. Claude sessiyalar oralig‘ida loyiha tuzilishini eslab qolishini istasangiz, Claude Code’da Ikkinchi Miya yarating (business/ papkasi + bog‘langan bilimlar bazasi). Loyiha skill’lariga qayta ishlatish mumkin bo‘lgan nomlar berish uchun esa Claude Code Skills maqolasini ko‘ring.

Ailoot orqali neyron tarmoqlardan foydalanish kerak bo‘lsa, Ailoot bilan tanishing.

Batafsil

Ko‘p beriladigan savollar

Nega hook JSON kirishini faqat bir marta o‘qishi kerak?

Stdin oqim: birinchi jq uni yutib, keyingisi EOF oladi. Kirishni bir marta saqlab, command va result’ni shu qiymatdan oling. Yo‘q yoki noma’lum natijani tasdiqlanmagan deb, auto-commit’ni o‘tkazing.

Regex hook’lar xavfsizlik chegarasimi?

Yo‘q. Aniq hodisa va taniladigan buyruq satrini ko‘radi. Shell redirection, alias, skript, MCP yoki boshqa yozish yo‘li aylanib o‘tishi mumkin. Qat’iy limitga tor credential, fayl ruxsati, sandbox va protected branch kerak.

Barcha maqolalar