1// Package hooks provides a Git-like hooks system for Crush.
2//
3// Hooks are executable scripts that run at specific points in the application
4// lifecycle. They can modify behavior, add context, control permissions, and
5// audit activity.
6package hooks
7
8import "context"
9
10// HookType represents the type of hook.
11type HookType string
12
13const (
14 // HookUserPromptSubmit executes after user submits prompt, before sending to LLM.
15 HookUserPromptSubmit HookType = "user-prompt-submit"
16
17 // HookPreToolUse executes after LLM requests tool use, before permission check & execution.
18 HookPreToolUse HookType = "pre-tool-use"
19
20 // HookPostToolUse executes after tool executes, before result sent to LLM.
21 HookPostToolUse HookType = "post-tool-use"
22
23 // HookStop executes when agent conversation loop stops or is cancelled.
24 HookStop HookType = "stop"
25)
26
27// HookContext contains the data passed to hooks.
28type HookContext struct {
29 // HookType is the type of hook being executed.
30 HookType HookType
31
32 // SessionID is the current session ID.
33 SessionID string
34
35 // WorkingDir is the working directory.
36 WorkingDir string
37
38 // Data is hook-specific data marshaled to JSON and passed via stdin.
39 // For UserPromptSubmit: prompt, attachments, model, is_first_message
40 // For PreToolUse: tool_name, tool_call_id, tool_input
41 // For PostToolUse: tool_name, tool_call_id, tool_input, tool_output, execution_time_ms
42 // For Stop: reason
43 Data map[string]any
44
45 // ToolName is the tool name (for tool hooks only).
46 ToolName string
47
48 // ToolCallID is the tool call ID (for tool hooks only).
49 ToolCallID string
50
51 // Environment contains additional environment variables to pass to the hook.
52 Environment map[string]string
53}
54
55// HookResult contains the result of hook execution.
56type HookResult struct {
57 // Continue indicates whether to continue execution.
58 // If false, execution stops.
59 Continue bool
60
61 // Permission decision (for PreToolUse hooks only).
62 // Values: "ask" (default), "approve", "deny"
63 Permission string
64
65 // ModifiedPrompt is the modified user prompt (for UserPromptSubmit).
66 ModifiedPrompt *string
67
68 // ModifiedInput is the modified tool input parameters (for PreToolUse).
69 // This is a map that can be merged with the original tool input.
70 ModifiedInput map[string]any
71
72 // ModifiedOutput is the modified tool output (for PostToolUse).
73 ModifiedOutput map[string]any
74
75 // ContextContent is raw text content to add to LLM context.
76 ContextContent string
77
78 // ContextFiles is a list of file paths to load and add to LLM context.
79 ContextFiles []string
80
81 // Message is a user-facing message (logged and potentially displayed).
82 Message string
83}
84
85// Manager coordinates hook discovery and execution.
86type Manager interface {
87 // ExecuteHooks executes all hooks for the given type in order.
88 // Returns accumulated results from all hooks.
89 ExecuteHooks(ctx context.Context, hookType HookType, context HookContext) (HookResult, error)
90
91 // ListHooks returns all discovered hooks for a given type.
92 ListHooks(hookType HookType) []string
93}