Help us shape the future of Go! Take the 2026 Go Developer Survey

hook

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Overview

Package hook implements lifecycle hooks that observe and control the agent loop, in the style of Claude Code hooks.

Index

Constants

View Source
const DefaultStopBlockCap = 8

DefaultStopBlockCap is the default number of consecutive times Stop or SubagentStop hooks may keep the agent working, like Claude Code's 8-consecutive-continuation cap.

Variables

This section is empty.

Functions

func Middleware

func Middleware(m *Manager) loop.Middleware

Middleware returns runtime middleware that dispatches lifecycle events to m. Hook errors are logged and otherwise ignored unless m is FailClosed. Context queued for the run's session with Manager.AddContext, such as the results of Async hooks, is added to the run's input and to tool results.

PreCompact and PostCompact hooks run through PreCompactGuard and PostCompactObserver, SubagentStart and SubagentStop hooks through agent.AsTool, and SessionEnd hooks through agent.Runner.EndSession.

func PostCompactObserver

func PostCompactObserver(m *Manager) func(ctx context.Context, run *loop.Run, reason string, c *loop.Compaction)

PostCompactObserver returns a function that runs the PostCompact hooks of m after a compaction, with the summary in Event.Message, and then its SessionStart hooks with source "compact", as Claude Code does. PostCompact results are ignored; the AdditionalContext of the SessionStart hooks is added to the first user message of the compacted conversation, next to the summary. Errors are logged. Pass it to context.WithCompactObserver.

func PreCompactGuard

func PreCompactGuard(m *Manager) func(ctx context.Context, run *loop.Run, reason string) bool

PreCompactGuard returns a function that runs the PreCompact hooks of m and reports whether compaction may proceed. Pass it to context.WithCompactGuard.

func StopFeedback

func StopFeedback(event EventType, res *Result) string

StopFeedback returns the input that continues an agent whose Stop or SubagentStop hooks, as given by event, returned res, or "" if it may stop: the Reason of a Deny and any AdditionalContext, which Claude Code delivers as hook feedback. A Halt lets the agent stop.

Types

type Agent

type Agent struct {
	Verifier Verifier
	Prompt   string
	// Model is passed to the verifier; "" selects its default.
	Model string
	// Timeout defaults to 60 seconds. A negative Timeout disables it.
	Timeout time.Duration
}

Agent is a hook that has an agent verify the event with tools, like Claude Code's agent hooks, which are experimental. Prompt is expanded as for a Prompt hook, followed by instructions to end with {"ok": true} or {"ok": false, "reason": "..."}. A block is handled like that of a Prompt hook with ContinueOnBlock set, and "impossible" is ignored.

func (*Agent) Handle

func (a *Agent) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle runs the verifier.

type Async

type Async struct {
	Hook   Hook
	Rewake bool
}

Async runs a hook in the background, like Claude Code's "async": true. The action that fired the event does not wait for it, and its decision, Halt and updates have no effect. When it finishes, its AdditionalContext and SystemMessage are queued for its session and added to the conversation at the next tool result or the next run's input, whichever comes first; see Manager.AddContext.

With Rewake, like Claude Code's "asyncRewake", a Deny (exit status 2 of a Command) also queues its Reason, the command's stderr or else its stdout, and sets AsyncResult.Rewake so an OnAsyncResult function can wake an idle session.

The hook's own timeout applies; settings files give async commands no timeout, as Claude Code does not enforce one. Manager.Close cancels the hooks still running.

func (*Async) Handle

func (a *Async) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle runs the hook synchronously, for an Async used outside a Manager. A Manager runs it in the background instead.

type AsyncResult

type AsyncResult struct {
	Event     EventType
	SessionID string
	RunID     string
	// Context is what was queued for the session: the hook's
	// AdditionalContext and SystemMessage, and for Rewake the Reason of a
	// Deny.
	Context string
	// Rewake is set when a Rewake hook denied (exited with status 2).
	Rewake bool
	// Err is the hook's error; context.Canceled if Manager.Close
	// cancelled it.
	Err error
}

AsyncResult is the outcome of an Async hook.

type Command

type Command struct {
	// Command is run with "sh -c" (or "cmd /d /s /c" on Windows). When Args
	// is non-nil, Command is instead the executable, run directly with Args
	// as its arguments; "${CLAUDE_PROJECT_DIR}" in Command and Args is
	// replaced by the project directory.
	Command string
	// Args, when non-nil (even empty), selects the exec form.
	Args []string
	// Dir is the working directory.
	Dir string
	// Env is added to the process environment.
	Env []string
	// Timeout defaults to 10 minutes, to 30 seconds for UserPromptSubmit
	// and to 1.5 seconds for SessionEnd (see SessionEndTimeout). A negative
	// Timeout disables it.
	Timeout time.Duration
}

Command is a hook that runs a command, compatible with Claude Code command hooks.

The event is written to the command's stdin as JSON. It carries Claude Code's fields: hook_event_name, session_id, transcript_path (always empty), cwd (Dir or the process's working directory) and permission_mode (Event.PermissionMode, or "default"); tool_name, tool_use_id and tool_input for tool events; tool_response for PostToolUse; error and is_interrupt for PostToolUseFailure; prompt; source for SessionStart; trigger for PreCompact and PostCompact, with custom_instructions (null) and compact_summary; message, title and notification_type for Notification; stop_hook_active and last_assistant_message for Stop and SubagentStop; agent_id (the sub-agent's run ID) and agent_type for SubagentStart; and agent_id, agent_type and agent_transcript_path (empty) for SubagentStop. tool_name and tool_input are agentx's, and tool_response is {"content": ..., "is_error": ...} rather than the structured output of Claude Code's built-in tools. The agentx fields run_id, agent, turn, reason and data (Event.Data) are added. The environment has CLAUDE_PROJECT_DIR (Dir or the working directory), AGENTX_HOOK_EVENT and AGENTX_SESSION_ID.

Exit status 0 succeeds. If stdout is a JSON object it is parsed as a hook output (see below); otherwise non-empty stdout becomes AdditionalContext for SessionStart and UserPromptSubmit. Exit status 2 denies the action with stderr as the reason; JSON fields on stdout still apply but cannot override the deny. Any other status is a hook error, unless stdout is a JSON object, which then decides alone. Processes the command leaves running in the background do not delay or discard its result for more than a second; on Unix they are also killed once it exits. On Windows they keep running unless the hook times out or its context is cancelled.

JSON output fields: decision ("allow", "approve", "ask", "defer", "deny" or "block"), reason, continue (false halts the run), stopReason, systemMessage (Result.SystemMessage), additionalContext and hookSpecificOutput with permissionDecision, permissionDecisionReason, additionalContext, updatedInput and updatedToolOutput. updatedToolOutput must be a string or an object with a string "content" field; other values are ignored. updatedMCPToolOutput is accepted in its place. suppressOutput has no effect, as in Claude Code. A "defer" decision drops updatedInput and additionalContext. Notification, PreCompact and PostCompact ignore continue and systemMessage.

func (*Command) Handle

func (c *Command) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle runs the command.

type Decision

type Decision string

Decision is a hook's verdict on the action that triggered it.

const (
	// Continue expresses no opinion.
	Continue Decision = ""
	// Allow approves the action and skips further approval.
	Allow Decision = "allow"
	// Ask requires approval before the action proceeds.
	Ask Decision = "ask"
	// Defer pauses a PreToolUse call so it can be decided later, like
	// Claude Code's "defer". agentx treats it like Ask: the call needs
	// approval, so without an Approver the run is interrupted and can be
	// resumed. It ranks between Ask and Deny.
	Defer Decision = "defer"
	// Deny blocks the action.
	Deny Decision = "deny"
)

type Event

type Event struct {
	Type      EventType `json:"hook_event_name"`
	SessionID string    `json:"session_id,omitempty"`
	RunID     string    `json:"run_id,omitempty"`
	Agent     string    `json:"agent,omitempty"`
	Turn      int       `json:"turn,omitempty"`
	// PermissionMode is the run's permission mode, such as "default" or
	// "plan"; see Manager.SetPermissionMode.
	PermissionMode string `json:"permission_mode,omitempty"`

	// Prompt is the user input for UserPromptSubmit and SessionStart.
	Prompt string `json:"prompt,omitempty"`
	// Request is the pending model request for PreModel. Hooks may modify it.
	Request *model.Request `json:"-"`
	// Response is the model response for PostModel.
	Response *model.Response `json:"-"`
	// ToolCall is set for tool events.
	ToolCall *model.ToolCall `json:"-"`
	// ToolResult is set for PostToolUse and PostToolUseFailure.
	ToolResult *model.ToolResult `json:"-"`
	// Messages is the conversation for Stop, SubagentStop, PreCompact and
	// PostCompact.
	Messages []*model.Message `json:"-"`
	// Message is the text of a Notification, the final text for Stop and
	// SubagentStop, or the summary for PostCompact.
	Message string `json:"message,omitempty"`
	// Title is the title of a Notification.
	Title string `json:"title,omitempty"`
	// Reason explains why the event fired: the source for SessionStart
	// ("startup", "resume", "clear", "fork" or "compact"), the reason for
	// SessionEnd, "auto" for PreCompact and PostCompact, which fire only for
	// automatic compaction, the sub-agent's name for SubagentStart and
	// SubagentStop, and "approval" for a Notification that asks for tool
	// approval.
	Reason string `json:"reason,omitempty"`
	// StopHookActive is true when the agent is already continuing because a
	// Stop or SubagentStop hook blocked a previous stop in the same run or
	// sub-agent call, even after later tool calls. Hooks use it to avoid
	// loops.
	StopHookActive bool `json:"stop_hook_active,omitempty"`
	// Data carries additional values.
	Data map[string]any `json:"data,omitempty"`
}

Event is the input to a hook.

func (*Event) ToolName

func (e *Event) ToolName() string

ToolName returns the tool name for tool events.

type EventType

type EventType string

EventType identifies a lifecycle point at which hooks run.

const (
	// SessionStart runs when a session starts, with Reason as Claude
	// Code's source: "startup" for the first run of a new session,
	// "resume" when an agent.Runner first runs or resumes an existing
	// session, "clear" and "fork" for the first run of a session made by
	// Runner.Clear or Runner.Fork, and "compact" after automatic
	// compaction. AdditionalContext is added to the conversation: to the
	// run's input, or after the compaction summary. It cannot block the
	// session.
	SessionStart EventType = "SessionStart"
	// SessionEnd runs when agent.Runner.EndSession ends a session, with
	// Reason as Claude Code's reason, such as "clear", "logout",
	// "prompt_input_exit" or "other". It cannot block, and its results are
	// ignored. Its hooks share a time budget; see SessionEndTimeout.
	SessionEnd EventType = "SessionEnd"
	// UserPromptSubmit runs before user input enters the conversation. Deny
	// blocks the run; AdditionalContext is attached to the input.
	UserPromptSubmit EventType = "UserPromptSubmit"
	// PreModel runs before each model call; hooks may modify Event.Request.
	PreModel EventType = "PreModel"
	// PostModel runs after each model call with Event.Response.
	PostModel EventType = "PostModel"
	// PreToolUse runs before a tool call. Deny rejects the call, Ask and
	// Defer request approval, Allow skips approval and UpdatedInput
	// replaces the arguments.
	PreToolUse EventType = "PreToolUse"
	// PostToolUse runs after a tool call that succeeded. UpdatedOutput
	// replaces the result, and AdditionalContext and the Reason of a Deny
	// are appended to it.
	PostToolUse EventType = "PostToolUse"
	// PostToolUseFailure runs instead of PostToolUse after a tool call
	// that ran and returned an error result. AdditionalContext and the
	// Reason of a Deny are appended to the result. Calls denied before
	// they ran fire neither event.
	PostToolUseFailure EventType = "PostToolUseFailure"
	// Stop runs when the model finishes without tool calls. Deny with a
	// Reason, or AdditionalContext, makes the agent continue with them as
	// new input, up to Manager.MaxStopBlocks times in a row (8 by
	// default); a turn with tool calls resets the count.
	Stop EventType = "Stop"
	// SubagentStop runs when a sub-agent invoked as a tool (agent.AsTool)
	// finishes. Like Stop, Deny with a Reason, or AdditionalContext, keeps
	// the sub-agent working with them as new input, under the same cap.
	SubagentStop EventType = "SubagentStop"
	// PreCompact runs before the conversation is compacted. Deny skips
	// automatic compaction.
	PreCompact EventType = "PreCompact"
	// PostCompact runs after the conversation was compacted, with the
	// summary in Message. Its result is ignored.
	PostCompact EventType = "PostCompact"
	// Notification carries informational messages such as approval requests.
	Notification EventType = "Notification"
	// SubagentStart runs when a sub-agent invoked as a tool (agent.AsTool)
	// starts a task, before its run. Agent and Reason are the sub-agent's
	// name, which the matcher matches, RunID is the ID given to its run and
	// Prompt is the task. It cannot block the sub-agent; AdditionalContext
	// is added in front of the task.
	SubagentStart EventType = "SubagentStart"
)

type Func

type Func func(ctx context.Context, ev *Event) (*Result, error)

Func adapts a function to Hook.

func (Func) Handle

func (f Func) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle calls f.

type HTTP

type HTTP struct {
	URL string
	// Headers are added to the request. "$NAME" and "${NAME}" in values are
	// replaced by the environment variable NAME if it is listed in
	// AllowedEnvVars, and by "" otherwise.
	Headers        map[string]string
	AllowedEnvVars []string
	// Timeout defaults to 10 minutes, to 30 seconds for UserPromptSubmit
	// and to 1.5 seconds for SessionEnd. A negative Timeout disables it.
	Timeout time.Duration
	// Client defaults to http.DefaultClient.
	Client *http.Client
}

HTTP is a hook that POSTs the event to a URL, compatible with Claude Code HTTP hooks.

The request body is the JSON a Command receives on stdin, with Content-Type application/json. As in Claude Code, a 2xx response with an empty body succeeds without output, and a 2xx response whose body is a JSON object is read like a command's JSON output. Any other body, a non-2xx status, a connection failure and a timeout are hook errors, which do not block the action unless the manager is FailClosed.

func (*HTTP) Handle

func (h *HTTP) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle sends the event.

type Hook

type Hook interface {
	Handle(ctx context.Context, ev *Event) (*Result, error)
}

Hook handles lifecycle events.

type MCPCaller

type MCPCaller interface {
	CallTool(ctx context.Context, server, tool string, args json.RawMessage) (text string, isError bool, err error)
}

MCPCaller calls a tool of a connected MCP server for MCPTool hooks and returns the text content of the result and whether the server reported it as an error. mcp.HookCaller returns one for mcp.Client values.

type MCPCallerFunc

type MCPCallerFunc func(ctx context.Context, server, tool string, args json.RawMessage) (string, bool, error)

MCPCallerFunc adapts a function to MCPCaller.

func (MCPCallerFunc) CallTool

func (f MCPCallerFunc) CallTool(ctx context.Context, server, tool string, args json.RawMessage) (string, bool, error)

CallTool calls f.

type MCPTool

type MCPTool struct {
	Caller MCPCaller
	Server string
	Tool   string
	// Input holds the tool arguments. "${path}" in its string values, such
	// as "${tool_input.file_path}", is replaced by the value at that
	// dotted path in the event's JSON input: strings as they are, other
	// values as JSON, and missing values by "".
	Input map[string]any
	// Timeout defaults to 10 minutes, to 30 seconds for UserPromptSubmit
	// and to 1.5 seconds for SessionEnd. A negative Timeout disables it.
	Timeout time.Duration
}

MCPTool is a hook that calls a tool of an MCP server, like Claude Code's mcp_tool hooks. The tool's text is read like a command's stdout on exit status 0, and a result marked as an error is a hook error.

func (*MCPTool) Handle

func (t *MCPTool) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle calls the tool.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager dispatches events to registered hooks.

A nil *Manager is valid and has no hooks. The zero value is an empty manager with the default options.

func LoadSettings

func LoadSettings(paths ...string) (*Manager, []string, error)

LoadSettings reads Claude Code settings files with SettingsOptions.Load without options, so only command and http handlers run.

func NewManager

func NewManager(opts ...Option) *Manager

NewManager returns an empty manager.

func ParseSettings

func ParseSettings(data []byte) (*Manager, []string, error)

ParseSettings returns a manager with the hooks configured in the "hooks" block of a Claude Code settings file, such as

{"hooks": {"PreToolUse": [{"matcher": "Bash", "hooks": [
	{"type": "command", "command": "./check.sh", "timeout": 30}]}]}}

It is SettingsOptions.Parse without options, so only command and http handlers run.

func (*Manager) AddContext

func (m *Manager) AddContext(sessionID, text string)

AddContext queues text for a session's conversation. The hook middleware adds it, as a system reminder, to the next tool result or the next run's input of the session, whichever comes first. Async hooks and agent.Runner, for the SessionStart hooks of a resumed session, use it. Empty text is ignored.

func (*Manager) Close

func (m *Manager) Close()

Close cancels the Async hooks running in the background and waits for them to finish, like Claude Code at the end of a non-interactive session. The manager remains usable.

func (*Manager) Dispatch

func (m *Manager) Dispatch(ctx context.Context, ev *Event) (res *Result, err error)

Dispatch runs the matching hooks and merges their results. It always returns a non-nil result.

As in Claude Code, the matching hooks run in parallel (see Parallelism), each with its own copy of ev, and identical Command, HTTP, MCPTool, Prompt and Agent hooks registered more than once run once. The results are merged in registration order, whatever order the hooks finish in: the most restrictive decision wins (deny > defer > ask > allow), with the Reason of the first hook that returned it; AdditionalContext and SystemMessage accumulate; the last UpdatedInput and UpdatedOutput in registration order win. For PreToolUse the merged UpdatedInput is then applied to ev.ToolCall. PreModel hooks, which may modify ev.Request, run one at a time in registration order on ev itself, and so does a lone hook.

Async hooks start in the background and do not contribute to the result. SessionEnd hooks share a time budget; see SessionEndTimeout. Hook errors and panics are returned joined; with FailClosed they also produce Deny. If ctx is done, hooks that have not started are skipped and its error is returned.

Inside a run traced by middleware.Tracing, hooks that run get a "hook {event}" span.

func (*Manager) DropContext

func (m *Manager) DropContext(sessionID string)

DropContext discards the context queued for a session, for example when it ends.

func (*Manager) Has

func (m *Manager) Has(event EventType) bool

Has reports whether any hook is registered for event.

func (*Manager) MaxStopBlocks

func (m *Manager) MaxStopBlocks() int

MaxStopBlocks returns how many consecutive times Stop or SubagentStop hooks may keep the agent working; zero means no limit. See StopBlockCap.

func (*Manager) Merge

func (m *Manager) Merge(other *Manager)

Merge registers all hooks from other into m. FailClosed carries over, and so do the other options of other that m does not set.

func (*Manager) On

func (m *Manager) On(event EventType, matcher string, h Hook) error

On registers a hook for an event.

matcher follows Claude Code's rules. An empty matcher or "*" matches everything. A matcher made only of letters, digits, '_', '-', spaces, ',' and '|' lists exact names separated by '|' or ','; for example "Edit|Write" or "Edit, Write". Any other matcher is a regular expression (Go RE2 syntax) that may match anywhere in the value, so "^Edit$" matches only Edit while "Edit.*" also matches NotebookEdit.

For tool events the value is the tool name. Claude Code's built-in tool names also select the agentx built-ins with the same role: Bash (bash), Read (read_file), Write (write_file), Edit and MultiEdit (edit_file), Glob (glob), Grep (grep), WebFetch (web_fetch) and TodoWrite (todo_write); Edit and Write also select apply_patch. For Notification the value is Event.Reason or Claude Code's notification type, such as permission_prompt for "approval"; for other events it is Event.Reason.

func (*Manager) OnFunc

func (m *Manager) OnFunc(event EventType, matcher string, f func(context.Context, *Event) (*Result, error)) error

OnFunc registers a function hook.

func (*Manager) SetPermissionMode

func (m *Manager) SetPermissionMode(f func(*loop.Run) string)

SetPermissionMode sets how the manager learns a run's permission mode, which events report as Event.PermissionMode and command hooks receive as permission_mode. agent.New sets it from a middleware with a PermissionMode(*loop.Run) string method, such as permission.Policy. Without it the mode is "default".

func (*Manager) Wait

func (m *Manager) Wait(ctx context.Context) error

Wait waits until the Async hooks running in the background finish, or ctx is done.

type Option

type Option func(*Manager)

Option configures a Manager.

func FailClosed

func FailClosed() Option

FailClosed makes hook errors deny the action instead of being ignored. Use it when hooks enforce security policy.

func OnAsyncResult

func OnAsyncResult(f func(AsyncResult)) Option

OnAsyncResult registers a function called when an Async hook finishes, after its context was queued for the session. Use it to wake an idle session when AsyncResult.Rewake is set, for example by starting a run; the queued context is added to that run's input. f runs on the hook's goroutine.

func Parallelism

func Parallelism(n int) Option

Parallelism bounds how many hooks of one event run at once. Zero, the default, runs all matching hooks at once, as Claude Code does, except that at most 12 Prompt and Agent hooks run at a time. 1 runs them one at a time in registration order.

func SessionEndTimeout

func SessionEndTimeout(d time.Duration) Option

SessionEndTimeout sets the time budget of the SessionEnd hooks of one dispatch, which is also the timeout of each Command, HTTP and MCPTool hook without its own, like Claude Code's CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS. By default the budget is 1.5 seconds, raised to the longest timeout set on a SessionEnd hook, up to a minute, and hooks without their own timeout get 1.5 seconds.

func StopBlockCap

func StopBlockCap(n int) Option

StopBlockCap sets how many consecutive times Stop or SubagentStop hooks may keep the agent working before the stop is let through anyway, like Claude Code's CLAUDE_CODE_STOP_HOOK_BLOCK_CAP. Zero disables the cap; a negative n restores the default, DefaultStopBlockCap.

type Prompt

type Prompt struct {
	Model  model.Model
	Prompt string
	// ModelName, if set, overrides the model name of the request.
	ModelName string
	// Timeout defaults to 30 seconds. A negative Timeout disables it.
	Timeout         time.Duration
	ContinueOnBlock bool
}

Prompt is a hook that asks a model to evaluate the event, like Claude Code's prompt hooks.

The model receives Prompt with "$ARGUMENTS" replaced by the event's JSON input, the input a Command receives; without "$ARGUMENTS" the input is appended. "\$" stands for a literal "$". It must answer with a JSON object: {"ok": true} lets the action proceed, and {"ok": false, "reason": "..."} blocks it, which depends on the event as in Claude Code:

  • Stop and SubagentStop: the agent continues with the reason, unless the answer also has "impossible": true, which lets it stop.
  • PreToolUse: the call is denied with the reason; unless ContinueOnBlock is set, the run also halts after the step, with the reason as a warning.
  • PostToolUse: unless ContinueOnBlock is set, the run halts with the reason as a warning; with it, the reason is added to the result.
  • PostToolUseFailure: the reason is added to the result.
  • UserPromptSubmit and other events: Deny with the reason.

An answer that is not such an object is a hook error.

func (*Prompt) Handle

func (p *Prompt) Handle(ctx context.Context, ev *Event) (*Result, error)

Handle asks the model.

type Result

type Result struct {
	Decision Decision
	// Reason explains the decision. For Deny it is shown to the model.
	Reason string
	// AdditionalContext is added to the conversation; where depends on the
	// event type.
	AdditionalContext string
	// UpdatedInput replaces the tool arguments for PreToolUse.
	UpdatedInput json.RawMessage
	// UpdatedOutput replaces the tool result content for PostToolUse.
	UpdatedOutput *string
	// Halt stops the run after the current step.
	Halt bool
	// HaltReason explains Halt.
	HaltReason string
	// SystemMessage is a warning for the user, not the model. The hook
	// middleware logs it.
	SystemMessage string
}

Result is the output of a hook. A nil result means Continue.

type SettingsOptions

type SettingsOptions struct {
	// Model evaluates "prompt" handlers. Their "model" field becomes
	// Prompt.ModelName.
	Model model.Model
	// Verifier runs "agent" handlers; see agent.HookVerifier.
	Verifier Verifier
	// MCP calls the tools of "mcp_tool" handlers; see mcp.HookCaller.
	MCP MCPCaller
	// HTTPClient sends "http" handlers; nil uses http.DefaultClient.
	HTTPClient *http.Client
}

SettingsOptions supplies what the hooks of a settings file need beyond commands. Handlers whose dependency is missing are skipped with a warning.

func (SettingsOptions) Load

func (o SettingsOptions) Load(paths ...string) (*Manager, []string, error)

Load reads Claude Code settings files with Parse and returns one manager with all their hooks. Pass the files in increasing precedence, for example ~/.claude/settings.json, .claude/settings.json and .claude/settings.local.json: the last disableAllHooks wins. Files that do not exist are skipped. A handler configured identically in more than one file runs once, as in Claude Code.

func (SettingsOptions) Parse

func (o SettingsOptions) Parse(data []byte) (*Manager, []string, error)

Parse returns a manager with the hooks configured in the "hooks" block of a Claude Code settings file.

Handlers become Command, HTTP, MCPTool, Prompt and Agent hooks: timeout is in seconds, args selects a command's exec form, async and asyncRewake commands are wrapped in Async (async commands get no timeout), and onFailure "block" makes a failing hook deny the action as exit status 2 would, except on Stop and SubagentStop and for async hooks. statusMessage and once are ignored. "disableAllHooks": true yields an empty manager. As in Claude Code, the CLAUDE_CODE_STOP_HOOK_BLOCK_CAP environment variable sets the manager's StopBlockCap, and CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS its SessionEndTimeout in milliseconds.

Handlers agentx cannot run as configured are skipped and described in the returned warnings: prompt, agent and mcp_tool handlers without the matching option, handler types an event does not support in Claude Code (SessionStart runs only command and mcp_tool handlers; prompt and agent handlers run only for UserPromptSubmit, PreToolUse, PostToolUse, PostToolUseFailure, Stop and SubagentStop), the if field, shell "powershell", events agentx does not dispatch, and invalid matchers. The error reports malformed JSON.

type Verifier

type Verifier interface {
	Verify(ctx context.Context, model, prompt string) (string, error)
}

Verifier runs the agentic check of an Agent hook: it works on prompt with tools, over as many turns as it needs, and returns its final answer. model is the model name the hook configures, or "" for the verifier's default. agent.HookVerifier returns one backed by an agent.

type VerifierFunc

type VerifierFunc func(ctx context.Context, model, prompt string) (string, error)

VerifierFunc adapts a function to Verifier.

func (VerifierFunc) Verify

func (f VerifierFunc) Verify(ctx context.Context, model, prompt string) (string, error)

Verify calls f.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL