index

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package index is the local index: a SQLite store of markdown files and their embedded chunks, plus the incremental (re)indexer that keeps it in sync with a directory tree. The driver is modernc.org/sqlite (pure Go — no cgo for the storage side; cgo is only ever pulled in by internal/embed for ONNX inference).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultDBPath

func DefaultDBPath(vault string) string

DefaultDBPath is where the index lives for a given vault root: <vault>/.semantic/index.db. Per-vault, gitignorable, travels with the tree.

Types

type ChunkRow

type ChunkRow struct {
	RelPath string
	Key     string
	Heading string
	Variant string
	Text    string
	Line    int
	Vec     embed.Vec
}

ChunkRow is one chunk joined to its file, as returned to the search layer.

type Embedder

type Embedder func(text string) (embed.Vec, error)

Embedder turns chunk text into a vector. Injected so the indexer is testable without the ONNX runtime; production passes embed.Get. A nil Embedder opts a Reindex call into skip-embed mode: chunks are stored with a zero-length placeholder vec instead, and a later Reindex with a real Embedder detects and heals them regardless of whether the file's stat or content hash otherwise looks unchanged.

type FileMeta

type FileMeta struct {
	RelPath string
	MtimeNS int64
	Size    int64
	Hash    string
}

FileMeta is the on-disk identity of a markdown file: its path relative to the vault root (forward-slashed) plus the stat + content-hash used to decide whether it needs re-embedding.

type LinkRow

type LinkRow struct {
	SrcRelPath string
	Target     string
	Anchor     string
	Kind       string
	Line       int
}

LinkRow is one stored outbound link joined to its source file's rel-path, as returned to the graph layer.

type Report

type Report struct {
	Added     int // files newly indexed
	Updated   int // files whose content changed and were re-embedded
	Unchanged int // files skipped (stat match, or hash match after a touch)
	Relinked  int // files whose links were re-extracted without re-embedding
	Deleted   int // files removed from the index (gone from disk)
	Files     int // total files in the index afterward
	Chunks    int // total chunks in the index afterward
	Duration  time.Duration

	// Rebuild explains why this run redid work the content hashes said was
	// unnecessary — an upgrade that changed the chunker, the link extractor, or
	// the embedding model. Empty on an ordinary incremental run. Callers should
	// surface it: an automatic rebuild is a long pause on a command that is
	// normally instant, and silence makes it look like a hang.
	Rebuild string
}

Report summarizes a Reindex run.

type Stats

type Stats struct {
	Files       int
	Chunks      int
	LastIndexed time.Time
}

Stats is index size and recency, for `semantic status`.

type Store

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

Store wraps the SQLite index database.

func Open

func Open(path string) (*Store, error)

Open opens (creating if needed) the index database at path, creating the parent directory and applying the schema. Foreign keys are enabled so a file delete cascades to its chunks; a busy timeout absorbs brief lock contention. A single open connection serializes access, which is all a single-process CLI needs and sidesteps SQLite "database is locked".

func (*Store) AllChunks

func (s *Store) AllChunks(pathPrefix string) ([]ChunkRow, error)

AllChunks returns every chunk in the index, optionally restricted to files whose rel_path begins with pathPrefix (empty = no filter). The search layer cosine-ranks these in memory.

func (*Store) AllFiles

func (s *Store) AllFiles() ([]string, error)

AllFiles returns every indexed file's rel-path, sorted. The graph layer uses this as the universe of link targets to resolve against.

func (s *Store) AllLinks() ([]LinkRow, error)

AllLinks returns every stored link edge (source file → raw target). Targets are unresolved — the graph layer maps them onto AllFiles.

func (*Store) Close

func (s *Store) Close() error

Close closes the underlying database.

func (*Store) FileHeadings

func (s *Store) FileHeadings() (map[string]map[string]bool, error)

FileHeadings returns, per indexed file rel-path, the set of section-anchor slugs that file defines — the valid targets for a link's #fragment. Slugs come from the stored heading breadcrumbs via the same slugifier the chunker uses for keys, so no re-parse is needed. Files with no headings are absent from the map (any #anchor into them is unresolvable).

func (*Store) RebuildReason

func (s *Store) RebuildReason(canEmbed bool) (string, error)

RebuildReason reports why the next Reindex will redo work that the content hashes alone would skip, or "" when it will not. Reindex reports the same string afterwards; this exists so a caller can say so *first*. A rebuild turns an ordinarily instant command into a multi-minute one, and an unexplained pause is indistinguishable from a hang.

canEmbed must match the embedder the caller will pass to Reindex, or the answer describes a different run than the one about to happen.

func (*Store) Reindex

func (s *Store) Reindex(root string, embedFn Embedder, force bool) (*Report, error)

Reindex walks root, incrementally syncing the index to the indexable files under it (markdown and source code — see chunkers): new/changed files are chunked and embedded, touched-but-identical files are cheaply restatted, and files gone from disk are removed. embedFn supplies vectors (embed.Get in production); pass nil to skip embedding entirely (see Embedder).

The change test is two-tier: a (mtime, size) match skips the file without reading it; otherwise the file is read and its sha256 compared, so a touch that didn't change bytes costs a read but no embedding. force bypasses both checks, re-chunking, re-embedding, and re-extracting links for every file regardless of whether its content changed — the escape hatch for when the chunker or link extractor itself changes behavior, since content-hash diffing has no way to know an unchanged file would now produce different chunks or links.

func (*Store) Stats

func (s *Store) Stats() (Stats, error)

Stats reports index size and recency for `semantic status`.

Jump to

Keyboard shortcuts

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