sight

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: MIT Imports: 17 Imported by: 0

README

sight

AI-powered code review on diffs. Parses unified diffs, enriches with surrounding code context and git history, then runs parallel multi-concern reviews through an LLM provider.

Design

  • Library only — no CLI, no binary
  • No LLM SDK dependency — defines a Provider interface; consumers implement it
  • No opinions — consumers inject their own LLM client (e.g., via eyrie)

Install

go get github.com/GrayCodeAI/sight@latest

Usage

One-shot review
result, err := sight.Review(ctx, diffText,
    sight.WithProvider(myProvider),
    sight.Thorough,
)
for _, f := range result.Findings {
    fmt.Printf("[%s] %s:%d - %s\n", f.Severity, f.File, f.Line, f.Message)
}
Reusable reviewer
r := sight.NewReviewer(sight.WithProvider(p), sight.Thorough)
result1, _ := r.Review(ctx, diff1)
result2, _ := r.Review(ctx, diff2)
Provider interface

Implement this with any LLM client:

type Provider interface {
    Complete(ctx context.Context, messages []Message) (string, error)
}

Presets

Preset Concerns Use case
Quick security, correctness Fast PR checks
Standard all (default) Balanced review
Thorough all + deeper analysis Critical code
SecurityFocus security only Security audit
CI all + fail-on threshold CI/CD gates

Findings

Each finding includes:

  • Concern: security, performance, correctness, maintainability, testing
  • Severity: critical, high, medium, low, info
  • File and Line: exact location in diff
  • Message: human-readable description
  • Fix: suggested code fix
  • CWE: reference (e.g., CWE-79)

Output Formats

  • Inline comments (GitHub/GitLab PR comments)
  • SARIF (static analysis interchange)
  • Human-readable terminal output

Configuration

File-based config via .sight.toml:

fail-on = "high"
exclude = ["vendor/", "generated/"]
concerns = ["security", "performance", "correctness"]

Testing

make test        # Unit tests
make test-race   # With race detector
make bench       # Benchmarks
make cover       # Coverage report

License

MIT

Documentation

Overview

Package sight performs AI-powered code review on diffs. It parses unified diffs, enriches them with surrounding code context and git history, then runs parallel multi-concern reviews through an LLM provider.

Sight has no CLI and no LLM SDK dependency — it defines a Provider interface that consumers (hawk) implement using their own LLM client (eyrie).

Usage:

result, err := sight.Review(ctx, diffText, sight.WithProvider(myProvider), sight.Thorough)
for _, f := range result.Findings {
    fmt.Printf("[%s] %s:%d — %s\n", f.Severity, f.File, f.Line, f.Message)
}

For repeated reviews, use the reusable Reviewer:

r := sight.NewReviewer(sight.WithProvider(p), sight.Thorough)
result1, _ := r.Review(ctx, diff1)
result2, _ := r.Review(ctx, diff2)

Index

Constants

View Source
const (
	FilterAdded       = comment.FilterAdded
	FilterDiffContext = comment.FilterDiffContext
	FilterFile        = comment.FilterFile
	FilterNone        = comment.FilterNone
)

Filter mode constants re-exported for public use.

Variables

View Source
var ErrContextCancelled = errors.New("sight: context cancelled")

ErrContextCancelled is returned when the context is cancelled during review.

View Source
var ErrEmptyDiff = errors.New("sight: empty diff; nothing to review")

ErrEmptyDiff is returned when the input diff is empty.

View Source
var ErrNoProvider = errors.New("sight: no provider configured; use WithProvider()")

ErrNoProvider is returned when Review is called without a Provider configured.

Functions

func CustomChecksToConcerns

func CustomChecksToConcerns(checks []CustomCheck) []review.Concern

CustomChecksToConcerns converts loaded custom checks into internal Concern values suitable for the review pipeline. Only enabled checks are included. If languages is non-empty, the concern prompt notes which languages apply.

func EvalSummary

func EvalSummary(results []EvalResult) (passed, failed int, rate float64)

EvalSummary returns pass/fail counts and overall success rate.

func FilterFindings added in v0.2.0

func FilterFindings(ctx context.Context, provider Provider, findings []Finding,
	fileContents map[string]string, config FilterConfig) ([]Finding, []FilterResult, error)

func LoadProjectRules

func LoadProjectRules(dir string) string

LoadProjectRules scans a directory for project-specific coding rules and standards. It looks for:

  • .cursor/rules/*.md
  • CLAUDE.md
  • CONTRIBUTING.md
  • .sight/rules/*.md

Found rules are concatenated with section headers and returned as a single string suitable for injection into an LLM system prompt. Returns an empty string if no rule files are found.

Types

type ChatOpts

type ChatOpts struct {
	Model       string  `json:"model,omitempty"`
	MaxTokens   int     `json:"max_tokens,omitempty"`
	Temperature float64 `json:"temperature,omitempty"`
	System      string  `json:"system,omitempty"`
}

ChatOpts controls the LLM request.

type ConcernSpec added in v0.2.0

type ConcernSpec struct {
	Type          ConcernType
	SystemPrompt  string
	Enabled       bool
	MinConfidence float64
}

func DefaultConcerns added in v0.2.0

func DefaultConcerns() []ConcernSpec

func RouteConcerns added in v0.2.0

func RouteConcerns(diff string, allConcerns []ConcernSpec) []ConcernSpec

type ConcernType added in v0.2.0

type ConcernType string
const (
	ConcernSecurity        ConcernType = "security"
	ConcernCorrectness     ConcernType = "correctness"
	ConcernPerformance     ConcernType = "performance"
	ConcernMaintainability ConcernType = "maintainability"
	ConcernStyle           ConcernType = "style"
	ConcernTestCoverage    ConcernType = "test_coverage"
)

type CustomCheck

type CustomCheck struct {
	// Name is derived from the filename (e.g., "no-console-log" from no-console-log.md).
	Name string

	// Prompt is the markdown body that describes the check rules and gets
	// injected into the LLM system prompt.
	Prompt string

	// Severity is the default severity for findings from this check.
	// Parsed from YAML frontmatter; defaults to "medium".
	Severity string

	// Languages restricts the check to files matching these extensions
	// (e.g., ["go", "py"]). Empty means all languages.
	Languages []string

	// Enabled controls whether the check is active. Defaults to true.
	Enabled bool
}

CustomCheck represents a user-defined review check loaded from a markdown file in the .sight/checks/ directory. Each file becomes a check whose content is injected into the LLM prompt as an additional concern.

func LoadChecks

func LoadChecks(dir string) ([]CustomCheck, error)

LoadChecks reads all markdown files from the given directory (typically ".sight/checks/") and parses them into CustomCheck values. Each .md file becomes one check. YAML frontmatter between --- delimiters is parsed for metadata (severity, languages, enabled); the remaining body becomes the check prompt.

Returns an empty slice (not an error) if the directory does not exist.

func LoadChecksFromRepo

func LoadChecksFromRepo(repoDir string) ([]CustomCheck, error)

LoadChecksFromRepo is a convenience that looks for .sight/checks/ relative to the given repository root directory.

type Description

type Description struct {
	Title      string   `json:"title"`
	Summary    string   `json:"summary"`
	Changes    []string `json:"changes"`
	ChangeType string   `json:"change_type"`
	Risk       string   `json:"risk"`
	TestPlan   string   `json:"test_plan"`
}

Description is the generated PR summary.

func Describe

func Describe(ctx context.Context, rawDiff string, opts ...Option) (*Description, error)

Describe generates a PR description from a diff using the configured LLM.

type EvalCase

type EvalCase struct {
	Name           string            `json:"name"`
	Diff           string            `json:"diff"`
	ExpectFindings []EvalExpectation `json:"expect_findings"`
	DenyFindings   []EvalDenial      `json:"deny_findings"`
}

EvalCase defines a single test case for evaluating review quality.

type EvalDenial

type EvalDenial struct {
	MessageContains string `json:"message_contains,omitempty"`
	Concern         string `json:"concern,omitempty"`
}

EvalDenial defines what the reviewer should NOT report (false positive check).

type EvalExpectation

type EvalExpectation struct {
	Concern         string `json:"concern,omitempty"`
	MinSeverity     string `json:"min_severity,omitempty"`
	MessageContains string `json:"message_contains,omitempty"`
	File            string `json:"file,omitempty"`
}

EvalExpectation defines what we expect the reviewer to find.

type EvalResult

type EvalResult struct {
	Case     string    `json:"case"`
	Passed   bool      `json:"passed"`
	Failures []string  `json:"failures,omitempty"`
	Findings []Finding `json:"findings"`
}

EvalResult is the outcome of running one eval case.

func RunEval

func RunEval(ctx context.Context, suite *EvalSuite, opts ...Option) ([]EvalResult, error)

RunEval executes an evaluation suite against the reviewer with the given options. For each case it runs Review() on the diff, then checks expectations and denials.

type EvalSuite

type EvalSuite struct {
	Cases []EvalCase `json:"cases"`
}

EvalSuite is a collection of eval cases.

func LoadEvalSuite

func LoadEvalSuite(path string) (*EvalSuite, error)

LoadEvalSuite loads eval cases from a JSON file.

func ParseEvalSuite

func ParseEvalSuite(data []byte) (*EvalSuite, error)

ParseEvalSuite parses eval cases from JSON bytes.

type FileChange

type FileChange struct {
	Path    string
	OldPath string
	Diff    string
	Content string
}

FileChange represents a single file's changes for review.

type FileConfig

type FileConfig struct {
	Model      string            `json:"model"`
	Concerns   []string          `json:"concerns"`
	FailOn     string            `json:"fail_on"`
	MaxTokens  int               `json:"max_tokens"`
	Exclude    []string          `json:"exclude"`
	GitContext *bool             `json:"git_context"`
	Reflection *bool             `json:"reflection"`
	Parallel   *bool             `json:"parallel"`
	Prompts    map[string]string `json:"prompts"`
}

FileConfig represents the contents of a .sight.toml configuration file.

func LoadConfigFile

func LoadConfigFile(dir string) (*FileConfig, error)

LoadConfigFile reads .sight.toml from the given directory (or parents). Returns nil if no config file is found. Errors only on malformed files.

type FilterConfig added in v0.2.0

type FilterConfig struct {
	MinSeverity         Severity
	ConfidenceThreshold float64
	MaxParallel         int
	BatchSize           int
}

func DefaultFilterConfig added in v0.2.0

func DefaultFilterConfig() FilterConfig

type FilterMode

type FilterMode = comment.FilterMode

FilterMode re-exports the comment package's FilterMode for public use. It controls which lines are eligible for inline comment placement.

type FilterResult added in v0.2.0

type FilterResult struct {
	Finding    Finding
	Confirmed  bool
	Confidence float64
	Reasoning  string
}

type Finding

type Finding struct {
	Concern   string   `json:"concern"`
	Severity  Severity `json:"severity"`
	File      string   `json:"file"`
	Line      int      `json:"line"`
	EndLine   int      `json:"end_line,omitempty"`
	Message   string   `json:"message"`
	Fix       string   `json:"fix,omitempty"`
	Reasoning string   `json:"reasoning,omitempty"`
	CWE       string   `json:"cwe,omitempty"`
}

Finding represents a single issue detected during review.

type ImproveResult

type ImproveResult struct {
	Improvements []Improvement `json:"improvements"`
	TokensUsed   int           `json:"tokens_used"`
}

ImproveResult is the output of an Improve operation.

func Improve

func Improve(ctx context.Context, rawDiff string, opts ...Option) (*ImproveResult, error)

Improve analyzes a diff and suggests code improvements — better naming, cleaner patterns, performance wins, idiomatic rewrites. Unlike Review(), Improve() focuses on making good code better, not finding bugs.

type Improvement

type Improvement struct {
	File        string `json:"file"`
	Line        int    `json:"line"`
	EndLine     int    `json:"end_line,omitempty"`
	Category    string `json:"category"`
	Description string `json:"description"`
	Before      string `json:"before"`
	After       string `json:"after"`
	Reasoning   string `json:"reasoning"`
}

Improvement represents a suggested code improvement.

type IncrementalState

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

IncrementalState tracks the last-reviewed commit SHA for incremental reviews. It is safe for concurrent use.

func NewIncrementalState

func NewIncrementalState(lastSHA string) *IncrementalState

NewIncrementalState creates a new state tracker, optionally seeded with a previously reviewed SHA for resumption.

func (*IncrementalState) LastReviewedSHA

func (s *IncrementalState) LastReviewedSHA() string

LastReviewedSHA returns the SHA of the last reviewed commit.

func (*IncrementalState) SetLastReviewedSHA

func (s *IncrementalState) SetLastReviewedSHA(sha string)

SetLastReviewedSHA updates the last-reviewed SHA after a successful review.

type InlineComment

type InlineComment struct {
	Path       string `json:"path"`
	StartLine  int    `json:"start_line"`
	EndLine    int    `json:"end_line,omitempty"`
	Body       string `json:"body"`
	Suggestion string `json:"suggestion,omitempty"`
}

InlineComment is a finding mapped to an exact position in a diff, ready for posting as a review comment.

type Message

type Message struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

Message represents a single message in a conversation.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option configures a review operation.

var CI Option = optFunc(func(c *config) {
	c.concerns = []string{"security", "bugs", "performance", "correctness"}
	c.contextLines = 10
	c.parallel = true
	c.failOn = SeverityHigh
})

CI configures for continuous integration: thorough, fail on high.

var Quick Option = optFunc(func(c *config) {
	c.concerns = []string{"security", "bugs"}
	c.contextLines = 5
	c.parallel = false
	c.gitContext = false
})

Quick performs a fast single-pass review focusing on bugs and security only.

var SecurityFocus Option = optFunc(func(c *config) {
	c.concerns = []string{"security"}
	c.contextLines = 20
	c.maxTokens = 8192
	c.gitContext = true
})

SecurityFocus limits review to security concerns with deeper analysis.

var Thorough Option = optFunc(func(c *config) {
	c.concerns = []string{"security", "bugs", "performance", "correctness", "style"}
	c.contextLines = 15
	c.parallel = true
	c.gitContext = true
	c.symbols = true
})

Thorough performs a comprehensive multi-concern parallel review.

func ApplyFileConfig

func ApplyFileConfig(fc *FileConfig) []Option

ApplyFileConfig converts a FileConfig into Options.

func WithConcerns

func WithConcerns(concerns ...string) Option

func WithContextLines

func WithContextLines(n int) Option

func WithCustomChecks

func WithCustomChecks(dir string) Option

WithCustomChecks loads checks from the given directory and appends them as additional concerns to the review. This is the primary integration point:

sight.Review(ctx, diff, sight.WithCustomChecks(".sight/checks"))

func WithCustomChecksFromRepo

func WithCustomChecksFromRepo(repoDir string) Option

WithCustomChecksFromRepo loads checks from .sight/checks/ within the repo root.

func WithExclude

func WithExclude(patterns ...string) Option

WithExclude sets file path patterns to exclude from review. Patterns support exact basenames ("go.sum") and glob wildcards ("*.min.js", "*.generated.*").

func WithFailOn

func WithFailOn(sev Severity) Option

func WithFilterMode

func WithFilterMode(mode FilterMode) Option

WithFilterMode sets the diff filter mode that controls which findings are included as inline comments. See FilterAdded, FilterDiffContext, FilterFile, and FilterNone.

func WithGitContext

func WithGitContext(enabled bool) Option

func WithMaxTokens

func WithMaxTokens(n int) Option

func WithMinScore

func WithMinScore(n int) Option

WithMinScore sets the minimum reflection score threshold (1-10). Findings scoring below this are filtered out during the reflection pass.

func WithModel

func WithModel(model string) Option

func WithParallel

func WithParallel(enabled bool) Option

func WithProjectRules

func WithProjectRules(rules string) Option

WithProjectRules injects project-specific rules into the LLM system prompt.

func WithProvider

func WithProvider(p Provider) Option

func WithReflection

func WithReflection(enabled bool) Option

func WithSymbols

func WithSymbols(enabled bool) Option

type PRSource

type PRSource struct {
	Owner  string
	Repo   string
	Number int
}

PRSource identifies a pull request to review.

type Provider

type Provider interface {
	Chat(ctx context.Context, messages []Message, opts ChatOpts) (*Response, error)
}

Provider is the LLM interface that consumers inject. This decouples sight from any specific LLM SDK. Hawk implements this using eyrie; tests use a mock.

type Response

type Response struct {
	Content    string `json:"content"`
	TokensUsed int    `json:"tokens_used"`
}

Response holds the LLM reply.

type Result

type Result struct {
	Findings []Finding       `json:"findings"`
	Comments []InlineComment `json:"comments"`
	Stats    Stats           `json:"stats"`
	Report   string          `json:"report"`
	FailOn   Severity        `json:"fail_on"`
}

Result is the complete output of a review operation.

func Review

func Review(ctx context.Context, diff string, opts ...Option) (*Result, error)

Review performs a one-shot review on a unified diff string.

func ReviewIncremental

func ReviewIncremental(ctx context.Context, base, head string, state *IncrementalState, opts ...Option) (*Result, error)

ReviewIncremental reviews only the changes between base and head commits. It uses `git diff base...head` to obtain the diff, reviews it, and records the head SHA in the provided state for future incremental runs.

If state is non-nil and has a LastReviewedSHA, that SHA is used as the base instead of the provided base argument (enabling resumption).

Pass nil for state if you don't need resumption tracking.

func (*Result) Failed

func (r *Result) Failed() bool

Failed returns true if any finding meets or exceeds the configured fail threshold.

func (*Result) MaxSeverity

func (r *Result) MaxSeverity() Severity

MaxSeverity returns the highest severity found.

type Reviewer

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

Reviewer is a reusable code reviewer. Create one with NewReviewer and call Review multiple times. It is safe for concurrent use.

func NewReviewer

func NewReviewer(opts ...Option) *Reviewer

NewReviewer creates a configured Reviewer.

func (*Reviewer) Review

func (r *Reviewer) Review(ctx context.Context, rawDiff string) (*Result, error)

Review parses the diff, builds context, and runs multi-concern analysis.

func (*Reviewer) ReviewFiles

func (r *Reviewer) ReviewFiles(ctx context.Context, files []FileChange) (*Result, error)

ReviewFiles reviews a set of file changes with explicit content.

type Severity

type Severity int

Severity represents the impact level of a review finding.

const (
	SeverityInfo Severity = iota
	SeverityLow
	SeverityMedium
	SeverityHigh
	SeverityCritical
)

func ParseSeverity

func ParseSeverity(s string) Severity

ParseSeverity converts a string to a Severity.

func (Severity) AtLeast

func (s Severity) AtLeast(threshold Severity) bool

AtLeast returns true if s >= threshold.

func (Severity) String

func (s Severity) String() string

type Stats

type Stats struct {
	FilesReviewed      int                      `json:"files_reviewed"`
	HunksAnalyzed      int                      `json:"hunks_analyzed"`
	FindingsTotal      int                      `json:"findings_total"`
	BySeverity         map[Severity]int         `json:"by_severity"`
	ByConcern          map[string]int           `json:"by_concern"`
	TokensUsed         int                      `json:"tokens_used"`
	DurationPerConcern map[string]time.Duration `json:"duration_per_concern"`
}

Stats provides review metrics.

Directories

Path Synopsis
internal
comment
Package comment maps review findings to inline diff positions.
Package comment maps review findings to inline diff positions.
context
Package context provides git and code context enrichment for diffs.
Package context provides git and code context enrichment for diffs.
diff
Package diff parses unified diffs into structured representations.
Package diff parses unified diffs into structured representations.
output
Package output formats review results for terminal and machine consumption.
Package output formats review results for terminal and machine consumption.
review
Package review implements the multi-concern LLM review pipeline.
Package review implements the multi-concern LLM review pipeline.

Jump to

Keyboard shortcuts

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