sight

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 28 Imported by: 0

README

Sight

AI-powered code review for diffs

Go License CI


Sight provides intelligent code review capabilities by analyzing diffs with AI. It understands context, identifies issues, and suggests improvements.

Ecosystem Boundaries

Sight is a Hawk support engine. Keep the dependency edge one-way:

  • use hawk-core-contracts for any cross-repo shared contracts (severity/finding vocabulary)
  • do not import hawk/internal/*
  • do not import removed legacy path hawk/shared/types; use hawk-core-contracts/types
  • do not import other engines (eyrie, yaad, tok, trace, inspect) — engines are peers, not dependencies

Features

  • Diff-aware analysis - Reviews only changed code with full context
  • Severity classification - Categorizes findings by impact
  • Provider agnostic - Works with any LLM provider through the Provider interface
  • Extensible rules - Add custom review rules for your codebase

Quick Start

go get github.com/GrayCodeAI/sight
import "github.com/GrayCodeAI/sight"

reviewer := sight.NewReviewer(
    sight.WithProvider(myLLMProvider),
    sight.Thorough,
)

result, err := reviewer.Review(ctx, diff)
for _, f := range result.Findings {
    fmt.Printf("[%s] %s:%d - %s\n", f.Severity, f.File, f.Line, f.Message)
}

Examples

See the examples/ directory for runnable code samples.

Provider Interface

Implement the Provider interface to use any LLM:

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

Installation

go get github.com/GrayCodeAI/sight@latest

Requires Go 1.26+.

Contributing

Contributions are welcome — please read CONTRIBUTING.md before opening a pull request.

License

MIT - see LICENSE for details.

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)

Package sight version metadata.

The Version variable is sourced at compile time from the VERSION file at the repo root, which is the single source of truth used by release tooling (release-please, goreleaser), and CI.

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.

View Source
var ParseSeverity = types.ParseSeverity

ParseSeverity converts a string to a Severity.

View Source
var Version = strings.TrimSpace(versionFile)

Version of the sight library. Do not edit this variable directly — bump the VERSION file at the repo root instead.

Functions

func BuildFusedPrompt added in v0.1.1

func BuildFusedPrompt(basePrompt string, sastFindings []Finding) string

BuildFusedPrompt injects SAST findings into the base review prompt. The SAST section is placed before the diff content so the LLM can factor the pre-analysis results into its review from the start.

func CalculateLLMConfidence added in v0.1.1

func CalculateLLMConfidence(responseJSON string, finding Finding) float64

CalculateLLMConfidence computes a confidence score for a finding produced by the LLM review pipeline.

It parses the raw LLM response JSON for an explicit "confidence" field. If the LLM provided a confidence value (0.0-1.0) for this finding, it is used directly. Otherwise the default of 0.6 is returned.

func CalculateStaticConfidence added in v0.1.1

func CalculateStaticConfidence(finding Finding, rule StaticRule) float64

CalculateStaticConfidence computes a confidence score for a finding produced by a static analysis rule.

Base:

  • 0.7 for pattern matches (default)
  • 0.9 for exact matches (when the rule pattern is a simple string literal)

Boosts (applied on top of base):

  • +0.1 if the rule's antipattern is absent (i.e., the antipattern was not triggered, meaning the finding survived the false-positive filter)
  • +0.1 if the finding's message contains confirming context keywords

Penalties:

  • -0.2 if the rule ID belongs to a known false-positive-prone set (e.g., COR-GO-001 unchecked error, COR-GO-002 goroutine leak)

The result is clamped to [0.0, 1.0].

func CalculateTaintConfidence added in v0.1.1

func CalculateTaintConfidence(source, sink string, sanitizers []string) float64

CalculateTaintConfidence computes a confidence score for a finding produced by taint analysis.

Base: 0.8 for direct taint (source -> sink with no intermediaries).

Degrade:

  • -0.1 per sanitizer present in the taint path
  • -0.2 per intermediate variable between source and sink

The result is clamped to [0.0, 1.0].

func ComputeConfidenceStats added in v0.1.1

func ComputeConfidenceStats(findings []Finding) (avg float64, highCount, lowCount int)

ComputeConfidenceStats calculates aggregate confidence statistics from a slice of findings.

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 DetectLanguage added in v0.1.1

func DetectLanguage(path string) string

DetectLanguage guesses the language from a file path extension.

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.1.1

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

func GenerateSARIF added in v0.1.1

func GenerateSARIF(findings []Finding, version string) string

GenerateSARIF produces a SARIF 2.1.0 JSON report from sight findings.

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.

func SecurityConcerns added in v0.1.1

func SecurityConcerns() []string

SecurityConcerns returns security-focused review concerns.

func ToContractFinding added in v0.1.1

func ToContractFinding(f Finding) reviewcontracts.Finding

ToContractFinding converts a sight finding into the shared review contract.

func ToContractFindings added in v0.1.1

func ToContractFindings(findings []Finding) []reviewcontracts.Finding

ToContractFindings converts sight findings into shared review contracts.

func ToContractInlineComment added in v0.1.1

func ToContractInlineComment(c InlineComment) reviewcontracts.InlineComment

ToContractInlineComment converts a sight inline comment into the shared review contract.

func ToContractInlineComments added in v0.1.1

func ToContractInlineComments(comments []InlineComment) []reviewcontracts.InlineComment

ToContractInlineComments converts sight inline comments into shared review contracts.

func ToContractResult added in v0.1.1

func ToContractResult(r *Result) *reviewcontracts.Result

ToContractResult converts a sight result into the shared review contract.

Types

type AutoFix added in v0.1.1

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

AutoFix generates fix suggestions for findings. Instead of just reporting problems, suggests concrete code changes.

func NewAutoFix added in v0.1.1

func NewAutoFix(provider Provider) *AutoFix

NewAutoFix creates an auto-fixer using the given LLM provider.

func (*AutoFix) SuggestFixes added in v0.1.1

func (af *AutoFix) SuggestFixes(ctx context.Context, findings []Finding, diff string) ([]FixSuggestion, error)

SuggestFixes generates fix suggestions for a set of findings.

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.1.1

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

func DefaultConcerns added in v0.1.1

func DefaultConcerns() []ConcernSpec

func RouteConcerns added in v0.1.1

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

type ConcernType added in v0.1.1

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

type ConfidenceBreakdown added in v0.1.1

type ConfidenceBreakdown struct {
	// High are findings with confidence >= 0.7.
	High []Finding `json:"high"`
	// Medium are findings with 0.5 <= confidence < 0.7.
	Medium []Finding `json:"medium"`
	// Low are findings with confidence < 0.5.
	Low []Finding `json:"low"`
}

ConfidenceBreakdown groups findings into bands for quick triage.

func BuildConfidenceBreakdown added in v0.1.1

func BuildConfidenceBreakdown(findings []Finding) *ConfidenceBreakdown

BuildConfidenceBreakdown groups findings into confidence bands.

type Convention added in v0.1.1

type Convention struct {
	Name        string
	Description string
	Pattern     string // regex pattern that indicates violation
	FilePattern string // only check files matching this glob
	Severity    Severity
	// contains filtered or unexported fields
}

Convention is a coding rule to enforce during review.

func ConventionsFromStrings added in v0.1.1

func ConventionsFromStrings(rules []string) []Convention

FromStrings creates conventions from simple string rules (e.g., from yaad memories).

type ConventionChecker added in v0.1.1

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

ConventionChecker validates diffs against a set of project conventions. Integrates with yaad: load conventions from yaad's memory graph and check if the diff violates any of them.

func NewConventionChecker added in v0.1.1

func NewConventionChecker(conventions []Convention) *ConventionChecker

NewConventionChecker creates a checker with the given conventions.

func (*ConventionChecker) Check added in v0.1.1

func (cc *ConventionChecker) Check(diff string) []Finding

Check validates a diff against all conventions and returns findings.

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 DedupConfig added in v0.1.1

type DedupConfig struct {
	SameFileOnly        bool    // Only merge findings within the same file
	MergeDistance       int     // Line distance threshold for merging nearby findings
	SimilarityThreshold float64 // Jaccard similarity threshold (0-1) for treating findings as near-duplicates
}

DedupConfig controls how findings are deduplicated.

func NewDedupConfig added in v0.1.1

func NewDedupConfig() DedupConfig

NewDedupConfig returns a DedupConfig with sensible defaults.

type DedupResult added in v0.1.1

type DedupResult struct {
	Unique     []Finding        // Findings that survived deduplication
	Duplicates []DuplicateGroup // Groups of findings that were merged
}

DedupResult contains the outcome of a deduplication pass.

func DeduplicateFindings added in v0.1.1

func DeduplicateFindings(findings []Finding, config DedupConfig) DedupResult

DeduplicateFindings removes duplicate or near-duplicate findings. It groups findings that have similar concern+message text and are nearby in line distance, keeping the highest-confidence finding as the representative.

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 DuplicateGroup added in v0.1.1

type DuplicateGroup struct {
	Representative Finding   // The highest-confidence finding in the group
	Duplicates     []Finding // The remaining findings that were folded in
	Reason         string    // Human-readable explanation of why they were grouped
}

DuplicateGroup describes a set of findings collapsed into one representative.

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.1.1

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

func DefaultFilterConfig added in v0.1.1

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.1.1

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"`
	// Confidence is a numeric score from 0.0 to 1.0 indicating how certain
	// the system is that this finding is a true positive. Values closer to
	// 1.0 mean higher confidence.
	Confidence float64 `json:"confidence"`
	// SASTSource marks findings that originated from static analysis (SAST)
	// and were fed into the LLM prompt for validation.
	SASTSource bool `json:"sast_source,omitempty"`
}

Finding represents a single issue detected during review.

func FromContractFinding added in v0.1.1

func FromContractFinding(f reviewcontracts.Finding) Finding

FromContractFinding converts a shared review contract into a sight finding.

type FixPipeline added in v0.1.1

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

FixPipeline evaluates a set of FixRules against findings and returns deduplicated, sorted fix suggestions.

func NewFixPipeline added in v0.1.1

func NewFixPipeline() *FixPipeline

NewFixPipeline returns a pipeline pre-loaded with the built-in remediation rules. Additional rules can be registered with AddRule.

func (*FixPipeline) AddRule added in v0.1.1

func (p *FixPipeline) AddRule(rule FixRule)

AddRule appends a custom fix rule to the pipeline. It is safe for concurrent use.

func (*FixPipeline) GenerateFixes added in v0.1.1

func (p *FixPipeline) GenerateFixes(findings []Finding) []FixSuggestion

GenerateFixes evaluates all registered rules against the supplied findings, deduplicates per finding (keeping the highest-confidence suggestion), and returns results sorted by Priority (ascending) then Confidence (descending).

type FixRule added in v0.1.1

type FixRule struct {
	// MatchFn returns true when this rule applies to the given Finding.
	MatchFn func(Finding) bool
	// Generator produces a FixSuggestion for a matched Finding.
	Generator func(Finding) FixSuggestion
}

FixRule is a pattern-matching rule that, when a Finding matches, produces a FixSuggestion. Rules are evaluated in the order they are registered.

type FixSuggestion added in v0.1.1

type FixSuggestion struct {
	Finding     *Finding
	FixedCode   string  // the corrected code
	Explanation string  // why this fix works
	Confidence  float64 // 0-1 how confident the fix is correct

	// FindingID links this suggestion back to the originating Finding.
	FindingID string `json:"finding_id"`
	// Title is a short, human-readable summary of the fix.
	Title string `json:"title"`
	// Description explains why the fix is needed and what it does.
	Description string `json:"description"`
	// FixCode contains the suggested code or configuration change.
	FixCode string `json:"fix_code"`
	// Category classifies the fix area, e.g. "input-validation", "auth",
	// "crypto", "injection", "xss", "ssrf".
	Category string `json:"category"`
	// Severity mirrors the severity of the original finding.
	Severity string `json:"severity"`
	// EstimatedEffort indicates how much work the fix requires:
	// "trivial", "easy", "moderate", or "complex".
	EstimatedEffort string `json:"estimated_effort"`
	// Priority ranks this suggestion (1 = highest, 5 = lowest).
	Priority int `json:"priority"`
}

FixSuggestion is a proposed code change to resolve a finding.

func (FixSuggestion) String added in v0.1.1

func (f FixSuggestion) String() string

String returns a human-readable summary of the fix suggestion.

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 MemoryBridge added in v0.1.1

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

MemoryBridge enriches code reviews with historical context from a MemorySource and persists new findings back for future recall.

func NewMemoryBridge added in v0.1.1

func NewMemoryBridge(source MemorySource, opts ...MemoryBridgeOption) *MemoryBridge

NewMemoryBridge creates a MemoryBridge backed by source. By default the bridge is enabled with a 2 000-token context budget.

func (*MemoryBridge) EnrichContext added in v0.1.1

func (b *MemoryBridge) EnrichContext(ctx context.Context, findings []string) (string, error)

EnrichContext queries the memory source for context relevant to the given findings and returns a single concatenated, token-truncated string. A nil or disabled bridge returns an empty string.

func (*MemoryBridge) RecallSimilar added in v0.1.1

func (b *MemoryBridge) RecallSimilar(ctx context.Context, concern string, limit int) ([]MemoryResult, error)

RecallSimilar retrieves past findings similar to concern. A nil or disabled bridge returns an empty slice.

func (*MemoryBridge) StoreFindings added in v0.1.1

func (b *MemoryBridge) StoreFindings(ctx context.Context, findings []Finding) error

StoreFindings persists review findings back to the memory source for future recall. A nil or disabled bridge is a no-op.

type MemoryBridgeOption added in v0.1.1

type MemoryBridgeOption func(*MemoryBridge)

MemoryBridgeOption configures a MemoryBridge.

func WithMaxContextTokens added in v0.1.1

func WithMaxContextTokens(n int) MemoryBridgeOption

WithMaxContextTokens sets the approximate maximum number of tokens included in the enriched context returned by EnrichContext.

func WithMemoryEnabled added in v0.1.1

func WithMemoryEnabled(enabled bool) MemoryBridgeOption

WithMemoryEnabled enables or disables the bridge. When disabled all operations become no-ops.

type MemoryResult added in v0.1.1

type MemoryResult struct {
	ID      string   `json:"id"`
	Content string   `json:"content"`
	Score   float64  `json:"score"`
	Tags    []string `json:"tags,omitempty"`
}

MemoryResult represents a single result retrieved from a memory store.

type MemorySource added in v0.1.1

type MemorySource interface {
	// Recall returns up to limit results relevant to query, sorted by
	// descending relevance score.
	Recall(ctx context.Context, query string, limit int) ([]MemoryResult, error)

	// Store persists content under key with the given tags for future recall.
	Store(ctx context.Context, key, content string, tags []string) error
}

MemorySource defines the interface for a memory backend (e.g. yaad). Using an interface keeps sight free of any direct yaad dependency.

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 WithPreAnalysis added in v0.1.1

func WithPreAnalysis(enabled bool) Option

WithPreAnalysis enables or disables static analysis and taint analysis as a pre-pass before the LLM review. When enabled, pattern-based static rules and data-flow taint analysis are run on the diff, and their findings are included in the review results alongside LLM findings.

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"`
	// SASTFusion tracks which SAST findings the LLM confirmed vs dismissed.
	// Only populated when SAST-LLM fusion is active (preAnalysis enabled).
	SASTFusion *SASTFusionResult `json:"sast_fusion,omitempty"`
	// ConfidenceBreakdown groups findings by confidence band for quick triage.
	ConfidenceBreakdown *ConfidenceBreakdown `json:"confidence_breakdown,omitempty"`
}

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.

If contextLines > 0, the review includes surrounding file context around each changed hunk for better understanding of the change.

func ReviewIncrementalWithContext added in v0.1.1

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

ReviewIncrementalWithContext reviews changes with surrounding file context. contextLines specifies how many lines of context to include around each hunk.

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 SASTCheck added in v0.1.1

type SASTCheck struct {
	ID          string
	Name        string
	Description string
	Severity    string // "critical", "high", "medium", "low"
	Languages   []string
	Pattern     string // regex or keyword pattern
	Check       func(source string, filePath string) []SASTFinding
}

SASTCheck represents a static analysis check.

func (*SASTCheck) AppliesTo added in v0.1.1

func (c *SASTCheck) AppliesTo(filePath string) bool

AppliesTo checks if the SAST check applies to the given file.

type SASTFinding added in v0.1.1

type SASTFinding struct {
	CheckID    string
	Rule       string
	Message    string
	File       string
	Line       int
	Severity   string
	Confidence float64 // 0-1
	Evidence   string  // the suspicious code
}

SASTFinding represents a finding from static analysis.

type SASTFusion added in v0.1.1

type SASTFusion struct {
	// MaxFindings caps the number of SAST findings injected into the prompt.
	// Zero means no limit.
	MaxFindings int
	// MaxEvidenceLen truncates each evidence snippet to this many characters.
	// Zero uses a default of 200.
	MaxEvidenceLen int
}

SASTFusion formats static analysis findings for injection into LLM prompts. This is the core of SAST-LLM fusion: feeding SAST results into the LLM so it can validate or dismiss each finding, reducing false positives.

func NewSASTFusion added in v0.1.1

func NewSASTFusion() *SASTFusion

NewSASTFusion creates a SASTFusion with sensible defaults.

func (*SASTFusion) FormatSASTForPrompt added in v0.1.1

func (sf *SASTFusion) FormatSASTForPrompt(findings []Finding) string

FormatSASTForPrompt creates a structured "Pre-analysis findings" section suitable for injection into an LLM prompt. Each finding is rendered with its rule, severity, file location, message, and evidence snippet.

type SASTFusionResult added in v0.1.1

type SASTFusionResult struct {
	// Confirmed lists SAST findings the LLM validated as real issues.
	Confirmed []Finding
	// Dismissed lists SAST findings the LLM considered false positives.
	Dismissed []Finding
	// Unaddressed lists SAST findings the LLM did not mention (implicitly dismissed).
	Unaddressed []Finding
}

SASTFusionResult tracks how the LLM handled SAST findings.

func TrackSASTOutcome added in v0.1.1

func TrackSASTOutcome(sastFindings []Finding, llmFindings []Finding) SASTFusionResult

TrackSASTOutcome compares SAST findings fed into the prompt against the LLM's final findings to determine which were confirmed vs dismissed. A SAST finding is considered confirmed if the LLM's findings contain a finding at the same file and line with a similar message. Otherwise it is considered dismissed.

type SASTIntegration added in v0.1.1

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

SASTIntegration combines Static Application Security Testing (SAST) with LLM-based review. Research shows this hybrid approach reduces false positives by 91% compared to SAST alone (SAST-Genius, IEEE S&P 2025).

func NewSASTIntegration added in v0.1.1

func NewSASTIntegration() *SASTIntegration

NewSASTIntegration creates a SAST integration with built-in security checks.

func (*SASTIntegration) Analyze added in v0.1.1

func (s *SASTIntegration) Analyze(source string, filePath string) []SASTFinding

Analyze runs all SAST checks on the given source code.

func (*SASTIntegration) BuildReviewPrompt added in v0.1.1

func (s *SASTIntegration) BuildReviewPrompt(sastFindings []SASTFinding, diff string) string

BuildReviewPrompt builds an enhanced review prompt that includes SAST findings. This is the key innovation from SAST-Genius: SAST findings guide the LLM's attention to suspicious code, reducing false positives by 91%.

type SSATaintAnalyzer added in v0.1.1

type SSATaintAnalyzer struct {
	// MaxFindings caps the number of findings returned (0 = unlimited).
	MaxFindings int
	// Env, when non-nil, overrides the environment used to load packages
	// (e.g. append "GOWORK=off" to ignore a parent workspace). Nil inherits the
	// process environment.
	Env []string
}

SSATaintAnalyzer performs inter-procedural (cross-function) taint analysis on Go packages using the SSA intermediate representation. Unlike TaintAnalyzer (which is regex/diff-based and resets at every function boundary), this analyzer follows tainted values across call boundaries: when a tainted value is passed as an argument to a function, the corresponding parameter becomes tainted inside the callee, so a source in one function reaching a sink in another is detected.

func NewSSATaintAnalyzer added in v0.1.1

func NewSSATaintAnalyzer() *SSATaintAnalyzer

NewSSATaintAnalyzer creates an analyzer with default settings.

func (*SSATaintAnalyzer) AnalyzePackages added in v0.1.1

func (a *SSATaintAnalyzer) AnalyzePackages(dir string, patterns ...string) ([]Finding, error)

AnalyzePackages loads the Go packages matched by the given patterns (e.g. "./...", "./internal/handlers") rooted at dir, builds SSA, and reports cross-function taint flows as Findings. A non-nil error is returned only for load failures; per-package type errors are tolerated where possible.

type Severity

type Severity = types.Severity

Severity represents the impact level of a review finding. Aliased from shared types for cross-module compatibility.

const (
	SeverityInfo     Severity = types.SeverityInfo
	SeverityLow      Severity = types.SeverityLow
	SeverityMedium   Severity = types.SeverityMedium
	SeverityHigh     Severity = types.SeverityHigh
	SeverityCritical Severity = types.SeverityCritical
)

Severity constants re-exported for convenience.

type StaticAnalyzer added in v0.1.1

type StaticAnalyzer struct {
	Rules []StaticRule
}

StaticAnalyzer runs pattern-based rules against code before the LLM review.

func NewStaticAnalyzer added in v0.1.1

func NewStaticAnalyzer() *StaticAnalyzer

NewStaticAnalyzer creates a StaticAnalyzer preloaded with the default rule set.

func (*StaticAnalyzer) Analyze added in v0.1.1

func (sa *StaticAnalyzer) Analyze(diff string, language string) []Finding

Analyze runs all matching rules against a unified diff string and returns findings. Only added lines (starting with "+") are checked. The language parameter filters rules to those matching the language or "any".

func (*StaticAnalyzer) AnalyzeFile added in v0.1.1

func (sa *StaticAnalyzer) AnalyzeFile(content string, language string) []Finding

AnalyzeFile runs all matching rules against a full file's content. Each line is checked independently. The language parameter filters rules.

func (*StaticAnalyzer) AnalyzeFileWithPath added in v0.1.1

func (sa *StaticAnalyzer) AnalyzeFileWithPath(content string, language string, path string) []Finding

AnalyzeFileWithPath is like AnalyzeFile but sets the File field on findings.

type StaticRule added in v0.1.1

type StaticRule struct {
	ID          string         // unique identifier, e.g. "SEC-GO-001"
	Name        string         // short human-readable name
	Description string         // detailed explanation
	Language    string         // "go", "python", "typescript", "javascript", "any"
	Pattern     *regexp.Regexp // primary detection pattern
	Antipattern *regexp.Regexp // if this also matches the same line, suppress the finding
	Severity    string         // "critical", "high", "medium", "low"
	Category    string         // "security", "correctness", "performance"
	CWE         string         // e.g., "CWE-89"
	Fix         string         // suggested fix description
}

StaticRule defines a pattern-based static analysis rule that can catch common issues without invoking an LLM. Rules are matched against diff content or full file content before the LLM review pass, saving tokens on obvious issues.

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"`
	// AverageConfidence is the mean confidence score across all findings (0.0-1.0).
	AverageConfidence float64 `json:"average_confidence"`
	// HighConfidenceCount is the number of findings with confidence >= 0.7.
	HighConfidenceCount int `json:"high_confidence_count"`
	// LowConfidenceCount is the number of findings with confidence < 0.5.
	LowConfidenceCount int `json:"low_confidence_count"`
}

Stats provides review metrics.

type TaintAnalyzer added in v0.1.1

type TaintAnalyzer struct{}

TaintAnalyzer performs basic taint analysis / data flow tracking on Go code. It identifies taint sources (user-controlled inputs), tracks propagation through variable assignments and string concatenation, and reports when tainted data reaches a security-sensitive sink without sanitization.

This is a function-level (not inter-procedural) analyzer operating on diff text.

func NewTaintAnalyzer added in v0.1.1

func NewTaintAnalyzer() *TaintAnalyzer

NewTaintAnalyzer creates a TaintAnalyzer ready for use.

func (*TaintAnalyzer) AnalyzeDiff added in v0.1.1

func (ta *TaintAnalyzer) AnalyzeDiff(rawDiff string) []Finding

AnalyzeDiff runs taint analysis on a unified diff, returning findings for Go files. Only added lines are analyzed. The analysis is function-scoped and tracks taint from source variables through assignments and string concatenation to sinks.

func (*TaintAnalyzer) AnalyzeSource added in v0.1.1

func (ta *TaintAnalyzer) AnalyzeSource(source string, filePath string) []Finding

AnalyzeSource runs taint analysis on Go source code directly (not a diff). Useful for SAST integration with full file content.

type TaintFinding added in v0.1.1

type TaintFinding struct {
	Source   string // description of the taint source
	Sink     string // description of the sink
	SinkType string // category: "sql_injection", "command_injection", "path_traversal", "log_leak"
	Variable string // the tainted variable name
	File     string
	Line     int
	Severity string
	CWE      string
	Message  string
	Fix      string
}

TaintFinding represents a data-flow vulnerability where tainted data reaches a sink.

Directories

Path Synopsis
examples
basic command
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