Unified Types
Imported from the package root or /types:
import type {
THostId,
TUnifiedEvent,
TUnifiedEventName,
TUnifiedTool,
IHookResponse,
THandlerMap,
} from "@pivanov/agent-hooks-bridge";THostId
type THostId = "claude" | "cursor" | "codex";TUnifiedEventName
type TUnifiedEventName =
| "SessionStart"
| "PreToolUse"
| "PostToolUse"
| "UserPromptSubmit"
| "Stop";TUnifiedEvent
Discriminated union over event. Common fields on every variant:
interface IUnifiedEventBase {
host: THostId;
session_id?: string;
cwd?: string;
transcript_path?: string | null;
model?: string;
_native?: unknown;
}model is lifted from the host payload when present (Codex and Cursor both ship it; Claude does not).
Variants
interface ISessionStartEvent extends IUnifiedEventBase {
event: "SessionStart";
source?: "startup" | "resume" | "clear" | "compact" | (string & {});
}
interface IPreToolUseEvent extends IUnifiedEventBase {
event: "PreToolUse";
tool: TUnifiedTool;
tool_input: Record<string, unknown>;
native_tool?: string;
}
interface IPostToolUseEvent extends IUnifiedEventBase {
event: "PostToolUse";
tool: TUnifiedTool;
tool_input: Record<string, unknown>;
tool_response?: Record<string, unknown> | string;
native_tool?: string;
duration_ms?: number;
sandbox?: boolean;
}
interface IUserPromptSubmitEvent extends IUnifiedEventBase {
event: "UserPromptSubmit";
prompt: string;
attachments?: IUserPromptSubmitAttachment[];
}
interface IUserPromptSubmitAttachment {
type: string;
file_path: string;
}
interface IStopEvent extends IUnifiedEventBase {
event: "Stop";
stop_hook_active?: boolean;
last_assistant_message?: string | null;
}Lifted native fields
The fields below come from the host's native payload but are surfaced as typed properties so handlers don't need to reach into _native:
| Field | Where | Source hosts |
|---|---|---|
model | IUnifiedEventBase | Codex, Cursor |
native_tool | IPreToolUseEvent, IPostToolUseEvent | All; equals the host's original tool_name (e.g. "apply_patch" on Codex) |
duration_ms | IPostToolUseEvent | Cursor afterShellExecution, afterMCPExecution |
sandbox | IPostToolUseEvent | Cursor afterShellExecution |
attachments | IUserPromptSubmitEvent | Cursor beforeSubmitPrompt |
last_assistant_message | IStopEvent | Codex Stop |
The native payload is still preserved on event._native for fields the bridge does not surface.
TUnifiedTool
type TUnifiedTool = "Bash" | "Edit" | "Write" | "Read" | "MCP" | (string & {});The (string & {}) suffix preserves autocomplete on the named values while accepting any string for tools the unified set doesn't enumerate (e.g. Claude's Glob, Grep, Task, MCP-named tools, etc.).
IHookResponse
interface IHookResponse {
decision?: "allow" | "deny" | "ask";
reason?: string;
user_message?: string;
modified_input?: Record<string, unknown>;
additional_context?: string;
}What every field maps to per host: see Capability Matrix.
THandlerMap
type THandlerMap = {
[E in TUnifiedEventName]?: (
event: TEventOf<E>,
) => IHookResponse | void | Promise<IHookResponse | void>;
};
type TEventOf<E extends TUnifiedEventName> = Extract<TUnifiedEvent, { event: E }>;defineHook accepts this map. TEventOf<E> narrows each handler's parameter to the variant matching its key: the PreToolUse handler sees IPreToolUseEvent, not the full union.