hooks

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 10 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", "memory-capture"}

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 "duet" (see builtin_duet.go) and "memory-capture" (see memory_capture.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"`
	// Extra holds event-specific metadata (e.g. tool output for PostToolUse,
	// summary for SessionEnd). Keys vary by event; callers must type-assert.
	Extra map[string]any `json:"extra,omitempty"`
}

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 MemoryCapture added in v0.4.0

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

MemoryCapture is a hook handler that auto-captures tool outputs and session summaries into the long-term memory store.

func NewMemoryCapture added in v0.4.0

func NewMemoryCapture(store memory.Store) *MemoryCapture

NewMemoryCapture returns a MemoryCapture wired to store.

func (*MemoryCapture) Handle added in v0.4.0

func (mc *MemoryCapture) Handle(ctx context.Context, input HookInput) error

Handle processes HookInput for EventPostToolUse and EventSessionEnd. It extracts meaningful text, strips secrets, and calls store.Remember (which handles SHA dedup internally).

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