SSD Nodes Learn Hosting plans →
మార్గదర్శకాలు Matt Connorద్వారా Matt Connor · అప్‌డేట్ చేయబడింది 2026-08-30

Claude Code hooks ఎలా పనిచేస్తాయి: పూర్తి వివరణ

Claude Code hooks అంటే ఏమిటి, అవి ఎలా పనిచేస్తాయి మరియు ఎప్పుడు అమలు అవుతాయో తెలుసుకోండి. Exit code 2 వల్ల టూల్ కాల్ ఎందుకు ఆగిపోతుందో మరియు వీటిలోని భద్రతా అంశాలను ఇక్కడ చూడండి.

Claude Code hook అంటే ఏమిటి

Claude Code hooks అనేవి Claude Code తన జీవితచక్రంలో నిర్ణీత సమయాల్లో స్వయంగా అమలు చేసే shell commands. hook మరియు rules file మధ్య ఉన్న ప్రధాన వ్యత్యాసం ఇదే. CLAUDE.md లోని సూచన కేవలం సలహా మాత్రమే, మోడల్ తన సందర్భంలోని ఇతర అంశాలతో పోల్చి దానిని పరిగణనలోకి తీసుకుంటుంది. కానీ hook అనేది ఒక code, మోడల్ అంగీకరించినా లేదా అంగీకరించకపోయినా అది కచ్చితంగా అమలు అవుతుంది. మీరు రెండుసార్లు చెప్పినా మీ agent formatter ను దాటవేస్తుంటే, దానికి మరింత కఠినమైన సూచన అవసరం లేదు. మీకు ఒక hook అవసరం.

దీని పనితీరు చాలా సరళమైనది. మీరు ఒక settings file లో event పేరు కింద ఒక command ను నమోదు చేస్తారు. ఆ event జరిగినప్పుడు, Claude Code మీ command ను రన్ చేసి, event డేటాను JSON (JavaScript object notation) రూపంలో దాని standard input (stdin) కు పంపుతుంది. మీ command ఆ డేటాను చదివి, తన పనిని పూర్తి చేసి, ఒక exit status తో సమాధానం ఇస్తుంది. PreToolUse hook నుండి వచ్చే exit 2, tool call అమలు కాకముందే దానిని రద్దు చేస్తుంది, మరియు మీ script standard error (stderr) కు రాసిన సమాచారం మోడల్‌కు కారణంలా తిరిగి పంపబడుతుంది.

ఇక్కడ ఉన్న event పేర్లు మరియు field పేర్లు Claude Code hooks reference నుండి సేకరించబడినవి, వీటిని ఆగస్టు 2026లో release 2.1.232 వెర్షన్‌తో సరిచూడడం జరిగింది. ఈ సాంకేతికత వేగంగా మారుతుంటుంది, కాబట్టి ఏదైనా blog post నుండి JSON ను కాపీ చేసే ముందు, మీ వెర్షన్ కోసం reference ను ఒకసారి తనిఖీ చేయండి. మీ స్వంత వివరాలను claude --version తో ప్రింట్ చేయండి.

Hook కాన్ఫిగరేషన్ ఎక్కడ ఉంటుంది

Hook అనేది settings ఫైల్‌లో ఉండే ఒక JSON బ్లాక్. ఇది ఆరు ప్రదేశాలలో ఉండవచ్చు, ఫైల్ యొక్క పరిధి (scope) దేనిపై ఉంటుందో, hook పరిధి కూడా అదే అవుతుంది.

  • ~/.claude/settings.json: మీ మెషీన్‌లోని ప్రతి ప్రాజెక్ట్, ఇతరులకు ఇది వర్తించదు.
  • .claude/settings.json: ఒక ప్రాజెక్ట్, ఇది రిపోజిటరీకి commit చేయబడుతుంది, కాబట్టి దీన్ని clone చేసుకున్న ప్రతి ఒక్కరికీ ఈ hook అందుతుంది.
  • .claude/settings.local.json: ఒక ప్రాజెక్ట్, కేవలం మీ మెషీన్‌కు మాత్రమే.
  • Managed policy settings: సంస్థ అంతటా వర్తించేవి, వీటిని అడ్మినిస్ట్రేటర్ సెట్ చేస్తారు.
  • hooks/hooks.json ఒక plugin లోపల, ఆ plugin enable లో ఉన్నంత వరకు ఇది పనిచేస్తుంది.
  • Skill లేదా subagent frontmatter, ఆ component active లో ఉన్నంత వరకు ఇది పనిచేస్తుంది.

ఈ ఫైళ్లలోని hook ఎంట్రీలు ఒకదానికొకటి override అవ్వకుండా కలిసి పనిచేస్తాయి (merge అవుతాయి). ఒక ప్రాజెక్ట్ settings ఫైల్ తన hookలను మీ user settings లో ఉన్న వాటికి జత చేస్తుంది, వాటిని తొలగించదు. కాబట్టి ఒకే event కోసం వివిధ ఫైళ్ల నుండి వచ్చిన అనేక hookలు అమలు కావచ్చు. "disableAllHooks": true సెట్టింగ్‌ను ఉపయోగించి వీటిని ఆపివేయవచ్చు, అయితే ఒక మినహాయింపు ఉంది: managed policy settings నుండి వచ్చే hookలు, ఆ సెట్టింగ్ కూడా managed settings లోనే అప్లై చేయకపోతే, నిరంతరాయంగా పనిచేస్తూనే ఉంటాయి.

ప్రస్తుతం రిజిస్టర్ అయిన ప్రతి hookను చూడటానికి session లో /hooks రన్ చేయండి. ఇవి event వారీగా, వాటి source ఫైల్ మరియు matcher వివరాలతో కనిపిస్తాయి. ఈ మెనూ కేవలం చదవడానికి మాత్రమే (read only), కాబట్టి మీరు hookను మార్చాలంటే settings ఫైల్‌ను ఎడిట్ చేయాలి. సాధారణంగా ఫైల్ వాచర్ (file watcher) ఎటువంటి restart అవసరం లేకుండానే మార్పులను గుర్తిస్తుంది.

ఏ Claude Code హుక్ ఈవెంట్‌లు అందుబాటులో ఉన్నాయి

Release 2.1.232 ముప్పై ఒకటి ఈవెంట్‌లను జాబితా చేస్తుంది, ఇవి SessionStart నుండి SessionEnd వరకు ఉంటాయి. ఇవి కాంపాక్షన్ (compaction), సబ్-ఏజెంట్లు, వర్క్‌ట్రీలు మరియు కాన్ఫిగరేషన్ ఫైళ్లను కవర్ చేస్తాయి. సర్వర్ పనిలో వీటిలో కొన్ని మాత్రమే ఉపయోగించబడతాయి.

  • PreToolUse: ఒక టూల్ కాల్ అమలు కావడానికి ముందు. ఇది బ్లాక్ చేయగల ఏకైక ఈవెంట్.
  • PostToolUse: ఒక టూల్ కాల్ విజయవంతమైన తర్వాత. అది విఫలమైనప్పుడు PostToolUseFailure ట్రిగ్గర్ అవుతుంది, కాబట్టి ప్రతి ఫలితాన్ని పర్యవేక్షించాల్సిన హుక్ రెండింటినీ ఉపయోగించాలి.
  • PermissionRequest: ఒక టూల్ కాల్‌కు అనుమతి నిర్ణయం అవసరమైనప్పుడు, అంటే అప్రూవల్ ప్రాంప్ట్ కనిపించే సమయం.
  • UserPromptSubmit: మీరు ప్రాంప్ట్‌ను సబ్మిట్ చేసినప్పుడు, Claude దానిని ప్రాసెస్ చేయడానికి ముందు. ఈ హుక్ stdout కు ప్రింట్ చేసే ఏదైనా సమాచారం మోడల్ కాంటెక్స్ట్‌కు జోడించబడుతుంది.
  • SessionStart మరియు SessionEnd: సెషన్ ప్రారంభంలో మరియు ముగింపులో. SessionStart కాంపాక్షన్ తర్వాత కూడా ఫైర్ అవుతుంది, దీనికి compact అనే మ్యాచర్ విలువ ఉంటుంది.
  • Stop: Claude స్పందించడం పూర్తి చేసినప్పుడు. ఇది ఒక టర్న్‌కు ఒకసారి మాత్రమే జరుగుతుంది, పూర్తి చేసిన టాస్క్‌కు ఒకసారి కాదు.

ప్రతి గ్రూపులో matcher ఉంటుంది, ఇది ఏ సందర్భాల్లో హుక్ రన్ అవ్వాలో నిర్ణయిస్తుంది. టూల్ ఈవెంట్‌లలో ఇది టూల్ పేరు ఆధారంగా ఫిల్టర్ చేస్తుంది, కాబట్టి "Edit|Write" కేవలం ఫైల్ ఎడిట్‌లపై మాత్రమే ఫైర్ అవుతుంది, వేరే దేనిపైనా కాదు. మ్యాచర్లు కేస్-సెన్సిటివ్ (case sensitive). ఖాళీ మ్యాచర్ ప్రతి సందర్భంలోనూ ఫైర్ అవుతుంది. MCP (model context protocol) సర్వర్ నుండి వచ్చే టూల్స్ mcp__<server>__<tool> అని పిలవబడతాయి, కాబట్టి "mcp__github__.*" అనే మ్యాచర్ ఒక సర్వర్ టూల్స్‌ను మాత్రమే పట్టుకుంటుంది మరియు మిగిలిన వాటిని వదిలేస్తుంది.

Stop హుక్స్‌ను రాసే ముందు తెలుసుకోవలసిన ఒక ముఖ్యమైన విషయం ఉంది. బ్లాక్ చేసే Stop హుక్ మోడల్‌ను తిరిగి పనిలోకి పంపుతుంది, మరియు వరుసగా ఎనిమిది సార్లు బ్లాక్ చేసిన తర్వాత Claude Code ఆ హుక్‌ను ఓవర్‌రైడ్ చేస్తుంది. హుక్ ఇన్‌పుట్ నుండి stop_hook_active ఫీల్డ్‌ను చదవండి మరియు అది ట్రూ (true) అయినప్పుడు exit 0 చేయండి, లేకపోతే మీ హుక్ ఆ పరిమితిని చేరుకునే వరకు లూప్‌లో తిరుగుతూనే ఉంటుంది.

ఒక hook stdin ద్వారా ఏమి స్వీకరిస్తుంది

Claude npm test ను రన్ చేయబోతున్నప్పుడు, Bash పై ఉన్న PreToolUse hook, stdin ద్వారా దీనిని చదువుతుంది:

{
  "session_id": "abc123",
  "cwd": "/home/deploy/myproject",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm test"
  }
}

ప్రతి ఈవెంట్ session_id, cwd, permission_mode, transcript_path మరియు hook_event_name లను కలిగి ఉంటుంది. టూల్ ఈవెంట్‌లు tool_name, tool_input మరియు tool_use_id లను జోడిస్తాయి. ఇతర ఈవెంట్‌లు వాటి స్వంత ఫీల్డ్‌లను కలిగి ఉంటాయి: UserPromptSubmit అనేది prompt టెక్స్ట్‌ను పొందుతుంది, మరియు SessionStart అనేది startup, resume, clear, compact లేదా fork ల యొక్క source ను పొందుతుంది.

షెల్ స్క్రిప్ట్ లోపల దీనిని చదవడానికి jq సాధారణ మార్గం, కానీ కనిష్ట సర్వర్ ఇమేజ్‌లో ఇది ఉండదు. Ubuntu మరియు Debian లలో దీనిని ముందుగా sudo apt install -y jq తో ఇన్‌స్టాల్ చేయండి.

టూల్ కాల్ జరుగుతున్నప్పుడు ఎగ్జిట్ స్టేటస్ ఎలా పనిచేస్తుంది

ఇక్కడ మూడు ఫలితాలు ఉంటాయి.

  • Exit 0 అంటే మీ హుక్ ఎటువంటి అభ్యంతరాన్ని తెలపడం లేదు అని అర్థం. PreToolUse పై ఇది ఆమోదం అని కాదు, సాధారణ అనుమతి ప్రక్రియ (permission flow) యథావిధిగా కొనసాగుతుంది. UserPromptSubmit మరియు SessionStart లపై, stdout మోడల్ యొక్క కాంటెక్స్ట్‌కు జోడించబడుతుంది.
  • Exit 2 అనేది నిరోధించగల ఈవెంట్‌లపై చర్యను అడ్డుకుంటుంది, వీటిలో PreToolUse కూడా ఉంది, మరియు stderr మోడల్‌కు చూపబడే కారణంగా మారుతుంది. PostToolUse వంటి నిరోధించలేని ఈవెంట్‌లపై, ఈ బ్లాక్ విస్మరించబడుతుంది, అయితే stderr ఫీడ్‌బ్యాక్‌గా మోడల్‌కు చేరుతుంది.
  • ఏ ఇతర ఎగ్జిట్ కోడ్ అయినా నాన్-బ్లాకింగ్ ఎర్రర్‌గా పరిగణించబడుతుంది. చర్య కొనసాగుతుంది. ట్రాన్స్‌క్రిప్ట్‌లో Failed with non-blocking status code: టెక్స్ట్ తర్వాత stderr యొక్క మొదటి లైన్‌ను కలిగి ఉన్న హుక్ ఎర్రర్ నోటీసు కనిపిస్తుంది.

బ్లాక్ చేయడం లేదా నిశ్శబ్దంగా ఉండటం కంటే ఎక్కువ చేయాలనుకుంటే, exit 0 ని ఉపయోగించి stdout కు ఒక JSON ఆబ్జెక్ట్‌ను ప్రింట్ చేయండి. ఒక PreToolUse హుక్ permissionDecision తో నిర్ణయం తీసుకుంటుంది:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Database drops go through a migration, not through the agent."
  }
}

"allow" ఇంటరాక్టివ్ ప్రాంప్ట్‌ను దాటవేస్తుంది, "deny" కాల్‌ను రద్దు చేసి ఆ కారణాన్ని మోడల్‌కు పంపుతుంది, మరియు "ask" ప్రాంప్ట్‌ను సాధారణంగా చూపిస్తుంది. ప్రతి హుక్‌కు ఒక శైలిని ఎంచుకోండి. exit 2 ని stdout లోని JSON నిర్ణయంతో కలిపితే, మీరు ఫలితాన్ని వెతకాల్సి ఉంటుంది.

ఒక ఈవెంట్‌కు అనేక హుక్స్ సరిపోలినప్పుడు, అవి సమాంతరంగా (parallel) నడుస్తాయి మరియు ప్రతి ఒక్కటి పూర్తిస్థాయిలో రన్ అవుతాయి. ఒక హుక్ నుండి వచ్చే deny దాని తోటి హుక్స్‌ను ఆపదు, కాబట్టి ఒక గార్డ్‌రైల్ హుక్ అదే కాల్‌ను తిరస్కరించినప్పటికీ, లాగింగ్ హుక్ తన లైన్‌ను రాస్తూనే ఉంటుంది. ఆ తర్వాత Claude Code సమాధానాలను విలీనం చేసి, deny, defer, ask, allow అనే క్రమంలో అత్యంత కఠినమైన దానిని ఉంచుతుంది.

ఉదాహరణ 1: ప్రమాదకరమైన కమాండ్‌ను రన్ అవ్వకముందే నిరోధించడం

దీనిని మీ ప్రాజెక్ట్‌లో .claude/hooks/block-destructive.shగా సేవ్ చేయండి:

#!/bin/bash
# Deny a Bash tool call whose command matches a banned pattern.
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

for pattern in 'rm -rf /' 'mkfs' 'dd if=' 'DROP TABLE'; do
  if printf '%s' "$COMMAND" | grep -qiF -- "$pattern"; then
    echo "Blocked by policy: the command matches '$pattern'. A human runs this one." >&2
    exit 2
  fi
done

exit 0

దీనిని executableగా మార్చి, ఆపై .claude/settings.jsonలోని PreToolUseలో రిజిస్టర్ చేయండి:

chmod +x .claude/hooks/block-destructive.sh
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-destructive.sh",
            "timeout": 10,
            "statusMessage": "Checking the command against policy"
          }
        ]
      }
    ]
  }
}

స్క్రిప్ట్‌ను నమ్మే ముందు మాన్యువల్‌గా పరీక్షించండి, ఎందుకంటే తన సొంత ఇన్‌పుట్‌తోనే క్రాష్ అయ్యే హుక్ (hook) ఏ రక్షణ ఇవ్వదు:

echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /var/lib/postgresql"}}' \
  | .claude/hooks/block-destructive.sh
echo $?

మీరు stderrలో Blocked by policy: లైన్‌ను మరియు 2 ఎగ్జిట్ కోడ్‌ను చూడాలి. దీనికి ls -la వంటి హానిలేని కమాండ్‌ను ఇన్‌పుట్‌గా ఇస్తే, ఎటువంటి అవుట్‌పుట్ రాకూడదు మరియు ఎగ్జిట్ కోడ్ 0 ఉండాలి. ఒక సెషన్‌లో, నిరోధించబడిన కాల్ ట్రాన్స్‌క్రిప్ట్‌లో మీ సందేశంతో పాటు కారణాన్ని చూపిస్తుంది, మోడల్ ఆ సందేశాన్ని చదివి తన ప్రవర్తనను మార్చుకుంటుంది.

ఒక ప్రత్యేకత వల్ల ఇది ఉపయోగకరంగా ఉంటుంది: PreToolUse హుక్స్ పర్మిషన్-మోడ్ చెక్ జరగకముందే, ప్రతి పర్మిషన్ మోడ్‌లోనూ రన్ అవుతాయి, కాబట్టి bypassPermissionsలో కూడా ఈ నిరోధకత పనిచేస్తుంది. Claude Code ఆటో మోడ్ మరియు దాని పర్మిషన్ సెట్టింగ్‌లతో పాటు ఈ హుక్ ఉపయోగపడటానికి కారణం ఇదే, ఎందుకంటే అక్కడ ప్రాంప్ట్‌లు తగ్గించబడినప్పటికీ హుక్ మాత్రం రన్ అవుతూనే ఉంటుంది.

ఇది ఏమిటో స్పష్టంగా అర్థం చేసుకోండి. కమాండ్ స్ట్రింగ్‌ను ప్యాటర్న్ మ్యాచింగ్ చేయడం అనేది ఏజెంట్ అజాగ్రత్తగా వ్యవహరించకుండా ఉండే ఒక రక్షణ కవచం మాత్రమే, ఇది ఏజెంట్ తెలివిగా వ్యవహరిస్తే ఆపలేదు, ఎందుకంటే అదే కమాండ్‌ను మీ grep గుర్తించలేని రూపంలో రాయవచ్చు. కఠినమైన నియమాలు పర్మిషన్ సిస్టమ్‌లో మరియు ఆ ప్రాసెస్ ఏ అకౌంట్ కింద రన్ అవుతుందో అక్కడ మాత్రమే ఉండాలి.

ఉదాహరణ 2: ప్రతి సవరణ తర్వాత ఫార్మాట్ చేయడం మరియు లింట్ చేయడం

PostToolUse తో కూడిన Edit|Write మ్యాచర్ ఏదైనా ఫైల్-ఎడిటింగ్ టూల్ తర్వాత రన్ అవుతుంది. దీన్ని .claude/hooks/after-edit.sh గా సేవ్ చేయండి:

#!/bin/bash
# Format the edited file, then report lint failures back to the model.
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
[ -z "$FILE" ] && exit 0

case "$FILE" in
  *.py)
    ruff format "$FILE" >/dev/null 2>&1
    if ! ruff check "$FILE" >&2; then
      exit 2
    fi
    ;;
  *.sh)
    if ! shellcheck "$FILE" >&2; then
      exit 2
    fi
    ;;
esac

exit 0
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/after-edit.sh",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

ఒక Python ఫైల్‌లో సరిగ్గా ఇండెంటేషన్ లేని ఫంక్షన్‌ను జోడించమని Claude ని అడగండి, ఆపై ఫైల్‌ను తెరవండి. అది ఫార్మాట్ చేయబడి తిరిగి వస్తుంది. హుక్ రన్ అయిందని నిర్ధారించుకోవడానికి ఇది ఒక మార్గం, ఎందుకంటే హుక్ విజయవంతమైతే సంభాషణలో ఏమీ కనిపించదు.

ఇక్కడ ఉన్న exit 2 దేనినీ వెనక్కి తీసుకోదు. PostToolUse అనేది టూల్ ఎగ్జిక్యూట్ అయిన తర్వాతే ఫైర్ అవుతుంది, కాబట్టి ఎడిట్ ఎలాగైనా డిస్క్‌లో సేవ్ అవుతుంది. exit 2 వల్ల కలిగే ప్రయోజనం ఏమిటంటే, ruff check అవుట్‌పుట్ మోడల్‌కు ఫీడ్‌బ్యాక్‌గా అందుతుంది, తద్వారా అది తదుపరి పనికి వెళ్లకుండా తాను చేసిన తప్పును సరిదిద్దుకుంటుంది. కమిట్ చేసే సమయంలో మీరు కనుగొనే లింట్ ఫెయిల్యూర్ మరియు ఏజెంట్ అదే టర్న్‌లో సరిదిద్దే లింట్ ఫెయిల్యూర్ మధ్య ఉన్న తేడా ఇదే.

ఇక్కడ రెండు మ్యాచర్ పరిమితులు ముఖ్యమైనవి. Edit|Write అనేది షెల్ కమాండ్ ద్వారా మార్చబడిన ఫైళ్లను చూడలేదు, మరియు Claude తరచుగా Bash ద్వారా ఫైళ్లను రాస్తుంది కాబట్టి ఆ లోపం నిజమైనదే. ప్రతి కాల్‌కు కవరేజ్ కోసం, Bash ని కూడా మ్యాచ్ చేయండి మరియు git status --porcelain తో మార్చబడిన ఫైళ్ల జాబితాను స్క్రిప్ట్ ద్వారా చూపండి. ప్రతి టర్న్‌కు ఒకసారి కవరేజ్ కోసం, స్కాన్‌ను Stop హుక్‌లో ఉంచండి.

ఉదాహరణ 3: ఆడిట్ కోసం ప్రతి టూల్ కాల్‌ను లాగ్ చేయడం

PostToolUse పై ఉన్న ఖాళీ మ్యాచర్ ప్రతి టూల్ కాల్‌పై పనిచేస్తుంది. రికార్డును హోమ్ డైరెక్టరీలోని ఫైల్‌కు పంపే బదులు సిస్టమ్ జర్నల్‌కు పంపడం వల్ల, అది ఏజెంట్ యొక్క స్వంత షెల్ పరిధికి అందకుండా ఉంటుంది:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{time: now|todate, session: .session_id, cwd: .cwd, tool: .tool_name, input: .tool_input}' | logger -t claude-code -p local0.info"
          }
        ]
      }
    ]
  }
}

దీనిని journalctl -t claude-code -o cat | tail -n 5 తో తిరిగి చదవండి. ప్రతి టూల్ కాల్‌కు ఒక JSON లైన్ కనిపిస్తుంది, కొత్తవి చివరన ఉంటాయి. ఏమీ కనిపించకపోతే హుక్ రన్ కాలేదని అర్థం, దీని గురించి కింద ఉన్న ట్రబుల్‌షూటింగ్ విభాగంలో చూడవచ్చు.

విఫలమైన కాల్‌లను కూడా క్యాప్చర్ చేయడానికి PostToolUseFailure కింద అదే బ్లాక్‌ను జోడించండి, ఎందుకంటే PostToolUse కేవలం సక్సెస్ అయినప్పుడు మాత్రమే పనిచేస్తుంది, కానీ సాధారణంగా విఫలమైన కమాండ్లే ముఖ్యమైనవి. మీ హోమ్ డైరెక్టరీలోని ఫైల్‌కు అపెండ్ చేసే బదులు logger ని ఎందుకు వాడాలంటే, అది యాజమాన్యానికి (ownership) సంబంధించినది: ఒక హుక్ ఏజెంట్ షెల్ వినియోగదారుడి అనుమతులతోనే రన్ అవుతుంది, కాబట్టి ఆ వినియోగదారుడు దేనికైనా అపెండ్ చేయగలిగితే, దానిని తొలగించగలడు (truncate) కూడా. జర్నల్ అనేది systemd-journald ద్వారా దాని స్వంత ఖాతాలో రాయబడుతుంది.

ఒక hook ఎంత సమయం రన్ అవ్వవచ్చు

ChartDefault hook timeout in seconds, by hook type and event
The data behind this chart
[
  {
    "label": "command, http or mcp_tool hook",
    "default_timeout_seconds": 600
  },
  {
    "label": "agent hook",
    "default_timeout_seconds": 60
  },
  {
    "label": "prompt hook",
    "default_timeout_seconds": 30
  },
  {
    "label": "command hook on UserPromptSubmit",
    "default_timeout_seconds": 30
  },
  {
    "label": "command hook on MessageDisplay",
    "default_timeout_seconds": 10
  },
  {
    "label": "any hook on SessionEnd",
    "default_timeout_seconds": 1.5
  }
]

ఒక command hook డిఫాల్ట్‌గా 600 సెకన్ల సమయాన్ని పొందుతుంది, అంటే పది నిమిషాలు. కొన్ని ఈవెంట్‌లు ఈ సమయాన్ని గణనీయంగా తగ్గిస్తాయి. SessionEnd hooks అన్నీ కలిసి 1.5 సెకన్ల బడ్జెట్‌ను పంచుకుంటాయి, కాబట్టి సెషన్ ముగింపులో చేసే క్లీనప్ పనులు త్వరగా పూర్తి కావాలి. అయితే, hook పై ఎక్కువ timeout సెట్ చేయడం ద్వారా ఈ షేర్డ్ బడ్జెట్‌ను 60 సెకన్ల వరకు పెంచుకోవచ్చు.

తనకు కేటాయించిన సమయం ముగిసేలోపు పూర్తికాని hook రద్దు చేయబడుతుంది మరియు అది ఎటువంటి నిర్ణయాన్ని ఇవ్వదు. ఒక PreToolUse guardrail విషయంలో దీని అర్థం అది అడ్డుకోదు అని: ఆ tool call సాధారణ అనుమతి ప్రక్రియ (permission flow) ద్వారా కొనసాగుతుంది. ఈ కారణం చేత guardrail స్క్రిప్ట్‌లను చిన్నవిగా ఉంచండి. లాగ్‌లను ఎక్కడికైనా పంపడం వంటి, ఎవరూ వేచి ఉండాల్సిన అవసరం లేని నెమ్మదైన పనుల కోసం, "async": true సెట్ చేయండి; అప్పుడు ఆ hook tool call ను ఆపకుండా బ్యాక్‌గ్రౌండ్‌లో రన్ అవుతుంది.

Hooks, rules files, skills మరియు MCP servers

ఏజెంట్ చేసే పనిని మార్చే నాలుగు అంశాలు ఒకదానితో ఒకటి గందరగోళానికి గురిచేస్తాయి. వీటిలో ఒకటి మాత్రమే సూచనగా ఉండటం ఆపివేస్తుంది.

ఒక rules file (CLAUDE.md, లేదా .claude/rules/ కింద ఉన్న ఫైల్) అనేది మోడల్ యొక్క context లోకి లోడ్ చేయబడిన టెక్స్ట్. ఇది ప్రవర్తనను రూపొందిస్తుంది కానీ దేనినీ బలవంతంగా అమలు చేయదు. సుదీర్ఘ సంభాషణ, పెద్ద diff మరియు కొత్త యూజర్ అభ్యర్థనల మధ్య, ఇందులో ఉన్న ఒక లైన్ ప్రభావం కోల్పోవచ్చు. ఏజెంట్లు మీరు రాసిన సూచనలను విస్మరించడం వెనుక ఉన్న సాధారణ కారణం ఇదే.

ఒక skill అనేది మోడల్ తనకు సంబంధితమని భావించినప్పుడు లోడ్ చేసే సూచనలు మరియు స్క్రిప్ట్‌ల ఫోల్డర్. ఆ నిర్ణయం తీసుకోవడమే skill యొక్క ముఖ్య ఉద్దేశ్యం, అదే దాని పరిమితి కూడా: మోడల్ ఇప్పటికీ నిర్ణయం తీసుకుంటుంది. Ponytail, ఇది ఏజెంట్‌ను పని చేసే అతి చిన్న మార్పు వైపు నెడుతుంది వంటి skill లో మీరు రెండు వైపులా చూడవచ్చు, ఎందుకంటే ఇది ఏ hook చేయలేని విధంగా మొత్తం పనిని ఎలా చేయాలో రూపొందిస్తుంది, మరియు మోడల్ దానిని లోడ్ చేయాలని ఎంచుకున్నప్పుడు మాత్రమే ఇది పనిచేస్తుంది.

ఒక MCP (model context protocol) server మోడల్‌కు కాల్ చేయడానికి కొత్త సాధనాలను అందిస్తుంది. ఇది ఏజెంట్ చేరుకోగల పరిధిని విస్తరిస్తుంది. ఇది ఏజెంట్‌ను దేనినైనా చేయమని బలవంతం చేయదు, మరియు ఇది మీరు నిర్వహించాల్సిన ఒక ప్రత్యేక ప్రక్రియ, ఇది ఒక విడిగా చేయాల్సిన పని: VPS పై MCP servers ను రన్ చేయడం చూడండి.

ఈ నాలుగింటిలో మోడల్ ఎంపికతో సంబంధం లేకుండా రన్ అయ్యేది hook మాత్రమే. ఒక ప్రాధాన్యత కోసం rules file ను, మరియు మోడల్ అనుసరించాల్సిన విధానం కోసం skill ను ఉపయోగించండి. ప్రతిసారీ జరగాల్సిన దశ కోసం లేదా ఎప్పటికీ జరగకూడని పని కోసం hook ను ఉపయోగించండి. skill ఎప్పుడు rules file కంటే మెరుగ్గా పనిచేస్తుందనే దానితో సహా లోతైన పోలిక skills, MCP మరియు rules files మధ్య పోలిక లో ఉంది.

plugin అనేది ఐదవ విధానం కాదు, ఇది కేవలం ప్యాకేజింగ్ మాత్రమే. ఇది hooks మరియు skills ను ఒకే install చేయదగిన యూనిట్‌గా కలుపుతుంది, దీని ద్వారా ఒక బృందం ప్రతి మెషీన్‌కు ఒకే రకమైన guardrail ను పంపిస్తుంది: Claude Code plugins ఎలా పనిచేస్తాయి చూడండి.

షేర్డ్ VPSలో భద్రతా నిర్ణయం

హుక్ (hook) అనేది ఏజెంట్ ట్రిగ్గర్ చేసే కోడ్, ఇది Claude Codeను ప్రారంభించిన వినియోగదారుని అనుమతులతోనే రన్ అవుతుంది. ఇది ఆ వినియోగదారుని ఎన్విరాన్మెంట్ మరియు ఫైల్ అనుమతులను పొందుతుంది. ల్యాప్‌టాప్‌లో ఇది కేవలం వర్క్‌ఫ్లోకు సంబంధించిన విషయం, కానీ ఏజెంట్ నిరంతరాయంగా రన్ అయ్యే VPSలో ఇది నాలుగు ఆచరణాత్మక అంశాలతో కూడిన భద్రతా సమస్య.

రిపోజిటరీలోని హుక్ మీరు రాయనటువంటి కోడ్. .claude/settings.json కమిట్ చేయబడి ఉంటుంది, కాబట్టి ఒక రిపోజిటరీని క్లోన్ చేసి, దాని లోపల సెషన్‌ను ప్రారంభించడం ద్వారా ఆ రిపోజిటరీతో వచ్చిన హుక్స్‌ను రిజిస్టర్ చేయవచ్చు. Claude Code ప్రాజెక్ట్ హుక్స్‌ను ఆ ఫోల్డర్ కోసం ఉండే వర్క్‌స్పేస్ ట్రస్ట్ డైలాగ్ ద్వారా నియంత్రిస్తుంది, అంటే మీరు ట్రస్ట్‌ను అంగీకరించిన క్షణమే వాటిని రన్ చేయడానికి నిర్ణయించుకున్నట్లు లెక్క. ముందుగా hooks బ్లాక్‌ను చదవండి.

హుక్ పూర్తి టూల్ ఇన్‌పుట్‌ను చూడగలదు. tool_inputను లాగ్ చేసే ఆడిట్ హుక్, ప్రతి కమాండ్ యొక్క ప్రతి ఆర్గ్యుమెంట్‌ను ఒక ఫైల్‌లోకి రాస్తుంది, ఇందులో కమాండ్ లైన్‌లో ఉన్న ఏదైనా టోకెన్ కూడా ఉండవచ్చు. ఆ లాగ్‌కు కూడా సీక్రెట్ ఉన్నంత భద్రత అవసరం, ఇది AI ఏజెంట్‌కు సీక్రెట్స్ అందకుండా చూడటం అనే విస్తృత సమస్యలో ఒక భాగం.

హుక్ మోడల్ కాంటెక్స్ట్‌లోకి రాయగలదు. SessionStart లేదా UserPromptSubmit హుక్ stdoutకు పంపే ఏదైనా సమాచారం సంభాషణలోకి జోడించబడుతుంది. బయటి నుంచి, అంటే ఇష్యూ ట్రాకర్ లేదా లాగ్ ఫైల్ నుంచి టెక్స్ట్‌ను పైప్ చేసే హుక్, మీరు స్వయంగా టైప్ చేసినట్లుగానే నమ్మదగని టెక్స్ట్‌ను మోడల్‌కు అందిస్తుంది. అదే VPSలో మరొక Claude Code సెషన్ నుంచి నోట్‌ను ఫార్వర్డ్ చేసే హుక్ కూడా అదే పని చేస్తుంది, మరియు ఒక ఏజెంట్ అవుట్‌పుట్‌కు ఇష్యూ ట్రాకర్ కంటే ఎక్కువ నమ్మకం ఉండదు. ఆ stdoutను అవుట్‌పుట్‌గా కాకుండా ఇన్‌పుట్‌గా పరిగణించండి.

ప్రివిలేజ్ (అధికారం) అనేది అసలైన నియంత్రణ. ఏజెంట్‌ను కేవలం దానికి అవసరమైన sudo రూల్స్ మాత్రమే ఉన్న ప్రత్యేకమైన, తక్కువ అధికారాలు కలిగిన వినియోగదారుగా రన్ చేయండి. PreToolUse డినై (deny) ఉండటం మంచిది, అయితే ఇది డిజైన్ ప్రకారం ఉత్తమ ప్రయత్నం మాత్రమే: if ఫిల్టర్ గురించి కూడా రిఫరెన్స్ ఇదే చెబుతుంది మరియు మీకు కఠినమైన నిరోధం (hard deny) కావాలంటే పర్మిషన్ సిస్టమ్‌ను ఉపయోగించమని సూచిస్తుంది. పర్మిషన్ రూల్స్ మరియు ప్రాసెస్ రన్ అయ్యే అకౌంట్ మాత్రమే ఒత్తిడిని తట్టుకోగలవు.

ప్రతి కాన్ఫిగరేషన్‌లో ఒక నియమం ఖచ్చితంగా పనిచేస్తుంది. PreToolUse హుక్స్ ప్రతి పర్మిషన్ మోడ్‌లో పర్మిషన్-మోడ్ చెక్ కంటే ముందే రన్ అవుతాయి, కాబట్టి ఒక హుక్ denyను రిటర్న్ చేస్తే, అది bypassPermissionsలో కూడా టూల్‌ను బ్లాక్ చేస్తుంది. హుక్స్ పర్మిషన్ రూల్స్ అనుమతించే వాటిని మరింత కఠినతరం చేయగలవు, కానీ వాటిని సడలించలేవు.

నా హుక్ (hook) ఎందుకు పనిచేయడం లేదు?

దీనిని క్రమ పద్ధతిలో పరిశీలించండి. ప్రతి దశలో మీరు చూసే లక్షణం పేర్కొనబడింది.

  • /hooks రన్ చేసి, మీరు ఆశించిన ఈవెంట్ కింద హుక్ కనిపిస్తుందో లేదో తనిఖీ చేయండి. మెనూలో హుక్ కనిపించకపోతే, సెట్టింగ్స్ ఫైల్‌లో JSON సింటాక్స్ లోపం ఉన్నట్లు అర్థం. ఎందుకంటే, చివరన ఉండే కామాలు (trailing commas) మరియు కామెంట్లను JSON అనుమతించదు, లేదా పైన పేర్కొన్న ఆరు స్థానాల్లో ఫైల్ లేకపోవచ్చు.
  • మ్యాచర్ (matcher) ను టూల్ పేరుతో సరిగ్గా పోల్చి చూడండి. మ్యాచర్లు కేస్ సెన్సిటివ్ (case sensitive), కాబట్టి "bash" అనేది Bash టూల్‌తో ఎప్పటికీ మ్యాచ్ అవ్వదు.
  • పైన ఉన్న ఉదాహరణ 1లో చూపినట్లుగా, శాంపిల్ ఇన్‌పుట్‌తో స్క్రిప్ట్‌ను మాన్యువల్‌గా రన్ చేయండి. మీరు ఆశించని ఎగ్జిట్ కోడ్ వస్తే అది మీ స్క్రిప్ట్‌లోని లోపం, అప్పుడు Claude Code దానిని నిర్ణయంగా కాకుండా హుక్ ఎర్రర్‌గా చూపిస్తుంది.
  • jq: command not found అని నోటీసు కనిపిస్తే, ఆ మెషీన్‌లో jq లేదని అర్థం. మీ స్వంత స్క్రిప్ట్ కోసం command not found వస్తే, పాత్ (path) సరిగ్గా రిజాల్వ్ అవ్వలేదని అర్థం, కాబట్టి ${CLAUDE_PROJECT_DIR} లేదా అబ్సల్యూట్ పాత్ (absolute path) ఉపయోగించండి. స్క్రిప్ట్ అస్సలు రన్ అవ్వకపోతే, అది ఎగ్జిక్యూటబుల్ (executable) ఫైల్ కాకపోవచ్చు.
  • హుక్ సరైన JSONను ప్రింట్ చేసినా ఏమీ జరగడం లేదు. షెల్-ఫార్మ్ హుక్ sh -c ద్వారా రన్ అవుతుంది, మీ షెల్ ప్రొఫైల్ ఏదైనా బ్యానర్‌ను ప్రింట్ చేస్తే, ఆ బ్యానర్ మీ JSONకు ముందు చేరుతుంది. అప్పుడు Stdout అనేది { తో ప్రారంభం కాదు, కాబట్టి Claude Code మొత్తం సమాచారాన్ని ప్లెయిన్ టెక్స్ట్‌గా చదివి ఆ నిర్ణయాన్ని విస్మరిస్తుంది. ఎగ్జిట్ 0 అయినప్పుడు డీబగ్ లాగ్ తప్ప మరెక్కడా ఏమీ రిపోర్ట్ అవ్వదు. మీ ప్రొఫైల్‌లోని ఏదైనా echo ను ఇంటరాక్టివ్ షెల్స్‌లో మాత్రమే రన్ అయ్యేలా మార్చండి.
  • ఇంకా సమస్య ఉంటే: claude --debug-file /tmp/claude.log తో సెషన్‌ను ప్రారంభించి, రెండవ టెర్మినల్‌లో tail -f /tmp/claude.log రన్ చేయండి. ఏ హుక్స్ మ్యాచ్ అయ్యాయి, ప్రతి ఒక్కటి ఏ ఎగ్జిట్ కోడ్‌ను ఇచ్చాయి, మరియు అవి stdout, stderr లో ఏమి రాశాయి అనే వివరాలన్నీ డీబగ్ లాగ్‌లో రికార్డ్ అవుతాయి.

FAQ

Claude Code hook మరియు CLAUDE.md instruction మధ్య తేడా ఏమిటి?

CLAUDE.md instruction అనేది మోడల్ యొక్క context లో ఉండే టెక్స్ట్, కాబట్టి ఇది సంభాషణతో మరియు ప్రస్తుత అభ్యర్థనతో ప్రాధాన్యత కోసం పోటీపడుతుంది, మరియు మోడల్ వీటితో పోల్చి దీనికి ప్రాముఖ్యతను ఇవ్వవచ్చు. Hook అనేది Claude Code దాని lifecycle లో ఒక నిర్ణీత సమయంలో రన్ చేసే shell command, కాబట్టి మోడల్ నిర్ణయంతో సంబంధం లేకుండా, ఆ ఈవెంట్ జరిగిన ప్రతిసారీ ఇది అమలు అవుతుంది. మీ ప్రాధాన్యతల కోసం instruction ను ఉపయోగించండి. తప్పనిసరిగా జరగాల్సిన దశ లేదా ఎప్పటికీ జరగకూడని చర్య కోసం hook ను ఉపయోగించండి.

ఒక నిర్దిష్ట shell command ను Claude Code రన్ చేయకుండా ఎలా ఆపాలి?

PreToolUse hook ను ఒక Bash matcher తో రిజిస్టర్ చేయండి. ఇది .tool_input.command నుండి కమాండ్‌ను చదివి, stderr కు ఒక కారణాన్ని రాసి, 2 తో exit అవుతుంది. Claude Code ఆ కాల్‌ను రద్దు చేసి, మీరు ఇచ్చిన కారణాన్ని మోడల్‌కు చూపిస్తుంది. ఇది permission-mode తనిఖీకి ముందే జరుగుతుంది, కాబట్టి bypassPermissions mode లో కూడా ఈ నిరాకరణ అమలులో ఉంటుంది. కమాండ్ స్ట్రింగ్‌పై pattern matching చేయడం అనేది ఒక భద్రతా సరిహద్దు కంటే, ఒక రక్షణ కవచం (guardrail) వంటిది. ఎందుకంటే అదే కమాండ్‌ను pattern గుర్తించలేని రూపంలో కూడా రాయవచ్చు, కాబట్టి దీనికి అదనంగా permission rules మరియు unprivileged account ను ఉపయోగించండి.

నా hook సరైన JSON ను ప్రింట్ చేస్తుంది, కానీ ఏమీ జరగడం లేదు. ఎందుకు?

దీనికి అత్యంత సాధారణ కారణం మీ shell profile. args ఫీల్డ్ లేని hook, sh -c ద్వారా రన్ అవుతుంది. కొన్ని profiles ప్రతి shell ప్రారంభంలో ఒక banner ను ప్రింట్ చేస్తాయి, ఇది మీ JSON కంటే ముందుగా stdout లో చేరుతుంది. అవుట్‌పుట్ ఇకపై { తో ప్రారంభం కాకపోవడం వల్ల, Claude Code దానిని సాధారణ టెక్స్ట్‌గా పరిగణించి, ఆ నిర్ణయాన్ని విస్మరిస్తుంది. exit 0 అయినప్పుడు transcript లో ఏమీ కనిపించదు. మీ profile లోని ఏదైనా echo ను interactive-shell టెస్ట్‌తో కవర్ చేయండి, ఆపై claude --debug-file /tmp/claude.log లోని debug log ను చదవడం ద్వారా పరిష్కారాన్ని నిర్ధారించుకోండి.

షేర్డ్ సర్వర్‌పై Claude Code hooks రన్ చేయడం సురక్షితమేనా?

Hooks, Claude Code ను ప్రారంభించిన వినియోగదారుని అనుమతులతో రన్ అవుతాయి, కాబట్టి ఆ ఖాతా చేయగలిగే దేనినైనా hook చేయగలదు. రెండు అలవాట్లు చాలా వరకు ప్రమాదాన్ని తగ్గిస్తాయి: ఏజెంట్‌ను పరిమిత sudo policy కలిగిన ప్రత్యేక unprivileged account గా రన్ చేయండి, మరియు ఏదైనా repository యొక్క workspace trust dialog ను అంగీకరించే ముందు దాని hooks బ్లాక్‌ను చదవండి, ఎందుకంటే project hooks అన్నీ .claude/settings.json లోపల ఉంటాయి. వీటిలో ఏవీ రన్ కాకూడదనుకుంటే, మీ settings ఫైల్‌లో "disableAllHooks": true ను సెట్ చేయండి.