code

package
v0.2.11 Latest Latest
Warning

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

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

Documentation

Overview

Package code provides shared implementations for Code service RPCs.

Plugins call into this library instead of reimplementing common logic. Language-specific behavior (e.g. which fixers to run) stays in the plugin.

Package code provides the DefaultCodeServer: a complete, language-agnostic implementation of the unified Code.Execute RPC. Plugins embed it and override only language-specific operations (Fix, dependency management).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComputeFileHashes

func ComputeFileHashes(vfs VFS, dir string, extensions map[string]bool) map[string]string

ComputeFileHashes walks a directory and hashes source files. If extensions is nil, all files are included. Otherwise only matching extensions. Files larger than maxHashFileSize are skipped. Shared by DefaultCodeServer and language-specific servers.

func DedentLines

func DedentLines(lines []string) []string

DedentLines strips the minimum common leading whitespace from all non-empty lines.

func FormatTimeline

func FormatTimeline(timelines []*FileTimeline) string

FormatTimeline produces a compact text representation of file timelines, suitable for LLM context or developer review.

func FormatTimelineStats

func FormatTimelineStats(s TimelineStats) string

FormatTimelineStats produces a readable summary.

func Levenshtein

func Levenshtein(a, b string) int

Levenshtein computes the edit distance between two strings.

func OperationName

func OperationName(req *codev0.CodeRequest) string

OperationName returns the oneof field name for dispatch/override keys. This is the SINGLE source of truth for operation name mapping. If you add a new operation to the proto, add it here AND in dispatch(). The test TestOperationName_MatchesDispatch verifies they stay in sync.

Types

type AgeBucket

type AgeBucket string

AgeBucket classifies code age relative to a reference date.

const (
	AgeRecent   AgeBucket = "recent"   // < 3 months
	AgeModerate AgeBucket = "moderate" // 3-12 months
	AgeOld      AgeBucket = "old"      // 1-3 years
	AgeAncient  AgeBucket = "ancient"  // > 3 years
)

type ByteLRU

type ByteLRU struct {

	// MaxEntrySize is the maximum size of a single entry (default 1MB).
	// Files larger than this are not cached.
	MaxEntrySize int64
	// contains filtered or unexported fields
}

ByteLRU is a byte-slice LRU cache with a configurable memory budget. Thread-safe. Used by CachedVFS to cache file contents in RAM.

func NewByteLRU

func NewByteLRU(capacity int64) *ByteLRU

NewByteLRU creates a new LRU cache with the given capacity in bytes.

func (*ByteLRU) Clear

func (c *ByteLRU) Clear()

Clear removes all entries.

func (*ByteLRU) Get

func (c *ByteLRU) Get(key string) []byte

Get returns the cached data for key, or nil if not present. Moves the entry to the front (most recently used).

func (*ByteLRU) Invalidate

func (c *ByteLRU) Invalidate(key string)

Invalidate removes a key from the cache.

func (*ByteLRU) Len

func (c *ByteLRU) Len() int

Len returns the number of cached entries.

func (*ByteLRU) Put

func (c *ByteLRU) Put(key string, data []byte)

Put stores data under key. If the entry exceeds MaxEntrySize, it is not cached. Evicts least recently used entries to stay within capacity.

func (*ByteLRU) Size

func (c *ByteLRU) Size() int64

Size returns the current memory usage in bytes.

type CachedVFS

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

CachedVFS wraps a base VFS (typically LocalVFS) with an in-memory file tree cache. Metadata operations (Stat, ReadDir, WalkDir) are served from cache. Reads/writes pass through to the base and update the cache.

On startup, the entire source directory is walked to build the cache. A fsnotify watcher keeps the cache fresh on file changes.

func NewCachedVFS

func NewCachedVFS(base VFS, dir string) (*CachedVFS, error)

NewCachedVFS creates a CachedVFS rooted at dir, backed by base. It walks dir to populate the cache and starts a background fsnotify watcher.

func (*CachedVFS) Close

func (c *CachedVFS) Close() error

Close stops the watcher and releases resources.

func (*CachedVFS) Invalidate

func (c *CachedVFS) Invalidate() error

Invalidate forces a full re-scan of the tree. Use sparingly.

func (*CachedVFS) MkdirAll

func (c *CachedVFS) MkdirAll(path string, perm os.FileMode) error

func (*CachedVFS) ReadDir

func (c *CachedVFS) ReadDir(path string) ([]os.DirEntry, error)

func (*CachedVFS) ReadFile

func (c *CachedVFS) ReadFile(path string) ([]byte, error)

func (*CachedVFS) Remove

func (c *CachedVFS) Remove(path string) error

func (*CachedVFS) Rename

func (c *CachedVFS) Rename(oldpath, newpath string) error

func (*CachedVFS) Stat

func (c *CachedVFS) Stat(path string) (os.FileInfo, error)

func (*CachedVFS) WalkDir

func (c *CachedVFS) WalkDir(root string, fn fs.WalkDirFunc) error

func (*CachedVFS) WriteFile

func (c *CachedVFS) WriteFile(path string, data []byte, perm os.FileMode) error

type CodeExecutor

type CodeExecutor interface {
	Execute(context.Context, *codev0.CodeRequest) (*codev0.CodeResponse, error)
}

CodeExecutor is the interface every code server (Default, Go, …) satisfies.

type CodebaseContext

type CodebaseContext struct {
	Module    string
	Language  string
	Packages  []*codev0.PackageInfo
	DepGraph  *DepGraph
	Timelines []*FileTimeline
	Stats     TimelineStats
}

CodebaseContext holds all analysis layers assembled from a single code server. It is the unified input for LLM prompts, relevance scoring, and edit planning.

func BuildCodebaseContext

func BuildCodebaseContext(ctx context.Context, server CodeExecutor) (*CodebaseContext, error)

BuildCodebaseContext runs the full analysis pipeline through a CodeExecutor (typically GoCodeServer) and returns a populated CodebaseContext.

func (*CodebaseContext) FilePaths

func (cc *CodebaseContext) FilePaths() []string

FilePaths returns all source file paths known to this context.

func (*CodebaseContext) Format

func (cc *CodebaseContext) Format(budget int) string

Format produces a token-budgeted text representation for LLM system prompts. Budget is in bytes; 0 means unlimited. Sections are included in priority order: header > dep graph > timeline.

type DefaultCodeServer

type DefaultCodeServer struct {
	codev0.UnimplementedCodeServer

	SourceDir string
	FS        VFS
	// contains filtered or unexported fields
}

DefaultCodeServer implements every Code.Execute operation with sensible, language-agnostic defaults. Plugins embed this and call Override to replace handlers for operations they specialize (e.g. Fix, deps).

func NewDefaultCodeServer

func NewDefaultCodeServer(sourceDir string, opts ...ServerOption) *DefaultCodeServer

NewDefaultCodeServer creates a server rooted at sourceDir. By default it uses LocalVFS (direct os.* calls).

func (*DefaultCodeServer) Close

func (s *DefaultCodeServer) Close() error

Close releases resources held by the server (e.g. CachedVFS watcher, git repo).

func (*DefaultCodeServer) Execute

Execute dispatches the incoming CodeRequest to the appropriate handler.

func (*DefaultCodeServer) FileOps

func (s *DefaultCodeServer) FileOps() FileOperation

FileOps returns a FileOperation view over this server's VFS and root. Use it when only file operations (read, write, list, delete, move, copy, search, replace) are needed, so Search and ReplaceInFile always run on the virtual layer (e.g. overlay) instead of disk.

func (*DefaultCodeServer) GetSourceDir

func (s *DefaultCodeServer) GetSourceDir() string

GetSourceDir returns the root directory for this server (implements VFSProvider).

func (*DefaultCodeServer) GetVFS

func (s *DefaultCodeServer) GetVFS() VFS

GetVFS returns the VFS backend used by this server (implements VFSProvider).

func (*DefaultCodeServer) Override

func (s *DefaultCodeServer) Override(op string, handler OperationHandler)

Override registers a custom handler for an operation name. Names match the oneof field names: "read_file", "write_file", "fix", etc.

func (*DefaultCodeServer) SetWriteListener

func (s *DefaultCodeServer) SetWriteListener(l WriteListener)

SetWriteListener installs a post-mutation hook. It is called after every successful WriteFile, CreateFile, DeleteFile, and MoveFile dispatched through Execute.

Safe to call after construction; nil clears the listener. The listener is invoked synchronously after the mutation commits; if you need async fire-and-forget, do the dispatch inside your own listener.

type DepEdge

type DepEdge struct {
	From string
	To   string
}

DepEdge represents a directed dependency from one package to another.

type DepGraph

type DepGraph struct {
	Module   string
	Packages []PackageNode
}

DepGraph represents the package dependency graph of a project. Nodes are packages; edges are import relationships.

func BuildDepGraph

func BuildDepGraph(module string, packages []PackageInput) *DepGraph

BuildDepGraph creates a DepGraph from raw package data.

func (*DepGraph) ConnectedComponents

func (g *DepGraph) ConnectedComponents() [][]string

ConnectedComponents returns groups of packages that are connected via internal imports (undirected). Packages in different components have no import relationship and can be worked on independently.

func (*DepGraph) Format

func (g *DepGraph) Format() string

Format produces a compact text representation of the dependency graph.

func (*DepGraph) InternalEdges

func (g *DepGraph) InternalEdges() []DepEdge

InternalEdges returns only edges between packages within the same module.

func (*DepGraph) Leaves

func (g *DepGraph) Leaves() []string

Leaves returns packages that don't import any other internal package.

func (*DepGraph) Roots

func (g *DepGraph) Roots() []string

Roots returns packages that are not imported by any other internal package.

type DiffKind

type DiffKind int

DiffKind describes whether a line was added, removed, or unchanged.

const (
	DiffContext DiffKind = iota // unchanged context line
	DiffAdd                     // added line
	DiffRemove                  // removed line
)

func (DiffKind) String

func (k DiffKind) String() string

type DiffLine

type DiffLine struct {
	Kind    DiffKind
	Content string
	OldLine int // 0 if the line doesn't exist in the old file
	NewLine int // 0 if the line doesn't exist in the new file
}

DiffLine is a single line within a hunk.

type EditResult

type EditResult struct {
	Content  string // the file after replacement
	Strategy string // which strategy matched
	OK       bool
}

EditResult holds the outcome of a smart edit attempt.

func SmartEdit

func SmartEdit(content, find, replace string) EditResult

SmartEdit tries all matching strategies to apply a FIND/REPLACE on content. Strategies are tried in order of decreasing precision:

  1. Exact substring match
  2. Trailing whitespace normalized
  3. Fully trimmed (all leading+trailing whitespace per line)
  4. Indentation-shifted (same content, different indent level)
  5. Anchor-based (first+last unique lines locate the region)
  6. Fuzzy scored (Levenshtein per line)
  7. Fuzzy block (60% line match threshold)

type FileChange

type FileChange struct {
	Path    string
	Type    string // "create", "modify", "delete"
	Content []byte // nil for deletes
}

FileChange records a single file mutation in the overlay.

type FileDiff

type FileDiff struct {
	OldPath string
	NewPath string
	Hunks   []Hunk
}

FileDiff represents the structured diff of a single file.

func ParseUnifiedDiff

func ParseUnifiedDiff(raw string) []FileDiff

ParseUnifiedDiff parses the output of `git diff` (unified format) into structured FileDiff objects with line numbers on every line.

func (*FileDiff) Summary

func (fd *FileDiff) Summary() string

Summary returns a concise description of the diff suitable for an LLM prompt.

type FileOperation

type FileOperation interface {
	ReadFile(ctx context.Context, path string) ([]byte, error)
	WriteFile(ctx context.Context, path string, data []byte) error
	ListFiles(ctx context.Context, path string, recursive bool, extensions []string) ([]string, error)
	DeleteFile(ctx context.Context, path string) error
	MoveFile(ctx context.Context, oldPath, newPath string) error
	CopyFile(ctx context.Context, srcPath, destPath string) error
	Search(ctx context.Context, opts SearchOpts) (*SearchResult, error)
	ReplaceInFile(ctx context.Context, path, find, replace string) (changed bool, err error)
}

FileOperation provides VFS-only operations. All paths are relative to the root passed at construction. Search and ReplaceInFile run on the VFS (no ripgrep on disk), so overlay/virtual state is consistent.

func NewFileOps

func NewFileOps(vfs VFS, root string) FileOperation

NewFileOps returns a FileOperation that uses vfs with all paths under root. Paths passed to its methods must be relative to root (e.g. "foo/bar.go").

type FileTimeline

type FileTimeline struct {
	Path   string
	Chunks []TimelineChunk
}

FileTimeline is the temporal breakdown of a single source file.

func BuildFileTimeline

func BuildFileTimeline(path string, blameLines []*codev0.GitBlameLine, refDate time.Time) *FileTimeline

BuildFileTimeline groups blame lines into consecutive chunks by commit hash, classifies each by age relative to refDate, and extracts a summary.

func BuildProjectTimeline

func BuildProjectTimeline(ctx context.Context, vfs VFS, rootDir string, extensions []string, refDate time.Time) ([]*FileTimeline, error)

BuildProjectTimeline blames every source file and returns timelines sorted by path. It uses the VFS to discover files, skipping test files, vendor, and generated directories, then runs git blame directly via exec.Command.

func (*FileTimeline) Lines

func (ft *FileTimeline) Lines() int

Lines returns total line count (EndLine of last chunk).

func (*FileTimeline) Newest

func (ft *FileTimeline) Newest() time.Time

Newest returns the most recent chunk date, or zero time if empty.

func (*FileTimeline) Oldest

func (ft *FileTimeline) Oldest() time.Time

Oldest returns the earliest chunk date, or zero time if empty.

type GitBlameLine

type GitBlameLine struct {
	Hash    string
	Author  string
	Date    string
	Line    int32
	Content string
}

GitBlameLine holds blame information for a single line.

type GitCommitInfo

type GitCommitInfo struct {
	Hash         string
	ShortHash    string
	Author       string
	Date         string
	Message      string
	FilesChanged int32
}

GitCommitInfo holds parsed commit data (used by both native and exec paths).

type GitDiffFileInfo

type GitDiffFileInfo struct {
	Path      string
	Additions int32
	Deletions int32
	Status    string
}

GitDiffFileInfo holds per-file diff statistics.

type GoCodeServer

type GoCodeServer struct {
	*DefaultCodeServer
}

GoCodeServer extends DefaultCodeServer with Go-specific project metadata and dependency operations.

func NewGoCodeServer

func NewGoCodeServer(dir string, serverOpts []ServerOption, goOpts ...GoServerOption) *GoCodeServer

NewGoCodeServer creates a Go-aware code server. ServerOptions are forwarded to the embedded DefaultCodeServer (e.g. WithVFS).

func (*GoCodeServer) GetProjectInfo

GetProjectInfo implements the standalone gRPC RPC (not through Execute).

func (*GoCodeServer) ListDependencies

ListDependencies implements the standalone gRPC RPC.

func (*GoCodeServer) VFS

func (s *GoCodeServer) VFS() VFS

VFS returns the underlying VFS of the code server.

type GoServerOption

type GoServerOption func(*GoCodeServer)

GoServerOption configures a GoCodeServer.

type HotspotFile

type HotspotFile struct {
	Path   string
	Chunks int
}

HotspotFile tracks files with many distinct commit chunks.

type Hunk

type Hunk struct {
	OldStart int // 1-based starting line in the old version
	OldCount int
	NewStart int // 1-based starting line in the new version
	NewCount int
	Header   string // optional hunk header (function name, etc.)
	Lines    []DiffLine
}

Hunk is a contiguous block of changes within a file diff.

type LocalVFS

type LocalVFS struct{}

LocalVFS delegates every call to the os/filepath standard library. This is the default for DefaultCodeServer -- zero behavior change from the original direct-os implementation.

func (LocalVFS) MkdirAll

func (LocalVFS) MkdirAll(path string, perm os.FileMode) error

func (LocalVFS) ReadDir

func (LocalVFS) ReadDir(path string) ([]os.DirEntry, error)

func (LocalVFS) ReadFile

func (LocalVFS) ReadFile(path string) ([]byte, error)

func (LocalVFS) Remove

func (LocalVFS) Remove(path string) error

func (LocalVFS) Rename

func (LocalVFS) Rename(oldpath, newpath string) error

func (LocalVFS) Stat

func (LocalVFS) Stat(path string) (os.FileInfo, error)

func (LocalVFS) WalkDir

func (LocalVFS) WalkDir(root string, fn fs.WalkDirFunc) error

func (LocalVFS) WriteFile

func (LocalVFS) WriteFile(path string, data []byte, perm os.FileMode) error

type MemoryVFS

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

MemoryVFS is a pure in-memory filesystem. All paths are absolute. Safe for concurrent use.

func NewMemoryVFS

func NewMemoryVFS() *MemoryVFS

NewMemoryVFS creates an empty in-memory filesystem.

func NewMemoryVFSFrom

func NewMemoryVFSFrom(files map[string]string) *MemoryVFS

NewMemoryVFSFrom creates a MemoryVFS pre-populated with the given files. Keys are absolute paths, values are file contents.

func (*MemoryVFS) MkdirAll

func (m *MemoryVFS) MkdirAll(path string, _ os.FileMode) error

func (*MemoryVFS) ReadDir

func (m *MemoryVFS) ReadDir(path string) ([]os.DirEntry, error)

func (*MemoryVFS) ReadFile

func (m *MemoryVFS) ReadFile(path string) ([]byte, error)

func (*MemoryVFS) Remove

func (m *MemoryVFS) Remove(path string) error

func (*MemoryVFS) Rename

func (m *MemoryVFS) Rename(oldpath, newpath string) error

func (*MemoryVFS) Stat

func (m *MemoryVFS) Stat(path string) (os.FileInfo, error)

func (*MemoryVFS) WalkDir

func (m *MemoryVFS) WalkDir(root string, fn fs.WalkDirFunc) error

func (*MemoryVFS) WriteFile

func (m *MemoryVFS) WriteFile(path string, data []byte, _ os.FileMode) error

type NativeGit

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

NativeGit wraps a go-git Repository for in-process git operations. Eliminates fork/exec overhead for common operations (log, show, diff). Falls back to exec for operations go-git doesn't support well (blame with line ranges).

func OpenNativeGit

func OpenNativeGit(dir string) *NativeGit

OpenNativeGit opens a git repository at dir. Returns nil (not error) if dir is not a git repo — callers should fall back to exec-based git.

func (*NativeGit) DiffStat

func (g *NativeGit) DiffStat(ctx context.Context, baseRef, headRef string) ([]*GitDiffFileInfo, error)

DiffStat returns file-level diff statistics between two refs. For full unified diff output, fall back to exec (go-git's patch is verbose).

func (*NativeGit) HEAD

func (g *NativeGit) HEAD() (string, error)

HEAD returns the current HEAD commit hash.

func (*NativeGit) ListBranches

func (g *NativeGit) ListBranches() ([]string, error)

ListBranches returns all local branch names.

func (*NativeGit) Log

func (g *NativeGit) Log(ctx context.Context, maxCount int, ref, path, since string) ([]*GitCommitInfo, error)

Log returns recent commits, optionally filtered by path and since date.

Walks the first-parent chain manually via CommitObject() rather than using repo.Log()'s iterator. On shallow clones (GitHub Actions default fetch-depth=1), go-git's log iterator tries to resolve the deepest commit's parent eagerly for DFS bookkeeping and fails with "object not found" BEFORE yielding even HEAD. Walking parent-by- parent keeps full control: every commit we do have is yielded, and the shallow boundary cleanly terminates iteration.

func (*NativeGit) Show

func (g *NativeGit) Show(ctx context.Context, ref, path string) (string, bool, error)

Show returns the content of a file at a given ref.

type NativeJJ

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

NativeJJ implements VCSProvider for Jujutsu (jj) repositories. All operations go through the jj CLI — there is no Go library for jj.

func OpenNativeJJ

func OpenNativeJJ(dir string) *NativeJJ

OpenNativeJJ returns a NativeJJ if dir contains a .jj directory and jj is installed. Returns nil if jj is not available or dir is not a jj repo.

func (*NativeJJ) Blame

func (j *NativeJJ) Blame(ctx context.Context, path string, startLine, endLine int32) ([]*GitBlameLine, error)

func (*NativeJJ) Diff

func (j *NativeJJ) Diff(ctx context.Context, baseRef, headRef, path string, contextLines int, statOnly bool) (string, []*GitDiffFileInfo, error)

func (*NativeJJ) Log

func (j *NativeJJ) Log(ctx context.Context, maxCount int, ref, path, since string) ([]*GitCommitInfo, error)

func (*NativeJJ) Show

func (j *NativeJJ) Show(ctx context.Context, ref, path string) (string, bool, error)

type OperationHandler

type OperationHandler func(ctx context.Context, req *codev0.CodeRequest) (*codev0.CodeResponse, error)

OperationHandler processes a single code operation within Execute.

type OverlayVFS

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

OverlayVFS layers in-memory writes/deletes on top of a base VFS. Reads check the overlay first, then fall through to the base. Writes never touch the base until Commit() is called.

func NewOverlayVFS

func NewOverlayVFS(base VFS) *OverlayVFS

NewOverlayVFS wraps an existing VFS with an in-memory overlay.

func (*OverlayVFS) Base

func (o *OverlayVFS) Base() VFS

Base returns the underlying VFS.

func (*OverlayVFS) BaseSnapshot

func (o *OverlayVFS) BaseSnapshot(path string) ([]byte, bool)

BaseSnapshot returns the base content captured when the overlay first touched a file. Returns nil, false if no snapshot exists.

func (*OverlayVFS) Commit

func (o *OverlayVFS) Commit() error

Commit flushes all overlay writes to the base VFS and applies deletes.

func (*OverlayVFS) DeletedFiles

func (o *OverlayVFS) DeletedFiles() []string

DeletedFiles returns the set of file paths that have pending deletes.

func (*OverlayVFS) Diff

func (o *OverlayVFS) Diff() []FileChange

Diff returns a list of all file changes in the overlay.

func (*OverlayVFS) Dirty

func (o *OverlayVFS) Dirty() bool

Dirty returns true if the overlay has any pending changes.

func (*OverlayVFS) MkdirAll

func (o *OverlayVFS) MkdirAll(path string, perm os.FileMode) error

func (*OverlayVFS) ModifiedFiles

func (o *OverlayVFS) ModifiedFiles() []string

ModifiedFiles returns the set of file paths that have pending writes.

func (*OverlayVFS) ReadDir

func (o *OverlayVFS) ReadDir(path string) ([]os.DirEntry, error)

func (*OverlayVFS) ReadFile

func (o *OverlayVFS) ReadFile(path string) ([]byte, error)

func (*OverlayVFS) Remove

func (o *OverlayVFS) Remove(path string) error

func (*OverlayVFS) Rename

func (o *OverlayVFS) Rename(oldpath, newpath string) error

func (*OverlayVFS) Rollback

func (o *OverlayVFS) Rollback()

Rollback discards all overlay changes.

func (*OverlayVFS) Stat

func (o *OverlayVFS) Stat(path string) (os.FileInfo, error)

func (*OverlayVFS) WalkDir

func (o *OverlayVFS) WalkDir(root string, fn fs.WalkDirFunc) error

func (*OverlayVFS) WriteFile

func (o *OverlayVFS) WriteFile(path string, data []byte, perm os.FileMode) error

type PackageInput

type PackageInput struct {
	Name    string
	Path    string
	Imports []string
	Files   []string
	Doc     string
}

BuildDepGraph constructs a dependency graph from package info.

type PackageNode

type PackageNode struct {
	Name    string
	Path    string
	Imports []string
	Files   []string
	Doc     string
}

PackageNode represents one package in the dependency graph.

type PythonCodeServer

type PythonCodeServer struct {
	*DefaultCodeServer
}

PythonCodeServer extends DefaultCodeServer with Python-specific operations: GetProjectInfo (pyproject.toml + uv) and ListDependencies (uv pip list).

func NewPythonCodeServer

func NewPythonCodeServer(dir string, serverOpts []ServerOption) *PythonCodeServer

NewPythonCodeServer creates a Python-aware code server.

func (*PythonCodeServer) GetProjectInfo

func (*PythonCodeServer) ListDependencies

type RelevanceScorer

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

RelevanceScorer ranks files by operational relevance to a text query. All signals are computed from data already available in CodebaseContext -- no embeddings or LLM calls required.

func NewRelevanceScorer

func NewRelevanceScorer(cc *CodebaseContext, vfs VFS, rootDir string, opts ...ScorerOption) *RelevanceScorer

NewRelevanceScorer creates a scorer from a CodebaseContext and its backing server. vfs and rootDir are used for the search signal; pass a DefaultCodeServer's FS and SourceDir.

func (*RelevanceScorer) ScoreFiles

func (r *RelevanceScorer) ScoreFiles(ctx context.Context, query string, files []string) []ScoredFile

ScoreFiles ranks the provided files by relevance to the query. Returns results sorted by descending score.

func (*RelevanceScorer) TopK

func (r *RelevanceScorer) TopK(ctx context.Context, query string, files []string, k int) []ScoredFile

TopK returns the top K files from ScoreFiles.

type ScoredFile

type ScoredFile struct {
	Path  string
	Score float64

	SearchHits  int
	RecentLines int
	Importers   int
}

ScoredFile is a file path annotated with a composite relevance score.

type ScorerOption

type ScorerOption func(*RelevanceScorer)

ScorerOption configures a RelevanceScorer.

func WithWeights

func WithWeights(search, recency, centrality float64) ScorerOption

WithWeights sets custom signal weights. Default: 0.60, 0.25, 0.15.

type SearchMatch

type SearchMatch struct {
	File string // relative to root
	Line int
	Text string
}

SearchMatch is one search result.

type SearchOpts

type SearchOpts struct {
	Pattern         string
	Literal         bool
	CaseInsensitive bool
	Path            string   // subdirectory (relative to root)
	Extensions      []string // e.g. [".go", ".py"]
	Exclude         []string // glob patterns
	MaxResults      int      // 0 = 100
	ContextLines    int
}

SearchOpts configures a text search.

type SearchResult

type SearchResult struct {
	Matches   []SearchMatch
	Truncated bool
}

SearchResult holds all matches.

func Search(ctx context.Context, root string, opts SearchOpts) (*SearchResult, error)

Search runs ripgrep on a local directory.

func SearchTrigram

func SearchTrigram(_ context.Context, vfs VFS, idx *TrigramIndex, root string, opts SearchOpts) (*SearchResult, error)

SearchTrigram performs trigram-accelerated search. The index narrows candidates to files containing the query's trigrams, then regex matches only those files. Falls back to SearchVFS if trigrams can't be extracted (e.g., pure wildcard pattern).

func SearchVFS

func SearchVFS(_ context.Context, vfs VFS, root string, opts SearchOpts) (*SearchResult, error)

SearchVFS performs regex-based text search over a VFS. Used when the filesystem is non-local (MemoryVFS, OverlayVFS) and ripgrep can't run.

type ServerOption

type ServerOption func(*DefaultCodeServer)

ServerOption configures a DefaultCodeServer.

func WithCachedFS

func WithCachedFS() ServerOption

WithCachedFS enables in-memory file tree caching backed by fsnotify. Metadata operations (Stat, ReadDir, WalkDir) are served from cache. File reads/writes pass through to disk. Cache is kept fresh via fsnotify.

func WithContentCache

func WithContentCache(budgetBytes int64) ServerOption

WithContentCache enables in-memory file content caching on top of CachedVFS. File reads are served from RAM with LRU eviction. Invalidated by fsnotify. Implies WithCachedFS. budgetBytes is the maximum memory for cached content (default 200MB if 0).

func WithTrigramIndex

func WithTrigramIndex() ServerOption

WithTrigramIndex enables trigram-based search indexing for sub-linear text search. Implies WithContentCache (trigram index reads content from cache). Files are indexed at startup and updated incrementally via fsnotify.

func WithVFS

func WithVFS(vfs VFS) ServerOption

WithVFS sets a custom VFS backend. Defaults to LocalVFS.

type TimelineChunk

type TimelineChunk struct {
	StartLine int
	EndLine   int
	Hash      string
	Author    string
	Date      time.Time
	Age       AgeBucket
	Summary   string // first non-blank content line in the range
}

TimelineChunk groups consecutive lines from the same commit.

type TimelineStats

type TimelineStats struct {
	TotalLines  int
	TotalFiles  int
	TotalChunks int

	LinesByAge map[AgeBucket]int // lines per bucket

	NewestFile string    // most recently modified file
	NewestDate time.Time // date of most recent change
	OldestFile string    // oldest untouched file
	OldestDate time.Time // date of oldest change

	Hotspots []HotspotFile // files with most distinct chunks (frequently patched)
}

TimelineStats summarizes the temporal distribution of a project's code.

func ComputeTimelineStats

func ComputeTimelineStats(timelines []*FileTimeline) TimelineStats

ComputeTimelineStats derives project-wide statistics from a set of timelines.

type TrigramIndex

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

TrigramIndex provides sub-linear text search by maintaining posting lists of trigrams (3-byte sequences) to file IDs. A search query extracts trigrams, intersects their posting lists, and only scans the resulting candidate files.

Typical speedup: 10-100x on large repos vs linear scan.

func NewTrigramIndex

func NewTrigramIndex() *TrigramIndex

NewTrigramIndex creates an empty trigram index.

func (*TrigramIndex) AddFile

func (idx *TrigramIndex) AddFile(path string, content []byte)

AddFile indexes the content of a file. If the file was previously indexed, it is removed first (full re-index of that file).

func (*TrigramIndex) Query

func (idx *TrigramIndex) Query(pattern string) []string

Query returns candidate file paths that contain ALL trigrams from the pattern. For short patterns (<3 bytes), returns all indexed files (no filtering possible). The candidates are a superset of actual matches — callers must verify with regex.

func (*TrigramIndex) RemoveFile

func (idx *TrigramIndex) RemoveFile(path string)

RemoveFile removes a file from the index.

func (*TrigramIndex) Size

func (idx *TrigramIndex) Size() int

Size returns the number of indexed files.

type TypeScriptCodeServer added in v0.1.161

type TypeScriptCodeServer struct {
	*DefaultCodeServer
}

TypeScriptCodeServer extends DefaultCodeServer with TypeScript / JavaScript-specific operations: GetProjectInfo (package.json + per-file import scan).

Per-file import extraction is line-based Go scanning — same philosophy as PythonCodeServer's scanPackageImports. We avoid requiring Node.js for the dependency view.

func NewTypeScriptCodeServer added in v0.1.161

func NewTypeScriptCodeServer(dir string, serverOpts []ServerOption) *TypeScriptCodeServer

NewTypeScriptCodeServer creates a TS-aware code server.

func (*TypeScriptCodeServer) GetProjectInfo added in v0.1.161

type VCSProvider

type VCSProvider interface {
	// Log returns recent commits, optionally filtered by ref, path, and date.
	Log(ctx context.Context, maxCount int, ref, path, since string) ([]*GitCommitInfo, error)

	// Diff returns a diff between two refs (or working copy if refs are empty).
	// Returns the full diff text and per-file statistics.
	Diff(ctx context.Context, baseRef, headRef, path string, contextLines int, statOnly bool) (string, []*GitDiffFileInfo, error)

	// Show returns the content of a file at a specific ref.
	Show(ctx context.Context, ref, path string) (string, bool, error)

	// Blame returns line-by-line authorship of a file.
	Blame(ctx context.Context, path string, startLine, endLine int32) ([]*GitBlameLine, error)
}

VCSProvider abstracts version control operations. Both git and jj implement this interface, allowing the DefaultCodeServer to dispatch VCS operations without knowing which VCS is in use.

The response types (GitCommitInfo, GitDiffFileInfo, etc.) are VCS-agnostic despite their "Git" prefix — they map to the Code proto responses.

type VFS

type VFS interface {
	ReadFile(path string) ([]byte, error)
	WriteFile(path string, data []byte, perm os.FileMode) error
	Remove(path string) error
	Rename(oldpath, newpath string) error
	Stat(path string) (os.FileInfo, error)
	MkdirAll(path string, perm os.FileMode) error
	WalkDir(root string, fn fs.WalkDirFunc) error
	ReadDir(path string) ([]os.DirEntry, error)
}

VFS abstracts filesystem operations so DefaultCodeServer can work with local disk, in-memory stores, overlay layers, or remote backends. All paths are absolute -- the server joins SourceDir + relative before calling.

type VFSProvider

type VFSProvider interface {
	GetVFS() VFS
	GetSourceDir() string
}

VFSProvider is implemented by servers that expose their underlying VFS and root directory for in-process use (e.g. relevance scoring, timeline building).

type WriteListener

type WriteListener func(ctx context.Context, kind, path, prevPath string, content []byte) error

WriteListener is called after every successful file mutation so that external indexes or subscribers can stay aligned with the VFS state.

The listener receives the mutation kind ("write", "create", "delete", "move"), the relative path (destination for moves), and the new file content if available. For deletes and moves the content argument is nil. For the move kind, prevPath is the source path; it is empty otherwise.

Errors returned by the listener are logged by the caller but do NOT fail the mutation; notification is best-effort.

Jump to

Keyboard shortcuts

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