Mwongozo

Claude Code hooks: jinsi ya kugeuza kanuni za wakala kuwa dhamana

Imesasishwa: · Skillaria.Top

Hooks za Claude Code ni amri za shell ambazo Claude Code yenyewe huziendesha kwenye matukio fulani: kabla na baada ya kuita zana, wakati ombi linatumwa, wakati kikao kinaanza, na kabla wakala hajasimama. Zinasanidiwa kwenye settings.json, na exit code 2 huzuia kitendo na kumrudishia wakala ujumbe wa kosa, hivyo hook inageuza kanuni ya CLAUDE.md kuwa dhamana ambayo modeli haiwezi kuisahau.

Hooks za Claude Code ni nini

Hook ni amri inayoendeshwa si na modeli, bali na programu ya Claude Code yenyewe wakati fulani wa kazi ya wakala. Wakala anakaribia kuendesha rm -rf — hook inaanza na kuamua kama amri ipitishwe. Wakala amehariri faili — hook inaendesha formatter. Wakala anataka kumaliza kazi — hook inaendesha majaribio na haimruhusu kusimama mpaka yapite.

Tofauti kuu na maelekezo kwenye CLAUDE.md: maelekezo ni maandishi ambayo modeli huzingatia kwa uwezekano fulani, wakati hook ni msimbo wa uhakika. Itafanya kazi kila wakati, bila kujali muktadha ni mrefu kiasi gani, wakala ameamua nini, au kama amesahau kanuni dakika ya mia ya kikao. Ndiyo maana hooks za claude code ndiyo njia kuu ya kugeuza matakwa kuwa dhamana.

Kwa nini kanuni katika CLAUDE.md hazitoshi

Picha ya kawaida: wakala ameongeza kipengele, majaribio ya kitengo ni ya kijani, na kwenye gumzo kuna jibu la uhakika «Imekamilika». Lakini hakuna aliyeendesha mfululizo wa mwisho-hadi-mwisho, linter haikuendeshwa, na migration ilianguka katikati. Kwenye CLAUDE.md imeandikwa «kabla ya kumaliza endesha majaribio». Modeli haidanganyi kwa makusudi — inajitathmini yenyewe tu, na kujitathmini huko si cha kuaminika.

Hapa ndipo kanuni ya harness inapotokea: kila kinachoweza kukaguliwa kwa mitambo, mitambo ndiyo inayokikagua, si modeli. Kanuni «endesha linter» inakuwa hook inayoendesha linter. Kanuni «usiguse config ya uzalishaji» inakuwa hook inayozuia kuandika kwenye faili hilo. Maelekezo ya maandishi yanabaki, lakini yanaeleza tu kwa nini wakala amesimamishwa.

Matukio: hooks zinaanza lini

Kila hook imefungwa kwenye tukio la mzunguko wa maisha wa kikao. Matukio makuu:

TukioLinaanza liniMatumizi ya kawaida
PreToolUsekabla ya kuita zana (Bash, Edit, Write n.k.)kuzuia amri hatari, kulinda faili
PostToolUsebaada ya zana kufanikiwaformatter, linter, majaribio ya haraka baada ya mabadiliko
UserPromptSubmitmtumiaji anapotuma ombi, kabla halijashughulikiwakuongeza muktadha, kukataa ombi lenye siri
Stopwakala anapokaribia kumaliza jibukuzuia kusimama hadi ukaguzi upite
SubagentStopsubagent anapomaliza kazikukagua matokeo ya subagent
SessionStartkikao kinapoanza au kuendeleakupakia hali: git status, mpango, jarida la maendeleo
SessionEndkikao kinapomalizikakusafisha, kuandika kumbukumbu
NotificationClaude Code inapotuma arifa (kwa mfano, inangoja ruhusa)sauti au ujumbe kwenye simu
PreCompactkabla ya kubana muktadhakuhifadhi kilicho muhimu kabla ya compaction

Yenye manufaa zaidi kwa uaminifu ni PreToolUse, PostToolUse na Stop: zinafunga udhaifu tatu wa wakala — vitendo hatari, mabadiliko yasiyokaguliwa, na «imekamilika» kabla ya wakati.

Mahali hooks zinapowekwa: settings.json

Hooks zinaelezwa kwenye faili za mipangilio za Claude Code:

  • ~/.claude/settings.json — zako binafsi, kwa miradi yote;
  • .claude/settings.json ndani ya hazina — za timu nzima, zinaingizwa kwenye git;
  • .claude/settings.local.json — za mradi wa ndani, haziingii kwenye git.

Muundo ni huu: tukio → orodha ya vikundi vyenye matcher → orodha ya amri.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/lint.sh",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

matcher ni jina la zana au regular expression juu yake: Bash, Edit|Write, .*. Inahitajika kwa matukio yanayohusu zana; kwa Stop au UserPromptSubmit unaweza kuiacha. Kigezo CLAUDE_PROJECT_DIR kinaelekeza kwenye mzizi wa mradi, kwa hiyo ni vyema kuweka hati kwenye .claude/hooks/ na kuziita kupitia kigezo hicho. Hooks zilizopo unaweza kuziona kwa amri /hooks ndani ya Claude Code.

Hook inapokea data na kujibu vipi

Ingizo: JSON kwenye stdin

Claude Code inampa hook JSON yenye taarifa za tukio: kitambulisho cha kikao, saraka ya kazi, jina la tukio, na kwa zana — tool_name na tool_input. Kwa Bash, amri iko kwenye tool_input.command; kwa Edit na Write, njia ya faili iko kwenye tool_input.file_path. Kusoma ni rahisi kwa jq.

{
  "session_id": "abc123",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "rm -rf build/" },
  "cwd": "/home/dev/project"
}

Matokeo: msimbo wa kurudi

MsimboKinachotokea
0mafanikio, kazi inaendelea; kwa UserPromptSubmit na SessionStart stdout inaongezwa kwenye muktadha wa wakala
2kosa la kuzuia: stderr inapelekwa kwa wakala, na kitendo kinasimamishwa (kwa PreToolUse — wito wa zana unaghairiwa, kwa Stop — wakala anaendelea kufanya kazi)
nyinginekosa lisilozuia: stderr inaonyeshwa kwa mtumiaji, kazi inaendelea

Exit code 2 ndiyo mtambo muhimu. Wakala anapokea maandishi ya stderr kama maoni na anaweza kujirekebisha: kuandika upya amri, kurekebisha jaribio, kutogusa faili. Kwa hiyo kwenye stderr andika si «kosa» tu, bali sababu wazi na kinachopaswa kufanywa badala yake.

Mbali na msimbo wa kurudi, hook inaweza kutoa kwenye stdout JSON yenye uamuzi, kwa mfano "decision": "block" na "reason". Hii ni kwa marekebisho ya kina, lakini kwa kazi nyingi inatosha code 2 na ujumbe kwenye stderr.

Mfano 1: linter na majaribio baada ya kila mabadiliko

Hook ya PostToolUse yenye matcher Edit|Write inaanza baada ya faili kubadilishwa. Zana tayari imeshatekelezwa, hivyo mabadiliko hayawezi kughairiwa, lakini code 2 inamrudishia wakala matokeo ya linter, naye atarekebisha kosa mara moja, si baada ya nusu saa.

#!/usr/bin/env bash
# .claude/hooks/lint.sh
file=$(jq -r '.tool_input.file_path // empty')
case "$file" in
  *.py)
    if ! out=$(ruff check "$file" 2>&1); then
      echo "Linter imepata makosa katika $file:" >&2
      echo "$out" >&2
      exit 2
    fi ;;
  *.php)
    if ! out=$(php -l "$file" 2>&1); then
      echo "$out" >&2
      exit 2
    fi ;;
esac
exit 0

Usiweke hapa majaribio kamili ya dakika kumi: hook inaanza kwa kila mabadiliko. Baada ya mabadiliko endesha ukaguzi wa haraka (sintaksia, linter, majaribio ya moduli moja), na ukaguzi mzito uwe kwenye hook ya Stop.

Mfano 2: kuzuia amri hatari

Hook ya PreToolUse yenye matcher Bash inaona amri kabla haijatekelezwa. Code 2 inaghairi wito, na wakala anapata maelezo.

#!/usr/bin/env bash
# .claude/hooks/guard.sh
cmd=$(jq -r '.tool_input.command // empty')
if echo "$cmd" | grep -Eq 'rm -rf /|git push (-f|--force)|DROP (TABLE|DATABASE)'; then
  echo "Amri imezuiwa na sera ya mradi: $cmd. Shughuli hatari hufanywa na binadamu." >&2
  exit 2
fi
exit 0

Kwa njia hiyo hiyo mafaili yanalindwa: hook ya Edit|Write inakagua file_path na kuzuia kuandika kwenye .env, config za uzalishaji, msimbo uliozalishwa au faili za migration ambazo tayari zimetumika. Kumbuka kwamba utafutaji kwa regular expression unaweza kukwepwa — wakala anaweza kuandika amri kwa njia nyingine. Hook ni kinga imara, lakini si mbadala wa ruhusa za ufikiaji na sanduku la mchanga.

Mfano 3: wakala hawezi kusema «imekamilika» wakati majaribio ni nyekundu

Hook ya Stop inaanza wakati wakala anakaribia kumaliza. Majaribio yasipopita, code 2 inazuia kusimama, na matokeo ya majaribio yanaenda kwa wakala kama kazi inayofuata. Hii ni toleo la kimitambo la Definition of Done.

#!/usr/bin/env bash
# .claude/hooks/done.sh
input=$(cat)
# ulinzi dhidi ya mzunguko usio na mwisho: hook tayari iliongeza kazi mara moja
if [ "$(echo "$input" | jq -r '.stop_hook_active')" = "true" ]; then
  exit 0
fi
if ! out=$(npm test --silent 2>&1); then
  echo "Majaribio yameshindwa, kazi haijakamilika:" >&2
  echo "$out" | tail -n 40 >&2
  exit 2
fi
exit 0

Sehemu stop_hook_active ina thamani true ikiwa wakala tayari anaendelea kazi kwa sababu ya stop hook. Bila ukaguzi huu hook inaweza kumzungusha wakala bila kikomo — hali hasa ya «anafanya kazi usiku kucha mahali pasipofaa». Katika mizunguko ya kujiendesha ongeza pia kikomo cha majaribio na sharti la kumwita binadamu.

Mfano 4: kupakia hali mwanzoni mwa kikao

Kwenye SessionStart, stdout ya hook inaingia kwenye muktadha. Ni vyema kuonyesha tawi la sasa, mabadiliko ambayo hayajawekwa commit, na kazi inayofuata kutoka kwenye mpango, ili wakala asianze kutoka mwanzo.

#!/usr/bin/env bash
echo "Tawi: $(git branch --show-current)"
git status --short | head -n 20
[ -f PROGRESS.md ] && tail -n 15 PROGRESS.md
exit 0

Jinsi hooks zinavyogeuza kanuni kuwa dhamana

Ni rahisi kugawanya kanuni za harness katika ngazi tatu. Ya kwanza ni maandishi kwenye CLAUDE.md: yanaeleza jinsi ya kufanya kazi, lakini yanafuatwa kwa uwezekano. Ya pili ni ukaguzi unaoweza kutekelezwa: majaribio, E2E, kanuni za usanifu kwa njia ya skripti inayoanguka inapovunjwa. Ya tatu ni hooks zinazoendesha ukaguzi huo kiotomatiki kwa wakati unaofaa, bila ushiriki wa modeli.

Kanuni ya vitendo: ikiwa wakala amevunja kanuni ileile mara mbili, usiongeze onyo jingine kwa herufi kubwa kwenye CLAUDE.md. Jiulize kama ukiukaji huo unaweza kukaguliwa kwa skripti. Ikiwezekana — tengeneza skripti na uiunganishe kwenye hook. Maelekezo ya maandishi yanakuwa mafupi, na tabia inakuwa thabiti zaidi.

Kanuni kwa maandishiDhamana kupitia hook
«Panga msimbo kwa kiwango»PostToolUse inaendesha formatter kwenye faili lililobadilishwa
«Usipushe kwa force»PreToolUse kwenye Bash inazuia amri, exit 2
«Usiseme imekamilika wakati majaribio ni nyekundu»Stop inaendesha majaribio na haimruhusu kumaliza
«Usihariri .env»PreToolUse kwenye Edit|Write inakagua njia
«Kumbuka ulipoishia»SessionStart inaonyesha mpango na git status

Makosa ya kawaida

  • Code 1 badala ya 2. Skripti inaanguka kwa code 1, wakala hajui chochote, na kitendo kinapita. Ni code 2 pekee inayozuia.
  • Ujumbe kwenye stdout. Kwa code 2 wakala anapokea stderr. Andika kupitia >&2.
  • Hook ya polepole kwenye tukio la mara kwa mara. Majaribio kamili kwenye PostToolUse yanafanya kila mabadiliko kuwa ya dakika moja. Vitu vizito viwe kwenye Stop.
  • Stop isiyo na mwisho. Hakuna ukaguzi wa stop_hook_active wala kikomo — wakala anazunguka bila kikomo.
  • Njia za jamaa. Hook inaendeshwa kwenye saraka ya kazi ya kikao; tumia $CLAUDE_PROJECT_DIR.
  • Hook ya mtu mwingine isiyokaguliwa. Hook inaendeshwa kwa ruhusa zako bila uthibitisho. Soma skripti za hazina za watu wengine kabla ya kuziamini.

Hitimisho

Hooks za Claude Code zinahamisha kanuni muhimu zaidi kutoka maandishi kwenda msimbo: PreToolUse inazuia vitendo hatari, PostToolUse inakagua kila mabadiliko, Stop haimruhusu wakala kutangaza utayari kabla ya wakati, na SessionStart inamrudishia wakala kumbukumbu ya mradi. Anza na hooks mbili au tatu kwa kanuni ambazo wakala tayari amezivunja, na weka ujumbe kwenye stderr uwe wazi — kwa njia hiyo wakala mwenyewe anarekebisha makosa, nawe unakagua matokeo, si mchakato. Uthibitisho, ukaguzi wa utayari na mizunguko ya kujiendesha tunafundisha kwa vitendo katika kozi.

Maswali ya mara kwa mara

Je, ninahitaji kuanzisha upya Claude Code baada ya kubadilisha hooks?

Mabadiliko kwenye settings.json yanaanza kutumika kwa uhakika zaidi kwenye kikao kipya; usanidi wa sasa wa hooks unaweza kuonekana kwa amri /hooks.

Je, hooks zinaweza kuandikwa kwa lugha nyingine isipokuwa bash?

Ndiyo, hook ni amri yoyote: skripti ya Python, Node.js au binary. Jambo la msingi ni kusoma JSON kutoka stdin na kurudisha msimbo sahihi wa kutoka.

Je, wakala anaona matokeo ya hook iliyofanikiwa?

Kwa kawaida hapana: kwa code 0 matokeo hayaingii kwenye muktadha. Isipokuwa ni UserPromptSubmit na SessionStart, ambapo stdout inaongezwa kwenye muktadha wa wakala.

Je, hooks zinafanya kazi kwa subagents?

Ndiyo, wito wa zana za subagents unapitia hooks zilezile za PreToolUse na PostToolUse, na kwa kumaliza kwao kuna tukio tofauti la SubagentStop.

Je, ni salama kuweka hooks kwenye hazina?

Ndiyo, .claude/settings.json na skripti za .claude/hooks/ ni mazoea ya kawaida kwa timu; hooks zako binafsi zihifadhiwe kwenye settings.local.json au ~/.claude/settings.json.