[{"data":1,"prerenderedAt":1827},["ShallowReactive",2],{"guide:/guides/claude-code-pretooluse-hook":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"tag":10,"date":11,"body":12,"_type":1821,"_id":1822,"_source":1823,"_file":1824,"_stem":1825,"_extension":1826},"/guides/claude-code-pretooluse-hook","guides",false,"","Gate tool calls with the Claude Code PreToolUse hook","The PreToolUse hook runs before Claude Code executes a tool, so it can inspect, log or block the call. Here is how to match tools and use it safely.","Hooks","2026-08-15",{"type":13,"children":14,"toc":1809},"root",[15,57,64,104,110,130,417,438,444,464,601,687,693,698,726,958,963,1129,1149,1168,1204,1210,1215,1421,1434,1440,1451,1546,1582,1588,1593,1685,1706,1712,1747,1753,1770,1776,1803],{"type":16,"tag":17,"props":18,"children":19},"element","p",{},[20,23,30,32,38,40,47,49,55],{"type":21,"value":22},"text","Most ",{"type":16,"tag":24,"props":25,"children":27},"a",{"href":26},"/guides/claude-code-hooks",[28],{"type":21,"value":29},"Claude Code hooks",{"type":21,"value":31}," ",{"type":16,"tag":33,"props":34,"children":35},"em",{},[36],{"type":21,"value":37},"react",{"type":21,"value":39}," to what happened. ",{"type":16,"tag":41,"props":42,"children":44},"code",{"className":43},[],[45],{"type":21,"value":46},"PreToolUse",{"type":21,"value":48}," is special: it runs ",{"type":16,"tag":50,"props":51,"children":52},"strong",{},[53],{"type":21,"value":54},"before",{"type":21,"value":56}," Claude executes a tool, so it is the one event that can look at a tool call and decide what happens next.",{"type":16,"tag":58,"props":59,"children":61},"h2",{"id":60},"when-it-fires",[62],{"type":21,"value":63},"When it fires",{"type":16,"tag":17,"props":65,"children":66},{},[67,72,74,80,82,88,89,95,96,102],{"type":16,"tag":41,"props":68,"children":70},{"className":69},[],[71],{"type":21,"value":46},{"type":21,"value":73}," fires immediately before Claude runs any tool: ",{"type":16,"tag":41,"props":75,"children":77},{"className":76},[],[78],{"type":21,"value":79},"Bash",{"type":21,"value":81},", ",{"type":16,"tag":41,"props":83,"children":85},{"className":84},[],[86],{"type":21,"value":87},"Edit",{"type":21,"value":81},{"type":16,"tag":41,"props":90,"children":92},{"className":91},[],[93],{"type":21,"value":94},"Write",{"type":21,"value":81},{"type":16,"tag":41,"props":97,"children":99},{"className":98},[],[100],{"type":21,"value":101},"Read",{"type":21,"value":103},", and the rest, including tools provided by MCP servers. The event payload includes the tool name and the input Claude is about to use, so your command can inspect exactly what is about to run before anything touches your machine.",{"type":16,"tag":58,"props":105,"children":107},{"id":106},"matching-tools",[108],{"type":21,"value":109},"Matching tools",{"type":16,"tag":17,"props":111,"children":112},{},[113,115,120,122,128],{"type":21,"value":114},"Unlike lifecycle events, ",{"type":16,"tag":41,"props":116,"children":118},{"className":117},[],[119],{"type":21,"value":46},{"type":21,"value":121}," uses a ",{"type":16,"tag":41,"props":123,"children":125},{"className":124},[],[126],{"type":21,"value":127},"matcher",{"type":21,"value":129},", a regular expression tested against the tool name, so you can target one tool or several:",{"type":16,"tag":131,"props":132,"children":136},"pre",{"className":133,"code":134,"language":135,"meta":7,"style":7},"language-json shiki shiki-themes github-light github-dark","{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          { \"type\": \"command\", \"command\": \"cat >> ~/claude-bash.jsonl\" }\n        ]\n      },\n      {\n        \"matcher\": \"Edit|Write\",\n        \"hooks\": [\n          { \"type\": \"command\", \"command\": \"echo 'about to change a file'\" }\n        ]\n      }\n    ]\n  }\n}\n","json",[137],{"type":16,"tag":41,"props":138,"children":139},{"__ignoreMap":7},[140,152,167,181,190,215,228,273,282,291,299,320,332,373,381,390,399,408],{"type":16,"tag":141,"props":142,"children":145},"span",{"class":143,"line":144},"line",1,[146],{"type":16,"tag":141,"props":147,"children":149},{"style":148},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[150],{"type":21,"value":151},"{\n",{"type":16,"tag":141,"props":153,"children":155},{"class":143,"line":154},2,[156,162],{"type":16,"tag":141,"props":157,"children":159},{"style":158},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[160],{"type":21,"value":161},"  \"hooks\"",{"type":16,"tag":141,"props":163,"children":164},{"style":148},[165],{"type":21,"value":166},": {\n",{"type":16,"tag":141,"props":168,"children":170},{"class":143,"line":169},3,[171,176],{"type":16,"tag":141,"props":172,"children":173},{"style":158},[174],{"type":21,"value":175},"    \"PreToolUse\"",{"type":16,"tag":141,"props":177,"children":178},{"style":148},[179],{"type":21,"value":180},": [\n",{"type":16,"tag":141,"props":182,"children":184},{"class":143,"line":183},4,[185],{"type":16,"tag":141,"props":186,"children":187},{"style":148},[188],{"type":21,"value":189},"      {\n",{"type":16,"tag":141,"props":191,"children":193},{"class":143,"line":192},5,[194,199,204,210],{"type":16,"tag":141,"props":195,"children":196},{"style":158},[197],{"type":21,"value":198},"        \"matcher\"",{"type":16,"tag":141,"props":200,"children":201},{"style":148},[202],{"type":21,"value":203},": ",{"type":16,"tag":141,"props":205,"children":207},{"style":206},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[208],{"type":21,"value":209},"\"Bash\"",{"type":16,"tag":141,"props":211,"children":212},{"style":148},[213],{"type":21,"value":214},",\n",{"type":16,"tag":141,"props":216,"children":218},{"class":143,"line":217},6,[219,224],{"type":16,"tag":141,"props":220,"children":221},{"style":158},[222],{"type":21,"value":223},"        \"hooks\"",{"type":16,"tag":141,"props":225,"children":226},{"style":148},[227],{"type":21,"value":180},{"type":16,"tag":141,"props":229,"children":231},{"class":143,"line":230},7,[232,237,242,246,251,255,259,263,268],{"type":16,"tag":141,"props":233,"children":234},{"style":148},[235],{"type":21,"value":236},"          { ",{"type":16,"tag":141,"props":238,"children":239},{"style":158},[240],{"type":21,"value":241},"\"type\"",{"type":16,"tag":141,"props":243,"children":244},{"style":148},[245],{"type":21,"value":203},{"type":16,"tag":141,"props":247,"children":248},{"style":206},[249],{"type":21,"value":250},"\"command\"",{"type":16,"tag":141,"props":252,"children":253},{"style":148},[254],{"type":21,"value":81},{"type":16,"tag":141,"props":256,"children":257},{"style":158},[258],{"type":21,"value":250},{"type":16,"tag":141,"props":260,"children":261},{"style":148},[262],{"type":21,"value":203},{"type":16,"tag":141,"props":264,"children":265},{"style":206},[266],{"type":21,"value":267},"\"cat >> ~/claude-bash.jsonl\"",{"type":16,"tag":141,"props":269,"children":270},{"style":148},[271],{"type":21,"value":272}," }\n",{"type":16,"tag":141,"props":274,"children":276},{"class":143,"line":275},8,[277],{"type":16,"tag":141,"props":278,"children":279},{"style":148},[280],{"type":21,"value":281},"        ]\n",{"type":16,"tag":141,"props":283,"children":285},{"class":143,"line":284},9,[286],{"type":16,"tag":141,"props":287,"children":288},{"style":148},[289],{"type":21,"value":290},"      },\n",{"type":16,"tag":141,"props":292,"children":294},{"class":143,"line":293},10,[295],{"type":16,"tag":141,"props":296,"children":297},{"style":148},[298],{"type":21,"value":189},{"type":16,"tag":141,"props":300,"children":302},{"class":143,"line":301},11,[303,307,311,316],{"type":16,"tag":141,"props":304,"children":305},{"style":158},[306],{"type":21,"value":198},{"type":16,"tag":141,"props":308,"children":309},{"style":148},[310],{"type":21,"value":203},{"type":16,"tag":141,"props":312,"children":313},{"style":206},[314],{"type":21,"value":315},"\"Edit|Write\"",{"type":16,"tag":141,"props":317,"children":318},{"style":148},[319],{"type":21,"value":214},{"type":16,"tag":141,"props":321,"children":323},{"class":143,"line":322},12,[324,328],{"type":16,"tag":141,"props":325,"children":326},{"style":158},[327],{"type":21,"value":223},{"type":16,"tag":141,"props":329,"children":330},{"style":148},[331],{"type":21,"value":180},{"type":16,"tag":141,"props":333,"children":335},{"class":143,"line":334},13,[336,340,344,348,352,356,360,364,369],{"type":16,"tag":141,"props":337,"children":338},{"style":148},[339],{"type":21,"value":236},{"type":16,"tag":141,"props":341,"children":342},{"style":158},[343],{"type":21,"value":241},{"type":16,"tag":141,"props":345,"children":346},{"style":148},[347],{"type":21,"value":203},{"type":16,"tag":141,"props":349,"children":350},{"style":206},[351],{"type":21,"value":250},{"type":16,"tag":141,"props":353,"children":354},{"style":148},[355],{"type":21,"value":81},{"type":16,"tag":141,"props":357,"children":358},{"style":158},[359],{"type":21,"value":250},{"type":16,"tag":141,"props":361,"children":362},{"style":148},[363],{"type":21,"value":203},{"type":16,"tag":141,"props":365,"children":366},{"style":206},[367],{"type":21,"value":368},"\"echo 'about to change a file'\"",{"type":16,"tag":141,"props":370,"children":371},{"style":148},[372],{"type":21,"value":272},{"type":16,"tag":141,"props":374,"children":376},{"class":143,"line":375},14,[377],{"type":16,"tag":141,"props":378,"children":379},{"style":148},[380],{"type":21,"value":281},{"type":16,"tag":141,"props":382,"children":384},{"class":143,"line":383},15,[385],{"type":16,"tag":141,"props":386,"children":387},{"style":148},[388],{"type":21,"value":389},"      }\n",{"type":16,"tag":141,"props":391,"children":393},{"class":143,"line":392},16,[394],{"type":16,"tag":141,"props":395,"children":396},{"style":148},[397],{"type":21,"value":398},"    ]\n",{"type":16,"tag":141,"props":400,"children":402},{"class":143,"line":401},17,[403],{"type":16,"tag":141,"props":404,"children":405},{"style":148},[406],{"type":21,"value":407},"  }\n",{"type":16,"tag":141,"props":409,"children":411},{"class":143,"line":410},18,[412],{"type":16,"tag":141,"props":413,"children":414},{"style":148},[415],{"type":21,"value":416},"}\n",{"type":16,"tag":17,"props":418,"children":419},{},[420,422,428,430,436],{"type":21,"value":421},"The first matcher logs every shell command Claude is about to run to a file; the second reacts whenever a file is about to be edited or written. ",{"type":16,"tag":41,"props":423,"children":425},{"className":424},[],[426],{"type":21,"value":427},"mcp__.*",{"type":21,"value":429}," catches every tool coming from an MCP server, and ",{"type":16,"tag":41,"props":431,"children":433},{"className":432},[],[434],{"type":21,"value":435},".*",{"type":21,"value":437}," catches everything.",{"type":16,"tag":58,"props":439,"children":441},{"id":440},"inspecting-the-payload",[442],{"type":21,"value":443},"Inspecting the payload",{"type":16,"tag":17,"props":445,"children":446},{},[447,449,454,456,462],{"type":21,"value":448},"Because ",{"type":16,"tag":41,"props":450,"children":452},{"className":451},[],[453],{"type":21,"value":46},{"type":21,"value":455}," receives the tool input on ",{"type":16,"tag":41,"props":457,"children":459},{"className":458},[],[460],{"type":21,"value":461},"stdin",{"type":21,"value":463},", you can read it and act on it. Logging the raw JSON is the fastest way to see the shape:",{"type":16,"tag":131,"props":465,"children":467},{"className":133,"code":466,"language":135,"meta":7,"style":7},"{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \".*\",\n        \"hooks\": [{ \"type\": \"command\", \"command\": \"cat >> ~/claude-pretool.jsonl\" }]\n      }\n    ]\n  }\n}\n",[468],{"type":16,"tag":41,"props":469,"children":470},{"__ignoreMap":7},[471,478,489,500,507,527,573,580,587,594],{"type":16,"tag":141,"props":472,"children":473},{"class":143,"line":144},[474],{"type":16,"tag":141,"props":475,"children":476},{"style":148},[477],{"type":21,"value":151},{"type":16,"tag":141,"props":479,"children":480},{"class":143,"line":154},[481,485],{"type":16,"tag":141,"props":482,"children":483},{"style":158},[484],{"type":21,"value":161},{"type":16,"tag":141,"props":486,"children":487},{"style":148},[488],{"type":21,"value":166},{"type":16,"tag":141,"props":490,"children":491},{"class":143,"line":169},[492,496],{"type":16,"tag":141,"props":493,"children":494},{"style":158},[495],{"type":21,"value":175},{"type":16,"tag":141,"props":497,"children":498},{"style":148},[499],{"type":21,"value":180},{"type":16,"tag":141,"props":501,"children":502},{"class":143,"line":183},[503],{"type":16,"tag":141,"props":504,"children":505},{"style":148},[506],{"type":21,"value":189},{"type":16,"tag":141,"props":508,"children":509},{"class":143,"line":192},[510,514,518,523],{"type":16,"tag":141,"props":511,"children":512},{"style":158},[513],{"type":21,"value":198},{"type":16,"tag":141,"props":515,"children":516},{"style":148},[517],{"type":21,"value":203},{"type":16,"tag":141,"props":519,"children":520},{"style":206},[521],{"type":21,"value":522},"\".*\"",{"type":16,"tag":141,"props":524,"children":525},{"style":148},[526],{"type":21,"value":214},{"type":16,"tag":141,"props":528,"children":529},{"class":143,"line":217},[530,534,539,543,547,551,555,559,563,568],{"type":16,"tag":141,"props":531,"children":532},{"style":158},[533],{"type":21,"value":223},{"type":16,"tag":141,"props":535,"children":536},{"style":148},[537],{"type":21,"value":538},": [{ ",{"type":16,"tag":141,"props":540,"children":541},{"style":158},[542],{"type":21,"value":241},{"type":16,"tag":141,"props":544,"children":545},{"style":148},[546],{"type":21,"value":203},{"type":16,"tag":141,"props":548,"children":549},{"style":206},[550],{"type":21,"value":250},{"type":16,"tag":141,"props":552,"children":553},{"style":148},[554],{"type":21,"value":81},{"type":16,"tag":141,"props":556,"children":557},{"style":158},[558],{"type":21,"value":250},{"type":16,"tag":141,"props":560,"children":561},{"style":148},[562],{"type":21,"value":203},{"type":16,"tag":141,"props":564,"children":565},{"style":206},[566],{"type":21,"value":567},"\"cat >> ~/claude-pretool.jsonl\"",{"type":16,"tag":141,"props":569,"children":570},{"style":148},[571],{"type":21,"value":572}," }]\n",{"type":16,"tag":141,"props":574,"children":575},{"class":143,"line":230},[576],{"type":16,"tag":141,"props":577,"children":578},{"style":148},[579],{"type":21,"value":389},{"type":16,"tag":141,"props":581,"children":582},{"class":143,"line":275},[583],{"type":16,"tag":141,"props":584,"children":585},{"style":148},[586],{"type":21,"value":398},{"type":16,"tag":141,"props":588,"children":589},{"class":143,"line":284},[590],{"type":16,"tag":141,"props":591,"children":592},{"style":148},[593],{"type":21,"value":407},{"type":16,"tag":141,"props":595,"children":596},{"class":143,"line":293},[597],{"type":16,"tag":141,"props":598,"children":599},{"style":148},[600],{"type":21,"value":416},{"type":16,"tag":17,"props":602,"children":603},{},[604,606,612,613,619,620,626,628,634,636,642,644,649,651,657,659,665,667,672,673,678,679,685],{"type":21,"value":605},"Watch that file while you work and you will see the base fields (",{"type":16,"tag":41,"props":607,"children":609},{"className":608},[],[610],{"type":21,"value":611},"session_id",{"type":21,"value":81},{"type":16,"tag":41,"props":614,"children":616},{"className":615},[],[617],{"type":21,"value":618},"cwd",{"type":21,"value":81},{"type":16,"tag":41,"props":621,"children":623},{"className":622},[],[624],{"type":21,"value":625},"hook_event_name",{"type":21,"value":627},") plus the two that matter here: ",{"type":16,"tag":41,"props":629,"children":631},{"className":630},[],[632],{"type":21,"value":633},"tool_name",{"type":21,"value":635},", and ",{"type":16,"tag":41,"props":637,"children":639},{"className":638},[],[640],{"type":21,"value":641},"tool_input",{"type":21,"value":643},", an object whose shape depends on the tool. For ",{"type":16,"tag":41,"props":645,"children":647},{"className":646},[],[648],{"type":21,"value":79},{"type":21,"value":650}," it carries ",{"type":16,"tag":41,"props":652,"children":654},{"className":653},[],[655],{"type":21,"value":656},"command",{"type":21,"value":658}," and ",{"type":16,"tag":41,"props":660,"children":662},{"className":661},[],[663],{"type":21,"value":664},"description",{"type":21,"value":666},"; for ",{"type":16,"tag":41,"props":668,"children":670},{"className":669},[],[671],{"type":21,"value":87},{"type":21,"value":658},{"type":16,"tag":41,"props":674,"children":676},{"className":675},[],[677],{"type":21,"value":94},{"type":21,"value":650},{"type":16,"tag":41,"props":680,"children":682},{"className":681},[],[683],{"type":21,"value":684},"file_path",{"type":21,"value":686}," and the content. Those are the fields you match on for your own hook.",{"type":16,"tag":58,"props":688,"children":690},{"id":689},"blocking-a-call",[691],{"type":21,"value":692},"Blocking a call",{"type":16,"tag":17,"props":694,"children":695},{},[696],{"type":21,"value":697},"There are two ways to stop a tool call.",{"type":16,"tag":17,"props":699,"children":700},{},[701,703,708,710,716,718,724],{"type":21,"value":702},"The blunt one is the ",{"type":16,"tag":50,"props":704,"children":705},{},[706],{"type":21,"value":707},"exit code",{"type":21,"value":709},": exit with ",{"type":16,"tag":41,"props":711,"children":713},{"className":712},[],[714],{"type":21,"value":715},"2",{"type":21,"value":717}," and Claude Code cancels the call, feeding whatever your script printed on ",{"type":16,"tag":41,"props":719,"children":721},{"className":720},[],[722],{"type":21,"value":723},"stderr",{"type":21,"value":725}," back to Claude as the reason. Claude then reads it and usually adapts, which is why the message is worth writing for a reader.",{"type":16,"tag":131,"props":727,"children":731},{"className":728,"code":729,"language":730,"meta":7,"style":7},"language-bash shiki shiki-themes github-light github-dark","#!/usr/bin/env bash\n# .claude/hooks/guard.sh\npayload=$(cat)\ncmd=$(echo \"$payload\" | jq -r '.tool_input.command // \"\"')\n\nif echo \"$cmd\" | grep -qE '(^|[;&|]\\s*)rm\\s+-rf\\s+/'; then\n  echo \"Blocked: rm -rf on an absolute path is never allowed here.\" >&2\n  exit 2\nfi\nexit 0\n","bash",[732],{"type":16,"tag":41,"props":733,"children":734},{"__ignoreMap":7},[735,744,752,782,842,851,906,924,937,945],{"type":16,"tag":141,"props":736,"children":737},{"class":143,"line":144},[738],{"type":16,"tag":141,"props":739,"children":741},{"style":740},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[742],{"type":21,"value":743},"#!/usr/bin/env bash\n",{"type":16,"tag":141,"props":745,"children":746},{"class":143,"line":154},[747],{"type":16,"tag":141,"props":748,"children":749},{"style":740},[750],{"type":21,"value":751},"# .claude/hooks/guard.sh\n",{"type":16,"tag":141,"props":753,"children":754},{"class":143,"line":169},[755,760,766,771,777],{"type":16,"tag":141,"props":756,"children":757},{"style":148},[758],{"type":21,"value":759},"payload",{"type":16,"tag":141,"props":761,"children":763},{"style":762},"--shiki-default:#D73A49;--shiki-dark:#F97583",[764],{"type":21,"value":765},"=",{"type":16,"tag":141,"props":767,"children":768},{"style":148},[769],{"type":21,"value":770},"$(",{"type":16,"tag":141,"props":772,"children":774},{"style":773},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[775],{"type":21,"value":776},"cat",{"type":16,"tag":141,"props":778,"children":779},{"style":148},[780],{"type":21,"value":781},")\n",{"type":16,"tag":141,"props":783,"children":784},{"class":143,"line":183},[785,790,794,798,803,808,813,818,823,828,833,838],{"type":16,"tag":141,"props":786,"children":787},{"style":148},[788],{"type":21,"value":789},"cmd",{"type":16,"tag":141,"props":791,"children":792},{"style":762},[793],{"type":21,"value":765},{"type":16,"tag":141,"props":795,"children":796},{"style":148},[797],{"type":21,"value":770},{"type":16,"tag":141,"props":799,"children":800},{"style":158},[801],{"type":21,"value":802},"echo",{"type":16,"tag":141,"props":804,"children":805},{"style":206},[806],{"type":21,"value":807}," \"",{"type":16,"tag":141,"props":809,"children":810},{"style":148},[811],{"type":21,"value":812},"$payload",{"type":16,"tag":141,"props":814,"children":815},{"style":206},[816],{"type":21,"value":817},"\"",{"type":16,"tag":141,"props":819,"children":820},{"style":762},[821],{"type":21,"value":822}," |",{"type":16,"tag":141,"props":824,"children":825},{"style":773},[826],{"type":21,"value":827}," jq",{"type":16,"tag":141,"props":829,"children":830},{"style":158},[831],{"type":21,"value":832}," -r",{"type":16,"tag":141,"props":834,"children":835},{"style":206},[836],{"type":21,"value":837}," '.tool_input.command // \"\"'",{"type":16,"tag":141,"props":839,"children":840},{"style":148},[841],{"type":21,"value":781},{"type":16,"tag":141,"props":843,"children":844},{"class":143,"line":192},[845],{"type":16,"tag":141,"props":846,"children":848},{"emptyLinePlaceholder":847},true,[849],{"type":21,"value":850},"\n",{"type":16,"tag":141,"props":852,"children":853},{"class":143,"line":217},[854,859,864,868,873,877,881,886,891,896,901],{"type":16,"tag":141,"props":855,"children":856},{"style":762},[857],{"type":21,"value":858},"if",{"type":16,"tag":141,"props":860,"children":861},{"style":158},[862],{"type":21,"value":863}," echo",{"type":16,"tag":141,"props":865,"children":866},{"style":206},[867],{"type":21,"value":807},{"type":16,"tag":141,"props":869,"children":870},{"style":148},[871],{"type":21,"value":872},"$cmd",{"type":16,"tag":141,"props":874,"children":875},{"style":206},[876],{"type":21,"value":817},{"type":16,"tag":141,"props":878,"children":879},{"style":762},[880],{"type":21,"value":822},{"type":16,"tag":141,"props":882,"children":883},{"style":773},[884],{"type":21,"value":885}," grep",{"type":16,"tag":141,"props":887,"children":888},{"style":158},[889],{"type":21,"value":890}," -qE",{"type":16,"tag":141,"props":892,"children":893},{"style":206},[894],{"type":21,"value":895}," '(^|[;&|]\\s*)rm\\s+-rf\\s+/'",{"type":16,"tag":141,"props":897,"children":898},{"style":148},[899],{"type":21,"value":900},"; ",{"type":16,"tag":141,"props":902,"children":903},{"style":762},[904],{"type":21,"value":905},"then\n",{"type":16,"tag":141,"props":907,"children":908},{"class":143,"line":230},[909,914,919],{"type":16,"tag":141,"props":910,"children":911},{"style":158},[912],{"type":21,"value":913},"  echo",{"type":16,"tag":141,"props":915,"children":916},{"style":206},[917],{"type":21,"value":918}," \"Blocked: rm -rf on an absolute path is never allowed here.\"",{"type":16,"tag":141,"props":920,"children":921},{"style":762},[922],{"type":21,"value":923}," >&2\n",{"type":16,"tag":141,"props":925,"children":926},{"class":143,"line":275},[927,932],{"type":16,"tag":141,"props":928,"children":929},{"style":158},[930],{"type":21,"value":931},"  exit",{"type":16,"tag":141,"props":933,"children":934},{"style":158},[935],{"type":21,"value":936}," 2\n",{"type":16,"tag":141,"props":938,"children":939},{"class":143,"line":284},[940],{"type":16,"tag":141,"props":941,"children":942},{"style":762},[943],{"type":21,"value":944},"fi\n",{"type":16,"tag":141,"props":946,"children":947},{"class":143,"line":293},[948,953],{"type":16,"tag":141,"props":949,"children":950},{"style":158},[951],{"type":21,"value":952},"exit",{"type":16,"tag":141,"props":954,"children":955},{"style":158},[956],{"type":21,"value":957}," 0\n",{"type":16,"tag":17,"props":959,"children":960},{},[961],{"type":21,"value":962},"Wire it up, and give it a short timeout so a slow guard never stalls a session:",{"type":16,"tag":131,"props":964,"children":966},{"className":133,"code":965,"language":135,"meta":7,"style":7},"{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          { \"type\": \"command\", \"command\": \"$CLAUDE_PROJECT_DIR/.claude/hooks/guard.sh\", \"timeout\": 5 }\n        ]\n      }\n    ]\n  }\n}\n",[967],{"type":16,"tag":41,"props":968,"children":969},{"__ignoreMap":7},[970,977,988,999,1006,1025,1036,1094,1101,1108,1115,1122],{"type":16,"tag":141,"props":971,"children":972},{"class":143,"line":144},[973],{"type":16,"tag":141,"props":974,"children":975},{"style":148},[976],{"type":21,"value":151},{"type":16,"tag":141,"props":978,"children":979},{"class":143,"line":154},[980,984],{"type":16,"tag":141,"props":981,"children":982},{"style":158},[983],{"type":21,"value":161},{"type":16,"tag":141,"props":985,"children":986},{"style":148},[987],{"type":21,"value":166},{"type":16,"tag":141,"props":989,"children":990},{"class":143,"line":169},[991,995],{"type":16,"tag":141,"props":992,"children":993},{"style":158},[994],{"type":21,"value":175},{"type":16,"tag":141,"props":996,"children":997},{"style":148},[998],{"type":21,"value":180},{"type":16,"tag":141,"props":1000,"children":1001},{"class":143,"line":183},[1002],{"type":16,"tag":141,"props":1003,"children":1004},{"style":148},[1005],{"type":21,"value":189},{"type":16,"tag":141,"props":1007,"children":1008},{"class":143,"line":192},[1009,1013,1017,1021],{"type":16,"tag":141,"props":1010,"children":1011},{"style":158},[1012],{"type":21,"value":198},{"type":16,"tag":141,"props":1014,"children":1015},{"style":148},[1016],{"type":21,"value":203},{"type":16,"tag":141,"props":1018,"children":1019},{"style":206},[1020],{"type":21,"value":209},{"type":16,"tag":141,"props":1022,"children":1023},{"style":148},[1024],{"type":21,"value":214},{"type":16,"tag":141,"props":1026,"children":1027},{"class":143,"line":217},[1028,1032],{"type":16,"tag":141,"props":1029,"children":1030},{"style":158},[1031],{"type":21,"value":223},{"type":16,"tag":141,"props":1033,"children":1034},{"style":148},[1035],{"type":21,"value":180},{"type":16,"tag":141,"props":1037,"children":1038},{"class":143,"line":230},[1039,1043,1047,1051,1055,1059,1063,1067,1072,1076,1081,1085,1090],{"type":16,"tag":141,"props":1040,"children":1041},{"style":148},[1042],{"type":21,"value":236},{"type":16,"tag":141,"props":1044,"children":1045},{"style":158},[1046],{"type":21,"value":241},{"type":16,"tag":141,"props":1048,"children":1049},{"style":148},[1050],{"type":21,"value":203},{"type":16,"tag":141,"props":1052,"children":1053},{"style":206},[1054],{"type":21,"value":250},{"type":16,"tag":141,"props":1056,"children":1057},{"style":148},[1058],{"type":21,"value":81},{"type":16,"tag":141,"props":1060,"children":1061},{"style":158},[1062],{"type":21,"value":250},{"type":16,"tag":141,"props":1064,"children":1065},{"style":148},[1066],{"type":21,"value":203},{"type":16,"tag":141,"props":1068,"children":1069},{"style":206},[1070],{"type":21,"value":1071},"\"$CLAUDE_PROJECT_DIR/.claude/hooks/guard.sh\"",{"type":16,"tag":141,"props":1073,"children":1074},{"style":148},[1075],{"type":21,"value":81},{"type":16,"tag":141,"props":1077,"children":1078},{"style":158},[1079],{"type":21,"value":1080},"\"timeout\"",{"type":16,"tag":141,"props":1082,"children":1083},{"style":148},[1084],{"type":21,"value":203},{"type":16,"tag":141,"props":1086,"children":1087},{"style":158},[1088],{"type":21,"value":1089},"5",{"type":16,"tag":141,"props":1091,"children":1092},{"style":148},[1093],{"type":21,"value":272},{"type":16,"tag":141,"props":1095,"children":1096},{"class":143,"line":275},[1097],{"type":16,"tag":141,"props":1098,"children":1099},{"style":148},[1100],{"type":21,"value":281},{"type":16,"tag":141,"props":1102,"children":1103},{"class":143,"line":284},[1104],{"type":16,"tag":141,"props":1105,"children":1106},{"style":148},[1107],{"type":21,"value":389},{"type":16,"tag":141,"props":1109,"children":1110},{"class":143,"line":293},[1111],{"type":16,"tag":141,"props":1112,"children":1113},{"style":148},[1114],{"type":21,"value":398},{"type":16,"tag":141,"props":1116,"children":1117},{"class":143,"line":301},[1118],{"type":16,"tag":141,"props":1119,"children":1120},{"style":148},[1121],{"type":21,"value":407},{"type":16,"tag":141,"props":1123,"children":1124},{"class":143,"line":322},[1125],{"type":16,"tag":141,"props":1126,"children":1127},{"style":148},[1128],{"type":21,"value":416},{"type":16,"tag":17,"props":1130,"children":1131},{},[1132,1134,1139,1141,1147],{"type":21,"value":1133},"The precise one is a ",{"type":16,"tag":50,"props":1135,"children":1136},{},[1137],{"type":21,"value":1138},"JSON decision",{"type":21,"value":1140}," printed on ",{"type":16,"tag":41,"props":1142,"children":1144},{"className":1143},[],[1145],{"type":21,"value":1146},"stdout",{"type":21,"value":1148},". It lets you deny with a reason, allow outright (skipping the permission prompt you would normally get), or force a prompt on something that would otherwise pass:",{"type":16,"tag":131,"props":1150,"children":1152},{"className":728,"code":1151,"language":730,"meta":7,"style":7},"echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"secrets live in .env, read .env.example instead\"}}'\n",[1153],{"type":16,"tag":41,"props":1154,"children":1155},{"__ignoreMap":7},[1156],{"type":16,"tag":141,"props":1157,"children":1158},{"class":143,"line":144},[1159,1163],{"type":16,"tag":141,"props":1160,"children":1161},{"style":158},[1162],{"type":21,"value":802},{"type":16,"tag":141,"props":1164,"children":1165},{"style":206},[1166],{"type":21,"value":1167}," '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"secrets live in .env, read .env.example instead\"}}'\n",{"type":16,"tag":17,"props":1169,"children":1170},{},[1171,1173,1179,1181,1187,1189,1195,1197,1202],{"type":21,"value":1172},"Swap ",{"type":16,"tag":41,"props":1174,"children":1176},{"className":1175},[],[1177],{"type":21,"value":1178},"deny",{"type":21,"value":1180}," for ",{"type":16,"tag":41,"props":1182,"children":1184},{"className":1183},[],[1185],{"type":21,"value":1186},"allow",{"type":21,"value":1188}," or ",{"type":16,"tag":41,"props":1190,"children":1192},{"className":1191},[],[1193],{"type":21,"value":1194},"ask",{"type":21,"value":1196}," as needed. Because ",{"type":16,"tag":41,"props":1198,"children":1200},{"className":1199},[],[1201],{"type":21,"value":1186},{"type":21,"value":1203}," bypasses the usual prompt, keep those rules narrow.",{"type":16,"tag":58,"props":1205,"children":1207},{"id":1206},"guarding-a-path",[1208],{"type":21,"value":1209},"Guarding a path",{"type":16,"tag":17,"props":1211,"children":1212},{},[1213],{"type":21,"value":1214},"The other common guard is a file one. This blocks any write to your environment files, whatever the tool:",{"type":16,"tag":131,"props":1216,"children":1218},{"className":728,"code":1217,"language":730,"meta":7,"style":7},"#!/usr/bin/env bash\npayload=$(cat)\npath=$(echo \"$payload\" | jq -r '.tool_input.file_path // \"\"')\n\ncase \"$path\" in\n  *.env|*.env.*|*/secrets/*)\n    echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"this path is off limits\"}}'\n    ;;\nesac\nexit 0\n",[1219],{"type":16,"tag":41,"props":1220,"children":1221},{"__ignoreMap":7},[1222,1229,1252,1305,1312,1338,1381,1394,1402,1410],{"type":16,"tag":141,"props":1223,"children":1224},{"class":143,"line":144},[1225],{"type":16,"tag":141,"props":1226,"children":1227},{"style":740},[1228],{"type":21,"value":743},{"type":16,"tag":141,"props":1230,"children":1231},{"class":143,"line":154},[1232,1236,1240,1244,1248],{"type":16,"tag":141,"props":1233,"children":1234},{"style":148},[1235],{"type":21,"value":759},{"type":16,"tag":141,"props":1237,"children":1238},{"style":762},[1239],{"type":21,"value":765},{"type":16,"tag":141,"props":1241,"children":1242},{"style":148},[1243],{"type":21,"value":770},{"type":16,"tag":141,"props":1245,"children":1246},{"style":773},[1247],{"type":21,"value":776},{"type":16,"tag":141,"props":1249,"children":1250},{"style":148},[1251],{"type":21,"value":781},{"type":16,"tag":141,"props":1253,"children":1254},{"class":143,"line":169},[1255,1260,1264,1268,1272,1276,1280,1284,1288,1292,1296,1301],{"type":16,"tag":141,"props":1256,"children":1257},{"style":148},[1258],{"type":21,"value":1259},"path",{"type":16,"tag":141,"props":1261,"children":1262},{"style":762},[1263],{"type":21,"value":765},{"type":16,"tag":141,"props":1265,"children":1266},{"style":148},[1267],{"type":21,"value":770},{"type":16,"tag":141,"props":1269,"children":1270},{"style":158},[1271],{"type":21,"value":802},{"type":16,"tag":141,"props":1273,"children":1274},{"style":206},[1275],{"type":21,"value":807},{"type":16,"tag":141,"props":1277,"children":1278},{"style":148},[1279],{"type":21,"value":812},{"type":16,"tag":141,"props":1281,"children":1282},{"style":206},[1283],{"type":21,"value":817},{"type":16,"tag":141,"props":1285,"children":1286},{"style":762},[1287],{"type":21,"value":822},{"type":16,"tag":141,"props":1289,"children":1290},{"style":773},[1291],{"type":21,"value":827},{"type":16,"tag":141,"props":1293,"children":1294},{"style":158},[1295],{"type":21,"value":832},{"type":16,"tag":141,"props":1297,"children":1298},{"style":206},[1299],{"type":21,"value":1300}," '.tool_input.file_path // \"\"'",{"type":16,"tag":141,"props":1302,"children":1303},{"style":148},[1304],{"type":21,"value":781},{"type":16,"tag":141,"props":1306,"children":1307},{"class":143,"line":183},[1308],{"type":16,"tag":141,"props":1309,"children":1310},{"emptyLinePlaceholder":847},[1311],{"type":21,"value":850},{"type":16,"tag":141,"props":1313,"children":1314},{"class":143,"line":192},[1315,1320,1324,1329,1333],{"type":16,"tag":141,"props":1316,"children":1317},{"style":762},[1318],{"type":21,"value":1319},"case",{"type":16,"tag":141,"props":1321,"children":1322},{"style":206},[1323],{"type":21,"value":807},{"type":16,"tag":141,"props":1325,"children":1326},{"style":148},[1327],{"type":21,"value":1328},"$path",{"type":16,"tag":141,"props":1330,"children":1331},{"style":206},[1332],{"type":21,"value":817},{"type":16,"tag":141,"props":1334,"children":1335},{"style":762},[1336],{"type":21,"value":1337}," in\n",{"type":16,"tag":141,"props":1339,"children":1340},{"class":143,"line":217},[1341,1346,1352,1357,1362,1367,1372,1377],{"type":16,"tag":141,"props":1342,"children":1343},{"style":762},[1344],{"type":21,"value":1345},"  *",{"type":16,"tag":141,"props":1347,"children":1349},{"style":1348},"--shiki-default:#032F62;--shiki-dark:#DBEDFF",[1350],{"type":21,"value":1351},".env",{"type":16,"tag":141,"props":1353,"children":1354},{"style":762},[1355],{"type":21,"value":1356},"|*",{"type":16,"tag":141,"props":1358,"children":1359},{"style":1348},[1360],{"type":21,"value":1361},".env.",{"type":16,"tag":141,"props":1363,"children":1364},{"style":762},[1365],{"type":21,"value":1366},"*|*",{"type":16,"tag":141,"props":1368,"children":1369},{"style":1348},[1370],{"type":21,"value":1371},"/secrets/",{"type":16,"tag":141,"props":1373,"children":1374},{"style":762},[1375],{"type":21,"value":1376},"*",{"type":16,"tag":141,"props":1378,"children":1379},{"style":762},[1380],{"type":21,"value":781},{"type":16,"tag":141,"props":1382,"children":1383},{"class":143,"line":230},[1384,1389],{"type":16,"tag":141,"props":1385,"children":1386},{"style":158},[1387],{"type":21,"value":1388},"    echo",{"type":16,"tag":141,"props":1390,"children":1391},{"style":206},[1392],{"type":21,"value":1393}," '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"deny\",\"permissionDecisionReason\":\"this path is off limits\"}}'\n",{"type":16,"tag":141,"props":1395,"children":1396},{"class":143,"line":275},[1397],{"type":16,"tag":141,"props":1398,"children":1399},{"style":148},[1400],{"type":21,"value":1401},"    ;;\n",{"type":16,"tag":141,"props":1403,"children":1404},{"class":143,"line":284},[1405],{"type":16,"tag":141,"props":1406,"children":1407},{"style":762},[1408],{"type":21,"value":1409},"esac\n",{"type":16,"tag":141,"props":1411,"children":1412},{"class":143,"line":293},[1413,1417],{"type":16,"tag":141,"props":1414,"children":1415},{"style":158},[1416],{"type":21,"value":952},{"type":16,"tag":141,"props":1418,"children":1419},{"style":158},[1420],{"type":21,"value":957},{"type":16,"tag":17,"props":1422,"children":1423},{},[1424,1426,1432],{"type":21,"value":1425},"Match it on ",{"type":16,"tag":41,"props":1427,"children":1429},{"className":1428},[],[1430],{"type":21,"value":1431},"Edit|Write|Read",{"type":21,"value":1433}," and it covers reading as well as writing.",{"type":16,"tag":58,"props":1435,"children":1437},{"id":1436},"what-your-exit-code-means",[1438],{"type":21,"value":1439},"What your exit code means",{"type":16,"tag":17,"props":1441,"children":1442},{},[1443,1444,1449],{"type":21,"value":448},{"type":16,"tag":41,"props":1445,"children":1447},{"className":1446},[],[1448],{"type":21,"value":46},{"type":21,"value":1450}," can change the outcome, its exit codes are worth memorising:",{"type":16,"tag":1452,"props":1453,"children":1454},"table",{},[1455,1474],{"type":16,"tag":1456,"props":1457,"children":1458},"thead",{},[1459],{"type":16,"tag":1460,"props":1461,"children":1462},"tr",{},[1463,1469],{"type":16,"tag":1464,"props":1465,"children":1466},"th",{},[1467],{"type":21,"value":1468},"Exit code",{"type":16,"tag":1464,"props":1470,"children":1471},{},[1472],{"type":21,"value":1473},"Effect",{"type":16,"tag":1475,"props":1476,"children":1477},"tbody",{},[1478,1503,1526],{"type":16,"tag":1460,"props":1479,"children":1480},{},[1481,1491],{"type":16,"tag":1482,"props":1483,"children":1484},"td",{},[1485],{"type":16,"tag":41,"props":1486,"children":1488},{"className":1487},[],[1489],{"type":21,"value":1490},"0",{"type":16,"tag":1482,"props":1492,"children":1493},{},[1494,1496,1501],{"type":21,"value":1495},"The call proceeds. ",{"type":16,"tag":41,"props":1497,"children":1499},{"className":1498},[],[1500],{"type":21,"value":1146},{"type":21,"value":1502}," is available for a JSON decision.",{"type":16,"tag":1460,"props":1504,"children":1505},{},[1506,1514],{"type":16,"tag":1482,"props":1507,"children":1508},{},[1509],{"type":16,"tag":41,"props":1510,"children":1512},{"className":1511},[],[1513],{"type":21,"value":715},{"type":16,"tag":1482,"props":1515,"children":1516},{},[1517,1519,1524],{"type":21,"value":1518},"The call is cancelled and ",{"type":16,"tag":41,"props":1520,"children":1522},{"className":1521},[],[1523],{"type":21,"value":723},{"type":21,"value":1525}," is sent back to Claude as the reason.",{"type":16,"tag":1460,"props":1527,"children":1528},{},[1529,1534],{"type":16,"tag":1482,"props":1530,"children":1531},{},[1532],{"type":21,"value":1533},"anything else",{"type":16,"tag":1482,"props":1535,"children":1536},{},[1537,1539,1544],{"type":21,"value":1538},"Non-blocking error: you see ",{"type":16,"tag":41,"props":1540,"children":1542},{"className":1541},[],[1543],{"type":21,"value":723},{"type":21,"value":1545},", the call proceeds anyway.",{"type":16,"tag":17,"props":1547,"children":1548},{},[1549,1551,1557,1559,1565,1567,1572,1574,1580],{"type":21,"value":1550},"That last row catches people out. A guard script that crashes on a missing ",{"type":16,"tag":41,"props":1552,"children":1554},{"className":1553},[],[1555],{"type":21,"value":1556},"jq",{"type":21,"value":1558}," exits with ",{"type":16,"tag":41,"props":1560,"children":1562},{"className":1561},[],[1563],{"type":21,"value":1564},"127",{"type":21,"value":1566},", which is ",{"type":16,"tag":33,"props":1568,"children":1569},{},[1570],{"type":21,"value":1571},"not",{"type":21,"value":1573}," a block, so the tool call runs. If your hook is a real guardrail, make it fail closed: check its dependencies at the top and ",{"type":16,"tag":41,"props":1575,"children":1577},{"className":1576},[],[1578],{"type":21,"value":1579},"exit 2",{"type":21,"value":1581}," if they are missing.",{"type":16,"tag":58,"props":1583,"children":1585},{"id":1584},"auditing-what-an-agent-actually-ran",[1586],{"type":21,"value":1587},"Auditing what an agent actually ran",{"type":16,"tag":17,"props":1589,"children":1590},{},[1591],{"type":21,"value":1592},"Blocking is the dramatic use; the quiet one is the record. Log every shell command to a file and you can answer \"what did it do?\" long after the session is gone:",{"type":16,"tag":131,"props":1594,"children":1596},{"className":728,"code":1595,"language":730,"meta":7,"style":7},"#!/usr/bin/env bash\npayload=$(cat)\njq -c '{ts: now, session: .session_id, cwd: .cwd, cmd: .tool_input.command}' <<< \"$payload\" >> ~/claude-audit.jsonl\nexit 0\n",[1597],{"type":16,"tag":41,"props":1598,"children":1599},{"__ignoreMap":7},[1600,1607,1630,1674],{"type":16,"tag":141,"props":1601,"children":1602},{"class":143,"line":144},[1603],{"type":16,"tag":141,"props":1604,"children":1605},{"style":740},[1606],{"type":21,"value":743},{"type":16,"tag":141,"props":1608,"children":1609},{"class":143,"line":154},[1610,1614,1618,1622,1626],{"type":16,"tag":141,"props":1611,"children":1612},{"style":148},[1613],{"type":21,"value":759},{"type":16,"tag":141,"props":1615,"children":1616},{"style":762},[1617],{"type":21,"value":765},{"type":16,"tag":141,"props":1619,"children":1620},{"style":148},[1621],{"type":21,"value":770},{"type":16,"tag":141,"props":1623,"children":1624},{"style":773},[1625],{"type":21,"value":776},{"type":16,"tag":141,"props":1627,"children":1628},{"style":148},[1629],{"type":21,"value":781},{"type":16,"tag":141,"props":1631,"children":1632},{"class":143,"line":169},[1633,1637,1642,1647,1652,1656,1660,1664,1669],{"type":16,"tag":141,"props":1634,"children":1635},{"style":773},[1636],{"type":21,"value":1556},{"type":16,"tag":141,"props":1638,"children":1639},{"style":158},[1640],{"type":21,"value":1641}," -c",{"type":16,"tag":141,"props":1643,"children":1644},{"style":206},[1645],{"type":21,"value":1646}," '{ts: now, session: .session_id, cwd: .cwd, cmd: .tool_input.command}'",{"type":16,"tag":141,"props":1648,"children":1649},{"style":762},[1650],{"type":21,"value":1651}," <<<",{"type":16,"tag":141,"props":1653,"children":1654},{"style":206},[1655],{"type":21,"value":807},{"type":16,"tag":141,"props":1657,"children":1658},{"style":148},[1659],{"type":21,"value":812},{"type":16,"tag":141,"props":1661,"children":1662},{"style":206},[1663],{"type":21,"value":817},{"type":16,"tag":141,"props":1665,"children":1666},{"style":762},[1667],{"type":21,"value":1668}," >>",{"type":16,"tag":141,"props":1670,"children":1671},{"style":206},[1672],{"type":21,"value":1673}," ~/claude-audit.jsonl\n",{"type":16,"tag":141,"props":1675,"children":1676},{"class":143,"line":183},[1677,1681],{"type":16,"tag":141,"props":1678,"children":1679},{"style":158},[1680],{"type":21,"value":952},{"type":16,"tag":141,"props":1682,"children":1683},{"style":158},[1684],{"type":21,"value":957},{"type":16,"tag":17,"props":1686,"children":1687},{},[1688,1690,1696,1698,1704],{"type":21,"value":1689},"Then read it back with the same tool: ",{"type":16,"tag":41,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":21,"value":1695},"jq -r 'select(.cmd) | .cmd' ~/claude-audit.jsonl | sort | uniq -c | sort -rn",{"type":21,"value":1697}," shows what your agents actually spend their time running, which is usually the fastest way to work out which commands belong in your ",{"type":16,"tag":41,"props":1699,"children":1701},{"className":1700},[],[1702],{"type":21,"value":1703},"permissions.allow",{"type":21,"value":1705}," list.",{"type":16,"tag":58,"props":1707,"children":1709},{"id":1708},"hook-or-permission-rule",[1710],{"type":21,"value":1711},"Hook or permission rule?",{"type":16,"tag":17,"props":1713,"children":1714},{},[1715,1717,1723,1725,1731,1733,1738,1740,1745],{"type":21,"value":1716},"A lot of this overlaps with the ",{"type":16,"tag":41,"props":1718,"children":1720},{"className":1719},[],[1721],{"type":21,"value":1722},"permissions.deny",{"type":21,"value":1724}," list in ",{"type":16,"tag":24,"props":1726,"children":1728},{"href":1727},"/guides/claude-code-settings-json",[1729],{"type":21,"value":1730},"your settings.json",{"type":21,"value":1732},", and when a static rule is enough, the rule wins: it is declarative, reviewable and costs nothing at runtime. Reach for ",{"type":16,"tag":41,"props":1734,"children":1736},{"className":1735},[],[1737],{"type":21,"value":46},{"type":21,"value":1739}," when the decision needs ",{"type":16,"tag":50,"props":1741,"children":1742},{},[1743],{"type":21,"value":1744},"logic",{"type":21,"value":1746},": inspecting the actual shell command, checking the current branch, calling out to your own policy service, or writing an audit trail of everything an agent tried.",{"type":16,"tag":58,"props":1748,"children":1750},{"id":1749},"use-it-for-guardrails-keep-it-fast",[1751],{"type":21,"value":1752},"Use it for guardrails, keep it fast",{"type":16,"tag":17,"props":1754,"children":1755},{},[1756,1761,1763,1768],{"type":16,"tag":41,"props":1757,"children":1759},{"className":1758},[],[1760],{"type":21,"value":46},{"type":21,"value":1762}," is where teams add lightweight guardrails: log every shell command for an audit trail, warn on writes to a sensitive path, or record what an agent touches. Keep the logic in a small script you control rather than a long inline command, keep it fast (it runs on the critical path of every tool call), and review project-level ",{"type":16,"tag":41,"props":1764,"children":1766},{"className":1765},[],[1767],{"type":21,"value":46},{"type":21,"value":1769}," hooks like any other code: they run automatically, with your permissions. Remember too that hooks are snapshotted at session start, so restart Claude Code after changing your guard.",{"type":16,"tag":58,"props":1771,"children":1773},{"id":1772},"see-what-each-session-is-doing-not-just-log-it",[1774],{"type":21,"value":1775},"See what each session is doing, not just log it",{"type":16,"tag":17,"props":1777,"children":1778},{},[1779,1781,1786,1788,1793,1795,1801],{"type":21,"value":1780},"A ",{"type":16,"tag":41,"props":1782,"children":1784},{"className":1783},[],[1785],{"type":21,"value":46},{"type":21,"value":1787}," hook is great for a record. But if what you want is to ",{"type":16,"tag":33,"props":1789,"children":1790},{},[1791],{"type":21,"value":1792},"see",{"type":21,"value":1794}," that a session is actively working (running tools right now versus sitting idle), ",{"type":16,"tag":24,"props":1796,"children":1798},{"href":1797},"/",[1799],{"type":21,"value":1800},"Blooby",{"type":21,"value":1802}," already reads this event, and every other, for you and shows it as a busy, animated mascot per session. No matchers, no scripts: it sets up its own hooks and reflects the state live.",{"type":16,"tag":1804,"props":1805,"children":1806},"style",{},[1807],{"type":21,"value":1808},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":7,"searchDepth":154,"depth":154,"links":1810},[1811,1812,1813,1814,1815,1816,1817,1818,1819,1820],{"id":60,"depth":154,"text":63},{"id":106,"depth":154,"text":109},{"id":440,"depth":154,"text":443},{"id":689,"depth":154,"text":692},{"id":1206,"depth":154,"text":1209},{"id":1436,"depth":154,"text":1439},{"id":1584,"depth":154,"text":1587},{"id":1708,"depth":154,"text":1711},{"id":1749,"depth":154,"text":1752},{"id":1772,"depth":154,"text":1775},"markdown","content:guides:claude-code-pretooluse-hook.md","content","guides/claude-code-pretooluse-hook.md","guides/claude-code-pretooluse-hook","md",1]