index

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BackfillEmbeddings

func BackfillEmbeddings(ctx context.Context, st backfillStore, embedder embed.Embedder, log *slog.Logger) (int, error)

BackfillEmbeddings embeds every symbol that has no stored vector (the state a --fast structure-only index leaves behind) and upserts the results in chunks, so an interrupted run resumes where it stopped. Returns the number of symbols embedded.

func ChunkSymbol

func ChunkSymbol(filePath, language string, sym store.Symbol) []store.SymbolChunk

ChunkSymbol splits a capped symbol's lossless body into embeddable windows. Each chunk is prefixed with the same natural-language header the per-symbol embedding leads with, because a bare window of code carries no clue about which symbol it belongs to. Returns nil when the symbol is not capped.

func ChunkingEnabled

func ChunkingEnabled() bool

ChunkingEnabled reports whether chunk embeddings should be built. It reads the same switch the retrieval channel uses, so the two cannot disagree: an index full of chunks no query will ever read is pure waste, and a weight pointing at chunks that were never built is a silent no-op.

func EmbeddingText

func EmbeddingText(filePath, language string, sym store.Symbol) string

EmbeddingText builds the index-time text embedded for a symbol. DECISION(2026-06): v2 profile — a natural-language line (name words, kind, path words) leads the text, followed by docstring, so paraphrastic queries can match symbols that have no doc comment. ASSUMES: the embedder weights early tokens more and the symbol name carries the core semantics. REVISIT IF: paraphrastic slice on the gen corpus does not improve vs v1.

func EmbeddingTextWithNeighbors

func EmbeddingTextWithNeighbors(filePath, language string, sym store.Symbol, neighbors []string) string

EmbeddingTextWithNeighbors adds the names of the symbol's graph neighbours.

DECISION(2026-09): the callers and callees of a symbol are free vocabulary that the symbol's own text does not carry. `resize()` in image.js has nothing to do with the word "avatar" until you notice that `uploadAvatar` calls it — which is exactly the gap that makes an issue report fail to find the code it describes. Measured on SWE-Explore, 14.3% of gold files sit in the index and are never retrieved even at rank 200, and every attempt to reach them by ranking, pool size or graph traversal failed; this attacks the same gap from the indexing side, at no query cost and with no model.

Only the backfill path can supply neighbours, because during the first index pass the edges do not exist yet — embeddings are computed before the call graph is extracted. ASSUMES: neighbour names are more signal than noise at this cap. REVISIT IF: hub symbols (high degree) get worse rather than better.

func IsTestFile

func IsTestFile(name string) bool

DECISION: test file patterns are filtered at the file level, not directory level, because some projects keep legitimate non-test code in directories named "test/". Patterns cover Go (_test.go), TS/JS (.test.*, .spec.*) and Python (test_*.py, *_test.py). IsTestFile reports whether a filename follows a test naming convention. Exported so ranking can ask the same question the walker asks: two copies of this rule silently disagreeing is how a knob ends up dead on arrival (the retrieval package's own isTestFile covers Go and TypeScript only).

func NormalizeDocstring

func NormalizeDocstring(doc string) string

NormalizeDocstring keeps the prose of a doc comment and drops the machinery around it: annotation-only lines, tool directives and markup noise.

DECISION(2026-08): a docstring is not free text to us — it is the largest semantic field in the embedding text, the reranker document and the agent payload. In three ecosystems the MAJORITY of what extractors captured carried no meaning at all: PHP 70% of documented symbols had only `@param Type $x` lines, C++ 59% (plus 22 symbols whose entire "doc" was a NOLINT suppression), TypeScript 61% were bare `/** @internal */`. Embedding those shapes the vector by annotation syntax instead of purpose, and a symbol left with nothing is better served by its name, signature and body. REVISIT IF: a language arrives whose tags carry the only description (then extract the tag's text rather than dropping the line).

func SkipDir

func SkipDir(name string) bool

SkipDir reports whether a directory (by base name) should be excluded from both indexing and watching: known build/vendor/VCS dirs and any dotfile dir.

func Watch

func Watch(ctx context.Context, root string, reindex func(context.Context) error, log *slog.Logger, debounce time.Duration) error

Watch monitors root for source-file changes and calls reindex, debounced by `debounce`. reindex is expected to be an incremental pass (hash-skip), so re-running it on any change re-embeds only what actually changed. Calls are single-flighted: changes arriving while a reindex runs set a dirty flag that schedules exactly one more pass afterward. Watch blocks until ctx is done.

Types

type ExtractorFactory

type ExtractorFactory func(language string) (LanguageExtractor, bool)

ExtractorFactory returns a LanguageExtractor for the given language name. The bool indicates whether the language is supported.

type FakeWalker

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

FakeWalker serves pre-supplied channels for use in tests.

func NewFakeWalker

func NewFakeWalker(records <-chan FileRecord, errs <-chan error) *FakeWalker

func (*FakeWalker) Walk

func (f *FakeWalker) Walk(_ context.Context, _ string) (<-chan FileRecord, <-chan error)

type FileRecord

type FileRecord struct {
	Path     string
	RelPath  string
	Language string
	Hash     string
	ModTime  int64
	Size     int64
}

type FileWalker

type FileWalker interface {
	Walk(ctx context.Context, root string) (<-chan FileRecord, <-chan error)
}

FileWalker is the walker interface consumed by Indexer.

type Indexer

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

func NewIndexer

func NewIndexer(s store.Store, p Parser, e embed.Embedder, w FileWalker, ef ExtractorFactory, log *slog.Logger) *Indexer

func (*Indexer) Index

func (idx *Indexer) Index(ctx context.Context, root string) (Stats, error)

DECISION: file processing is sequential (single goroutine consuming the walker channel). SQLite has a single-writer constraint, so parallelism here would require a work queue + serialized writes anyway. Add bounded parallelism for parse+extract if profiling shows it matters.

func (*Indexer) SetDocOverlay

func (idx *Indexer) SetDocOverlay(m map[string]string)

SetDocOverlay installs synthetic docstrings merged into symbols during indexing. DECISION(2026-06): purpose summaries close the vocabulary gap between intent-style queries ("why") and code text ("how") — the dominant paraphrastic failure on the gen corpus. The summary is prepended to any existing docstring so it leads the embedding text and the reranker document. REVISIT IF: paraphrastic slice does not improve after overlay reindex.

func (*Indexer) SetForceReindex

func (idx *Indexer) SetForceReindex(force bool)

SetForceReindex disables the unchanged-file hash skip so every file is re-parsed and re-embedded. Needed after the doc overlay changes: file hashes stay the same but embedding texts do not. Per-symbol embedding reuse still applies, so only symbols whose text actually changed hit the embedder.

type LanguageExtractor

type LanguageExtractor interface {
	Symbols(tree *tree_sitter.Tree, source []byte) []store.Symbol
	Edges(tree *tree_sitter.Tree, source []byte, nameToID map[string]int64) []store.Edge
}

LanguageExtractor extracts symbols and edges from a parsed syntax tree. SymbolID/FileID are NOT set on returned symbols — caller assigns after persistence. DECISION: intra-file resolution only — cross-file is fuzzy match later.

type Parser

type Parser interface {
	Parse(ctx context.Context, source []byte, language string) (*tree_sitter.Tree, error)
	LanguageNames() []string
	Close() error
}

func NewTreeSitterParser

func NewTreeSitterParser() (Parser, error)

type Stats

type Stats struct {
	FilesIndexed int
	FilesSkipped int
	FilesDeleted int
	Symbols      int
	Edges        int
	Duration     time.Duration
}

type Walker

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

func NewWalker

func NewWalker(log *slog.Logger) *Walker

func NewWalkerWithConfig

func NewWalkerWithConfig(log *slog.Logger, cfg WalkerConfig) *Walker

func (*Walker) SetKnownFiles

func (w *Walker) SetKnownFiles(files map[string]store.File)

func (*Walker) Walk

func (w *Walker) Walk(ctx context.Context, root string) (<-chan FileRecord, <-chan error)

type WalkerConfig

type WalkerConfig struct {
	IncludeTests bool
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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