{"version":3,"file":"executeHooks.mjs","sources":["../../../src/hooks/executeHooks.ts"],"sourcesContent":["// src/hooks/executeHooks.ts\nimport type { Logger } from 'winston';\nimport type { HookRegistry } from './HookRegistry';\nimport type {\n  HookInput,\n  HookEvent,\n  HookOutput,\n  HookMatcher,\n  ToolDecision,\n  StopDecision,\n  HookCallback,\n  AggregatedHookResult,\n} from './types';\nimport { matchesQuery } from './matchers';\n\n/** Default per-hook timeout when a matcher doesn't set its own. */\nexport const DEFAULT_HOOK_TIMEOUT_MS = 30_000;\n\n/**\n * Options for a single `executeHooks` call. The `input` drives everything —\n * the event name is read from `input.hook_event_name`, matchers are looked\n * up against that event, and each hook receives `input` directly.\n */\nexport interface ExecuteHooksOptions {\n  registry: HookRegistry;\n  input: HookInput;\n  /** Scope lookup to this session (in addition to global matchers). */\n  sessionId?: string;\n  /** Query string matched against each matcher's pattern (tool name, etc.). */\n  matchQuery?: string;\n  /** Parent AbortSignal — combined with per-hook timeout into the hook signal. */\n  signal?: AbortSignal;\n  /** Default per-hook timeout; overridden by `matcher.timeout` when present. */\n  timeoutMs?: number;\n  /** Optional winston logger for non-internal hook errors. */\n  logger?: Logger;\n}\n\ntype WideMatcher = HookMatcher<HookEvent>;\ntype WideCallback = HookCallback<HookEvent>;\n\ninterface HookOutcome {\n  matcher: WideMatcher;\n  output: HookOutput | null;\n  error: string | null;\n  timedOut: boolean;\n}\n\nfunction freshResult(): AggregatedHookResult {\n  return {\n    additionalContexts: [],\n    errors: [],\n  };\n}\n\nfunction combineSignals(\n  parent: AbortSignal | undefined,\n  timeoutMs: number\n): AbortSignal {\n  const timeoutSignal = AbortSignal.timeout(timeoutMs);\n  if (parent === undefined) {\n    return timeoutSignal;\n  }\n  return AbortSignal.any([parent, timeoutSignal]);\n}\n\nfunction isTimeout(err: unknown): boolean {\n  if (err instanceof Error) {\n    return err.name === 'TimeoutError' || err.name === 'AbortError';\n  }\n  return false;\n}\n\nfunction describeError(err: unknown): string {\n  if (err instanceof Error) {\n    return err.message !== '' ? err.message : err.name;\n  }\n  return String(err);\n}\n\nfunction makeAbortPromise(signal: AbortSignal): {\n  promise: Promise<never>;\n  cleanup: () => void;\n} {\n  let onAbort: (() => void) | undefined;\n  const promise = new Promise<never>((_resolve, reject) => {\n    if (signal.aborted) {\n      reject(\n        signal.reason instanceof Error ? signal.reason : new Error('aborted')\n      );\n      return;\n    }\n    onAbort = (): void => {\n      reject(\n        signal.reason instanceof Error ? signal.reason : new Error('aborted')\n      );\n    };\n    signal.addEventListener('abort', onAbort, { once: true });\n  });\n  const cleanup = (): void => {\n    if (onAbort !== undefined) {\n      signal.removeEventListener('abort', onAbort);\n      onAbort = undefined;\n    }\n  };\n  return { promise, cleanup };\n}\n\nasync function runHook(\n  hook: WideCallback,\n  input: HookInput,\n  signal: AbortSignal,\n  matcher: WideMatcher\n): Promise<HookOutcome> {\n  const hookPromise = Promise.resolve().then(() => hook(input, signal));\n  const { promise: abortPromise, cleanup } = makeAbortPromise(signal);\n  try {\n    const output = await Promise.race([hookPromise, abortPromise]);\n    return { matcher, output, error: null, timedOut: false };\n  } catch (err) {\n    return {\n      matcher,\n      output: null,\n      error: describeError(err),\n      timedOut: isTimeout(err),\n    };\n  } finally {\n    cleanup();\n  }\n}\n\nfunction reportErrors(\n  outcomes: readonly HookOutcome[],\n  event: HookEvent,\n  logger: Logger | undefined\n): void {\n  for (const outcome of outcomes) {\n    if (outcome.error === null) {\n      continue;\n    }\n    if (outcome.matcher.internal === true) {\n      continue;\n    }\n    const label = outcome.timedOut ? 'timed out' : 'threw an error';\n    const message = `Hook for ${event} ${label}: ${outcome.error}`;\n    if (logger !== undefined) {\n      logger.warn(message);\n      continue;\n    }\n    // eslint-disable-next-line no-console\n    console.warn(message);\n  }\n}\n\nfunction applyToolDecision(\n  agg: AggregatedHookResult,\n  decision: ToolDecision,\n  reason: string | undefined\n): void {\n  if (decision === 'deny') {\n    if (agg.decision === 'deny') {\n      return;\n    }\n    agg.decision = 'deny';\n    agg.reason = reason;\n    return;\n  }\n  if (decision === 'ask') {\n    if (agg.decision === 'deny' || agg.decision === 'ask') {\n      return;\n    }\n    agg.decision = 'ask';\n    agg.reason = reason;\n    return;\n  }\n  if (agg.decision === undefined) {\n    agg.decision = 'allow';\n    agg.reason = reason;\n  }\n}\n\nfunction applyStopDecision(\n  agg: AggregatedHookResult,\n  decision: StopDecision,\n  reason: string | undefined\n): void {\n  if (decision === 'block') {\n    if (agg.stopDecision === 'block') {\n      return;\n    }\n    agg.stopDecision = 'block';\n    agg.reason = reason;\n    return;\n  }\n  if (agg.stopDecision === undefined) {\n    agg.stopDecision = 'continue';\n    if (agg.reason === undefined) {\n      agg.reason = reason;\n    }\n  }\n}\n\nfunction applyDecision(agg: AggregatedHookResult, output: HookOutput): void {\n  if (!('decision' in output) || output.decision === undefined) {\n    return;\n  }\n  const decision = output.decision;\n  const reason =\n    'reason' in output && typeof output.reason === 'string'\n      ? output.reason\n      : undefined;\n  if (decision === 'deny' || decision === 'ask' || decision === 'allow') {\n    applyToolDecision(agg, decision, reason);\n    return;\n  }\n  applyStopDecision(agg, decision, reason);\n}\n\nfunction applyContext(agg: AggregatedHookResult, output: HookOutput): void {\n  if (\n    typeof output.additionalContext === 'string' &&\n    output.additionalContext.length > 0\n  ) {\n    agg.additionalContexts.push(output.additionalContext);\n  }\n}\n\nfunction applyStopFlag(agg: AggregatedHookResult, output: HookOutput): void {\n  if (output.preventContinuation !== true) {\n    return;\n  }\n  agg.preventContinuation = true;\n  if (typeof output.stopReason === 'string' && agg.stopReason === undefined) {\n    agg.stopReason = output.stopReason;\n  }\n}\n\nfunction applyUpdatedInput(\n  agg: AggregatedHookResult,\n  output: HookOutput\n): void {\n  if (!('updatedInput' in output) || output.updatedInput === undefined) {\n    return;\n  }\n  agg.updatedInput = output.updatedInput;\n}\n\nfunction applyUpdatedOutput(\n  agg: AggregatedHookResult,\n  output: HookOutput\n): void {\n  if (!('updatedOutput' in output) || output.updatedOutput === undefined) {\n    return;\n  }\n  agg.updatedOutput = output.updatedOutput;\n}\n\nfunction fold(outcomes: readonly HookOutcome[]): AggregatedHookResult {\n  const agg = freshResult();\n  for (const outcome of outcomes) {\n    if (outcome.error !== null) {\n      if (outcome.matcher.internal !== true) {\n        agg.errors.push(outcome.error);\n      }\n      continue;\n    }\n    const output = outcome.output;\n    if (output === null) {\n      continue;\n    }\n    applyContext(agg, output);\n    applyStopFlag(agg, output);\n    applyDecision(agg, output);\n    applyUpdatedInput(agg, output);\n    applyUpdatedOutput(agg, output);\n  }\n  return agg;\n}\n\n/**\n * Fires every matcher registered against `input.hook_event_name`, folding\n * their results per `deny > ask > allow` precedence and accumulating\n * context/errors.\n *\n * ## Parallelism and determinism\n *\n * All matching hooks fire simultaneously and are awaited via `Promise.all`,\n * which preserves input-array order in its returned results. The fold\n * therefore iterates outcomes in **registration order** — outer loop over\n * matchers as they sit in the registry (global first, then session), inner\n * loop over each matcher's `hooks` array. Last-writer-wins fields\n * (`updatedInput`, `updatedOutput`) are deterministic in that order, even\n * though hooks may complete in arbitrary wall-clock order.\n *\n * Consumers that need a single authoritative rewrite should still scope\n * `updatedInput`/`updatedOutput` to one hook per matcher to avoid subtle\n * precedence bugs when matchers are added in a different order than\n * expected.\n *\n * ## Timeouts and cancellation\n *\n * Each matcher receives **one shared `AbortSignal`** derived from the\n * caller's parent signal combined with `matcher.timeout` (falling back to\n * `opts.timeoutMs`, default {@link DEFAULT_HOOK_TIMEOUT_MS}). Sharing the\n * signal across hooks in a matcher collapses N timer allocations into\n * one, which matters on the PreToolUse hot path where a matcher with\n * several hooks fires on every tool call. Each hook call is raced\n * against the shared signal, so even a hook that ignores the signal is\n * force-unblocked when the timeout fires. Timeout/abort errors are\n * swallowed into the aggregated result's `errors` array (non-fatal by\n * default).\n *\n * ## Internal matchers\n *\n * A matcher with `internal: true` is excluded from both the `errors` array\n * and the logger output. Use it for infrastructure hooks whose failures\n * should not pollute user-visible diagnostics.\n *\n * ## Once semantics — atomic at-most-once\n *\n * A matcher with `once: true` is removed from the registry **before any\n * hook runs**, inside the synchronous prefix of `executeHooks` (between\n * `getMatchers` and the first `await`). Because Node's event loop serialises\n * sync work, two concurrent `executeHooks` calls can never both observe\n * and dispatch the same `once` matcher — whichever call runs its sync\n * prefix first consumes it, and the loser sees an empty bucket.\n *\n * Trade-off: if every hook in a `once` matcher throws, the matcher is\n * still gone. \"Once\" here means \"at most one dispatch, ever\", not \"at\n * most one successful execution with retry on failure\". Hosts that need\n * retry semantics should register a normal matcher and self-unregister\n * via the `unregister` callback returned from `registry.register`.\n */\nexport async function executeHooks(\n  opts: ExecuteHooksOptions\n): Promise<AggregatedHookResult> {\n  const {\n    registry,\n    input,\n    sessionId,\n    matchQuery,\n    signal,\n    timeoutMs = DEFAULT_HOOK_TIMEOUT_MS,\n    logger,\n  } = opts;\n  const event = input.hook_event_name;\n  const matchers = registry.getMatchers(event, sessionId);\n  if (matchers.length === 0) {\n    return freshResult();\n  }\n\n  // --- SYNC CRITICAL SECTION: once-matcher removal must complete before any await ---\n  const tasks: Promise<HookOutcome>[] = [];\n  for (const matcher of matchers) {\n    if (!matchesQuery(matcher.pattern, matchQuery)) {\n      continue;\n    }\n    if (matcher.once === true) {\n      registry.removeMatcher(event, matcher, sessionId);\n    }\n    const perHookTimeout = matcher.timeout ?? timeoutMs;\n    const matcherSignal = combineSignals(signal, perHookTimeout);\n    for (const hook of matcher.hooks) {\n      tasks.push(runHook(hook, input, matcherSignal, matcher));\n    }\n  }\n  // --- END SYNC CRITICAL SECTION ---\n  if (tasks.length === 0) {\n    return freshResult();\n  }\n\n  const outcomes = await Promise.all(tasks);\n  reportErrors(outcomes, event, logger);\n  return fold(outcomes);\n}\n"],"names":[],"mappings":"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"}