topology

package
v0.0.0-...-215f043 Latest Latest
Warning

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

Go to latest
Published: Jun 16, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package topology maintains a persistent, disk-based semantic index of the workspace codebase using SQLite + FTS5.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContentHash

func ContentHash(text string) string

ContentHash hashes an embed doc; with the model name it is the cache key for a vector. Content-keyed (not node-id-keyed) so the cache survives re-indexing.

func DBPath

func DBPath(workspace string) string

DBPath returns the canonical path to the topology database for the given workspace.

func EmbedDoc

func EmbedDoc(n Node) string

EmbedDoc is the text embedded for a node — name, signature, and docstring, the fields that carry meaning for semantic search. Capped so a giant docstring cannot blow the embedder's per-input token limit.

func FormatStatus

func FormatStatus(s Status, workspace string) string

FormatStatus renders a Status as a human-readable string for the topology_status tool.

Types

type Direction

type Direction int

Direction controls which edges a directed BFS traversal follows.

const (
	// DirectionBoth follows edges in both directions (default, undirected).
	DirectionBoth Direction = 0
	// DirectionOutward follows edges from the frontier (from_id → to_id).
	DirectionOutward Direction = 1
	// DirectionInward follows edges toward the frontier (to_id → from_id).
	DirectionInward Direction = 2
)

type Edge

type Edge struct {
	ID         int64
	FromID     int64
	ToID       int64
	Kind       EdgeKind
	Confidence float64
	Source     string
}

Edge is a directed relationship between two nodes.

type EdgeKind

type EdgeKind string

EdgeKind is the type of a relationship between two nodes.

const (
	EdgeCalls      EdgeKind = "calls"
	EdgeImports    EdgeKind = "imports"
	EdgeContains   EdgeKind = "contains"
	EdgeDefines    EdgeKind = "defines"
	EdgeInherits   EdgeKind = "inherits"
	EdgeImplements EdgeKind = "implements"
)

type ExploreOpts

type ExploreOpts struct {
	Depth         int
	MaxNodes      int
	MaxBytes      int
	IncludeSource string // none | signatures | snippets | full
	EdgeKinds     []string
	Direction     Direction // defaults to DirectionBoth
}

ExploreOpts controls the bounded BFS neighbourhood expansion.

type Extractor

type Extractor interface {
	// Language returns the canonical language name (e.g. "go", "python").
	Language() string
	// Extensions returns file extensions this extractor handles (e.g. ".go").
	Extensions() []string
	// Extract parses src (content of the file at workspace-relative path).
	// Returns (nil, nil, nil) for files that cannot be parsed or should be skipped.
	Extract(ctx context.Context, path string, src []byte) ([]Node, []Edge, error)
}

Extractor parses source files and returns nodes and edges. Implementations must be stateless and safe for concurrent use.

type ImpactOpts

type ImpactOpts struct {
	Depth     int
	MaxNodes  int
	MaxBytes  int
	EdgeKinds []string
}

ImpactOpts controls the bidirectional BFS used by topology_impact.

type ImpactResult

type ImpactResult struct {
	Centre       Node
	DependsOn    *Neighbourhood // outward: what centre depends on
	DependedOnBy *Neighbourhood // inward: what depends on centre
}

ImpactResult is the result of a bidirectional BFS around a centre node.

func Impact

func Impact(ctx context.Context, db *sql.DB, name string, opts ImpactOpts) (*ImpactResult, error)

Impact performs two directed BFS traversals from the named symbol:

  • DependsOn: outward (centre → what it depends on)
  • DependedOnBy: inward (what depends on centre → centre)

The same hard caps as Explore apply.

func ImpactFrom

func ImpactFrom(ctx context.Context, db *sql.DB, centre Node, opts ImpactOpts) (*ImpactResult, error)

ImpactFrom performs the bidirectional BFS from an already-resolved centre node, so a caller that disambiguated an ambiguous name (via ResolveNodes) controls exactly which node anchors the blast-radius analysis.

type Indexer

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

Indexer manages background extraction and persistence for one workspace. It owns a queue channel and a single background goroutine.

Concurrency: all exported methods are safe for concurrent use.

func (*Indexer) Enqueue

func (idx *Indexer) Enqueue(path string, kind opKind)

Enqueue adds a file operation to the background queue. Non-blocking; drops silently if the queue is full (capacity 256 is generous for typical usage).

func (*Indexer) LastError

func (idx *Indexer) LastError() string

LastError returns the most recent indexing error, or "".

func (*Indexer) LastSync

func (idx *Indexer) LastSync() time.Time

LastSync returns the time of the most recent completed resync.

func (*Indexer) Start

func (idx *Indexer) Start()

Start launches the background worker and enqueues an initial full resync.

func (*Indexer) State

func (idx *Indexer) State() string

State returns the current indexer state string.

func (*Indexer) Stop

func (idx *Indexer) Stop()

Stop signals the background worker to exit and waits for it to drain its current operation before returning. The wg.Wait() ensures any in-progress transaction completes before the caller may close the database. Safe to call more than once; subsequent calls are no-ops.

type Neighbourhood

type Neighbourhood struct {
	Centre    Node
	Nodes     []Node
	Edges     []Edge
	Truncated bool
}

Neighbourhood is the result of a BFS exploration around a centre node.

func Explore

func Explore(ctx context.Context, db *sql.DB, name string, opts ExploreOpts) (*Neighbourhood, error)

Explore performs a bounded BFS from the named symbol and returns its neighbourhood.

func ExploreFrom

func ExploreFrom(ctx context.Context, db *sql.DB, centre Node, opts ExploreOpts) (*Neighbourhood, error)

ExploreFrom performs the bounded BFS from an already-resolved centre node. Callers that disambiguate an ambiguous symbol name themselves (via ResolveNodes) use this so the traversal is guaranteed to start from the intended node rather than an arbitrary first match.

type Node

type Node struct {
	ID        int64
	FileID    int64
	Kind      NodeKind
	Name      string
	Qualified string
	Signature string
	StartLine int
	EndLine   int
	Docstring string
	Language  string
	Path      string // workspace-relative
}

Node is a semantic entity in the topology graph.

func ResolveNodes

func ResolveNodes(ctx context.Context, db *sql.DB, name string, hint NodeHint) ([]Node, error)

ResolveNodes returns every indexed node whose name or qualified name equals name, ordered deterministically by path then start line. When hint is non-empty and matches at least one candidate the result is restricted to the matching nodes; a hint that matches nothing is ignored, so a stale hint never turns a real symbol into a miss. The first element is the best pick for a traversal start; any remaining elements are genuine same-name alternatives a caller can surface for disambiguation.

type NodeHint

type NodeHint struct {
	PathSubstr string // case-insensitive substring of the node's file path
	Kind       string // exact NodeKind match (e.g. "function", "method")
}

NodeHint narrows an ambiguous symbol-name resolution to a specific node. Both fields are optional; an empty hint matches every candidate.

type NodeKind

type NodeKind string

NodeKind is the type of a semantic node in the topology graph.

const (
	KindFile     NodeKind = "file"
	KindPackage  NodeKind = "package"
	KindFunction NodeKind = "function"
	KindMethod   NodeKind = "method"
	KindType     NodeKind = "type"
	KindConstant NodeKind = "constant"
	KindVariable NodeKind = "variable"
	KindImport   NodeKind = "import"
	KindClass    NodeKind = "class"
	KindTest     NodeKind = "test"
	// KindField is a key/column of a data-format file: a SQL column, a TOML or
	// YAML key. Used by the config/markup tree-sitter extractors. NOTE: a member
	// field/property of a *code* type (struct field, class property) is NOT a
	// KindField — it is a KindConstant (when declared immutable) or KindVariable,
	// per the documented extractor conventions.
	KindField NodeKind = "field"
	// KindSection is a document heading (a Markdown section). Used by the
	// markup tree-sitter extractors for navigable document outlines.
	KindSection NodeKind = "section"
)

type SearchOpts

type SearchOpts struct {
	Kinds    []string
	Language string
	Limit    int
	Snippets bool
}

SearchOpts controls the behaviour of a topology search query.

type SearchResult

type SearchResult struct {
	Node    Node
	Score   float64
	Field   string
	Snippet string
}

SearchResult is one ranked hit from a topology FTS5 search.

func Search(ctx context.Context, db *sql.DB, query string, opts SearchOpts) ([]SearchResult, error)

Search performs a ranked FTS5 search over the topology index.

type Status

type Status struct {
	IndexedFiles int
	SkippedFiles int
	EmptyFiles   int // successfully indexed files with zero nodes (comment-only, unsupported language, etc.)
	TotalNodes   int
	TotalEdges   int
	DBSizeBytes  int64
	LastSync     time.Time
	IndexerState string
	Languages    []string
	LastError    string
}

Status is a snapshot of the topology index health.

func Report

func Report(db *sql.DB, workspace string, idx *Indexer) Status

Report builds a Status snapshot of the topology index.

func StatusForWorkspace

func StatusForWorkspace(ws string) (Status, error)

StatusForWorkspace opens the topology index for ws strictly read-only and returns a Status snapshot without starting an indexer. It is intended for out-of-daemon inspectors such as `plumb doctor` and the TUI. A missing database is reported as an error satisfying os.IsNotExist; the IndexerState in the returned Status is "stopped" because no live indexer is attached.

The connection is opened with mode=ro so the inspection is side-effect-free: it never writes the main database and — when the daemon is down and the WAL has been checkpointed away on clean shutdown — creates no -wal/-shm sidecars. This mirrors stats.OpenReadOnly.

type Store

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

Store is the public API for topology. It owns a database connection and an Indexer. Obtain one via Open; release resources with Close.

Concurrency: Store is safe for concurrent use after Open returns.

func Open

func Open(workspace string, cfg config.TopologyConfig, exts []Extractor) (*Store, error)

Open opens or creates the topology index for workspace. It starts the background indexer automatically. The caller must call Close when done.

func (*Store) Close

func (s *Store) Close() error

Close stops the indexer and closes the database. Safe to call from any goroutine; subsequent calls are no-ops.

func (*Store) Enqueue

func (s *Store) Enqueue(path string)

Enqueue schedules a file for re-indexing. path may be absolute or workspace-relative. Non-blocking; drops silently if the queue is full. When the file no longer exists on disk, processUpsert detects the ENOENT and automatically routes to processDelete — callers do not need a separate delete call.

func (*Store) Explore

func (s *Store) Explore(ctx context.Context, name string, opts ExploreOpts) (*Neighbourhood, error)

Explore performs a bounded BFS neighbourhood from the named symbol.

func (*Store) ExploreFrom

func (s *Store) ExploreFrom(ctx context.Context, centre Node, opts ExploreOpts) (*Neighbourhood, error)

ExploreFrom performs a bounded BFS from an already-resolved centre node.

func (*Store) ExtractFile

func (s *Store) ExtractFile(ctx context.Context, path string) ([]Node, error)

ExtractFile re-parses the CURRENT content of path with the matching structural extractor and returns its nodes, WITHOUT touching the persisted index. Unlike SymbolsInFile (which reads the possibly-stale index), this reflects the file exactly as it is on disk right now — the property a symbol-edit fallback needs when the language server cannot parse the file. Returns (nil, nil) when no extractor handles the path.

func (*Store) GetEmbeddings

func (s *Store) GetEmbeddings(ctx context.Context, model string, hashes []string) (map[string][]float32, error)

GetEmbeddings returns the cached vectors for the given content hashes under model, keyed by hash. Missing hashes are simply absent from the result.

func (*Store) Impact

func (s *Store) Impact(ctx context.Context, name string, opts ImpactOpts) (*ImpactResult, error)

Impact performs a bidirectional BFS around the named symbol.

func (*Store) ImpactFrom

func (s *Store) ImpactFrom(ctx context.Context, centre Node, opts ImpactOpts) (*ImpactResult, error)

ImpactFrom performs a bidirectional BFS from an already-resolved centre node.

func (*Store) NodesByKind

func (s *Store) NodesByKind(ctx context.Context, kinds ...NodeKind) ([]Node, error)

NodesByKind returns every indexed node of the given kinds, with docstrings populated, ordered by path then start line. It is the enumeration primitive behind the curated structural_query checks (undocumented exports, long functions, …) that scan the index by symbol category rather than by name. Returns an empty slice when no kinds are supplied or none match.

func (*Store) PutEmbeddings

func (s *Store) PutEmbeddings(ctx context.Context, model string, byHash map[string][]float32) error

PutEmbeddings upserts vectors for model, keyed by content hash, in one transaction.

func (*Store) ResolveNodes

func (s *Store) ResolveNodes(ctx context.Context, name string, hint NodeHint) ([]Node, error)

ResolveNodes returns the indexed nodes matching name (optionally narrowed by hint), ordered deterministically. The tools use it to disambiguate a symbol name to a specific node before starting an ID-correct traversal.

func (*Store) Resync

func (s *Store) Resync()

Resync triggers a full workspace resync in the background.

func (*Store) Search

func (s *Store) Search(ctx context.Context, query string, opts SearchOpts) ([]SearchResult, error)

Search performs a ranked FTS5 search over the topology index.

func (*Store) Status

func (s *Store) Status() Status

Status returns a snapshot of the index health.

func (*Store) SymbolsInFile

func (s *Store) SymbolsInFile(ctx context.Context, path string) ([]Node, error)

SymbolsInFile returns the indexed symbols for a single file, ordered by start line. path may be absolute, a file:// URI, or workspace-relative. Returns an empty slice (no error) when the file is not in the index.

func (*Store) TestsInDirs

func (s *Store) TestsInDirs(ctx context.Context, dirs []string) ([]Node, error)

TestsInDirs returns the indexed test nodes (KindTest) whose file sits directly in one of the given workspace-relative directories. It is the recall booster for topology_affected: an extractor only emits intra-file call edges, so a test in a sibling file (Go `foo_test.go`, Python `test_foo.py`) that exercises a changed symbol is not graph-connected — but it is co-located, which is a strong (if heuristic) signal it should be run. Directories are compared by exact parent match, so subdirectory tests are not pulled in.

Directories

Path Synopsis
extractors
golang
Package golang provides a Go AST-based topology extractor.
Package golang provides a Go AST-based topology extractor.
treesitter
Package treesitter provides gotreesitter-backed topology extractors.
Package treesitter provides gotreesitter-backed topology extractors.
typescript
Package typescript provides a regex-based topology extractor for TypeScript and JavaScript source files (.ts, .tsx, .js, .jsx, .mjs, .cjs).
Package typescript provides a regex-based topology extractor for TypeScript and JavaScript source files (.ts, .tsx, .js, .jsx, .mjs, .cjs).

Jump to

Keyboard shortcuts

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