hooks

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jan 18, 2026 License: MIT Imports: 4 Imported by: 0

README

OmniConfig Hooks

Go Reference

The hooks package provides a unified interface for managing automation/lifecycle hooks across multiple AI coding assistants.

Overview

Hooks are callbacks that execute at defined stages of the AI agent loop. They can:

  • Observe agent behavior (logging, metrics)
  • Block operations (security gates, validation)
  • Modify behavior (inject context, transform outputs)

Supported Tools

Tool Config Location Format
Claude Code .claude/settings.json JSON with hooks key
Cursor IDE .cursor/hooks.json JSON
Windsurf .windsurf/hooks.json JSON

Installation

go get github.com/agentplexus/assistantkit/hooks

Quick Start

Creating a Hooks Configuration
package main

import (
    "github.com/agentplexus/assistantkit/hooks"
    "github.com/agentplexus/assistantkit/hooks/claude"
)

func main() {
    cfg := hooks.NewConfig()

    // Add a hook before shell commands
    cfg.AddHookWithMatcher(hooks.BeforeCommand, "Bash",
        hooks.NewCommandHook("echo 'Executing command...'"))

    // Add a hook before file writes
    cfg.AddHook(hooks.BeforeFileWrite,
        hooks.NewCommandHook("./scripts/validate-write.sh"))

    // Write to Claude format
    if err := claude.WriteProjectConfig(cfg); err != nil {
        panic(err)
    }
}
Reading an Existing Configuration
package main

import (
    "fmt"
    "github.com/agentplexus/assistantkit/hooks/cursor"
)

func main() {
    cfg, err := cursor.ReadProjectConfig()
    if err != nil {
        panic(err)
    }

    fmt.Printf("Found %d hooks\n", cfg.HookCount())

    for _, event := range cfg.Events() {
        fmt.Printf("Event: %s\n", event)
        for _, hook := range cfg.GetAllHooksForEvent(event) {
            fmt.Printf("  - %s\n", hook.Command)
        }
    }
}
Converting Between Formats
package main

import (
    "os"
    "github.com/agentplexus/assistantkit/hooks"
)

func main() {
    // Read Claude hooks
    data, _ := os.ReadFile(".claude/settings.json")

    // Convert to Cursor format
    cursorData, err := hooks.Convert(data, "claude", "cursor")
    if err != nil {
        panic(err)
    }

    os.WriteFile(".cursor/hooks.json", cursorData, 0644)
}

Event Reference

File Operations
Event Description Can Block
before_file_read Before reading a file Yes
after_file_read After reading a file No
before_file_write Before writing a file Yes
after_file_write After writing a file No
Command Operations
Event Description Can Block
before_command Before shell command execution Yes
after_command After shell command execution No
MCP Operations
Event Description Can Block
before_mcp Before MCP tool call Yes
after_mcp After MCP tool call No
Session Lifecycle
Event Description Can Block
before_prompt Before user prompt processing Yes
on_stop When agent stops No
on_session_start When session starts No
on_session_end When session ends No
Tool-Specific Events
Event Tool Description
after_response Cursor After AI response
after_thought Cursor After AI thought/reasoning
on_permission Claude Permission request
on_notification Claude Notification event
before_compact Claude Before context compaction
on_subagent_stop Claude When subagent stops
before_tab_read Cursor Before reading editor tab
after_tab_edit Cursor After editing tab

Tool Support Matrix

Event Claude Cursor Windsurf
before_file_read Yes Yes Yes
after_file_read Yes No Yes
before_file_write Yes No Yes
after_file_write Yes Yes Yes
before_command Yes Yes Yes
after_command Yes Yes Yes
before_mcp Yes Yes Yes
after_mcp Yes Yes Yes
before_prompt Yes Yes Yes
on_stop Yes Yes No
on_session_start Yes No No
on_session_end Yes No No
after_response No Yes No
after_thought No Yes No
on_permission Yes No No

Hook Types

Command Hooks

Execute shell commands when the event fires:

hook := hooks.NewCommandHook("./my-script.sh")
hook = hook.WithTimeout(30)           // 30 second timeout
hook = hook.WithWorkingDir("/tmp")    // Set working directory
hook = hook.WithShowOutput(true)      // Show output (Windsurf)
Prompt Hooks (Claude-only)

Run AI prompts for validation:

hook := hooks.NewPromptHook("Check if this file write is safe")

Configuration Options

cfg := hooks.NewConfig()

// Disable all hooks
cfg.DisableAllHooks = true

// Only allow managed hooks (enterprise)
cfg.AllowManagedHooksOnly = true

// Filter config for specific tool
claudeCfg := cfg.FilterByTool("claude")

Format Examples

Claude Code
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'before bash'"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "./validate.sh"
          }
        ]
      }
    ]
  }
}
Cursor
{
  "version": 1,
  "hooks": {
    "beforeShellExecution": [
      {
        "command": "echo 'before shell'"
      }
    ],
    "afterFileEdit": [
      {
        "command": "./validate.sh"
      }
    ]
  }
}
Windsurf
{
  "hooks": {
    "pre_run_command": [
      {
        "command": "echo 'before command'",
        "show_output": true
      }
    ],
    "post_write_code": [
      {
        "command": "./validate.sh"
      }
    ]
  }
}

Architecture

hooks/
├── hooks.go          # Package entry point with re-exports
├── core/
│   ├── event.go      # Canonical event types
│   ├── hook.go       # Hook definition
│   ├── config.go     # Configuration type
│   └── adapter.go    # Adapter interface and registry
├── claude/
│   └── adapter.go    # Claude Code adapter
├── cursor/
│   └── adapter.go    # Cursor IDE adapter
└── windsurf/
    └── adapter.go    # Windsurf adapter

Use Cases

Security Gate

Block dangerous commands:

cfg.AddHookWithMatcher(hooks.BeforeCommand, "Bash",
    hooks.NewCommandHook("./security-check.sh"))
Audit Logging

Log all file modifications:

cfg.AddHook(hooks.AfterFileWrite,
    hooks.NewCommandHook("./audit-log.sh"))
Code Quality

Lint before commits:

cfg.AddHook(hooks.BeforeCommand,
    hooks.NewCommandHook("./pre-commit-check.sh"))
Context Injection

Add context before prompts:

cfg.AddHook(hooks.BeforePrompt,
    hooks.NewCommandHook("./inject-context.sh"))

API Reference

See the Go documentation for complete API reference.

Testing

The hooks package has comprehensive test coverage:

Package Tests Coverage
hooks 12 100.0%
hooks/claude 32 89.8%
hooks/core 44 98.7%
hooks/cursor 26 87.1%
hooks/windsurf 29 85.9%
Total 143 92.2%

Run tests:

go test ./hooks/...

Run tests with coverage:

go test -cover ./hooks/...

License

MIT License - see LICENSE for details.

Documentation

Overview

Package hooks provides a unified interface for managing hook configurations across multiple AI coding assistants.

Hooks are automation callbacks that execute at defined stages of the agent loop. They can observe, block, or modify agent behavior.

Supported tools:

  • Claude Code (.claude/settings.json)
  • Cursor IDE (.cursor/hooks.json)
  • Windsurf / Codeium (.windsurf/hooks.json)

The package provides:

  • A canonical Config type that represents hook configuration
  • Adapters for reading/writing tool-specific formats
  • Conversion between different tool formats

Example usage:

// Read Claude hooks config
cfg, err := claude.ReadProjectConfig()
if err != nil {
    log.Fatal(err)
}

// Write to Cursor format
err = cursor.WriteProjectConfig(cfg)

// Or use the adapter registry for dynamic conversion
data, err := hooks.Convert(jsonData, "claude", "cursor")

Index

Constants

View Source
const (
	HookTypeCommand = core.HookTypeCommand
	HookTypePrompt  = core.HookTypePrompt
)

Hook type constants

View Source
const (
	BeforeFileRead  = core.BeforeFileRead
	AfterFileRead   = core.AfterFileRead
	BeforeFileWrite = core.BeforeFileWrite
	AfterFileWrite  = core.AfterFileWrite
)

Event constants - File operations

View Source
const (
	BeforeCommand = core.BeforeCommand
	AfterCommand  = core.AfterCommand
)

Event constants - Command operations

View Source
const (
	BeforeMCP = core.BeforeMCP
	AfterMCP  = core.AfterMCP
)

Event constants - MCP operations

View Source
const (
	BeforePrompt   = core.BeforePrompt
	OnStop         = core.OnStop
	OnSessionStart = core.OnSessionStart
	OnSessionEnd   = core.OnSessionEnd
)

Event constants - Prompt/Lifecycle

View Source
const (
	AfterResponse  = core.AfterResponse  // Cursor
	AfterThought   = core.AfterThought   // Cursor
	OnPermission   = core.OnPermission   // Claude
	OnNotification = core.OnNotification // Claude
	BeforeCompact  = core.BeforeCompact  // Claude
	OnSubagentStop = core.OnSubagentStop // Claude
	BeforeTabRead  = core.BeforeTabRead  // Cursor
	AfterTabEdit   = core.AfterTabEdit   // Cursor
)

Event constants - Tool-specific

Variables

This section is empty.

Functions

func AdapterNames

func AdapterNames() []string

AdapterNames returns the names of all registered adapters.

func Convert

func Convert(data []byte, from, to string) ([]byte, error)

Convert converts configuration data between formats. Example: Convert(data, "claude", "cursor")

func SupportedTools

func SupportedTools() []string

SupportedTools returns a list of tools that support hooks.

Types

type Adapter

type Adapter = core.Adapter

Adapter is the interface for tool-specific adapters.

func GetAdapter

func GetAdapter(name string) (Adapter, bool)

GetAdapter returns an adapter by name from the default registry. Supported names: "claude", "cursor", "windsurf"

type Config

type Config = core.Config

Config is the canonical hooks configuration.

func NewConfig

func NewConfig() *Config

NewConfig creates a new empty configuration.

type Event

type Event = core.Event

Event is a hook event type.

func AllEvents

func AllEvents() []Event

AllEvents returns all defined canonical events.

type Hook

type Hook = core.Hook

Hook is a single hook definition.

func NewCommandHook

func NewCommandHook(command string) Hook

NewCommandHook creates a new command-type hook.

func NewPromptHook

func NewPromptHook(prompt string) Hook

NewPromptHook creates a new prompt-type hook (Claude-specific).

type HookEntry

type HookEntry = core.HookEntry

HookEntry is a collection of hooks with optional matcher.

type HookType

type HookType = core.HookType

HookType is the type of hook execution.

Directories

Path Synopsis
Package claude provides an adapter for Claude Code hooks configuration.
Package claude provides an adapter for Claude Code hooks configuration.
Package core provides the canonical types for hook configuration that can be converted to/from various AI assistant formats.
Package core provides the canonical types for hook configuration that can be converted to/from various AI assistant formats.
Package cursor provides an adapter for Cursor IDE hooks configuration.
Package cursor provides an adapter for Cursor IDE hooks configuration.
Package windsurf provides an adapter for Windsurf (Codeium) hooks configuration.
Package windsurf provides an adapter for Windsurf (Codeium) hooks configuration.

Jump to

Keyboard shortcuts

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