MCPcopy
hub / github.com/claude-code-best/claude-code / executeHooks

Function executeHooks

src/utils/hooks.ts:2088–3109  ·  view source on GitHub ↗

* Common logic for executing hooks * @param hookInput The structured hook input that will be validated and converted to JSON * @param toolUseID The ID for tracking this hook execution * @param matchQuery The query to match against hook matchers * @param signal Optional AbortSignal to cancel hook

({
  hookInput,
  toolUseID,
  matchQuery,
  signal,
  timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS,
  toolUseContext,
  messages,
  forceSyncExecution,
  requestPrompt,
  toolInputSummary,
}: {
  hookInput: HookInput
  toolUseID: string
  matchQuery?: string
  signal?: AbortSignal
  timeoutMs?: number
  toolUseContext?: ToolUseContext
  messages?: Message[]
  forceSyncExecution?: boolean
  requestPrompt?: (
    sourceName: string,
    toolInputSummary?: string | null,
  ) => (request: PromptRequest) => Promise<PromptResponse>
  toolInputSummary?: string | null
})

Source from the content-addressed store, hash-verified

2086 * @returns Async generator that yields progress messages and hook results
2087 */
2088async function* executeHooks({
2089 hookInput,
2090 toolUseID,
2091 matchQuery,
2092 signal,
2093 timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS,
2094 toolUseContext,
2095 messages,
2096 forceSyncExecution,
2097 requestPrompt,
2098 toolInputSummary,
2099}: {
2100 hookInput: HookInput
2101 toolUseID: string
2102 matchQuery?: string
2103 signal?: AbortSignal
2104 timeoutMs?: number
2105 toolUseContext?: ToolUseContext
2106 messages?: Message[]
2107 forceSyncExecution?: boolean
2108 requestPrompt?: (
2109 sourceName: string,
2110 toolInputSummary?: string | null,
2111 ) => (request: PromptRequest) => Promise<PromptResponse>
2112 toolInputSummary?: string | null
2113}): AsyncGenerator<AggregatedHookResult> {
2114 if (shouldDisableAllHooksIncludingManaged()) {
2115 return
2116 }
2117
2118 if (isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE)) {
2119 return
2120 }
2121
2122 const hookEvent = hookInput.hook_event_name
2123 const hookName = matchQuery ? `${hookEvent}:${matchQuery}` : hookEvent
2124
2125 // Bind the prompt callback to this hook's name and tool input summary so the UI can display context
2126 const boundRequestPrompt = requestPrompt?.(hookName, toolInputSummary)
2127
2128 // SECURITY: ALL hooks require workspace trust in interactive mode
2129 // This centralized check prevents RCE vulnerabilities for all current and future hooks
2130 if (shouldSkipHookDueToTrust()) {
2131 logForDebugging(
2132 `Skipping ${hookName} hook execution - workspace trust not accepted`,
2133 )
2134 return
2135 }
2136
2137 const appState = toolUseContext ? toolUseContext.getAppState() : undefined
2138 // Use the agent's session ID if available, otherwise fall back to main session
2139 const sessionId = toolUseContext?.agentId ?? getSessionId()
2140 const matchingHooks = await getMatchingHooks(
2141 appState,
2142 sessionId,
2143 hookEvent,
2144 hookInput,
2145 toolUseContext?.options?.tools,

Callers 13

executePreToolHooksFunction · 0.85
executePostToolHooksFunction · 0.85
executeStopHooksFunction · 0.85
executeTeammateIdleHooksFunction · 0.85
executeTaskCreatedHooksFunction · 0.85
executeSessionStartHooksFunction · 0.85
executeSetupHooksFunction · 0.85

Calls 15

shouldSkipHookDueToTrustFunction · 0.85
getSessionIdFunction · 0.85
getMatchingHooksFunction · 0.85
isInternalHookFunction · 0.85
getPluginHookCountsFunction · 0.85
getHookTypeCountsFunction · 0.85
logEventFunction · 0.85
jsonStringifyFunction · 0.85
getStatsStoreFunction · 0.85
addToTurnHookDurationFunction · 0.85
isBetaTracingEnabledFunction · 0.85

Tested by

no test coverage detected