Skip to main content

rustbrain_core/
lib.rs

1//! # rustbrain-core
2//!
3//! Project-scoped **knowledge graph engine** for software repositories: Markdown notes,
4//! optional Rust AST symbols, ranked full-text search, and graph-aware AI agent context.
5//!
6//! This is the primary library crate for embedding rustbrain in tools, agents, and CLIs.
7//! Humans edit plain Markdown (Obsidian-compatible WikiLinks and YAML frontmatter);
8//! `rustbrain-core` derives a SQLite graph + FTS index and an optional CSR `graph.mmap` cache.
9//!
10//! ## Quick start
11//!
12//! ```no_run
13//! use rustbrain_core::{Brain, ContextOptions, QueryOptions, Result};
14//!
15//! fn main() -> Result<()> {
16//!     // Creates `<cwd>/.brain/db.sqlite` if missing
17//!     let mut brain = Brain::open_or_create(".")?;
18//!
19//!     // Walk Markdown / Rust / Canvas, update FTS, resolve links, bake graph.mmap
20//!     let stats = brain.sync()?;
21//!     let _ = stats.markdown_files;
22//!
23//!     // Ranked search: BM25 + tag/alias/title boosts
24//!     let hits = brain.query_ranked("raft consensus", &QueryOptions::default())?;
25//!     for hit in hits.iter().take(3) {
26//!         println!("{:.2} {}", hit.score, hit.node.title);
27//!     }
28//!
29//!     // Agent context: seeds + CSR neighbors, packed under a token budget
30//!     let ctx = brain.context_for_prompt_with(
31//!         "explain log compaction",
32//!         &ContextOptions {
33//!             max_tokens: 1024,
34//!             hop_depth: 1,
35//!             ..ContextOptions::default()
36//!         },
37//!     )?;
38//!     print!("{}", ctx.to_xml());
39//!     Ok(())
40//! }
41//! ```
42//!
43//! ## Crates.io layout
44//!
45//! Only two packages are published:
46//!
47//! | Package | Role |
48//! |---------|------|
49//! | **`rustbrain-core`** (this crate) | Library for apps and agents |
50//! | **`rustbrain`** | CLI binary (`cargo install rustbrain`) |
51//!
52//! AST and Obsidian parsing live **inside** this crate behind feature flags
53//! (`ast`, `obsidian`) — not as separate published crates.
54//!
55//! ## On-disk layout
56//!
57//! Under `<workspace>/.brain/`:
58//!
59//! | Path | Role |
60//! |------|------|
61//! | `db.sqlite` | Source of truth (nodes, edges, FTS5, aliases, symbols) |
62//! | `graph.mmap` | CSR adjacency + node-id table for fast neighborhood walks |
63//! | `workspace.json` | Workspace marker |
64//!
65//! ## Feature flags
66//!
67//! | Feature | Default | Purpose |
68//! |---------|---------|---------|
69//! | `ast` | yes | Tree-sitter Rust symbol extraction |
70//! | `obsidian` | yes | WikiLinks, frontmatter, Canvas |
71//! | `mmap` | yes | Compile and read `.brain/graph.mmap` |
72//! | `watch` | no | Debounced filesystem watcher |
73//! | `jshift` | no | In-place JSON field mutation helpers |
74//! | `full` | no | Enables every optional feature |
75//!
76//! ## Error handling
77//!
78//! Fallible APIs return [`Result<T>`] aliasing [`BrainError`]. Match on variants at
79//! library boundaries; the CLI may wrap errors in `anyhow`.
80//!
81//! ## Non-goals (v0.1)
82//!
83//! - Neural embeddings / ANN indexes (product path uses `vector_dim = 0`)
84//! - Multi-user servers or cloud sync
85//! - Full Obsidian vault write-back (ingest only)
86
87#![warn(missing_docs)]
88
89#[cfg(feature = "ast")]
90pub mod ast;
91pub mod brain;
92pub mod context;
93pub mod error;
94pub mod exporter;
95pub mod fts;
96pub mod id;
97pub mod indexer;
98pub mod mmap;
99pub mod mutator;
100#[cfg(feature = "obsidian")]
101pub mod obsidian;
102pub mod query;
103pub mod registry;
104pub mod storage;
105pub mod symbols;
106pub mod types;
107pub mod watch;
108
109pub use brain::Brain;
110pub use context::ContextOptions;
111pub use error::{BrainError, Result};
112pub use exporter::{BrainExporter, BrainImporter, PortableBrainBundle, BUNDLE_VERSION};
113pub use indexer::WorkspaceIndexer;
114pub use mmap::{CsrCompiler, CsrMmapGraph, MMAP_VERSION};
115pub use query::{QueryOptions, RankedHit};
116pub use registry::{GlobalRankedHit, GlobalRegistry};
117pub use storage::{Database, SCHEMA_VERSION};
118pub use symbols::{extract_symbol_refs, symbol_node_id, SymbolRef};
119pub use types::{
120    xml_escape, ContextBundle, ContextNode, ContextRole, Edge, Node, NodeType, SyncStats,
121};
122pub use watch::WatchConfig;
123
124#[cfg(feature = "ast")]
125pub use ast::{compute_symbol_hash, AstError, CodeAstParser, SymbolAnchor};
126
127#[cfg(feature = "obsidian")]
128pub use obsidian::{
129    extract_wikilinks, parse_frontmatter, CanvasEdge, CanvasNode, Frontmatter, ObsidianCanvas,
130    WikiLink,
131};
132
133#[cfg(feature = "jshift")]
134pub use mutator::{extract_json_field_slice, update_json_field_inplace};
135
136#[cfg(feature = "watch")]
137pub use watch::watch_workspace;