@monoes/monograph
v2.24.0
Published
Code intelligence engine for monomind — tree-sitter WASM grammars + SQLite knowledge graph, no native builds
Readme
@monoes/monograph
Code intelligence as a graph — tree-sitter parses your codebase into a SQLite-backed knowledge graph of files, functions, classes, imports, and call relationships. Query blast radius, find callers, and navigate architecture without grep.
Part of the Monomind ecosystem.
Install
npm install @monoes/monographWhat it does
Monograph walks your source tree with tree-sitter, extracts symbols and their relationships, and stores them in a SQLite database. The result is a queryable graph where:
- Nodes are files, functions, classes, methods, and exports
- Edges are imports, calls, extends, and contains relationships
CLI usage
# Build the graph for the current project
monomind monograph build
# Search the knowledge graph (BM25, semantic, or hybrid)
monomind monograph search -q "authentication flow"
# Show graph statistics
monomind monograph stats
# Watch for changes and rebuild incrementally
monomind monograph watch
# Start the LSP server for editor integration
monomind monograph lsp
# Build a document knowledge graph from docs & PDFs (separate from the code graph above)
monomind monograph wiki
impact(blast radius),god-nodes(high-centrality files), and freshness/staleness checks have no CLI subcommand — they're MCP-tool-only (monograph_impact,monograph_god_nodes,monograph_health,monograph_staleness), see MCP tools below.statsabove reports graph size, not freshness — don't confuse the two.
Programmatic usage
import { buildAsync, openDb, queryGraph, getMonographImpact } from '@monoes/monograph';
await buildAsync(process.cwd());
const db = openDb('.monomind/monograph.db');
const results = queryGraph(db, { query: 'authenticate' });
const impact = getMonographImpact(db, { name: 'login', filePath: 'src/auth/login.ts' });MCP tools
When used via Monomind's MCP server, monograph exposes 19 tools by default (+27 advanced via MONOGRAPH_MCP_ADVANCED=1):
| Tool | Purpose |
|---|---|
| monograph_suggest | Start every task — ranked relevant files |
| monograph_query | BM25 keyword search with PPR graph reranking |
| monograph_impact | Blast radius analysis (upstream + downstream) |
| monograph_god_nodes | High-centrality internal files |
| monograph_context | 360° view of a file |
| monograph_augment | Graph-RAG context retrieval |
| monograph_dead_code | Dead exports, orphan files, stale dist |
| monograph_detect_changes | Map git diff to affected graph nodes |
| monograph_route_map | List HTTP routes with handlers |
| monograph_watch | Start incremental file watcher — rebuilds on file changes |
| monograph_watch_stop | Stop the incremental file watcher |
| monograph_health | Manual, on-demand staleness check |
| monograph_staleness | Staleness check — auto-triggers a background rebuild if >3 commits behind HEAD |
Supported languages & Parsers
Monograph utilizes a dual-tier parsing strategy for extracting code structure and symbols.
This section is the authoritative source for Monograph's language/grammar counts. Other docs in this repo should link here instead of restating the numbers.
- Tree-sitter AST Parsers — 14 grammar modules, 25 supported extensions:
- Grammar modules (one
LanguageConfig+ tree-sitter package each,src/parsers/):c,cpp,csharp,dart,go,java,kotlin,php,python,ruby,rust,swift,typescript,vue— 14 total. (typescriptalso covers JavaScript; there is no separate JS grammar.) - Extensions:
.ts,.tsx,.js,.jsx,.mjs,.cjs,.py,.go,.rs,.java,.c,.h,.cpp,.cc,.cxx,.hpp,.hxx,.cs,.rb,.swift,.php,.vue,.kt,.kts,.dart— 25 total, mapped onto the 14 grammar modules above. - Grammar Loader: Dynamically loads and caches Tree-sitter grammars per extension via
getParser(ext)(loader.ts:64-83). Supports<script>block isolation for.vuefiles (loader.ts:128-142). - Best-effort grammars:
getParser()validates every grammar by binding it to a scratchParserbefore trusting it — arequire()that succeeds can still return an ABI-incompatibleLanguageobject, only caught on use (MEM-2,loader.ts:91-108).vuehas an explicit fallback to the TypeScript grammar when its own binding fails this check (vue.ts).csharp(loads a prebuilt native binding directly sincetree-sitter-c-sharp's ESM entry can't berequire()d) anddartare currently failing this validation in this checkout/environment (csharp grammar load failed (tree-sitter-c-sharp: Cannot read properties of undefined ...);dart grammar load failed (tree-sitter-dart: Invalid language object)) and fall through to no symbols (csharp, which has no regex fallback) or the regex extractor (dart). Whether they work depends on the native binding's ABI compatibility with the installedtree-sittercore on a given platform/Node version — treatcsharpanddartas best-effort, not guaranteed-working; the other 12 grammar modules validated successfully as of this writing.
- Grammar modules (one
- Regex Fallback Parsers (5 languages, 6 including the
dartfallback when its tree-sitter grammar fails validation):- Lightweight regex-based symbol extractors used when a Tree-sitter grammar is uninstalled, unsupported, or fails MEM-2 validation: Scala, Lua, Zig, PowerShell, Elixir, and (fallback-only) Dart (
language-parsers.ts:1-122).
- Lightweight regex-based symbol extractors used when a Tree-sitter grammar is uninstalled, unsupported, or fails MEM-2 validation: Scala, Lua, Zig, PowerShell, Elixir, and (fallback-only) Dart (
SQLite Database Schema
The graph is stored in a WAL-mode SQLite database (PRAGMA journal_mode = WAL) managed in schema.ts and db.ts:
nodes: Code symbols and files (id,label,name,norm_label,file_path,start_line,end_line,community_id,is_exported,language,properties,embedding).edges: Directed relationships between nodes (id,source_id,target_id,relation,confidence,confidence_score,weight,reason,evidence).communities: Hierarchical community clusters (id,label,size,cohesion_score).file_cache: SHA-256 incremental parse cache (file_path,content_hash,last_parsed,node_count,edge_count).nodes_fts: Trigram-tokenized FTS5 virtual table (tokenize='trigram') indexingname,norm_label, andfile_pathwith sync triggers for rapid symbol and fuzzy text queries.index_meta: Key-value system index metadata (includinglast_commit_hash).
Relationship Types
Monograph defines typed edges (types.ts:20-29) categorized into structural, static analysis, and semantic relationships:
CONTAINS: Parent container to child element (e.g. File contains Class/Function, Class contains Method).IMPORTS: File/Module import dependency (import { x } from './y').CALLS: Function/Method invocation between symbols.ENTRY_POINT_OF: Entry point symbol associated with an agent process or application workflow.- Additional relations include
RE_EXPORTS,EXTENDS,IMPLEMENTS,HAS_METHOD,HAS_PROPERTY,ACCESSES,HANDLES_ROUTE,FETCHES,HANDLES_TOOL,WRAPS,QUERIES,REFERENCES,CO_OCCURS, and LLM-inferred semantic relations (DESCRIBES,CAUSES,CONTRASTS_WITH,PART_OF,RELATED_TO,USES,STRUCTURALLY_SIMILAR).
Blast Radius Calculation (rippleImpact)
Monograph calculates downstream cascade impact using the multi-hop rippleImpact BFS algorithm (ripple-impact.ts:51-84):
- Algorithm: Breadth-First Search propagating through outgoing directed edge adjacency maps.
- Scoring Formula:
$$\text{TotalScore} = \sum_{\text{depth}=1}^{\text{maxDepth}} N_{\text{depth}} \times (\text{decayFactor})^{\text{depth}}$$
(Default
maxDepth = 3,decayFactor = 0.5) - Output: Groups affected nodes by depth level (
byDepth: Record<number, string[]>) and calculates a weighted decay impact score (totalScore). Exposes native blast radius insights via themonograph_impactMCP tool.
Graph Freshness & Git Staleness Tracking
Monograph maintains graph synchronization with git repository state without full re-indexes (git-staleness.ts:13-66):
- Commit Verification: Compares stored
last_commit_hashinindex_metaagainstgit rev-parse HEAD. - Change Diffing: If hashes diverge, executes
git diff --name-only <indexedCommit>..HEADto populatechangedSincefiles. - Divergence Timestamp: Identifies
staleSinceISO timestamp viagit log --format="%ai" <indexedCommit>..HEAD --reverse --max-count=1. - File Content Caching: Computes SHA-256 hashes (
file_cachetable) to skip parsing untouched files during incremental builds.
Incremental Watch Mode
monomind monograph watch (and the monograph_watch MCP tool) debounces file changes by 3s (watcher.ts:108-110), then updates the graph per changed file — delete existing nodes/edges for that file, re-parse, re-insert (orchestrator.ts:312-365):
- Incremental Threshold: If a batch exceeds
INCREMENTAL_THRESHOLD(20 changed files), it falls back to a full rebuild instead of per-file updates (orchestrator.ts:269-279). - Deferred Full Rebuild: After
FULL_REBUILD_IDLE_MS(60s) with no further incremental activity, watch mode runs one full rebuild to refresh aggregate phases (communities, god-nodes, surprises, churn, report) that incremental updates don't recompute (watcher.ts:40-59).
Links
License
MIT
