chore: hook up config

Kujtim Hoxha created

Change summary

internal/app/app.go        |  5 +++++
internal/config/config.go  |  3 +++
internal/hooks/builtins.go |  1 -
internal/hooks/config.go   | 16 ++++++++--------
4 files changed, 16 insertions(+), 9 deletions(-)

Detailed changes

internal/app/app.go 🔗

@@ -23,6 +23,7 @@ import (
 	"github.com/charmbracelet/crush/internal/db"
 	"github.com/charmbracelet/crush/internal/format"
 	"github.com/charmbracelet/crush/internal/history"
+	"github.com/charmbracelet/crush/internal/hooks"
 	"github.com/charmbracelet/crush/internal/log"
 	"github.com/charmbracelet/crush/internal/lsp"
 	"github.com/charmbracelet/crush/internal/message"
@@ -46,6 +47,7 @@ type App struct {
 	Permissions permission.Service
 
 	AgentCoordinator agent.Coordinator
+	HooksManager     hooks.Manager
 
 	LSPClients *csync.Map[string, *lsp.Client]
 
@@ -89,6 +91,9 @@ func New(ctx context.Context, conn *sql.DB, cfg *config.Config) (*App, error) {
 		tuiWG:           &sync.WaitGroup{},
 	}
 
+	// Initialize hooks manager.
+	app.HooksManager = hooks.NewManager(cfg.WorkingDir(), cfg.Options.DataDirectory, cfg.Hooks)
+
 	app.setupEvents()
 
 	// Initialize LSP clients in the background.

internal/config/config.go 🔗

@@ -14,6 +14,7 @@ import (
 	"github.com/charmbracelet/catwalk/pkg/catwalk"
 	"github.com/charmbracelet/crush/internal/csync"
 	"github.com/charmbracelet/crush/internal/env"
+	"github.com/charmbracelet/crush/internal/hooks"
 	"github.com/invopop/jsonschema"
 	"github.com/tidwall/sjson"
 )
@@ -326,6 +327,8 @@ type Config struct {
 
 	Tools Tools `json:"tools,omitzero" jsonschema:"description=Tool configurations"`
 
+	Hooks *hooks.Config `json:"hooks,omitempty" jsonschema:"description=Hook system configuration"`
+
 	Agents map[string]Agent `json:"-"`
 
 	// Internal

internal/hooks/builtins.go 🔗

@@ -39,7 +39,6 @@ func crushGetInput(ctx context.Context, args []string) error {
 // Usage: COMMAND=$(crush_get_tool_input "command")
 func crushGetToolInput(ctx context.Context, args []string) error {
 	hc := interp.HandlerCtx(ctx)
-
 	if len(args) != 2 {
 		fmt.Fprintln(hc.Stderr, "Usage: crush_get_tool_input <param_name>")
 		return interp.ExitStatus(1)

internal/hooks/config.go 🔗

@@ -3,33 +3,33 @@ package hooks
 // Config defines hook system configuration.
 type Config struct {
 	// Enabled controls whether hooks are executed.
-	Enabled bool
+	Enabled bool `json:"enabled,omitempty" jsonschema:"description=Enable or disable hook execution,default=true"`
 
 	// TimeoutSeconds is the maximum time a hook can run.
-	TimeoutSeconds int
+	TimeoutSeconds int `json:"timeout_seconds,omitempty" jsonschema:"description=Maximum execution time for hooks in seconds,default=30,example=30"`
 
 	// Directories are additional directories to search for hooks.
 	// Defaults to [".crush/hooks"] if empty.
-	Directories []string
+	Directories []string `json:"directories,omitempty" jsonschema:"description=Directories to search for hook scripts,example=.crush/hooks"`
 
 	// Inline hooks defined directly in configuration.
 	// Map key is the hook type (e.g., "pre-tool-use").
-	Inline map[string][]InlineHook
+	Inline map[string][]InlineHook `json:"inline,omitempty" jsonschema:"description=Inline hook scripts defined in configuration"`
 
 	// Disabled is a list of hook paths to skip.
 	// Paths are relative to the hooks directory.
 	// Example: ["pre-tool-use/02-slow-check.sh"]
-	Disabled []string
+	Disabled []string `json:"disabled,omitempty" jsonschema:"description=List of hook paths to disable,example=pre-tool-use/02-slow-check.sh"`
 
 	// Environment variables to pass to hooks.
-	Environment map[string]string
+	Environment map[string]string `json:"environment,omitempty" jsonschema:"description=Environment variables to pass to all hooks"`
 }
 
 // InlineHook is a hook defined inline in the config.
 type InlineHook struct {
 	// Name is the name of the hook (used as filename).
-	Name string
+	Name string `json:"name" jsonschema:"required,description=Name of the hook script,example=audit.sh"`
 
 	// Script is the bash script content.
-	Script string
+	Script string `json:"script" jsonschema:"required,description=Bash script content to execute"`
 }