Help us shape the future of Go! Take the 2026 Go Developer Survey

steer

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package steer decides whether an agent's search (grep, glob, shell) should be redirected to the code graph. This file holds pure path-scope helpers.

Index

Constants

View Source
const (
	// DefaultSoftBudget is the balanced-mode deny budget per (session,
	// agent) used when config.SoftBudget is not positive.
	DefaultSoftBudget = 8
	// DefaultLookupBudget bounds the graph lookup of one decision.
	DefaultLookupBudget = 25 * time.Millisecond
	// LookupLimit is the number of graph results quoted in a reason.
	LookupLimit = 12
	// MaxReasonLen caps a deny reason in bytes.
	MaxReasonLen = 1200
	// RepoMapMaxLines caps the repo_map quoted for an exploration.
	RepoMapMaxLines = 40
	// ReadOutlineMinLines is the size above which a whole-file read of a
	// code file gets an outline.
	ReadOutlineMinLines = 400
	// ReadOutlineMaxLines caps that outline.
	ReadOutlineMaxLines = 25
)

Steering limits (PLAN "Steering algoritması").

View Source
const MaxStartContextBytes = 600 * 4

MaxStartContextBytes caps SessionStart / SubagentStart context (600 tokens at ~4 bytes per token).

Variables

This section is empty.

Functions

func AllNonCode

func AllNonCode(paths []string, exts ExtSet) bool

AllNonCode reports whether every target is non-code. An empty target list means the current directory and therefore returns false.

func AllOutsideRoot

func AllOutsideRoot(root, cwd string, targets []string) bool

AllOutsideRoot reports whether every target lies outside root. An empty list means cwd, which is checked instead.

func Decide

Decide is Engine.Decide with a one-shot engine (one hook process).

func IsCodePath

func IsCodePath(path string, exts ExtSet) bool

IsCodePath reports whether path names a file with an enabled code extension. Directories and extensionless names are not code paths.

func OutsideRoot

func OutsideRoot(root, cwd, target string) bool

OutsideRoot reports whether target (relative to cwd unless absolute) lies outside root. It is pure path arithmetic; symlinks are not resolved.

func SessionStartContext

func SessionStartContext(ctx context.Context, ev hookapi.HookEvent, cfg config.Config) string

SessionStartContext is Engine.SessionStartContext with a one-shot engine.

func SubagentStartContext

func SubagentStartContext(ctx context.Context, ev hookapi.HookEvent, cfg config.Config) string

SubagentStartContext is Engine.SubagentStartContext with a one-shot engine.

Types

type Engine

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

Engine makes steering decisions for hook events. It caches opened indexes per repository root; it is safe for concurrent use.

func New

func New(opts Options) *Engine

New returns an Engine.

func (*Engine) Close

func (e *Engine) Close() error

Close closes the indexes the engine opened.

func (*Engine) Decide

func (e *Engine) Decide(ctx context.Context, ev hookapi.HookEvent, cfg config.Config) (d hookapi.Decision)

Decide steers one PreToolUse event (grep, glob, read or shell). Any other event or tool, and every internal error, yields allow.

func (*Engine) SessionStartContext

func (e *Engine) SessionStartContext(ctx context.Context, ev hookapi.HookEvent, cfg config.Config) string

SessionStartContext returns the context injected at session start: index statistics, the MCP tool cheat-sheet, the steering rules of the mode and the top-level repo_map, within MaxStartContextBytes. A missing index is built first (the session start budget allows it). Outside a repository it returns "".

func (*Engine) SubagentStartContext

func (e *Engine) SubagentStartContext(ctx context.Context, ev hookapi.HookEvent, cfg config.Config) string

SubagentStartContext is the subagent variant (Claude's Explore / Plan agents do not read CLAUDE.md). It never builds in the foreground: a missing index is handed to StartBuild and the rules are still returned.

type ExtSet

type ExtSet map[string]struct{}

ExtSet is a set of enabled code file extensions (with leading dot). A nil ExtSet means "every supported language".

func DefaultExtSet

func DefaultExtSet() ExtSet

DefaultExtSet returns the extensions of every supported language.

func NewExtSet

func NewExtSet(langs []model.Lang) ExtSet

NewExtSet builds the extension set for the given languages.

func (ExtSet) Has

func (s ExtSet) Has(ext string) bool

Has reports whether ext (with leading dot) is a code extension. Exact case is tried first so ".C" can differ from ".c"; then a lowercase match.

type GlobClass

type GlobClass struct {
	Kind GlobKind
	// Name is the literal last segment (GlobLiteral only).
	Name string
	// Stem is Name without its extension when the glob has a single literal
	// expansion; empty otherwise.
	Stem string
	// Hint is the longest identifier-like literal fragment of a wildcard
	// file name (GlobExplore only), e.g. "Service" for "*Service*.java".
	Hint string
}

GlobClass is the result of ClassifyGlob.

func ClassifyGlob

func ClassifyGlob(glob string, exts ExtSet) GlobClass

ClassifyGlob decides whether a glob is a literal file lookup, a non-code scan or a broad code exploration. Negated globs ("!x") never widen a search and are reported as GlobNonCode.

func (GlobClass) Allow

func (g GlobClass) Allow() bool

Allow reports whether the glob should pass through without steering.

type GlobKind

type GlobKind int

GlobKind is the steering class of a file-name glob.

const (
	// GlobExplore is a broad, code-scoped scan such as "**/*.ts" or "src/**".
	GlobExplore GlobKind = iota
	// GlobLiteral names a specific file, e.g. "**/user_service.go".
	GlobLiteral
	// GlobNonCode can only match non-code files, e.g. "**/*.md".
	GlobNonCode
)

func (GlobKind) String

func (k GlobKind) String() string

type Index

type Index interface {
	query.Backend
	Freshen(ctx context.Context, budget time.Duration) (*index.Result, error)
}

Index is the code graph the engine consults. *index.Indexer implements it.

type Options

type Options struct {
	// Open opens the index of a located repository. The default is
	// index.Open with the real resolver. Indexes implementing io.Closer are
	// closed by Engine.Close.
	Open func(ctx context.Context, loc *index.Location, cfg *config.Config) (Index, error)
	// StartBuild is the hook point for building a missing index in the
	// background (e.g. spawning a detached `graphmaster index --quiet`).
	// Decisions never build an index themselves. Nil does nothing.
	StartBuild func(root string)
	// LookupBudget bounds the graph lookup (default 25ms).
	LookupBudget time.Duration
	// Now is the session clock (default time.Now).
	Now func() time.Time
	// Logf receives internal errors; steering always fails open.
	Logf func(format string, args ...any)
}

Options configure an Engine. Every field is optional.

type PatternClass

type PatternClass struct {
	// SymbolLike is true when the pattern looks like a lookup of a code
	// symbol (identifier, qualified name, call, keyword-prefixed definition).
	SymbolLike bool
	// Idents are the unique identifier tokens in first-seen order, without
	// definition keywords or a leading '$'. Filled best-effort for
	// non-symbol patterns too.
	Idents []string
	// Queries are the symbol expressions worth looking up, one per
	// alternative / ".*" fragment, e.g. "pkg.Func" or "Foo::bar".
	Queries []string
	// Norm (pnorm) is the sorted unique Idents joined by a space, case kept.
	// Equal norms mean "the same search" for retry detection.
	Norm string
	// Reason explains a non-symbol verdict; empty when SymbolLike.
	Reason string
}

PatternClass is the result of classifying a search pattern.

func ClassifyFixed

func ClassifyFixed(p string) PatternClass

ClassifyFixed classifies a fixed-string pattern (grep -F, rg -F): no anchors, escapes, alternation or ".*" are interpreted.

func ClassifyPattern

func ClassifyPattern(p string) PatternClass

ClassifyPattern classifies a regular-expression search pattern (grep, grep -E, rg, the Grep tool).

func ClassifyPatterns

func ClassifyPatterns(ps []string, fixed bool) PatternClass

ClassifyPatterns classifies several patterns of one search (e.g. multiple -e flags). The set is symbol-like only if every pattern is.

type SearchCall

type SearchCall struct {
	// Tool is the canonical tool name: grep, egrep, fgrep, rg, ag, ack,
	// "git grep", find, fd, ls, tree or locate.
	Tool string
	// Patterns are the literal search patterns (content regexes, or file-name
	// patterns for NameSearch tools). Dynamic ($VAR) patterns are omitted.
	Patterns []string
	// Paths are the explicit or implied (".") targets. Nil when the input is
	// stdin or an unknown file list (xargs, find -exec).
	Paths []string
	// Globs are file filters: --include, -g, -t TYPE, -name, -e EXT, ...
	Globs []string
	// Recursive is true for tree-wide searches (not a single file / stdin).
	Recursive bool
	// ReadsStdin is true when the tool searches its standard input.
	ReadsStdin bool
	// Fixed is true for fixed-string matching (-F, -Q, fgrep).
	Fixed bool
	// NameSearch is true when file names, not contents, are searched.
	NameSearch bool
}

SearchCall is one recognised search command inside a shell command line.

type ShellAnalysis

type ShellAnalysis struct {
	Searches []SearchCall
	// AllReadOnly is true when every command is a known side-effect-free
	// command (search tools, cat, head, sort, sed -n, ...) and no output is
	// redirected to a file.
	AllReadOnly bool
	// UnknownDir is true when a cd/pushd/popd or "git -C" moved a command to
	// a directory that cannot be resolved statically (no argument, ~, -,
	// $VAR). Search scopes are then unknown, so the line is never steered.
	UnknownDir bool
}

ShellAnalysis is the result of AnalyzeShell.

func AnalyzeShell

func AnalyzeShell(cmd string) (ShellAnalysis, error)

AnalyzeShell parses a shell command line and reports the searches it runs. A parse error means the command could not be understood; callers must allow it.

func (ShellAnalysis) Steerable

func (a ShellAnalysis) Steerable() bool

Steerable reports whether the command line should be steered: everything is read-only and at least one search walks a tree reading files.

type TargetKind

type TargetKind int

TargetKind classifies a search target (file, directory or path glob).

const (
	// TargetTree is a directory or anything that may contain code files.
	TargetTree TargetKind = iota
	// TargetCode is a single code file (or a glob limited to code files).
	TargetCode
	// TargetNonCode only covers non-code files (docs, configs, stdin...).
	TargetNonCode
)

func ClassifyTarget

func ClassifyTarget(path string, exts ExtSet) TargetKind

ClassifyTarget classifies a single target path without touching the filesystem. Extensionless names are assumed to be directories.

func (TargetKind) String

func (k TargetKind) String() string

Jump to

Keyboard shortcuts

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