/** * hooks.ts — Enterprise Hook System for Subagent Lifecycle * * Inspired by Claude Code's hook events and OpenCode's plugin architecture. * Features: * - Priority-based execution (before/after/around middleware) * - Async middleware chain with short-circuit support * - Per-hook metrics (latency, error rate, invocation count) * - Hook composition (chain multiple handlers into one) * - Graceful degradation with circuit breaker patterns * - Timeout and error protection (handlers never crash the agent) */ /** All hook event types in the subagent lifecycle. */ export type HookEvent = "subagent:start" | "subagent:end" | "subagent:error" | "subagent:spawn" | "subagent:steer" | "tool:call" | "tool:result" | "compaction:start" | "compaction:end" | "turn:start" | "turn:end" | "swarm:join" | "swarm:leave" | "validation:start" | "validation:end"; /** Payload delivered to hook handlers. */ export interface HookPayload { event: HookEvent; agentId: string; data?: Record; /** Timestamp when the event fired. */ timestamp?: number; } /** * Response from a blocking hook handler. * * String forms remain the primary contract. The object form is only for * `block` so a quality-gate hook can return revision feedback without a * side channel. */ export type HookResponse = "allow" | "block" | "modify" | { action: "block"; reason?: string; feedback?: string; }; /** Normalized decision used by the runner and compose helpers. */ export interface NormalizedHookDecision { action: "allow" | "block" | "modify"; reason?: string; feedback?: string; } /** True when a handler result is a blocking decision (string or object). */ export declare function isBlockResponse(result: HookResponse | undefined): result is "block" | { action: "block"; reason?: string; feedback?: string; }; /** Collapse string/object hook results into a single decision shape. */ export declare function normalizeHookResponse(result: HookResponse | undefined): NormalizedHookDecision; /** Hook priority: lower numbers run first. */ export type HookPriority = "critical" | "high" | "normal" | "low" | "background"; /** A hook handler function with metadata. */ export interface HookHandler { fn: (payload: HookPayload) => Promise | HookResponse | undefined; priority: number; id: string; /** If true, handler errors are fatal (default: false). */ fatal?: boolean; /** Max executions before auto-unregister (for one-shot hooks). */ maxExecutions?: number; /** Circuit breaker: max consecutive errors before disabling. */ circuitBreakerThreshold?: number; } /** Registry for hook handlers with fail-open semantics and rich metadata. */ export declare class HookRegistry { private handlers; private metrics; private handlerEventMap; private globalMiddleware; /** Register a handler for a specific event with priority. */ register(event: HookEvent, handler: HookHandler["fn"], options?: { priority?: HookPriority | number; id?: string; fatal?: boolean; maxExecutions?: number; circuitBreakerThreshold?: number; }): string; /** Register multiple handlers at once. */ registerAll(handlers: Record, options?: { priority?: HookPriority | number; circuitBreakerThreshold?: number; }): string[]; /** Add global middleware that wraps all hook executions. */ use(middleware: (payload: HookPayload, next: () => Promise) => Promise): void; /** Remove a previously registered handler by ID. */ unregisterById(handlerId: string): boolean; /** Remove a previously registered handler by function reference (legacy). */ unregister(event: HookEvent, handler: HookHandler["fn"]): void; /** * Dispatch an event to all registered handlers. * * Execution order: * 1. Global middleware chain (if any) * 2. Priority-sorted handlers (critical → background) * 3. Short-circuit on "block", aggregate "modify" * * Each handler runs with timeout protection. Failures are caught and logged. */ dispatch(event: HookEvent, agentId: string, data?: Record, timeoutMs?: number): Promise; private runHandlers; /** Get metrics snapshot for monitoring/dashboard. */ getMetrics(): Array<{ id: string; event: HookEvent; invocations: number; errors: number; timeouts: number; avgLatencyMs: number; disabled: boolean; }>; /** Reset metrics and re-enable circuit-broken handlers. */ resetMetrics(): void; /** Get a frozen snapshot of the handler map for inspection/testing. */ getHandlers(): ReadonlyMap>; } /** Compose multiple hook handlers into a single handler (sequential execution). */ export declare function composeHandlers(...handlers: HookHandler["fn"][]): (payload: HookPayload) => Promise;