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

hookrun

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package hookrun runs graphmaster's short-lived hook processes: dispatch, dedupe, timeouts and payload recording.

Index

Constants

View Source
const (
	HomePlaceholder = "{{HOME}}"
	RepoPlaceholder = "{{REPO}}"
)

Placeholders substituted for machine-specific paths in recordings.

View Source
const DedupeTTL = 10 * time.Minute

DedupeTTL is how long a cached decision can be replayed (PLAN: 10 min).

View Source
const LogFileName = "log"

LogFileName is the hook error log inside <root>/.graphmaster.

View Source
const RecordEnv = "GRAPHMASTER_RECORD"

RecordEnv names the environment variable that enables payload capture. When set to a directory, every hook invocation dumps its raw stdin and a scrubbed env snapshot under <dir>/<agent>/<event>-<n>.json.

Variables

This section is empty.

Functions

func EventTimeout

func EventTimeout(e hookapi.Event, cfg *config.Config) time.Duration

EventTimeout returns how long the dispatcher may work on one event before it gives up and answers fail-open. It is the event's freshness lock budget from cfg (config.Timeouts) plus a per-event grace, capped at maxEventTimeout. A nil cfg uses config.Default.

func SnapshotEnv

func SnapshotEnv(environ []string, s *Scrubber) map[string]string

SnapshotEnv keeps the agent-related variables from environ, redacting secret-looking values and scrubbing paths in the rest.

func SpawnIndex

func SpawnIndex(root string) error

SpawnIndex starts `<this executable> index --quiet` in root as a detached process (its own session, no stdio) and does not wait for it. It is the one-shot background build agents that cannot block use at session start (PLAN step 10); it is not a daemon.

Types

type Dispatcher

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

Dispatcher runs hook invocations. It never fails: every internal error, panic or timeout produces the adapter's no-opinion output (fail-open) and a line in <root>/.graphmaster/log.

func New

func New(opts Options) *Dispatcher

New returns a Dispatcher.

func (*Dispatcher) Run

func (d *Dispatcher) Run(ctx context.Context, req Request) (out adapters.HookOutput)

Run handles one invocation and returns what to write back to the agent.

type Options

type Options struct {
	// Adapter looks up an agent adapter (default adapters.Get).
	Adapter func(hookapi.Agent) (adapters.Agent, bool)
	// Open opens a located repository's index (default index.Open with
	// the real resolver).
	Open func(ctx context.Context, loc *index.Location, cfg *config.Config) (steer.Index, error)
	// Spawn starts a detached background build in root (default
	// SpawnIndex).
	Spawn func(root string) error
	// Timeout is the per-event deadline (default EventTimeout).
	Timeout func(hookapi.Event, *config.Config) time.Duration
	// LookupBudget bounds the steering graph lookup (steer default 25ms).
	LookupBudget time.Duration
	// DedupeWait bounds the wait for a concurrent duplicate (default 2s).
	DedupeWait time.Duration
	// Now is the clock (default time.Now).
	Now func() time.Time
}

Options configure a Dispatcher. Every field is optional.

type Recorder

type Recorder struct {
	Dir  string // output root
	Home string // replaced by {{HOME}}; empty disables
	Repo string // replaced by {{REPO}}; empty disables
	// Environ is the environment to snapshot; nil means os.Environ().
	Environ []string
}

Recorder dumps hook payloads for building replay fixtures. A nil *Recorder is a valid no-op.

func RecorderFromEnv

func RecorderFromEnv(getenv func(string) string, repoRoot string) *Recorder

RecorderFromEnv returns a Recorder when RecordEnv is set, else nil. repoRoot is the repository root resolved by the caller (may be empty).

func (*Recorder) Record

func (r *Recorder) Record(agent, event string, stdin []byte, cwd string) (string, error)

Record writes one recording and returns its path. cwd defaults to the process working directory when empty. Agent and event names are sanitized into safe path components.

type Recording

type Recording struct {
	Agent string            `json:"agent"`
	Event string            `json:"event"`
	CWD   string            `json:"cwd"`
	Env   map[string]string `json:"env"`
	// Stdin holds the payload when it is valid JSON (the normal case).
	Stdin json.RawMessage `json:"stdin,omitempty"`
	// StdinText holds the payload verbatim when it is not valid JSON.
	StdinText string `json:"stdin_text,omitempty"`
}

Recording is the on-disk shape of one captured hook invocation.

type Request

type Request struct {
	// Event is the CLI event argument (canonical kebab-case, e.g.
	// "pre-tool-use"); empty or unknown lets the adapter use the payload.
	Event string
	// Agent is the --agent value.
	Agent string
	// Stdin is the raw hook payload.
	Stdin []byte
	// Env is the process environment (os.Environ form); nil means the real
	// environment.
	Env []string
	// WorkDir is the process working directory, used when the payload
	// carries no cwd.
	WorkDir string
}

Request is one `graphmaster hook <event> --agent <name>` invocation.

type Scrubber

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

Scrubber replaces machine-specific path roots with placeholders.

func NewScrubber

func NewScrubber(home, repo string) *Scrubber

NewScrubber builds a scrubber for the home and repo roots. Each root is also matched in its symlink-resolved form and in its JSON-escaped form (doubled backslashes, for Windows paths inside JSON strings). Empty roots and filesystem roots are ignored.

func (*Scrubber) Scrub

func (s *Scrubber) Scrub(in string) string

Scrub replaces every root occurrence that sits on path-component boundaries with its placeholder.

Jump to

Keyboard shortcuts

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