/** * The loaded control-plane bindings, narrowed to non-undefined — or a throw * the calling hook's catch converts into its own failure posture. Overrides * exist so tests can drive the unavailable arm in-process. * @param {{ claudeAdapter?: unknown, Decision?: unknown, EventKind?: unknown }} [overrides] * @returns {{ * claudeAdapter: typeof import("agent-control-plane-core/claude").claudeAdapter, * Decision: typeof import("agent-control-plane-core/contract").Decision, * EventKind: typeof import("agent-control-plane-core/contract").EventKind, * }} */ export function controlPlane(overrides?: { claudeAdapter?: unknown; Decision?: unknown; EventKind?: unknown; }): { claudeAdapter: typeof import("agent-control-plane-core/claude").claudeAdapter; Decision: typeof import("agent-control-plane-core/contract").Decision; EventKind: typeof import("agent-control-plane-core/contract").EventKind; }; /** * Serialize a rendered NativeResponse for Claude Code's stdout, or null when * the body carries nothing a silent exit 0 doesn't already say. The adapter's * exit_code is deliberately NOT honored by the hooks: Claude Code parses hook * stdout as JSON only on exit 0 — under the adapter's exit-2 enforced-deny * channel it discards stdout and reads the (empty) stderr instead, so the * deny would land without its reason. For this host the stdout JSON's * permissionDecision IS the enforcement channel, and hooks always exit 0. * @param {{ stdout?: unknown }} response a NativeResponse from adapter.render * @returns {string | null} */ export function nativeStdout(response: { stdout?: unknown; }): string | null; /** * Run a judge hook's CLI transport: read the native payload from stdin, parse * it through the claude adapter, render the judge's verdict, and write the * native response. This encodes the two transport invariants every gate hook * shares: stdin is read BEFORE the control-plane bindings are touched, so a * package-load failure still lands in `onError` with the parsed input in hand; * and the process always exits 0 with the verdict in the stdout JSON (see * nativeStdout — exit-code enforcement is deliberately not used). Any throw — * unparsable stdin, missing package, a judge error — is reported on stderr and * routed to `onError(err, input)` (`input` undefined when stdin never parsed), * where the hook applies its declared fail posture. * * It is also where every judge hook is TIMED: the verdict picks up a * performance note when the judge overran the hook budget (see * lib/hook-timing.mjs), so no hook has to remember to measure itself. * @param {string} hookName prefix for the stderr diagnostic, and the hook name * a slow-run notice reports * @param {(event: import("agent-control-plane-core").ToolCallEvent) => * import("agent-control-plane-core").Verdict | * Promise} judge * @param {object} opts * @param {(err: unknown, input: unknown) => void} opts.onError fail-posture emitter * @param {(input: unknown) => unknown} [opts.transformInput] raw-payload normalization before adapter.parse * @param {() => Promise} [opts.readInput] injectable stdin reader * @param {(chunk: string) => void} [opts.write] injectable stdout writer * @returns {Promise} */ export function runJudgeCli(hookName: string, judge: (event: import("agent-control-plane-core").ToolCallEvent) => import("agent-control-plane-core").Verdict | Promise, { onError, transformInput, readInput, write, }: { onError: (err: unknown, input: unknown) => void; transformInput?: ((input: unknown) => unknown) | undefined; readInput?: (() => Promise) | undefined; write?: ((chunk: string) => void) | undefined; }): Promise;