hooks

package
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: May 31, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package hooks provides an extensible hook system for deepseekcode. Hooks fire at named lifecycle events (PreToolUse, PostToolUse, etc.) and can be either in-process builtin functions or subprocess commands.

Fail-open semantics: a hook that errors or times out returns a "continue" decision, never blocking the agent loop.

Index

Constants

This section is empty.

Variables

View Source
var KnownBuiltinNames = []string{"duet"}

KnownBuiltinNames is the authoritative set of builtin hook names this binary can register (the constructors live in this package; the wiring lives in cmd/dsc). Config validation cross-checks user hook configs against it so a typo'd builtin name (e.g. "duett") is rejected at validation time instead of silently fail-opening at runtime.

Keep this in sync with the builtin registrations in cmd/dsc — currently the single "duet" hook (see builtin_duet.go).

Functions

func IsKnownBuiltin

func IsKnownBuiltin(name string) bool

IsKnownBuiltin reports whether name is a registered builtin hook.

Types

type BuiltinHook

type BuiltinHook func(ctx context.Context, in HookInput) (HookOutput, error)

BuiltinHook is a hook implemented as an in-process Go function.

func NewDuetHook

func NewDuetHook(client DuetClient, extraDestructive []string, cwd string, secretPatterns []string, modelFn func() string, transcriptFn func() []byte) BuiltinHook

NewDuetHook returns a BuiltinHook implementing destructive-call validation via the pro model. Safe to register under name "duet".

modelFn supplies the current main-loop model so the hook can skip self-validation when the user has switched to pro via /models. transcriptFn supplies recent conversation context for pro to judge.

type DuetClient

type DuetClient interface {
	ValidatePro(ctx context.Context, prompt string) (approve bool, reasoning string, err error)
}

DuetClient is the LLM-call dependency for the Duet builtin hook. Satisfied by llm.Client via its ValidatePro method.

type HookConfig

type HookConfig struct {
	Event   HookEvent
	Type    HookType
	Command string        // when Type == subprocess
	Name    string        // when Type == builtin
	Timeout time.Duration // default 30s
}

HookConfig describes one registered hook. Event + (Command xor Name) identifies what fires and how.

type HookEvent

type HookEvent string

HookEvent names a point in the agent lifecycle where hooks are fired.

const (
	EventPreToolUse         HookEvent = "PreToolUse"
	EventPostToolUse        HookEvent = "PostToolUse"
	EventPostToolUseFailure HookEvent = "PostToolUseFailure"
	EventSessionStart       HookEvent = "SessionStart"
	EventSessionEnd         HookEvent = "SessionEnd"
)

type HookInput

type HookInput struct {
	Event     HookEvent       `json:"event"`
	ToolName  string          `json:"tool_name,omitempty"`
	ToolInput json.RawMessage `json:"tool_input,omitempty"`
	CWD       string          `json:"cwd"`
	SessionID string          `json:"session_id"`
}

HookInput is the JSON payload delivered to every hook invocation.

type HookOutput

type HookOutput struct {
	Decision string `json:"decision"` // "allow" | "deny" | "ask" | "continue"
	Reason   string `json:"reason,omitempty"`
}

HookOutput is the structured response a hook must produce on stdout (subprocess) or return (builtin).

type HookType

type HookType string

HookType distinguishes in-process builtins from spawned subprocesses.

const (
	TypeSubprocess HookType = "subprocess"
	TypeBuiltin    HookType = "builtin"
)

type Runner

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

Runner dispatches hooks at lifecycle events. It owns the list of configured hooks and the registry of builtin implementations.

func NewRunner

func NewRunner() *Runner

NewRunner returns an empty Runner with no hooks configured.

func (*Runner) Configure

func (r *Runner) Configure(configs []HookConfig)

Configure replaces the current hook config list. Typical usage: load HookConfig list from TOML, then call Configure once.

func (*Runner) Register

func (r *Runner) Register(name string, fn BuiltinHook)

Register adds a builtin hook by name. Hook configs whose Type is "builtin" and Name matches will dispatch here.

func (*Runner) Run

func (r *Runner) Run(ctx context.Context, event HookEvent, in HookInput) (HookOutput, error)

Run fires all configured hooks for the given event. Returns the first non-"continue" decision. Order: deny short-circuits, then ask, then allow. If no hooks are configured for this event, returns allow.

Fail-open: any error or timeout inside a hook results in a "continue" decision, logged with the reason, and execution proceeds.

Jump to

Keyboard shortcuts

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