Documentation
¶
Overview ¶
Package claude provides types and helpers for Claude Code hooks.
Claude Code hooks allow you to observe, control, and extend the AI agent loop using custom scripts. Hooks are spawned processes that communicate over stdio using JSON.
Hook Events ¶
Claude Code supports the following hook events:
- StopInput/StopOutput: Agent finished responding
- SubagentStopInput/SubagentStopOutput: Subagent (Task tool) finished
- SessionStartInput/SessionStartOutput: Session started or resumed
- SessionEndInput/SessionEndOutput: Session ending
- PreToolUseInput/PreToolUseOutput: Before tool execution
- PostToolUseInput/PostToolUseOutput: After tool execution
- PermissionRequestInput/PermissionRequestOutput: Permission dialog shown
- UserPromptSubmitInput/UserPromptSubmitOutput: User submitted a prompt
- NotificationInput/NotificationOutput: Notification sent
- PreCompactInput/PreCompactOutput: Before context compaction
Stop Hooks ¶
Stop hooks control whether Claude should stop or continue working:
hookshot.Run(func(input claude.StopInput) claude.StopOutput {
// IMPORTANT: Always check StopHookActive to prevent infinite loops
if input.StopHookActive {
return claude.Continue()
}
if hasUnresolvedIssues() {
return claude.Block("Please fix the security vulnerabilities first")
}
return claude.Continue()
})
PreToolUse Hooks ¶
PreToolUse hooks control tool execution:
hookshot.Run(func(input claude.PreToolUseInput) claude.PreToolUseOutput {
// Block specific MCP servers
if strings.HasPrefix(input.ToolName, "mcp__blocked__") {
return claude.Deny("This MCP server is not allowed")
}
// Auto-approve safe operations
if input.ToolName == "Read" {
return claude.AllowSilent()
}
// Let normal flow proceed
return claude.PassThrough()
})
UserPromptSubmit Hooks ¶
UserPromptSubmit hooks validate or augment user prompts:
hookshot.Run(func(input claude.UserPromptSubmitInput) claude.UserPromptSubmitOutput {
// Block sensitive content
if containsSecrets(input.Prompt) {
return claude.BlockPrompt("Please don't include secrets in prompts")
}
// Add context to all prompts
return claude.AddContext("Project uses Go 1.21+")
})
SessionStart Hooks ¶
SessionStart hooks can inject context at the beginning of a session:
hookshot.Run(func(input claude.SessionStartInput) claude.SessionStartOutput {
context := loadProjectContext()
return claude.SessionStartContext(context)
})
Helper Functions ¶
This package provides helper functions for common responses:
Stop/SubagentStop:
PreToolUse:
- Allow: Permit execution with a reason
- AllowSilent: Permit without showing output
- AllowWithInput: Permit with modified tool input
- Deny: Block execution with a reason
- Ask: Prompt user to confirm
- PassThrough: Let normal permission flow proceed
PermissionRequest:
- AllowPermission: Grant the permission
- AllowPermissionWithInput: Grant with modified input
- DenyPermission: Reject with message
- DenyPermissionAndStop: Reject and stop Claude
PostToolUse:
- PostToolOK: Normal flow
- PostToolBlock: Send feedback to Claude
- PostToolContext: Add context for Claude
UserPromptSubmit:
- AllowPrompt: Process normally
- BlockPrompt: Reject with reason
- AddContext: Add context to the prompt
SessionStart:
- SessionStartOK: Normal flow
- SessionStartContext: Add session context
Configuration ¶
Configure Claude Code hooks in ~/.claude/settings.json:
{
"hooks": {
"Stop": [{
"hooks": [{ "type": "command", "command": "/path/to/hooks claude-stop" }]
}],
"PreToolUse": [{
"matcher": "mcp__.*",
"hooks": [{ "type": "command", "command": "/path/to/hooks claude-pre-tool" }]
}]
}
}
See https://docs.claude.com/en/docs/claude-code/hooks for full documentation.
Package claude provides types and helpers for Claude Code hooks.
Claude Code hooks are configured in settings files and execute shell commands at various points in the agent loop. See https://docs.claude.com/en/docs/claude-code/hooks
Index ¶
- type BaseInput
- type BaseOutput
- type NotificationHookOutput
- type NotificationInput
- type NotificationOutput
- type PermissionRequestDecision
- type PermissionRequestHookOutput
- type PermissionRequestInput
- type PermissionRequestOutput
- func AllowPermission() PermissionRequestOutput
- func AllowPermissionWithInput(updatedInput map[string]any) PermissionRequestOutput
- func AllowPermissionWithPermissions(updatedPermissions any) PermissionRequestOutput
- func DenyPermission(message string) PermissionRequestOutput
- func DenyPermissionAndStop(message string) PermissionRequestOutput
- type PermissionSuggestion
- type PostToolUseHookOutput
- type PostToolUseInput
- type PostToolUseOutput
- type PreCompactInput
- type PreCompactOutput
- type PreToolUseHookOutput
- type PreToolUseInput
- type PreToolUseOutput
- func Allow(reason string) PreToolUseOutput
- func AllowSilent() PreToolUseOutput
- func AllowWithContext(reason, context string) PreToolUseOutput
- func AllowWithInput(reason string, updatedInput map[string]any) PreToolUseOutput
- func Ask(reason string) PreToolUseOutput
- func Deny(reason string) PreToolUseOutput
- func PassThrough() PreToolUseOutput
- type SessionEndInput
- type SessionEndOutput
- type SessionStartHookOutput
- type SessionStartInput
- type SessionStartOutput
- type StopInput
- type StopOutput
- type SubagentStopInput
- type SubagentStopOutput
- type UserPromptSubmitHookOutput
- type UserPromptSubmitInput
- type UserPromptSubmitOutput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseInput ¶
type BaseInput struct {
SessionID string `json:"session_id"`
TranscriptPath string `json:"transcript_path"`
Cwd string `json:"cwd"`
PermissionMode string `json:"permission_mode"` // "default", "plan", "acceptEdits", "dontAsk", "bypassPermissions"
HookEventName string `json:"hook_event_name"`
}
BaseInput contains fields present in all Claude Code hook inputs.
type BaseOutput ¶
type BaseOutput struct {
// Continue controls whether Claude should continue after hook execution.
// Default is true. Set to false to stop Claude entirely.
Continue *bool `json:"continue,omitempty"`
// StopReason is shown to the user when Continue is false.
StopReason string `json:"stopReason,omitempty"`
// SuppressOutput hides stdout from transcript mode when true.
SuppressOutput bool `json:"suppressOutput,omitempty"`
// SystemMessage is an optional warning message shown to the user.
SystemMessage string `json:"systemMessage,omitempty"`
}
BaseOutput contains common fields that can be included in any hook output.
type NotificationHookOutput ¶
type NotificationHookOutput struct {
HookEventName string `json:"hookEventName,omitempty"`
AdditionalContext string `json:"additionalContext,omitempty"`
}
NotificationHookOutput contains notification-specific output fields.
type NotificationInput ¶
type NotificationInput struct {
BaseInput
Message string `json:"message"`
Title string `json:"title,omitempty"`
NotificationType string `json:"notification_type"` // "permission_prompt", "idle_prompt", "auth_success", "elicitation_dialog"
}
NotificationInput is received when Claude Code sends a notification.
type NotificationOutput ¶
type NotificationOutput struct {
BaseOutput
HookSpecificOutput *NotificationHookOutput `json:"hookSpecificOutput,omitempty"`
}
NotificationOutput can add context to the conversation.
func NotificationContext ¶
func NotificationContext(context string) NotificationOutput
NotificationContext adds context to the conversation from a notification hook.
func NotificationOK ¶
func NotificationOK() NotificationOutput
NotificationOK returns an empty output for notifications.
type PermissionRequestDecision ¶
type PermissionRequestDecision struct {
Behavior string `json:"behavior"` // "allow" or "deny"
UpdatedInput map[string]any `json:"updatedInput,omitempty"` // For "allow": modified tool input
UpdatedPermissions any `json:"updatedPermissions,omitempty"` // For "allow": permission rule updates (equivalent to "always allow")
Message string `json:"message,omitempty"` // For "deny": shown to Claude
Interrupt bool `json:"interrupt,omitempty"` // For "deny": stop Claude if true
}
PermissionRequestDecision controls how the permission request is handled.
type PermissionRequestHookOutput ¶
type PermissionRequestHookOutput struct {
HookEventName string `json:"hookEventName,omitempty"`
Decision *PermissionRequestDecision `json:"decision,omitempty"`
}
PermissionRequestHookOutput contains permission-request-specific output fields.
type PermissionRequestInput ¶
type PermissionRequestInput struct {
BaseInput
ToolName string `json:"tool_name"`
ToolInput json.RawMessage `json:"tool_input"`
ToolUseID string `json:"tool_use_id"`
PermissionSuggestions []PermissionSuggestion `json:"permission_suggestions,omitempty"`
}
PermissionRequestInput is received when the user is shown a permission dialog.
type PermissionRequestOutput ¶
type PermissionRequestOutput struct {
BaseOutput
HookSpecificOutput *PermissionRequestHookOutput `json:"hookSpecificOutput,omitempty"`
}
PermissionRequestOutput controls the permission dialog response.
func AllowPermission ¶
func AllowPermission() PermissionRequestOutput
AllowPermission grants the permission request.
func AllowPermissionWithInput ¶
func AllowPermissionWithInput(updatedInput map[string]any) PermissionRequestOutput
AllowPermissionWithInput grants the permission with modified tool input.
func AllowPermissionWithPermissions ¶
func AllowPermissionWithPermissions(updatedPermissions any) PermissionRequestOutput
AllowPermissionWithPermissions grants the permission and applies permission rule updates (equivalent to the user selecting an "always allow" option).
func DenyPermission ¶
func DenyPermission(message string) PermissionRequestOutput
DenyPermission rejects the permission request.
func DenyPermissionAndStop ¶
func DenyPermissionAndStop(message string) PermissionRequestOutput
DenyPermissionAndStop rejects the permission and stops Claude.
type PermissionSuggestion ¶
PermissionSuggestion represents an "always allow" option from the permission dialog.
type PostToolUseHookOutput ¶
type PostToolUseHookOutput struct {
HookEventName string `json:"hookEventName,omitempty"`
AdditionalContext string `json:"additionalContext,omitempty"` // Added to context for Claude
UpdatedMCPToolOutput any `json:"updatedMCPToolOutput,omitempty"` // For MCP tools: replaces the tool's output
}
PostToolUseHookOutput contains post-tool-use-specific output fields.
type PostToolUseInput ¶
type PostToolUseInput struct {
BaseInput
ToolName string `json:"tool_name"`
ToolInput json.RawMessage `json:"tool_input"`
ToolResponse json.RawMessage `json:"tool_response"` // Tool-specific response JSON
ToolUseID string `json:"tool_use_id"`
}
PostToolUseInput is received after a tool executes successfully.
type PostToolUseOutput ¶
type PostToolUseOutput struct {
BaseOutput
// Decision should be "block" to provide feedback to Claude, or omitted.
Decision string `json:"decision,omitempty"`
// Reason is shown to Claude when Decision is "block".
Reason string `json:"reason,omitempty"`
HookSpecificOutput *PostToolUseHookOutput `json:"hookSpecificOutput,omitempty"`
}
PostToolUseOutput can provide feedback to Claude after tool execution.
func PostToolBlock ¶
func PostToolBlock(reason string) PostToolUseOutput
PostToolBlock provides feedback to Claude that something needs attention.
func PostToolContext ¶
func PostToolContext(context string) PostToolUseOutput
PostToolContext adds context for Claude to consider.
func PostToolOK ¶
func PostToolOK() PostToolUseOutput
PostToolOK returns an empty output, allowing normal flow to continue.
func PostToolReplaceMCPOutput ¶
func PostToolReplaceMCPOutput(output any) PostToolUseOutput
PostToolReplaceMCPOutput replaces an MCP tool's output with the provided value.
type PreCompactInput ¶
type PreCompactInput struct {
BaseInput
Trigger string `json:"trigger"` // "manual" or "auto"
CustomInstructions string `json:"custom_instructions"` // For manual trigger only
}
PreCompactInput is received before Claude Code runs a compact operation.
type PreCompactOutput ¶
type PreCompactOutput struct {
BaseOutput
}
PreCompactOutput has no decision control - hooks just run for side effects.
func PreCompactOK ¶
func PreCompactOK() PreCompactOutput
PreCompactOK returns an empty output for pre-compact.
type PreToolUseHookOutput ¶
type PreToolUseHookOutput struct {
HookEventName string `json:"hookEventName,omitempty"`
PermissionDecision string `json:"permissionDecision,omitempty"` // "allow", "deny", "ask"
PermissionDecisionReason string `json:"permissionDecisionReason,omitempty"` // Shown to user (allow/ask) or Claude (deny)
UpdatedInput map[string]any `json:"updatedInput,omitempty"` // Modified tool input
AdditionalContext string `json:"additionalContext,omitempty"` // Added to Claude's context before tool executes
}
PreToolUseHookOutput contains pre-tool-use-specific output fields.
type PreToolUseInput ¶
type PreToolUseInput struct {
BaseInput
ToolName string `json:"tool_name"`
ToolInput json.RawMessage `json:"tool_input"` // Tool-specific JSON
ToolUseID string `json:"tool_use_id"`
}
PreToolUseInput is received before Claude executes a tool.
type PreToolUseOutput ¶
type PreToolUseOutput struct {
BaseOutput
HookSpecificOutput *PreToolUseHookOutput `json:"hookSpecificOutput,omitempty"`
}
PreToolUseOutput controls whether the tool should execute.
func Allow ¶
func Allow(reason string) PreToolUseOutput
Allow permits the tool to execute without asking the user.
func AllowSilent ¶
func AllowSilent() PreToolUseOutput
AllowSilent permits the tool to execute without showing output.
func AllowWithContext ¶
func AllowWithContext(reason, context string) PreToolUseOutput
AllowWithContext permits the tool and adds context for Claude.
func AllowWithInput ¶
func AllowWithInput(reason string, updatedInput map[string]any) PreToolUseOutput
AllowWithInput permits the tool with modified input parameters.
func Ask ¶
func Ask(reason string) PreToolUseOutput
Ask prompts the user to confirm the tool execution.
func PassThrough ¶
func PassThrough() PreToolUseOutput
PassThrough returns an empty output, letting the normal permission flow proceed.
type SessionEndInput ¶
type SessionEndInput struct {
BaseInput
// Reason indicates why the session ended: "clear", "logout", "prompt_input_exit", "bypass_permissions_disabled", "other"
Reason string `json:"reason"`
}
SessionEndInput is received when a Claude Code session ends.
type SessionEndOutput ¶
type SessionEndOutput struct {
BaseOutput
}
SessionEndOutput has no decision control - hooks just run for cleanup.
func SessionEndOK ¶
func SessionEndOK() SessionEndOutput
SessionEndOK returns an empty output for session end.
type SessionStartHookOutput ¶
type SessionStartHookOutput struct {
HookEventName string `json:"hookEventName,omitempty"`
AdditionalContext string `json:"additionalContext,omitempty"`
}
SessionStartHookOutput contains session-start-specific output fields.
type SessionStartInput ¶
type SessionStartInput struct {
BaseInput
// Source indicates how the session started: "startup", "resume", "clear", "compact"
Source string `json:"source"`
// Model is the model identifier (e.g. "claude-sonnet-4-6").
Model string `json:"model"`
// AgentType is the agent name when started via `claude --agent <name>`. May be empty.
AgentType string `json:"agent_type,omitempty"`
}
SessionStartInput is received when Claude Code starts or resumes a session.
type SessionStartOutput ¶
type SessionStartOutput struct {
BaseOutput
HookSpecificOutput *SessionStartHookOutput `json:"hookSpecificOutput,omitempty"`
}
SessionStartOutput can add context to the session.
func SessionStartContext ¶
func SessionStartContext(context string) SessionStartOutput
SessionStartContext adds context at the start of a session.
func SessionStartOK ¶
func SessionStartOK() SessionStartOutput
SessionStartOK returns an empty output for session start.
type StopInput ¶
type StopInput struct {
BaseInput
// StopHookActive is true when Claude is already continuing as a result of a stop hook.
// Check this to prevent infinite loops.
StopHookActive bool `json:"stop_hook_active"`
}
StopInput is received when the main Claude Code agent finishes responding.
type StopOutput ¶
type StopOutput struct {
BaseOutput
// Decision should be "block" to prevent stopping, or omitted to allow stopping.
Decision string `json:"decision,omitempty"`
// Reason is shown to Claude when Decision is "block".
Reason string `json:"reason,omitempty"`
}
StopOutput controls whether Claude should stop or continue.
func Block ¶
func Block(reason string) StopOutput
Block prevents Claude from stopping and sends a message.
func StopWith ¶
func StopWith(reason string) StopOutput
StopWith creates a StopOutput that halts Claude entirely.
type SubagentStopInput ¶
type SubagentStopInput struct {
BaseInput
// StopHookActive is true when the subagent is already continuing as a result of a stop hook.
StopHookActive bool `json:"stop_hook_active"`
// AgentID is the unique identifier for the subagent.
AgentID string `json:"agent_id"`
// AgentType is the agent type name (e.g. "Bash", "Explore", "Plan", or custom agent names).
// This is the value used for matcher filtering.
AgentType string `json:"agent_type"`
// AgentTranscriptPath is the path to the subagent's own transcript file.
AgentTranscriptPath string `json:"agent_transcript_path,omitempty"`
}
SubagentStopInput is received when a Claude Code subagent (Task tool) finishes.
type SubagentStopOutput ¶
type SubagentStopOutput = StopOutput
SubagentStopOutput controls whether a subagent should stop or continue. Uses the same decision format as StopOutput.
type UserPromptSubmitHookOutput ¶
type UserPromptSubmitHookOutput struct {
HookEventName string `json:"hookEventName,omitempty"`
AdditionalContext string `json:"additionalContext,omitempty"` // Added to context
}
UserPromptSubmitHookOutput contains user-prompt-submit-specific output fields.
type UserPromptSubmitInput ¶
UserPromptSubmitInput is received when the user submits a prompt.
type UserPromptSubmitOutput ¶
type UserPromptSubmitOutput struct {
BaseOutput
// Decision should be "block" to prevent processing, or omitted.
Decision string `json:"decision,omitempty"`
// Reason is shown to the user when Decision is "block".
Reason string `json:"reason,omitempty"`
HookSpecificOutput *UserPromptSubmitHookOutput `json:"hookSpecificOutput,omitempty"`
}
UserPromptSubmitOutput controls whether the prompt should be processed.
func AddContext ¶
func AddContext(context string) UserPromptSubmitOutput
AddContext allows the prompt and adds context for Claude.
func AllowPrompt ¶
func AllowPrompt() UserPromptSubmitOutput
AllowPrompt allows the prompt to be processed normally.
func BlockPrompt ¶
func BlockPrompt(reason string) UserPromptSubmitOutput
BlockPrompt prevents the prompt from being processed.