hookserver

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package hookserver provides a tiny localhost HTTP server that receives PreToolUse hook calls from the claude CLI and exposes them as a channel of HookEvents. Each event blocks the HTTP request until the caller sends a HookResponse through the event's ResponseCh, allowing the TUI to approve or deny tool invocations interactively.

Usage:

srv, err := hookserver.New()
if err != nil { ... }
go srv.Start(ctx)
fmt.Printf("hook server listening on port %d\n", srv.Port())

for evt := range srv.Events() {
    // inspect evt, then:
    evt.ResponseCh <- hookserver.HookResponse{Allow: true}
    // OR close(evt.ResponseCh) to allow (same as Allow:true)
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HookEvent

type HookEvent struct {
	// Type is the hook type string, e.g. "PreToolUse".
	Type string

	// Tool is the tool name, e.g. "Bash", "Edit", "Read".
	Tool string

	// Args holds the tool arguments as decoded from the request JSON.
	Args map[string]any

	// Cwd is the working directory context for the tool call (may be empty).
	Cwd string

	// Timestamp is when the event was received.
	Timestamp time.Time

	// ResponseCh is written to exactly once by the consumer to reply.
	// Sending a HookResponse with Allow=false and a non-empty Reason
	// causes the HTTP response to deny the tool call. Sending Allow=true
	// (or closing the channel) approves it. The server drains the channel
	// regardless so callers must not leave it un-answered — they'll block
	// the corresponding HTTP request indefinitely otherwise.
	ResponseCh chan HookResponse
}

HookEvent represents a single PreToolUse hook invocation from the claude CLI. The HTTP request that delivered this event is blocked until ResponseCh receives a value or is closed.

type HookResponse

type HookResponse struct {
	// Allow indicates whether the tool call should proceed.
	// When false the server returns an HTTP 200 with a JSON deny payload.
	Allow bool

	// Reason is an optional human-readable string included in the deny response.
	// Ignored when Allow is true.
	Reason string
}

HookResponse is the reply the consumer sends back through HookEvent.ResponseCh.

type Server

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

Server is the localhost HTTP hook server. Construct with New; start with Start.

func New

func New() (*Server, error)

New creates a new Server bound to 127.0.0.1:0 (OS-assigned free port) with a fresh per-process auth token. Returns an error if the listener cannot be opened or the random token cannot be generated.

func (*Server) Events

func (s *Server) Events() <-chan HookEvent

Events returns the read-only channel on which incoming HookEvents arrive. Consumers must drain this channel and reply via each event's ResponseCh, otherwise the corresponding HTTP request (and the claude CLI) will block.

func (*Server) Port

func (s *Server) Port() int

Port returns the port the server is bound to. Only valid after New() succeeds.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start begins serving requests. It blocks until ctx is canceled, at which point it performs a graceful shutdown and closes the events channel. Start is safe to call in a goroutine. It must only be called once.

func (*Server) Token

func (s *Server) Token() string

Token returns the per-process auth token clients must present to post hook events. Tells the user how to wire the URL into Claude Code's hook config; never include this in any persistent log.

func (*Server) URL

func (s *Server) URL() string

URL returns the full callback URL (including the auth token) that Claude Code's hook config should point at.

Jump to

Keyboard shortcuts

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