graph

package
v0.1.1 Latest Latest
Warning

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

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

Documentation

Overview

Package graph defines the knowledge-graph data model and its SQLite store.

The model is deliberately tiny — two entities, Node and Edge — mirroring the upstream codebase-memory-mcp schema. All the richness lives in Node.Props / Edge.Props (JSON blobs) so we never have to migrate columns as the analysis passes get smarter. See docs/ARCHITECTURE.md.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Snippet

func Snippet(repoRoot, filePath string, start, end int) (string, error)

Snippet reads the source lines [start,end] for a node from disk. repoRoot is the absolute root the file_path values are relative to.

Types

type CallEdge

type CallEdge struct {
	SourceQN   string
	TargetQN   string
	SourceFile string
	Props      map[string]any
}

CallEdge is a stored CALLS edge plus its caller's file path — enough for incremental indexing to decide, by scope, which edges to reuse across a re-index.

type Edge

type Edge struct {
	Project  string
	SourceQN string // qualified_name of the source node
	TargetQN string // qualified_name of the target node
	Type     EdgeType
	Props    map[string]any
}

Edge is a directed relationship between two nodes (by qualified name at build time; resolved to node IDs by the store on flush).

type EdgeType

type EdgeType string

EdgeType is the kind of a relationship between two nodes. The MVP only emits a subset; the rest are reserved so query code can be written against the full vocabulary from day one. Mirrors the upstream edge types.

const (
	EdgeDefines       EdgeType = "DEFINES"       // container -> member (file defines func, class defines method)
	EdgeContainsFile  EdgeType = "CONTAINS_FILE" // folder/module -> file
	EdgeCalls         EdgeType = "CALLS"         // caller -> callee (needs real resolution / LSP)
	EdgeImports       EdgeType = "IMPORTS"       // module -> imported module
	EdgeInherits      EdgeType = "INHERITS"      // class -> base class
	EdgeImplements    EdgeType = "IMPLEMENTS"    // class -> interface
	EdgeDecorates     EdgeType = "DECORATES"     // decorator -> target (Nest @Injectable etc.)
	EdgeHTTPCalls     EdgeType = "HTTP_CALLS"    // call-site -> route (cross-service)
	EdgeSimilarTo     EdgeType = "SIMILAR_TO"    // near-clone (MinHash + LSH)
	EdgeSemanticalRel EdgeType = "SEMANTICALLY_RELATED"
)

type HubCount

type HubCount struct {
	Node    Node
	Callers int
}

HubCount is a call hub plus how many distinct callers point at it.

type Node

type Node struct {
	ID            int64          // assigned by the store on insert
	Project       string         // project name (one store can hold many)
	Label         NodeLabel      //
	Name          string         // short name, e.g. "getActiveCode"
	QualifiedName string         // unique within project
	FilePath      string         // repo-relative path
	StartLine     int            //
	EndLine       int            //
	Props         map[string]any // signature, params, complexity, is_test, ...
}

Node is a symbol or container in the codebase. qualified_name is the unique key within a project (e.g. "proj.apps.api.src.foo.Bar.baz").

type NodeLabel

type NodeLabel string

NodeLabel is the kind of a graph node (its "type" in graph terms).

const (
	LabelFile      NodeLabel = "File"
	LabelModule    NodeLabel = "Module"
	LabelFunction  NodeLabel = "Function"
	LabelMethod    NodeLabel = "Method"
	LabelClass     NodeLabel = "Class"
	LabelInterface NodeLabel = "Interface" // TS interface
	LabelType      NodeLabel = "Type"      // TS type alias
	LabelEnum      NodeLabel = "Enum"      // TS enum
	LabelVariable  NodeLabel = "Variable"  // exported/top-level binding
	LabelRoute     NodeLabel = "Route"     // HTTP endpoint (later pass)
)

type SearchHit

type SearchHit struct {
	Node Node
	Rank float64
}

SearchHit is a ranked result from the FTS index.

type Store

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

Store is the SQLite-backed knowledge graph. Two tables (nodes, edges) plus an FTS5 index over node names. The whole "graph" is an adjacency list with indexes on edge source/target/type — graph queries are just indexed SQL.

func Open

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

Open opens (creating if needed) the graph store at path.

func (*Store) CallEdges

func (s *Store) CallEdges(project string) ([]CallEdge, error)

CallEdges returns every CALLS edge in the project with its caller's file path. Read before a re-index so unchanged scopes' edges can be kept instead of re-resolved (the expensive scip / go+VTA pass).

func (*Store) CallHubs

func (s *Store) CallHubs(project string, limit int) ([]HubCount, error)

CallHubs returns the most-called nodes with their inbound-CALLS count — the call hotspots for get_architecture (TopByInboundCalls without the count loses the metric).

func (*Store) Close

func (s *Store) Close() error

func (*Store) EdgeTypeCounts

func (s *Store) EdgeTypeCounts(project string) (map[string]int, error)

func (*Store) FileHashes

func (s *Store) FileHashes(project string) (map[string]string, error)

FileHashes returns the stored sha256 content hash of every File node in the project, keyed by repo-relative path. The basis for incremental indexing: comparing these against the files currently on disk yields the change set.

func (*Store) FileSymbolCounts

func (s *Store) FileSymbolCounts(project string) (map[string]int, error)

FileSymbolCounts returns symbol count per file (File nodes excluded) — the query layer folds these into per-directory package stats.

func (*Store) FunctionsWithoutInboundCalls

func (s *Store) FunctionsWithoutInboundCalls(project string) ([]Node, error)

FunctionsWithoutInboundCalls returns Function/Method nodes that no in-graph CALLS edge points at — the raw candidate set for the dead-code hint. It is only the graph half of the answer: the query layer still drops entry points (exported, decorated, main/init, tests) before reporting, because those have no in-graph caller by design, not because they're dead.

func (*Store) InsertEdges

func (s *Store) InsertEdges(edges []Edge) (inserted, dropped int, err error)

InsertEdges resolves source/target qualified names to node IDs and inserts. QN→id resolution is done once in memory (was one correlated subquery per edge — O(edges) two-table lookups). Edges whose endpoints don't exist are dropped.

func (*Store) InsertNodes

func (s *Store) InsertNodes(nodes []Node) error

InsertNodes inserts nodes and assigns IDs, keeping the FTS index in sync.

func (*Store) LabelCounts

func (s *Store) LabelCounts(project string) (map[string]int, error)

LabelCounts / EdgeTypeCounts / LanguageCounts are the headline aggregates for get_architecture: nodes per label, edges per type, and File nodes per language.

func (*Store) LanguageCounts

func (s *Store) LanguageCounts(project string) (map[string]int, error)

func (*Store) Neighbors

func (s *Store) Neighbors(project, qualifiedName, direction, edgeType string, limit int) ([]Node, error)

Neighbors returns nodes connected to the given qualified name. direction is "out" (callees/dependencies), "in" (callers/dependents) or "both". edgeType filters by relationship when non-empty.

func (*Store) ReplaceProject

func (s *Store) ReplaceProject(project string) error

ReplaceProject wipes a project's nodes/edges/FTS so a re-index is clean. (Incremental indexing — only changed files — is a later milestone.)

func (*Store) SampleByLabel

func (s *Store) SampleByLabel(project, label string, limit int) ([]Node, error)

SampleByLabel returns a deterministic sample of nodes of a given label (ordered by qualified name) — used to pick "where is X defined" questions.

func (*Store) Search

func (s *Store) Search(project, query, label string, limit int) ([]SearchHit, error)

Search runs a BM25 FTS query over node names/qualified names. `label` filters by node kind when non-empty.

func (*Store) Stats

func (s *Store) Stats(project string) (nodes, edges int, err error)

Stats returns node/edge counts for a project.

func (*Store) TopByComplexity

func (s *Store) TopByComplexity(project string, limit int) ([]Node, error)

TopByComplexity returns Function/Method nodes ranked by stored cyclomatic complexity (properties.complexity), highest first — the complexity hotspots.

func (*Store) TopByInboundCalls

func (s *Store) TopByInboundCalls(project string, limit int) ([]Node, error)

TopByInboundCalls returns the nodes with the most inbound CALLS edges — the call hubs. These make the most discriminating benchmark questions ("who calls X"): a real caller set the grep baseline has to reconstruct by hand.

func (*Store) TopByOutboundCalls

func (s *Store) TopByOutboundCalls(project string, limit int) ([]Node, error)

TopByOutboundCalls returns the nodes that call the most other nodes — useful for "what does X call" (callees) benchmark/quality questions.

Jump to

Keyboard shortcuts

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