Documentation
¶
Overview ¶
Package hooks gives a caller a named, multi-handler registry for a lifecycle point: Point, Handler, and a Registry whose Fire runs every handler at a point in registration order and stops at the first veto. A leaf package: no I/O, no goroutine, no persistence.
Map: point.go = Point, its named constants, Validate, and String; registry.go = Handler, Registry, New, Add, Remove, Fire, and the sentinel errors ErrBlankName, ErrNilHandler, ErrDuplicateName, ErrVetoed. Rationale: ../docs/plans/hooks.md. Contribution rules: ../AGENTS.md.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrBlankName is Add's error when name is empty after // strings.TrimSpace. ErrBlankName = errors.New("hooks: name must not be blank") // ErrNilHandler is Add's error for a nil Handler; a hook with // nothing to run has no purpose. ErrNilHandler = errors.New("hooks: handler must not be nil") // ErrDuplicateName is Add's error for a name already registered // at the same point. The same name may register at another point. ErrDuplicateName = errors.New("hooks: name already registered at point") // ErrVetoed is Fire's wrapped error when a handler returns false // with a nil error; test with errors.Is. ErrVetoed = errors.New("hooks: handler vetoed") )
Sentinel errors for Registry operations; test with errors.Is.
Functions ¶
This section is empty.
Types ¶
type Handler ¶
Handler observes or vetoes one lifecycle point's action. payload is opaque to hooks: the caller that fires a point supplies whatever value that point's real action carries. Handler returns true, nil to allow the action to continue, false, nil to veto it, or a non-nil error when the handler itself failed to decide.
type Point ¶
type Point int
Point names a lifecycle point a Registry groups handlers under.
const ( // PointPreTool fires before a tool call runs. PointPreTool Point // PointPostTool fires after a step's ack confirms, tool or Ask round trip. PointPostTool // PointStop fires at a run's stop. PointStop )
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds named handlers grouped by Point, in registration order. Safe for concurrent Add, Remove, and Fire; a sync.Mutex guards the map. Build one with New.
func (*Registry) Add ¶
Add registers h under name at point. Rejects an invalid point with its Validate error, a blank name (empty after strings.TrimSpace) with ErrBlankName, a nil h with ErrNilHandler, and a name already registered at that same point with ErrDuplicateName. The same name may register at two different points; name scopes to one Point.
func (*Registry) Fire ¶
Fire runs every handler registered at point, in registration order. An invalid point returns its Validate error at once, with no handler call. A point with no registered handlers returns nil at once. A handler returning true, nil moves Fire to the next handler. A handler returning false, nil stops Fire and returns ErrVetoed wrapped `hooks: %s: handler %q: %w`. A handler returning a non-nil error stops Fire and returns that error wrapped the same way. Fire returns nil once every handler has allowed. Fire releases the mutex before it calls a handler, so a slow handler never blocks a concurrent Add or Remove.