hook

package
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package hook brokers backend interactions through usher's web UI. Claude's stdio permission callback, Codex app-server approvals, and the command hook used for AskUserQuestion all submit here and wait for a UI response.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Event

type Event struct {
	SessionID   string
	ToolUseID   string
	Event       string
	ToolName    string
	ToolInput   json.RawMessage
	Cwd         string
	AllowAlways bool
}

Event is the input usher receives from `usher hook` and forwards to Submit.

type Manager

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

Manager owns pending interactions and the per-session blanket auto-approve flag. Auto-approve is persisted to disk so the trust boundary survives restarts.

func New

func New(autoPath string) *Manager

New constructs a Manager. autoPath is the file backing the auto-approve flag map; pass "" to disable persistence (e.g. in tests). If the file exists at construction time, its state is loaded; subsequent calls to SetAutoApprove rewrite it atomically.

func (*Manager) IsAutoApprove

func (m *Manager) IsAutoApprove(sessionID string) bool

IsAutoApprove reports whether sessionID is currently in blanket-allow mode.

func (*Manager) List

func (m *Manager) List() []Pending

List returns a snapshot of all currently-pending interactions.

func (*Manager) QuickDecide

func (m *Manager) QuickDecide(ev Event) (Response, bool)

QuickDecide settles ev from blanket auto-approve without UI; returns (zero, false) when input is needed.

func (*Manager) Respond

func (m *Manager) Respond(id string, r Response) error

Respond delivers the user's decision to the matching pending interaction. Returns an error if the ID is unknown or the entry has already been resolved.

func (*Manager) SetAutoApprove

func (m *Manager) SetAutoApprove(sessionID string, enabled bool)

SetAutoApprove flips the blanket "allow every tool call" flag for a session and persists the change to disk so it survives restarts.

func (*Manager) Submit

func (m *Manager) Submit(ctx context.Context, ev Event) (Response, error)

Submit blocks until the user responds via Respond or ctx is cancelled. Short-circuits via QuickDecide first.

func (*Manager) SubscribePending added in v0.4.0

func (m *Manager) SubscribePending() (<-chan Pending, func())

SubscribePending returns a buffered channel that receives each new pending interaction as it is submitted, plus a cancel function. The web UI polls List() instead; this push path lets the web-push dispatcher surface permission prompts as notifications without polling. Drop-on-full, so a slow consumer never blocks Submit.

type Pending

type Pending struct {
	ID        string          `json:"id"`
	SessionID string          `json:"session_id"`
	Event     string          `json:"event"`
	ToolName  string          `json:"tool_name,omitempty"`
	ToolInput json.RawMessage `json:"tool_input,omitempty"`
	Cwd       string          `json:"cwd,omitempty"`
	// AllowAlways is true only when the originating backend advertised a
	// native rule or repeated-approval decision for this request.
	AllowAlways bool      `json:"allow_always"`
	CreatedAt   time.Time `json:"created_at"`
}

Pending describes a permission request waiting for a user decision.

type Response

type Response struct {
	Behavior string `json:"behavior"` // allow | deny
	Reason   string `json:"reason,omitempty"`
	// Scope is "once" (default) or "session". "session" is the historical API
	// spelling for the UI's "always" choice; the backend owns its exact scope.
	Scope string `json:"scope,omitempty"`
	// Answers resolves an AskUserQuestion tool call: each entry maps a
	// question (verbatim from the tool input) to the option label the user
	// chose in the web UI. When set, the server merges it into the tool's
	// updatedInput so claude proceeds with the answer instead of blocking on
	// the pane TUI selector. Behavior is "allow" in this case.
	Answers map[string]string `json:"answers,omitempty"`
}

Response is the user's decision on a pending interaction.

Jump to

Keyboard shortcuts

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