TypeScript SDK 参考:Hook 类型
Agent SDK TypeScript 的 HookEvent、HookCallback、HookCallbackMatcher,每个事件的输入类型(PreToolUse、PostToolUse、Stop、SessionStart、PreModelSwitch 等)以及 HookJSONOutput 的同步与异步输出形状。
本页是 TypeScript Agent SDK 参考的第四部分:Options.hooks 用到的类型。用 hooks 的指南和常见模式见「Agent SDK:Hooks」。
HookEvent
可用的 hook 事件。
type HookEvent =
| "PreToolUse"
| "PostToolUse"
| "PostToolUseFailure"
| "PostToolBatch"
| "Notification"
| "UserPromptSubmit"
| "UserPromptExpansion"
| "SessionStart"
| "SessionEnd"
| "Stop"
| "StopFailure"
| "SubagentStart"
| "SubagentStop"
| "PreCompact"
| "PostCompact"
| "PreModelSwitch"
| "PostModelSwitch"
| "PermissionRequest"
| "PermissionDenied"
| "Setup"
| "TeammateIdle"
| "TaskCreated"
| "TaskCompleted"
| "Elicitation"
| "ElicitationResult"
| "ConfigChange"
| "DirectoryAdded"
| "WorktreeCreate"
| "WorktreeRemove"
| "InstructionsLoaded"
| "CwdChanged"
| "FileChanged"
| "MessageDisplay";HookCallback
Hook 回调函数类型。
type HookCallback = (
input: HookInput, // 所有 hook 输入类型的联合
toolUseID: string | undefined,
options: { signal: AbortSignal }
) => Promise<HookJSONOutput>;HookCallbackMatcher
带可选匹配器的 hook 配置。
interface HookCallbackMatcher {
matcher?: string;
hooks: HookCallback[];
timeout?: number; // 该匹配器内所有 hooks 的超时秒数
}HookInput
所有 hook 输入类型的联合。
type HookInput =
| PreToolUseHookInput
| PostToolUseHookInput
| PostToolUseFailureHookInput
| PostToolBatchHookInput
| PermissionDeniedHookInput
| NotificationHookInput
| UserPromptSubmitHookInput
| UserPromptExpansionHookInput
| SessionStartHookInput
| SessionEndHookInput
| StopHookInput
| StopFailureHookInput
| SubagentStartHookInput
| SubagentStopHookInput
| PreCompactHookInput
| PostCompactHookInput
| PreModelSwitchHookInput
| PostModelSwitchHookInput
| PermissionRequestHookInput
| SetupHookInput
| TeammateIdleHookInput
| TaskCreatedHookInput
| TaskCompletedHookInput
| ElicitationHookInput
| ElicitationResultHookInput
| ConfigChangeHookInput
| InstructionsLoadedHookInput
| DirectoryAddedHookInput
| WorktreeCreateHookInput
| WorktreeRemoveHookInput
| CwdChangedHookInput
| FileChangedHookInput
| MessageDisplayHookInput;BaseHookInput
所有 hook 输入类型扩展的基础接口。
type BaseHookInput = {
session_id: string;
transcript_path: string;
cwd: string;
prompt_id?: string;
permission_mode?: string;
effort?: { level: string };
agent_id?: string;
agent_type?: string;
};prompt_id 字段是标识当前正在处理的用户提示的 UUID,与 OpenTelemetry 事件上的 prompt.id 属性一致,在第一次用户输入之前不存在(需要 Claude Code v2.1.196 及以上)。
各事件的输入类型
PreToolUseHookInput
type PreToolUseHookInput = BaseHookInput & {
hook_event_name: "PreToolUse";
tool_name: string;
tool_input: unknown;
tool_use_id: string;
mcp_server?: McpServerProvenance;
};当工具来自 MCP 服务器时存在 mcp_server(见 McpServerProvenance);PostToolUse、PostToolUseFailure、PermissionRequest 和 PermissionDenied 的输入带同一个字段。该字段需要 Agent SDK v0.3.274 及以上。
PostToolUseHookInput
type PostToolUseHookInput = BaseHookInput & {
hook_event_name: "PostToolUse";
tool_name: string;
tool_input: unknown;
tool_response: unknown;
tool_use_id: string;
duration_ms?: number;
mcp_server?: McpServerProvenance;
};PostToolUseFailureHookInput
type PostToolUseFailureHookInput = BaseHookInput & {
hook_event_name: "PostToolUseFailure";
tool_name: string;
tool_input: unknown;
tool_use_id: string;
error: string;
is_interrupt?: boolean;
duration_ms?: number;
mcp_server?: McpServerProvenance;
};PostToolBatchHookInput:一批工具调用全部解决之后、下一次模型请求之前触发一次。tool_response 携带模型看到的序列化 tool_result 内容;形状不同于 PostToolUseHookInput 的结构化 Output 对象。
type PostToolBatchHookInput = BaseHookInput & {
hook_event_name: "PostToolBatch";
tool_calls: PostToolBatchToolCall[];
};
type PostToolBatchToolCall = {
tool_name: string;
tool_input: unknown;
tool_use_id: string;
tool_response?: unknown;
};PermissionDeniedHookInput
type PermissionDeniedHookInput = BaseHookInput & {
hook_event_name: "PermissionDenied";
tool_name: string;
tool_input: unknown;
tool_use_id: string;
reason: string;
mcp_server?: McpServerProvenance;
};NotificationHookInput
type NotificationHookInput = BaseHookInput & {
hook_event_name: "Notification";
message: string;
title?: string;
notification_type: string;
};UserPromptSubmitHookInput
type UserPromptSubmitHookInput = BaseHookInput & {
hook_event_name: "UserPromptSubmit";
prompt: string;
session_title?: string;
};UserPromptExpansionHookInput
type UserPromptExpansionHookInput = BaseHookInput & {
hook_event_name: "UserPromptExpansion";
expansion_type: "slash_command" | "mcp_prompt";
command_name: string;
command_args: string;
command_source?: string;
prompt: string;
};SessionStartHookInput
type SessionStartHookInput = BaseHookInput & {
hook_event_name: "SessionStart";
source: "startup" | "resume" | "clear" | "compact" | "fork";
agent_type?: string;
model?: string;
session_title?: string;
};SessionEndHookInput
type SessionEndHookInput = BaseHookInput & {
hook_event_name: "SessionEnd";
reason: ExitReason; // 来自 EXIT_REASONS 数组的字符串
};StopHookInput
type StopHookInput = BaseHookInput & {
hook_event_name: "Stop";
stop_hook_active: boolean;
last_assistant_message?: string;
background_tasks?: BackgroundTaskSummary[];
session_crons?: SessionCronSummary[];
};StopFailureHookInput
type StopFailureHookInput = BaseHookInput & {
hook_event_name: "StopFailure";
error: SDKAssistantMessageError;
error_details?: string;
last_assistant_message?: string;
};SubagentStartHookInput
type SubagentStartHookInput = BaseHookInput & {
hook_event_name: "SubagentStart";
agent_id: string;
agent_type: string;
};SubagentStopHookInput(与 StopHookInput 共用的摘要类型也定义在这里)
type SubagentStopHookInput = BaseHookInput & {
hook_event_name: "SubagentStop";
stop_hook_active: boolean;
agent_id: string;
agent_transcript_path: string;
agent_type: string;
last_assistant_message?: string;
background_tasks?: BackgroundTaskSummary[];
session_crons?: SessionCronSummary[];
};
type BackgroundTaskSummary = {
id: string;
type: string;
status: string;
description: string;
command?: string;
agent_type?: string;
server?: string;
tool?: string;
name?: string;
};
type SessionCronSummary = {
id: string;
schedule: string;
recurring: boolean;
prompt: string;
};PreCompactHookInput 与 PostCompactHookInput
type PreCompactHookInput = BaseHookInput & {
hook_event_name: "PreCompact";
trigger: "manual" | "auto";
custom_instructions: string | null;
};
type PostCompactHookInput = BaseHookInput & {
hook_event_name: "PostCompact";
trigger: "manual" | "auto";
compact_summary: string;
};PreModelSwitchHookInput:在请求的模型切换生效之前触发。context_tokens 及其后的字段估算把对话重新发送给新模型的成本;完整字段描述和阻止语义见 hooks 页的 PreModelSwitch。
type PreModelSwitchHookInput = BaseHookInput & {
hook_event_name: "PreModelSwitch";
from_model: string;
to_model: string;
requested_model: string | null;
source: "command" | "picker" | "sdk";
context_tokens: number;
prompt_cache_warm: boolean;
cache_ttl: "5m" | "1h";
estimated_cache_write_usd: number;
pricing: "configured" | "catalog" | "default";
};PostModelSwitchHookInput:会话的模型改变之后触发。它携带与 PreModelSwitchHookInput 相同的字段,source 多两个值(见 hooks 页的 PostModelSwitch)。
type PostModelSwitchHookInput = BaseHookInput & {
hook_event_name: "PostModelSwitch";
from_model: string;
to_model: string;
requested_model: string | null;
source: "command" | "picker" | "sdk" | "auto" | "resume";
context_tokens: number;
prompt_cache_warm: boolean;
cache_ttl: "5m" | "1h";
estimated_cache_write_usd: number;
pricing: "configured" | "catalog" | "default";
};PermissionRequestHookInput
type PermissionRequestHookInput = BaseHookInput & {
hook_event_name: "PermissionRequest";
tool_name: string;
tool_input: unknown;
permission_suggestions?: PermissionUpdate[];
mcp_server?: McpServerProvenance;
};SetupHookInput
type SetupHookInput = BaseHookInput & {
hook_event_name: "Setup";
trigger: "init" | "maintenance";
};TeammateIdleHookInput、TaskCreatedHookInput、TaskCompletedHookInput(team_name 自 v2.1.178 起已弃用,携带由会话派生的团队名,将被移除)
type TeammateIdleHookInput = BaseHookInput & {
hook_event_name: "TeammateIdle";
teammate_name: string;
/** @deprecated since v2.1.178. */
team_name: string;
};
type TaskCreatedHookInput = BaseHookInput & {
hook_event_name: "TaskCreated";
task_id: string;
task_subject: string;
task_description?: string;
teammate_name?: string;
/** @deprecated since v2.1.178. */
team_name?: string;
};
type TaskCompletedHookInput = BaseHookInput & {
hook_event_name: "TaskCompleted";
task_id: string;
task_subject: string;
task_description?: string;
teammate_name?: string;
/** @deprecated since v2.1.178. */
team_name?: string;
};ElicitationHookInput 与 ElicitationResultHookInput
type ElicitationHookInput = BaseHookInput & {
hook_event_name: "Elicitation";
mcp_server_name: string;
message: string;
mode?: "form" | "url";
url?: string;
elicitation_id?: string;
requested_schema?: Record<string, unknown>;
};
type ElicitationResultHookInput = BaseHookInput & {
hook_event_name: "ElicitationResult";
mcp_server_name: string;
elicitation_id?: string;
mode?: "form" | "url";
action: "accept" | "decline" | "cancel";
content?: Record<string, unknown>;
};ConfigChangeHookInput、InstructionsLoadedHookInput、DirectoryAddedHookInput
type ConfigChangeHookInput = BaseHookInput & {
hook_event_name: "ConfigChange";
source:
| "user_settings"
| "project_settings"
| "local_settings"
| "policy_settings"
| "skills";
file_path?: string;
};
type InstructionsLoadedHookInput = BaseHookInput & {
hook_event_name: "InstructionsLoaded";
file_path: string;
memory_type: "User" | "Project" | "Local" | "Managed";
load_reason:
| "session_start"
| "nested_traversal"
| "path_glob_match"
| "include"
| "compact";
globs?: string[];
trigger_file_path?: string;
parent_file_path?: string;
};
type DirectoryAddedHookInput = BaseHookInput & {
hook_event_name: "DirectoryAdded";
directory: string;
source: "slash_command" | "register_repo_root";
};DirectoryAdded 里 directory 是被添加目录的绝对路径;source 在由 /add-dir 添加时是 "slash_command",由 SDK 控制请求添加时是 "register_repo_root"。
WorktreeCreateHookInput、WorktreeRemoveHookInput、CwdChangedHookInput、FileChangedHookInput、MessageDisplayHookInput
type WorktreeCreateHookInput = BaseHookInput & {
hook_event_name: "WorktreeCreate";
name: string;
};
type WorktreeRemoveHookInput = BaseHookInput & {
hook_event_name: "WorktreeRemove";
worktree_path: string;
};
type CwdChangedHookInput = BaseHookInput & {
hook_event_name: "CwdChanged";
old_cwd: string;
new_cwd: string;
};
type FileChangedHookInput = BaseHookInput & {
hook_event_name: "FileChanged";
file_path: string;
event: "change" | "add" | "unlink";
};
type MessageDisplayHookInput = BaseHookInput & {
hook_event_name: "MessageDisplay";
turn_id: string;
message_id: string;
index: number;
final: boolean;
delta: string;
};HookJSONOutput
Hook 的返回值。
type HookJSONOutput = AsyncHookJSONOutput | SyncHookJSONOutput;AsyncHookJSONOutput
type AsyncHookJSONOutput = {
async: true;
asyncTimeout?: number;
};SyncHookJSONOutput
type SyncHookJSONOutput = {
continue?: boolean;
suppressOutput?: boolean;
stopReason?: string;
decision?: "approve" | "block";
systemMessage?: string;
/**
* 让 Claude Code 代你发出的终端转义序列(如 OSC 9 / OSC 777 桌面通知)。
* 只允许通知/标题 OSC(0、1、2、9、99、777)和 BEL;含其他任何内容的值整体被忽略。
* 只有交互式 CLI 会发出它;SDK 忽略该字段。
*/
terminalSequence?: string;
reason?: string;
hookSpecificOutput?:
| {
hookEventName: "PreToolUse";
permissionDecision?: "allow" | "deny" | "ask" | "defer";
permissionDecisionReason?: string;
updatedInput?: Record<string, unknown>;
additionalContext?: string;
}
| {
hookEventName: "UserPromptSubmit";
additionalContext?: string;
sessionTitle?: string;
/** decision 为 "block" 时,从阻止消息里省略原始提示。 */
suppressOriginalPrompt?: boolean;
}
| {
hookEventName: "UserPromptExpansion";
additionalContext?: string;
}
| {
hookEventName: "SessionStart";
additionalContext?: string;
initialUserMessage?: string;
sessionTitle?: string;
watchPaths?: string[];
/**
* SessionStart hooks 完成后重新扫描 skill 和命令目录,
* 使 hook 安装的 skills 在同一会话里可用。
*/
reloadSkills?: boolean;
}
| {
hookEventName: "Setup";
additionalContext?: string;
}
| {
hookEventName: "PreModelSwitch";
/**
* 与 PreToolUse 同样的约定:"allow" 继续,"deny" 取消切换,
* "ask" 请用户确认。只有交互式会话里的 /model 会显示该提示;
* 其他每种入口(包括 set_model 请求)都把 "ask" 视为拒绝。
*/
permissionDecision?: "allow" | "deny" | "ask";
permissionDecisionReason?: string;
}
| {
hookEventName: "PostModelSwitch";
/** 随新模型服务的下一个请求到达模型。 */
additionalContext?: string;
}
| {
hookEventName: "SubagentStart";
additionalContext?: string;
}
| {
hookEventName: "PostToolUse";
additionalContext?: string;
/**
* 给 auto 模式权限分类器的、关于这次工具调用结果的简短说明。
* 上限 2000 字符,由响应同一次调用的所有 hooks 共享;
* 只在同步 hook 响应上采纳。不要把不受信任的工具输出复制进来。
*/
classifierContext?: string;
updatedToolOutput?: unknown;
/** @deprecated 改用对所有工具都有效的 `updatedToolOutput`。 */
updatedMCPToolOutput?: unknown;
}
| {
hookEventName: "PostToolUseFailure";
additionalContext?: string;
}
| {
hookEventName: "PostToolBatch";
additionalContext?: string;
}
| {
hookEventName: "Stop";
additionalContext?: string;
}
| {
hookEventName: "SubagentStop";
additionalContext?: string;
}
| {
hookEventName: "PermissionDenied";
retry?: boolean;
}
| {
hookEventName: "Notification";
additionalContext?: string;
}
| {
hookEventName: "PermissionRequest";
decision:
| {
behavior: "allow";
updatedInput?: Record<string, unknown>;
updatedPermissions?: PermissionUpdate[];
}
| {
behavior: "deny";
message?: string;
interrupt?: boolean;
};
}
| {
hookEventName: "Elicitation";
action?: "accept" | "decline" | "cancel";
content?: Record<string, unknown>;
}
| {
hookEventName: "ElicitationResult";
action?: "accept" | "decline" | "cancel";
content?: Record<string, unknown>;
}
| {
hookEventName: "CwdChanged";
watchPaths?: string[];
}
| {
hookEventName: "FileChanged";
watchPaths?: string[];
}
| {
hookEventName: "WorktreeCreate";
worktreePath: string;
}
| {
hookEventName: "MessageDisplay";
/** 代替 delta 显示的文本;省略(或原样返回 delta)则显示原文。 */
displayContent?: string;
};
};