sessiongate

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package sessiongate holds the session gates the agent harness installs into every session it runs: structural checks Claude Code calls as hooks around a tool call. The wait gate rejects a Bash command that would wait on nothing (a shell poll loop, pgrep -f, a foreground sleep) and names the replacement; the ready gate runs tools/check-merge.sh in the worktree before a command marks a pull request ready and denies it on any consistency regression; the commit gate pushes the work branch after a git commit and opens its draft pull request, on the repository it pushed to, if none exists. Every decision is written to the run's event log under the run's trace.

A gate is a library. The binary Claude Code calls reads the hook's input, grants the process capability and writes the returned output.

Index

Constants

View Source
const (
	GateWait   = "wait"
	GateReady  = "ready"
	GateCommit = "commit"

	DecisionAllow     = "allow"
	DecisionDeny      = "deny"
	DecisionSkip      = "skip"
	DecisionMalformed = "malformed"
	DecisionOpened    = "opened"
	DecisionExists    = "exists"
	DecisionFailed    = "failed"
)

The gates and their decisions, as the event log records them.

Variables

View Source
var (
	// ErrInvalidOption reports a nil option or an option value the gate
	// cannot use.
	ErrInvalidOption = errors.New("session gate: invalid option")
	// ErrNoLauncher reports a gate built without the process capability.
	ErrNoLauncher = errors.New("session gate: a process launcher is required")
	// ErrNoRunDirectory reports a gate built without its run directory.
	ErrNoRunDirectory = errors.New("session gate: a run directory is required")
	// ErrMalformedHookInput reports hook input that is not the JSON object
	// Claude Code sends.
	ErrMalformedHookInput = errors.New("session gate: malformed hook input")
	// ErrUnknownEvent reports a hook event the harness installs no gate on.
	ErrUnknownEvent = errors.New("session gate: no gate for this hook event")
	// ErrPush reports a work branch git could not push.
	ErrPush = errors.New("session gate: could not push the work branch")
	// ErrPullRequest reports a draft pull request gh could not find or open.
	ErrPullRequest = errors.New("session gate: could not open the draft pull request")
)
View Source
var ErrUnparsedCommand = errors.New("session gate: command is not valid shell")

ErrUnparsedCommand reports a command the shell parser could not read.

Functions

func RunsGitCommit

func RunsGitCommit(command string) (bool, error)

RunsGitCommit reports whether command runs git commit anywhere in it, including inside sh -c. Whether the commit succeeded is for git to say.

func RunsPullRequestReady

func RunsPullRequestReady(command string) (bool, error)

RunsPullRequestReady reports whether command marks a pull request ready for review (gh pr ready, not gh pr ready --undo) anywhere in it, including inside sh -c.

Types

type HookInput

type HookInput struct {
	SessionID     string `json:"session_id"`
	HookEventName string `json:"hook_event_name"`
	ToolName      string `json:"tool_name"`
	ToolUseID     string `json:"tool_use_id"`
	ToolInput     struct {
		Command         string `json:"command"`
		RunInBackground bool   `json:"run_in_background"`
	} `json:"tool_input"`
}

HookInput is the part of a command hook's standard input the gates read.

type HookOutput

type HookOutput struct {
	HookSpecificOutput *HookSpecificOutput `json:"hookSpecificOutput,omitempty"`
}

HookOutput is a command hook's standard output.

type HookSpecificOutput

type HookSpecificOutput struct {
	HookEventName            string `json:"hookEventName"`
	PermissionDecision       string `json:"permissionDecision,omitempty"`
	PermissionDecisionReason string `json:"permissionDecisionReason,omitempty"`
	AdditionalContext        string `json:"additionalContext,omitempty"`
}

HookSpecificOutput is the event-specific decision Claude Code reads.

type Rule

type Rule string

Rule names a shell shape the wait gate rejects.

const (
	// RulePollLoop is a while, until or for loop whose body or condition
	// sleeps: a hand-rolled poll.
	RulePollLoop Rule = "poll_loop"
	// RuleSelfMatchingPgrep is pgrep -f (or --full): its pattern is matched
	// against whole command lines, including the shell that runs it.
	RuleSelfMatchingPgrep Rule = "pgrep_full"
	// RuleForegroundSleep is a sleep the turn waits for.
	RuleForegroundSleep Rule = "foreground_sleep"
)

The rules of the wait gate. Each is a way an agent waits that cannot end on its own: nothing joins a poll loop, a pgrep -f pattern matches the loop's own command line, and a foreground sleep holds the turn while waiting on nothing.

type SessionGate

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

SessionGate answers the gated hooks of one run.

func NewSessionGate

func NewSessionGate(options ...SessionGateOption) (*SessionGate, error)

NewSessionGate validates the whole option set before building the gate.

func (*SessionGate) Handle

func (gate *SessionGate) Handle(ctx context.Context, event string, input []byte) (*HookOutput, error)

Handle answers one hook call: event is the hook event the harness installed the call on and input is the hook's standard input. A nil output means the call proceeds without a word from the gate. A gate that could not finish its work returns both the output telling the agent and the error.

type SessionGateOption

type SessionGateOption func(gate *SessionGate) error

SessionGateOption configures a SessionGate.

func WithLauncher

func WithLauncher(launcher proc.ILauncher) SessionGateOption

WithLauncher grants the process capability git and gh start through. Required.

func WithRunDirectory

func WithRunDirectory(directory string) SessionGateOption

WithRunDirectory names the run the gate answers for: the directory the harness recorded it in. Required.

type ShellFinding

type ShellFinding struct {
	Rule Rule
	// Snippet is the offending source text.
	Snippet string
}

ShellFinding is one rejected shape in a command.

func FindShellWaits

func FindShellWaits(command string) ([]ShellFinding, error)

FindShellWaits parses command as bash and returns every shape the wait gate rejects, in source order. A literal script handed to sh -c or bash -c is parsed and checked the same way. Heredoc bodies and quoted text are data, not commands, and never match.

func (ShellFinding) Message

func (finding ShellFinding) Message() string

Message is the rejection text the agent reads.

func (ShellFinding) Replacement

func (finding ShellFinding) Replacement() string

Replacement is what to do instead, as the rejection message states it.

Jump to

Keyboard shortcuts

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