hooksreg

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package hooksreg implements a lifecycle hook system for jungi. Hook packages are directories containing a hook.json definition file and executable scripts. Both user-level (~/.config/jungi/hooks/) and project-level (.jungi/hooks/) directories are scanned and merged into a Registry. Scripts run unsandboxed with context supplied via environment variables; errors are logged as warnings and never block the lifecycle event.

Index

Constants

View Source
const (
	EnvSessionID     = "SESSION_ID"
	EnvWorkDir       = "WORK_DIR"
	EnvRepoRoot      = "REPO_ROOT"
	EnvWorktreePath  = "WORKTREE_PATH"
	EnvPlanSlug      = "PLAN_SLUG"
	EnvTicketSlug    = "TICKET_SLUG"
	EnvTicketName    = "TICKET_NAME"
	EnvBranchName    = "BRANCH_NAME"
	EnvBaseRef       = "BASE_REF"
	EnvPhaseNames    = "PHASE_NAMES"
	EnvPhaseName     = "PHASE_NAME"
	EnvCommitSHA     = "COMMIT_SHA"
	EnvCommitMessage = "COMMIT_MESSAGE"
)

Canonical environment variable keys shared by hook producers and consumers. Using these constants instead of ad-hoc string literals keeps producer, catalog contract, and consumer hooks spelling the same keys.

Variables

This section is empty.

Functions

func TruncateOutput

func TruncateOutput(b []byte) string

TruncateOutput trims trailing whitespace from combined command output and, if it exceeds maxTruncatedOutput bytes, keeps only the tail and prefixes an elision marker. This is the shared truncation policy for any hook that execs an external command and wants to surface that command's output in an error or log message without unbounded growth.

Types

type Descriptor

type Descriptor struct {
	// Event is the lifecycle event this descriptor documents.
	Event Event
	// Doc is a short human-readable description of when this event fires.
	Doc string
	// Keys lists the environment variable keys a Payload for this event
	// must populate. Registry.Emit validates a payload's Env() against this
	// list before dispatching to each registered hook.
	Keys []string
}

Descriptor describes a lifecycle event known to the hook system: what it means, and which environment variable keys its payload is contractually guaranteed to populate.

func Lookup

func Lookup(event Event) (Descriptor, bool)

Lookup returns the descriptor for event, if any.

type Event

type Event string

Event is a lifecycle event identifier.

const (
	EventWorktreeCreated      Event = "worktree.created"
	EventWorktreePruned       Event = "worktree.pruned"
	EventSessionCreated       Event = "session.created"
	EventSessionDeleted       Event = "session.deleted"
	EventPlanCreated          Event = "plan.created"
	EventPlanCompleted        Event = "plan.completed"
	EventTicketStarted        Event = "ticket.started"
	EventTicketCompleted      Event = "ticket.completed"
	EventTicketReadyForReview Event = "ticket.ready_for_review"
	EventTicketReviewed       Event = "ticket.reviewed"
	EventPhaseCommitted       Event = "phase.committed"
)

Event identifiers for every lifecycle event known to the hook system. These are the only valid Event values — see the catalog below for each event's documentation and env-key contract.

type EventBinding

type EventBinding struct {
	Event   Event    `json:"event"`
	Scripts []string `json:"scripts"`
}

EventBinding maps a lifecycle event to one or more script paths.

type FuncHook

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

FuncHook is a Hook backed by a Go function, used for code-defined built-ins.

func (*FuncHook) Name

func (h *FuncHook) Name() string

func (*FuncHook) Run

func (h *FuncHook) Run(ctx context.Context, event Event, env map[string]string, workDir string) error

Run calls the underlying function, forwarding all arguments including the context deadline set by Registry.Emit.

type Hook

type Hook interface {
	// Name returns the human-readable name used in log messages.
	Name() string
	// Run executes the hook for the given event. ctx carries the per-hook
	// execution deadline set by Emit. env provides additional environment
	// variables layered on top of the process environment. workDir is the
	// working directory for the hook. Returned errors are logged by Emit;
	// they never block the lifecycle event.
	Run(ctx context.Context, event Event, env map[string]string, workDir string) error
}

Hook is the interface implemented by all lifecycle hooks, whether they are filesystem script hooks or code-defined built-ins.

func NewFuncHook

func NewFuncHook(name string, fn func(ctx context.Context, event Event, env map[string]string, workDir string) error) Hook

NewFuncHook returns a Hook that delegates Run to fn. name is the human-readable label used in log messages.

func NewScriptHook

func NewScriptHook(name, scriptPath string) Hook

NewScriptHook returns a Hook that executes the script at scriptPath when Run is called. name is the human-readable label used in log messages.

type HookPackage

type HookPackage struct {
	// Name is the human-readable hook package name used in log messages.
	Name string `json:"name"`
	// Hooks is the list of event bindings.
	Hooks []EventBinding `json:"hooks"`
	// contains filtered or unexported fields
}

HookPackage represents a parsed hook.json file plus the directory it lives in.

type Payload

type Payload interface {
	// Event returns the lifecycle event this payload represents.
	Event() Event
	// Env returns the environment variables to expose to hooks. The keys
	// present must satisfy the catalog Descriptor.Keys contract for Event().
	Env() map[string]string
	// WorkDir returns the working directory hooks should run in.
	WorkDir() string
}

Payload is implemented by subsystem-specific event data so it can be emitted through Registry.Emit without callers hand-assembling env maps.

type Registry

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

Registry holds hooks indexed by lifecycle event.

func NewRegistry

func NewRegistry(log *logger.Logger, dirs ...string) *Registry

NewRegistry scans each directory in dirs for hook packages and merges the results into a single Registry. Warnings from individual invalid hook.json files are emitted via log (nil-safe). dir errors (non-existence aside) are also logged as warnings — they never prevent the registry from being returned.

func (*Registry) Add

func (r *Registry) Add(event Event, hook Hook)

Add registers hook for event. It is the primary way to attach code-defined built-in hooks (FuncHook) to the registry after construction.

func (*Registry) Emit

func (r *Registry) Emit(payload Payload)

Emit validates payload against the catalog contract and asynchronously dispatches it to every hook registered for payload.Event(), using payload.Env() and payload.WorkDir(). If a Descriptor is registered for the event, Env() is checked against the descriptor's declared Keys and any missing keys are logged as a warning — validation never blocks dispatch. Hook execution happens in a background goroutine so Emit always returns immediately; hooks for a given call still run in sequence relative to one another, each wrapped with a 5-minute execution deadline. Start and error messages are logged via the registry's logger. Emit never returns an error — failures are warnings only. Emit is nil-safe: a nil receiver or nil payload is a no-op. Use Wait to block until dispatched hooks finish, e.g. in tests or during graceful shutdown.

func (*Registry) ForEvent

func (r *Registry) ForEvent(event Event) []Hook

ForEvent returns all hooks registered for the given event. Returns nil if none are registered.

func (*Registry) Wait

func (r *Registry) Wait()

Wait blocks until every hook dispatched via Emit has finished running. Intended for tests and graceful-shutdown paths that need dispatched hooks to complete before proceeding. Wait is nil-safe: a nil receiver returns immediately.

Source Files

  • catalog.go
  • dispatch.go
  • hooks.go
  • registry.go
  • run.go

Jump to

Keyboard shortcuts

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