老城里有一座藏书极深的私人书院,门口立着一道看似繁琐、却几十年没出过纰漏的取书规矩。
一位读者写好取书条,递到取书台。司事并不立刻动身去库房——他先把条子压在柜台的玻璃板下,一层一层地比对。
第一层是一本黑名册:册上记着的书,概不外借。只要书名落在黑名册里,司事连库房的方向都不会瞥一眼,当场退条,没有商量。
过了黑名册,还有一本「须先请示」的册子:这些书不是不借,而是非得当面问过掌院不可。
再往下,是这一类书各自的门道——有的要看读者的来头,有的要看今天借去做什么。
院里偶尔设「通览日」,持通览牌的人本可畅行无阻;可即便如此,黑名册上的书、和注明「须先请示」的书,通览牌照样压不过去。
最后是一本常借册:在册的书,循例放行。
倘若一本书层层比下来仍无定论,规矩是宁可多问一句——默认转为「去请示」。
到了真要请示这一步,书院有两套办法。安静的时候,有位坐堂的评士替读者把条子从头读一遍,自行裁夺,不必惊动旁人。人多手杂的时候,则同时摇响柜台的铃、给掌院的手机递个信、招呼一旁的助手、再让一台小机器飞快验上一遍——谁先回话,就照谁的;而且台上备着一枚签子,头一个回话的人取走它,后到的回话便再也翻不动这桩事。
最要紧的一条,压在所有规矩之上:哪怕掌院亲口说了「借」,只要黑名册上还记着这本书的名字,这本书照样借不走。
唯有层层比对全数通过,司事才真的转身走向库房,把书取出来——这,正是一次工具调用在 Claude Code 里能否真正执行,所必须穿过的那道门:权限与派发(permission & dispatch)。
先猜揭晓前,先押一个猜测 · 你觉得这讲的是?
谜底 · The Concept
Tool permission & dispatch — the gate every tool call must pass
Tools · 工具系统
中文速览 · Quick read
When the model emits a ToolUseBlock, nothing actually happens to the world until a separate subsystem answers one question: is this specific call, with these specific arguments, allowed to run right now? That subsystem is the permission-and-dispatch path. Its entry point is runToolUse (claude-code/src/services/tools/toolExecution.ts:337), which hands the call to streamedCheckPermissionsAndCallTool (claude-code/src/services/tools/toolExecution.ts:455) — a thin wrapper that runs checkPermissionsAndCallTool and funnels its progress and final result into a single Stream (claude-code/src/services/tools/toolExecution.ts:492, claude-code/src/services/tools/toolExecution.ts:509). The decision is not a single boolean: it is a layered pipeline of rules, a tool's own self-assessment, mode overrides, lifecycle hooks, and — when still undecided — either an AI classifier or a race between several human-facing approval channels. Only an allow verdict reaches tool.call(...) (claude-code/src/services/tools/toolExecution.ts:1207); a deny becomes a <tool_use_error> returned to the model (claude-code/src/services/tools/toolExecution.ts:1064).
How it works
Before any rule check, runPreToolUseHooks executes (claude-code/src/services/tools/toolExecution.ts:800); a hook may yield a hookPermissionResult (claude-code/src/services/tools/toolExecution.ts:832) carrying permissionBehavior of allow, ask, or deny (claude-code/src/services/tools/toolHooks.ts:510), or merely a hookUpdatedInput passthrough that rewrites the arguments without deciding (claude-code/src/services/tools/toolExecution.ts:837). The result is reconciled by resolveHookPermissionDecision (claude-code/src/services/tools/toolHooks.ts:332, invoked at claude-code/src/services/tools/toolExecution.ts:921). The crucial invariant: a hook allow does not bypass settings.json deny/ask rules — it still runs checkRuleBasedPermissions (claude-code/src/services/tools/toolHooks.ts:373), and a matching deny rule overrides the hook approval outright (claude-code/src/services/tools/toolHooks.ts:386). A hook deny returns immediately (claude-code/src/services/tools/toolHooks.ts:408); a hook ask is threaded through as a forceDecision so the dialog shows the hook's message (claude-code/src/services/tools/toolHooks.ts:415). This is the parable's iron rule: even the curator's spoken "lend it" cannot move a book whose name is still in the blacklist.
For everything not short-circuited above, control reaches canUseTool (claude-code/src/hooks/useCanUseTool.tsx:32), which calls hasPermissionsToUseTool (claude-code/src/hooks/useCanUseTool.tsx:37, claude-code/src/utils/permissions/permissions.ts:473). Its core, hasPermissionsToUseToolInner (claude-code/src/utils/permissions/permissions.ts:1158), runs the layered checks in order: (1a) a deny rule for the tool → deny (claude-code/src/utils/permissions/permissions.ts:1171); (1b) an ask rule → ask (claude-code/src/utils/permissions/permissions.ts:1184); (1c) the tool's own checkPermissions (claude-code/src/utils/permissions/permissions.ts:1216), whose deny is honored even in bypass mode (claude-code/src/utils/permissions/permissions.ts:1226); (2a) bypassPermissions/plan-with-bypass mode → allow (claude-code/src/utils/permissions/permissions.ts:1268); (2b) an "always allowed" rule → allow (claude-code/src/utils/permissions/permissions.ts:1284); and finally (3) any leftover passthrough is converted to ask (claude-code/src/utils/permissions/permissions.ts:1299) — the parable's "when in doubt, ask." These map one-to-one onto the blacklist, the must-ask register, each book's own rules, the open-browsing pass, and the standing-loan register.
An ask is not the end — it must become a concrete allow/deny. The outer hasPermissionsToUseTool first applies mode transforms: dontAsk mode rewrites ask to deny (claude-code/src/utils/permissions/permissions.ts:505); in auto (or active plan) mode an AI classifier is consulted instead of a human (claude-code/src/utils/permissions/permissions.ts:520), but only after two cheap escape hatches — an acceptEdits fast-path that auto-allows safe edits without an API call (claude-code/src/utils/permissions/permissions.ts:600) and a safe-tool allowlist (claude-code/src/utils/permissions/permissions.ts:660) — before finally invoking classifyYoloAction (claude-code/src/utils/permissions/permissions.ts:690). This is the seated assessor who reads the ticket and rules alone. In a headless/async-agent context (shouldAvoidPermissionPrompts), there is no human to ask: PermissionRequest hooks get a chance to allow/deny, and absent any hook decision the call is auto-denied (claude-code/src/utils/permissions/permissions.ts:932).
When a real prompt is needed, canUseTool routes by session type. Background/coordinator workers take handleCoordinatorPermission (claude-code/src/hooks/useCanUseTool.tsx:95), which awaits the automated checks sequentially — hooks first (claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:33), then the bash classifier (claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:41) — before falling through to the dialog (claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:59), avoiding async-context hazards. The normal interactive session takes handleInteractivePermission (claude-code/src/hooks/useCanUseTool.tsx:160, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:57), which fires several approval channels in parallel and lets the first responder win: the bridge relay to claude.ai (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:244), the channel relay to Telegram/iMessage (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:316), the async PermissionRequest hooks (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:411), and the async bash classifier (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:434) — all alongside the local terminal dialog as the floor. The atomicity that makes this safe is createResolveOnce's claim() token (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:70): every racer's callback calls claim() before resolving (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:160), so the first winner takes the token and every later response simply no-ops. That is the single signing-chit on the desk.
The resolved PermissionDecision returns to checkPermissionsAndCallTool. If it is anything other than allow, the harness logs the rejection and returns a tool_result error to the model (claude-code/src/services/tools/toolExecution.ts:995, claude-code/src/services/tools/toolExecution.ts:1064). If it is allow, any permission-supplied updatedInput replaces the model's arguments (claude-code/src/services/tools/toolExecution.ts:1130) — with a special case that restores the model's original file_path when a backfilled value matches, to keep transcript/VCR hashes stable (claude-code/src/services/tools/toolExecution.ts:1189) — and only then does tool.call(...) execute (claude-code/src/services/tools/toolExecution.ts:1207). Afterward, PostToolUse hooks may even rewrite an MCP tool's output (claude-code/src/services/tools/toolExecution.ts:1483, claude-code/src/services/tools/toolExecution.ts:1494).
Why it matters
Every decision carries a decisionReason whose type records its source — rule, hook, classifier, mode, safety check (claude-code/src/hooks/toolPermission/permissionLogging.ts:29) — and logPermissionDecision is the single fan-out point that turns each verdict into analytics events, an OTel tool_decision event (claude-code/src/hooks/toolPermission/permissionLogging.ts:230), and a toolUseContext.toolDecisions map entry for downstream inspection (claude-code/src/hooks/toolPermission/permissionLogging.ts:224); the headless path emits the same OTel event directly (claude-code/src/services/tools/toolExecution.ts:962). This layering is what lets one harness be safe by default yet flexible: a deny rule is absolute (no hook, no mode, no classifier can override it), an ask always has a deterministic resolver (classifier, race, or queue) so a tool never silently hangs, and the claim() token guarantees that four parallel approval surfaces resolve exactly one decision. The model proposes; this gate disposes — and only its allow ever touches the world.
Read the source
- Entry and streaming wrapper: claude-code/src/services/tools/toolExecution.ts:337, claude-code/src/services/tools/toolExecution.ts:455, claude-code/src/services/tools/toolExecution.ts:492.
- Hooks-first and the deny-overrides-hook invariant: claude-code/src/services/tools/toolExecution.ts:800, claude-code/src/services/tools/toolHooks.ts:332, claude-code/src/services/tools/toolHooks.ts:386, claude-code/src/services/tools/toolHooks.ts:510.
- The layered rule pipeline, 1a→3: claude-code/src/utils/permissions/permissions.ts:1158, claude-code/src/utils/permissions/permissions.ts:1171, claude-code/src/utils/permissions/permissions.ts:1184, claude-code/src/utils/permissions/permissions.ts:1216, claude-code/src/utils/permissions/permissions.ts:1268, claude-code/src/utils/permissions/permissions.ts:1284, claude-code/src/utils/permissions/permissions.ts:1299.
- Resolving
ask— classifier, fast-paths, headless: claude-code/src/utils/permissions/permissions.ts:520, claude-code/src/utils/permissions/permissions.ts:600, claude-code/src/utils/permissions/permissions.ts:660, claude-code/src/utils/permissions/permissions.ts:932. - Dispatch — interactive race vs. coordinator queue, with
claim()atomicity: claude-code/src/hooks/useCanUseTool.tsx:160, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:70, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:244, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:434, claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:33. - Acting on the verdict — deny error, updatedInput,
tool.call: claude-code/src/services/tools/toolExecution.ts:1064, claude-code/src/services/tools/toolExecution.ts:1130, claude-code/src/services/tools/toolExecution.ts:1207. - Logging the decision source: claude-code/src/hooks/toolPermission/permissionLogging.ts:181, claude-code/src/hooks/toolPermission/permissionLogging.ts:230.
When the model emits a ToolUseBlock, nothing actually happens to the world until a separate subsystem answers one question: is this specific call, with these specific arguments, allowed to run right now? That subsystem is the permission-and-dispatch path. Its entry point is runToolUse (claude-code/src/services/tools/toolExecution.ts:337), which hands the call to streamedCheckPermissionsAndCallTool (claude-code/src/services/tools/toolExecution.ts:455) — a thin wrapper that runs checkPermissionsAndCallTool and funnels its progress and final result into a single Stream (claude-code/src/services/tools/toolExecution.ts:492, claude-code/src/services/tools/toolExecution.ts:509). The decision is not a single boolean: it is a layered pipeline of rules, a tool's own self-assessment, mode overrides, lifecycle hooks, and — when still undecided — either an AI classifier or a race between several human-facing approval channels. Only an allow verdict reaches tool.call(...) (claude-code/src/services/tools/toolExecution.ts:1207); a deny becomes a <tool_use_error> returned to the model (claude-code/src/services/tools/toolExecution.ts:1064).
How it works
PreToolUse hooks run first, but cannot launder a banned call. Before any rule check, runPreToolUseHooks executes (claude-code/src/services/tools/toolExecution.ts:800); a hook may yield a hookPermissionResult (claude-code/src/services/tools/toolExecution.ts:832) carrying permissionBehavior of allow, ask, or deny (claude-code/src/services/tools/toolHooks.ts:510), or merely a hookUpdatedInput passthrough that rewrites the arguments without deciding (claude-code/src/services/tools/toolExecution.ts:837). The result is reconciled by resolveHookPermissionDecision (claude-code/src/services/tools/toolHooks.ts:332, invoked at claude-code/src/services/tools/toolExecution.ts:921). The crucial invariant: a hook allow does not bypass settings.json deny/ask rules — it still runs checkRuleBasedPermissions (claude-code/src/services/tools/toolHooks.ts:373), and a matching deny rule overrides the hook approval outright (claude-code/src/services/tools/toolHooks.ts:386). A hook deny returns immediately (claude-code/src/services/tools/toolHooks.ts:408); a hook ask is threaded through as a forceDecision so the dialog shows the hook's message (claude-code/src/services/tools/toolHooks.ts:415). This is the parable's iron rule: even the curator's spoken "lend it" cannot move a book whose name is still in the blacklist.
The rule pipeline. For everything not short-circuited above, control reaches canUseTool (claude-code/src/hooks/useCanUseTool.tsx:32), which calls hasPermissionsToUseTool (claude-code/src/hooks/useCanUseTool.tsx:37, claude-code/src/utils/permissions/permissions.ts:473). Its core, hasPermissionsToUseToolInner (claude-code/src/utils/permissions/permissions.ts:1158), runs the layered checks in order: (1a) a deny rule for the tool → deny (claude-code/src/utils/permissions/permissions.ts:1171); (1b) an ask rule → ask (claude-code/src/utils/permissions/permissions.ts:1184); (1c) the tool's own checkPermissions (claude-code/src/utils/permissions/permissions.ts:1216), whose deny is honored even in bypass mode (claude-code/src/utils/permissions/permissions.ts:1226); (2a) bypassPermissions/plan-with-bypass mode → allow (claude-code/src/utils/permissions/permissions.ts:1268); (2b) an "always allowed" rule → allow (claude-code/src/utils/permissions/permissions.ts:1284); and finally (3) any leftover passthrough is converted to ask (claude-code/src/utils/permissions/permissions.ts:1299) — the parable's "when in doubt, ask." These map one-to-one onto the blacklist, the must-ask register, each book's own rules, the open-browsing pass, and the standing-loan register.
Resolving an ask. An ask is not the end — it must become a concrete allow/deny. The outer hasPermissionsToUseTool first applies mode transforms: dontAsk mode rewrites ask to deny (claude-code/src/utils/permissions/permissions.ts:505); in auto (or active plan) mode an AI classifier is consulted instead of a human (claude-code/src/utils/permissions/permissions.ts:520), but only after two cheap escape hatches — an acceptEdits fast-path that auto-allows safe edits without an API call (claude-code/src/utils/permissions/permissions.ts:600) and a safe-tool allowlist (claude-code/src/utils/permissions/permissions.ts:660) — before finally invoking classifyYoloAction (claude-code/src/utils/permissions/permissions.ts:690). This is the seated assessor who reads the ticket and rules alone. In a headless/async-agent context (shouldAvoidPermissionPrompts), there is no human to ask: PermissionRequest hooks get a chance to allow/deny, and absent any hook decision the call is auto-denied (claude-code/src/utils/permissions/permissions.ts:932).
Interactive dispatch is a race; coordinator dispatch is a queue. When a real prompt is needed, canUseTool routes by session type. Background/coordinator workers take handleCoordinatorPermission (claude-code/src/hooks/useCanUseTool.tsx:95), which awaits the automated checks sequentially — hooks first (claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:33), then the bash classifier (claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:41) — before falling through to the dialog (claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:59), avoiding async-context hazards. The normal interactive session takes handleInteractivePermission (claude-code/src/hooks/useCanUseTool.tsx:160, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:57), which fires several approval channels in parallel and lets the first responder win: the bridge relay to claude.ai (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:244), the channel relay to Telegram/iMessage (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:316), the async PermissionRequest hooks (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:411), and the async bash classifier (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:434) — all alongside the local terminal dialog as the floor. The atomicity that makes this safe is createResolveOnce's claim() token (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:70): every racer's callback calls claim() before resolving (claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:160), so the first winner takes the token and every later response simply no-ops. That is the single signing-chit on the desk.
Acting on the verdict. The resolved PermissionDecision returns to checkPermissionsAndCallTool. If it is anything other than allow, the harness logs the rejection and returns a tool_result error to the model (claude-code/src/services/tools/toolExecution.ts:995, claude-code/src/services/tools/toolExecution.ts:1064). If it is allow, any permission-supplied updatedInput replaces the model's arguments (claude-code/src/services/tools/toolExecution.ts:1130) — with a special case that restores the model's original file_path when a backfilled value matches, to keep transcript/VCR hashes stable (claude-code/src/services/tools/toolExecution.ts:1189) — and only then does tool.call(...) execute (claude-code/src/services/tools/toolExecution.ts:1207). Afterward, PostToolUse hooks may even rewrite an MCP tool's output (claude-code/src/services/tools/toolExecution.ts:1483, claude-code/src/services/tools/toolExecution.ts:1494).
Why it matters
Every decision carries a decisionReason whose type records its source — rule, hook, classifier, mode, safety check (claude-code/src/hooks/toolPermission/permissionLogging.ts:29) — and logPermissionDecision is the single fan-out point that turns each verdict into analytics events, an OTel tool_decision event (claude-code/src/hooks/toolPermission/permissionLogging.ts:230), and a toolUseContext.toolDecisions map entry for downstream inspection (claude-code/src/hooks/toolPermission/permissionLogging.ts:224); the headless path emits the same OTel event directly (claude-code/src/services/tools/toolExecution.ts:962). This layering is what lets one harness be safe by default yet flexible: a deny rule is absolute (no hook, no mode, no classifier can override it), an ask always has a deterministic resolver (classifier, race, or queue) so a tool never silently hangs, and the claim() token guarantees that four parallel approval surfaces resolve exactly one decision. The model proposes; this gate disposes — and only its allow ever touches the world.
Read the source
- Entry and streaming wrapper: claude-code/src/services/tools/toolExecution.ts:337, claude-code/src/services/tools/toolExecution.ts:455, claude-code/src/services/tools/toolExecution.ts:492.
- Hooks-first and the deny-overrides-hook invariant: claude-code/src/services/tools/toolExecution.ts:800, claude-code/src/services/tools/toolHooks.ts:332, claude-code/src/services/tools/toolHooks.ts:386, claude-code/src/services/tools/toolHooks.ts:510.
- The layered rule pipeline, 1a→3: claude-code/src/utils/permissions/permissions.ts:1158, claude-code/src/utils/permissions/permissions.ts:1171, claude-code/src/utils/permissions/permissions.ts:1184, claude-code/src/utils/permissions/permissions.ts:1216, claude-code/src/utils/permissions/permissions.ts:1268, claude-code/src/utils/permissions/permissions.ts:1284, claude-code/src/utils/permissions/permissions.ts:1299.
- Resolving
ask— classifier, fast-paths, headless: claude-code/src/utils/permissions/permissions.ts:520, claude-code/src/utils/permissions/permissions.ts:600, claude-code/src/utils/permissions/permissions.ts:660, claude-code/src/utils/permissions/permissions.ts:932. - Dispatch — interactive race vs. coordinator queue, with
claim()atomicity: claude-code/src/hooks/useCanUseTool.tsx:160, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:70, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:244, claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:434, claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:33. - Acting on the verdict — deny error, updatedInput,
tool.call: claude-code/src/services/tools/toolExecution.ts:1064, claude-code/src/services/tools/toolExecution.ts:1130, claude-code/src/services/tools/toolExecution.ts:1207. - Logging the decision source: claude-code/src/hooks/toolPermission/permissionLogging.ts:181, claude-code/src/hooks/toolPermission/permissionLogging.ts:230.
来源 · Source citations
- [1]
claude-code/src/services/tools/toolExecution.ts:337 - [2]
claude-code/src/services/tools/toolExecution.ts:455 - [3]
claude-code/src/services/tools/toolExecution.ts:492 - [4]
claude-code/src/services/tools/toolExecution.ts:509 - [5]
claude-code/src/services/tools/toolExecution.ts:800 - [6]
claude-code/src/services/tools/toolExecution.ts:832 - [7]
claude-code/src/services/tools/toolExecution.ts:837 - [8]
claude-code/src/services/tools/toolExecution.ts:921 - [9]
claude-code/src/services/tools/toolExecution.ts:962 - [10]
claude-code/src/services/tools/toolExecution.ts:995 - [11]
claude-code/src/services/tools/toolExecution.ts:1064 - [12]
claude-code/src/services/tools/toolExecution.ts:1130 - [13]
claude-code/src/services/tools/toolExecution.ts:1189 - [14]
claude-code/src/services/tools/toolExecution.ts:1207 - [15]
claude-code/src/services/tools/toolExecution.ts:1483 - [16]
claude-code/src/services/tools/toolExecution.ts:1494 - [17]
claude-code/src/services/tools/toolHooks.ts:332 - [18]
claude-code/src/services/tools/toolHooks.ts:373 - [19]
claude-code/src/services/tools/toolHooks.ts:386 - [20]
claude-code/src/services/tools/toolHooks.ts:408 - [21]
claude-code/src/services/tools/toolHooks.ts:415 - [22]
claude-code/src/services/tools/toolHooks.ts:510 - [23]
claude-code/src/hooks/useCanUseTool.tsx:32 - [24]
claude-code/src/hooks/useCanUseTool.tsx:37 - [25]
claude-code/src/hooks/useCanUseTool.tsx:95 - [26]
claude-code/src/hooks/useCanUseTool.tsx:160 - [27]
claude-code/src/utils/permissions/permissions.ts:473 - [28]
claude-code/src/utils/permissions/permissions.ts:505 - [29]
claude-code/src/utils/permissions/permissions.ts:520 - [30]
claude-code/src/utils/permissions/permissions.ts:600 - [31]
claude-code/src/utils/permissions/permissions.ts:660 - [32]
claude-code/src/utils/permissions/permissions.ts:690 - [33]
claude-code/src/utils/permissions/permissions.ts:932 - [34]
claude-code/src/utils/permissions/permissions.ts:1158 - [35]
claude-code/src/utils/permissions/permissions.ts:1171 - [36]
claude-code/src/utils/permissions/permissions.ts:1184 - [37]
claude-code/src/utils/permissions/permissions.ts:1216 - [38]
claude-code/src/utils/permissions/permissions.ts:1226 - [39]
claude-code/src/utils/permissions/permissions.ts:1268 - [40]
claude-code/src/utils/permissions/permissions.ts:1284 - [41]
claude-code/src/utils/permissions/permissions.ts:1299 - [42]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:57 - [43]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:70 - [44]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:160 - [45]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:244 - [46]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:316 - [47]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:411 - [48]
claude-code/src/hooks/toolPermission/handlers/interactiveHandler.ts:434 - [49]
claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:26 - [50]
claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:33 - [51]
claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:41 - [52]
claude-code/src/hooks/toolPermission/handlers/coordinatorHandler.ts:59 - [53]
claude-code/src/hooks/toolPermission/permissionLogging.ts:29 - [54]
claude-code/src/hooks/toolPermission/permissionLogging.ts:181 - [55]
claude-code/src/hooks/toolPermission/permissionLogging.ts:224 - [56]
claude-code/src/hooks/toolPermission/permissionLogging.ts:230