nano-brain 2026.7.13 → 2026.7.101
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +397 -902
- package/npm/postinstall.js +308 -0
- package/npm/postinstall.test.js +345 -0
- package/npm/run.js +41 -0
- package/package.json +24 -49
- package/.opencode/command/nano-brain-init.md +0 -47
- package/.opencode/command/nano-brain-reindex.md +0 -56
- package/.opencode/command/nano-brain-status.md +0 -49
- package/.opencode/command/opsx-apply.md +0 -149
- package/.opencode/command/opsx-archive.md +0 -154
- package/.opencode/command/opsx-explore.md +0 -170
- package/.opencode/command/opsx-propose.md +0 -103
- package/.opencode/skills/openspec-apply-change/SKILL.md +0 -156
- package/.opencode/skills/openspec-archive-change/SKILL.md +0 -114
- package/.opencode/skills/openspec-explore/SKILL.md +0 -288
- package/.opencode/skills/openspec-propose/SKILL.md +0 -110
- package/AGENTS.md +0 -90
- package/AGENTS_SNIPPET.md +0 -48
- package/SKILL.md +0 -145
- package/bin/cli.js +0 -48
- package/config.default.yml +0 -34
- package/dist/bandits.d.ts +0 -36
- package/dist/bandits.d.ts.map +0 -1
- package/dist/bandits.js +0 -117
- package/dist/bandits.js.map +0 -1
- package/dist/bench.d.ts +0 -3
- package/dist/bench.d.ts.map +0 -1
- package/dist/bench.js +0 -897
- package/dist/bench.js.map +0 -1
- package/dist/cache.d.ts +0 -20
- package/dist/cache.d.ts.map +0 -1
- package/dist/cache.js +0 -44
- package/dist/cache.js.map +0 -1
- package/dist/categorizer.d.ts +0 -2
- package/dist/categorizer.d.ts.map +0 -1
- package/dist/categorizer.js +0 -56
- package/dist/categorizer.js.map +0 -1
- package/dist/chunker.d.ts +0 -15
- package/dist/chunker.d.ts.map +0 -1
- package/dist/chunker.js +0 -464
- package/dist/chunker.js.map +0 -1
- package/dist/codebase.d.ts +0 -48
- package/dist/codebase.d.ts.map +0 -1
- package/dist/codebase.js +0 -725
- package/dist/codebase.js.map +0 -1
- package/dist/collections.d.ts +0 -27
- package/dist/collections.d.ts.map +0 -1
- package/dist/collections.js +0 -213
- package/dist/collections.js.map +0 -1
- package/dist/connection-graph.d.ts +0 -13
- package/dist/connection-graph.d.ts.map +0 -1
- package/dist/connection-graph.js +0 -37
- package/dist/connection-graph.js.map +0 -1
- package/dist/consolidation-worker.d.ts +0 -23
- package/dist/consolidation-worker.d.ts.map +0 -1
- package/dist/consolidation-worker.js +0 -93
- package/dist/consolidation-worker.js.map +0 -1
- package/dist/consolidation.d.ts +0 -56
- package/dist/consolidation.d.ts.map +0 -1
- package/dist/consolidation.js +0 -363
- package/dist/consolidation.js.map +0 -1
- package/dist/db/corruption-recovery.d.ts +0 -85
- package/dist/db/corruption-recovery.d.ts.map +0 -1
- package/dist/db/corruption-recovery.js +0 -217
- package/dist/db/corruption-recovery.js.map +0 -1
- package/dist/embeddings.d.ts +0 -29
- package/dist/embeddings.d.ts.map +0 -1
- package/dist/embeddings.js +0 -419
- package/dist/embeddings.js.map +0 -1
- package/dist/entity-extraction.d.ts +0 -21
- package/dist/entity-extraction.d.ts.map +0 -1
- package/dist/entity-extraction.js +0 -93
- package/dist/entity-extraction.js.map +0 -1
- package/dist/entity-merger.d.ts +0 -25
- package/dist/entity-merger.d.ts.map +0 -1
- package/dist/entity-merger.js +0 -191
- package/dist/entity-merger.js.map +0 -1
- package/dist/event-store.d.ts +0 -16
- package/dist/event-store.d.ts.map +0 -1
- package/dist/event-store.js +0 -58
- package/dist/event-store.js.map +0 -1
- package/dist/expansion.d.ts +0 -12
- package/dist/expansion.d.ts.map +0 -1
- package/dist/expansion.js +0 -42
- package/dist/expansion.js.map +0 -1
- package/dist/extraction.d.ts +0 -23
- package/dist/extraction.d.ts.map +0 -1
- package/dist/extraction.js +0 -173
- package/dist/extraction.js.map +0 -1
- package/dist/flow-detection.d.ts +0 -31
- package/dist/flow-detection.d.ts.map +0 -1
- package/dist/flow-detection.js +0 -173
- package/dist/flow-detection.js.map +0 -1
- package/dist/fts-client.d.ts +0 -7
- package/dist/fts-client.d.ts.map +0 -1
- package/dist/fts-client.js +0 -119
- package/dist/fts-client.js.map +0 -1
- package/dist/fts-worker.d.ts +0 -2
- package/dist/fts-worker.d.ts.map +0 -1
- package/dist/fts-worker.js +0 -206
- package/dist/fts-worker.js.map +0 -1
- package/dist/graph.d.ts +0 -26
- package/dist/graph.d.ts.map +0 -1
- package/dist/graph.js +0 -581
- package/dist/graph.js.map +0 -1
- package/dist/harvester.d.ts +0 -51
- package/dist/harvester.d.ts.map +0 -1
- package/dist/harvester.js +0 -696
- package/dist/harvester.js.map +0 -1
- package/dist/host.d.ts +0 -3
- package/dist/host.d.ts.map +0 -1
- package/dist/host.js +0 -30
- package/dist/host.js.map +0 -1
- package/dist/importance.d.ts +0 -21
- package/dist/importance.d.ts.map +0 -1
- package/dist/importance.js +0 -74
- package/dist/importance.js.map +0 -1
- package/dist/index.d.ts +0 -22
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3673
- package/dist/index.js.map +0 -1
- package/dist/intent-classifier.d.ts +0 -16
- package/dist/intent-classifier.d.ts.map +0 -1
- package/dist/intent-classifier.js +0 -41
- package/dist/intent-classifier.js.map +0 -1
- package/dist/llm-categorizer.d.ts +0 -12
- package/dist/llm-categorizer.d.ts.map +0 -1
- package/dist/llm-categorizer.js +0 -75
- package/dist/llm-categorizer.js.map +0 -1
- package/dist/llm-provider.d.ts +0 -35
- package/dist/llm-provider.d.ts.map +0 -1
- package/dist/llm-provider.js +0 -115
- package/dist/llm-provider.js.map +0 -1
- package/dist/logger.d.ts +0 -22
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -134
- package/dist/logger.js.map +0 -1
- package/dist/memory-graph.d.ts +0 -25
- package/dist/memory-graph.d.ts.map +0 -1
- package/dist/memory-graph.js +0 -156
- package/dist/memory-graph.js.map +0 -1
- package/dist/metrics.d.ts +0 -52
- package/dist/metrics.d.ts.map +0 -1
- package/dist/metrics.js +0 -79
- package/dist/metrics.js.map +0 -1
- package/dist/preference-model.d.ts +0 -17
- package/dist/preference-model.d.ts.map +0 -1
- package/dist/preference-model.js +0 -106
- package/dist/preference-model.js.map +0 -1
- package/dist/providers/qdrant.d.ts +0 -26
- package/dist/providers/qdrant.d.ts.map +0 -1
- package/dist/providers/qdrant.js +0 -235
- package/dist/providers/qdrant.js.map +0 -1
- package/dist/providers/sqlite-vec.d.ts +0 -17
- package/dist/providers/sqlite-vec.d.ts.map +0 -1
- package/dist/providers/sqlite-vec.js +0 -200
- package/dist/providers/sqlite-vec.js.map +0 -1
- package/dist/pruning.d.ts +0 -21
- package/dist/pruning.d.ts.map +0 -1
- package/dist/pruning.js +0 -53
- package/dist/pruning.js.map +0 -1
- package/dist/reranker.d.ts +0 -12
- package/dist/reranker.d.ts.map +0 -1
- package/dist/reranker.js +0 -74
- package/dist/reranker.js.map +0 -1
- package/dist/search.d.ts +0 -75
- package/dist/search.d.ts.map +0 -1
- package/dist/search.js +0 -563
- package/dist/search.js.map +0 -1
- package/dist/sequence-analyzer.d.ts +0 -51
- package/dist/sequence-analyzer.d.ts.map +0 -1
- package/dist/sequence-analyzer.js +0 -360
- package/dist/sequence-analyzer.js.map +0 -1
- package/dist/server.d.ts +0 -79
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -3739
- package/dist/server.js.map +0 -1
- package/dist/service-installer.d.ts +0 -25
- package/dist/service-installer.d.ts.map +0 -1
- package/dist/service-installer.js +0 -220
- package/dist/service-installer.js.map +0 -1
- package/dist/storage.d.ts +0 -17
- package/dist/storage.d.ts.map +0 -1
- package/dist/storage.js +0 -232
- package/dist/storage.js.map +0 -1
- package/dist/store.d.ts +0 -44
- package/dist/store.d.ts.map +0 -1
- package/dist/store.js +0 -3130
- package/dist/store.js.map +0 -1
- package/dist/symbol-graph.d.ts +0 -167
- package/dist/symbol-graph.d.ts.map +0 -1
- package/dist/symbol-graph.js +0 -465
- package/dist/symbol-graph.js.map +0 -1
- package/dist/symbols.d.ts +0 -13
- package/dist/symbols.d.ts.map +0 -1
- package/dist/symbols.js +0 -474
- package/dist/symbols.js.map +0 -1
- package/dist/telemetry.d.ts +0 -24
- package/dist/telemetry.d.ts.map +0 -1
- package/dist/telemetry.js +0 -95
- package/dist/telemetry.js.map +0 -1
- package/dist/treesitter.d.ts +0 -44
- package/dist/treesitter.d.ts.map +0 -1
- package/dist/treesitter.js +0 -730
- package/dist/treesitter.js.map +0 -1
- package/dist/types.d.ts +0 -818
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -204
- package/dist/types.js.map +0 -1
- package/dist/vector-store.d.ts +0 -50
- package/dist/vector-store.d.ts.map +0 -1
- package/dist/vector-store.js +0 -23
- package/dist/vector-store.js.map +0 -1
- package/dist/wake-up.d.ts +0 -20
- package/dist/wake-up.d.ts.map +0 -1
- package/dist/wake-up.js +0 -81
- package/dist/wake-up.js.map +0 -1
- package/dist/watcher.d.ts +0 -61
- package/dist/watcher.d.ts.map +0 -1
- package/dist/watcher.js +0 -777
- package/dist/watcher.js.map +0 -1
- package/dist/web/assets/index-Dh0GlmPP.css +0 -1
- package/dist/web/assets/index-IH5W4yGw.js +0 -236
- package/dist/web/index.html +0 -13
- package/dist/web/src/api/client.d.ts +0 -180
- package/dist/web/src/api/client.d.ts.map +0 -1
- package/dist/web/src/api/client.js +0 -65
- package/dist/web/src/api/client.js.map +0 -1
- package/dist/web/src/lib/colors.d.ts +0 -21
- package/dist/web/src/lib/colors.d.ts.map +0 -1
- package/dist/web/src/lib/colors.js +0 -70
- package/dist/web/src/lib/colors.js.map +0 -1
- package/dist/web/src/lib/graph-adapter.d.ts +0 -35
- package/dist/web/src/lib/graph-adapter.d.ts.map +0 -1
- package/dist/web/src/lib/graph-adapter.js +0 -308
- package/dist/web/src/lib/graph-adapter.js.map +0 -1
- package/dist/web/src/store/app.d.ts +0 -7
- package/dist/web/src/store/app.d.ts.map +0 -1
- package/dist/web/src/store/app.js +0 -6
- package/dist/web/src/store/app.js.map +0 -1
- package/dist/web/vite.config.d.ts +0 -3
- package/dist/web/vite.config.d.ts.map +0 -1
- package/dist/web/vite.config.js +0 -18
- package/dist/web/vite.config.js.map +0 -1
- package/dist/workspace-profile.d.ts +0 -26
- package/dist/workspace-profile.d.ts.map +0 -1
- package/dist/workspace-profile.js +0 -51
- package/dist/workspace-profile.js.map +0 -1
- package/docker-compose.yml +0 -59
- package/opencode-mcp.json +0 -9
- package/src/bandits.ts +0 -144
- package/src/bench.ts +0 -1133
- package/src/cache.ts +0 -59
- package/src/categorizer.ts +0 -61
- package/src/chunker.ts +0 -553
- package/src/codebase.ts +0 -876
- package/src/collections.ts +0 -279
- package/src/connection-graph.ts +0 -50
- package/src/consolidation-worker.ts +0 -109
- package/src/consolidation.ts +0 -436
- package/src/db/corruption-recovery.ts +0 -285
- package/src/embeddings.ts +0 -490
- package/src/entity-extraction.ts +0 -124
- package/src/entity-merger.ts +0 -267
- package/src/event-store.ts +0 -75
- package/src/expansion.ts +0 -61
- package/src/extraction.ts +0 -234
- package/src/flow-detection.ts +0 -250
- package/src/fts-client.ts +0 -138
- package/src/fts-worker.ts +0 -238
- package/src/graph.ts +0 -710
- package/src/harvester.ts +0 -858
- package/src/host.ts +0 -31
- package/src/importance.ts +0 -101
- package/src/index.ts +0 -3988
- package/src/intent-classifier.ts +0 -56
- package/src/llm-categorizer.ts +0 -99
- package/src/llm-provider.ts +0 -140
- package/src/logger.ts +0 -141
- package/src/memory-graph.ts +0 -192
- package/src/metrics.ts +0 -98
- package/src/preference-model.ts +0 -142
- package/src/providers/qdrant.ts +0 -281
- package/src/providers/sqlite-vec.ts +0 -227
- package/src/pruning.ts +0 -83
- package/src/reranker.ts +0 -104
- package/src/search.ts +0 -758
- package/src/sequence-analyzer.ts +0 -422
- package/src/server.ts +0 -4167
- package/src/storage.ts +0 -269
- package/src/store.ts +0 -3648
- package/src/symbol-graph.ts +0 -704
- package/src/symbols.ts +0 -556
- package/src/telemetry.ts +0 -105
- package/src/treesitter.ts +0 -861
- package/src/types.ts +0 -921
- package/src/vector-store.ts +0 -84
- package/src/wake-up.ts +0 -122
- package/src/watcher.ts +0 -874
- package/src/web/index.html +0 -12
- package/src/web/package-lock.json +0 -3209
- package/src/web/package.json +0 -36
- package/src/web/src/App.tsx +0 -29
- package/src/web/src/api/client.ts +0 -233
- package/src/web/src/components/EntityDetailPanel.tsx +0 -94
- package/src/web/src/components/ErrorBoundary.tsx +0 -49
- package/src/web/src/components/Layout.tsx +0 -99
- package/src/web/src/components/NodeDetail.tsx +0 -27
- package/src/web/src/components/QueryStatus.tsx +0 -65
- package/src/web/src/components/ReactFlowGraph.tsx +0 -112
- package/src/web/src/components/SearchResult.tsx +0 -44
- package/src/web/src/components/Skeleton.tsx +0 -45
- package/src/web/src/components/nodes/DocumentNode.tsx +0 -31
- package/src/web/src/components/nodes/EntityNode.tsx +0 -43
- package/src/web/src/components/nodes/FileNode.tsx +0 -33
- package/src/web/src/components/nodes/SymbolNode.tsx +0 -37
- package/src/web/src/index.css +0 -81
- package/src/web/src/lib/colors.ts +0 -83
- package/src/web/src/lib/graph-adapter.ts +0 -349
- package/src/web/src/main.tsx +0 -29
- package/src/web/src/store/app.ts +0 -11
- package/src/web/src/views/CodeGraph.tsx +0 -109
- package/src/web/src/views/ConnectionsView.tsx +0 -217
- package/src/web/src/views/Dashboard.tsx +0 -159
- package/src/web/src/views/FlowsView.tsx +0 -191
- package/src/web/src/views/GraphExplorer.tsx +0 -198
- package/src/web/src/views/InfrastructureView.tsx +0 -199
- package/src/web/src/views/Search.tsx +0 -82
- package/src/web/src/views/SymbolGraph.tsx +0 -134
- package/src/web/tsconfig.json +0 -20
- package/src/web/tsconfig.tsbuildinfo +0 -1
- package/src/web/vite.config.ts +0 -18
- package/src/workspace-profile.ts +0 -64
package/README.md
CHANGED
|
@@ -1,1064 +1,559 @@
|
|
|
1
1
|
# nano-brain
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Built for agents. Not humans.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
A persistent memory server for AI coding agents. It solves the #1 problem with AI assistants: **they forget everything between sessions.**
|
|
5
|
+
Agent-oriented memory and code intelligence. AI agents don't read docs — they need structured context, impact analysis, and call chains. nano-brain provides exactly that via MCP.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
[](https://go.dev/)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://github.com/nano-step/nano-brain)
|
|
10
|
+
[](https://www.npmjs.com/package/@nano-step/nano-brain)
|
|
11
|
+
[](https://hub.docker.com/r/nano-step/nano-brain)
|
|
12
|
+
[](https://discord.gg/nano-brain)
|
|
10
13
|
|
|
11
|
-
## Key Features
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- **Code intelligence** — symbol graph, call flow detection, impact analysis, change detection via Tree-sitter AST
|
|
15
|
-
- **Automatic data ingestion** — session harvesting (2min poll), file watching (chokidar), codebase indexing
|
|
16
|
-
- **Multi-workspace isolation** — per-workspace SQLite databases, cross-workspace search with `--scope=all`
|
|
17
|
-
- **Flexible embedding providers** — VoyageAI, Ollama, OpenAI-compatible
|
|
18
|
-
- **Dual vector stores** — Qdrant (production) or sqlite-vec (embedded)
|
|
19
|
-
- **Privacy-first** — 100% local processing option, your code never leaves your machine
|
|
20
|
-
- **MCP + CLI** — stdio/HTTP/SSE transports for local or containerized environments
|
|
21
|
-
- **Automatic corruption recovery** — detects & recovers from database corruption on startup with zero user intervention
|
|
22
|
-
- **Self-learning system** — Thompson Sampling tunes search parameters, preference learning personalizes results
|
|
23
|
-
- **Knowledge graph** — LLM-extracted entities and relationships, graph traversal, temporal queries
|
|
24
|
-
- **Memory intelligence** — LLM categorization, entity pruning, proactive suggestions
|
|
25
|
-
|
|
26
|
-
Inspired by [QMD](https://github.com/tobi/qmd) and [OpenClaw](https://github.com/openclaw/openclaw).
|
|
15
|
+
### Install
|
|
27
16
|
|
|
28
|
-
|
|
17
|
+
```bash
|
|
18
|
+
# Via npm (recommended)
|
|
19
|
+
npm install -g @nano-step/nano-brain
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
│
|
|
33
|
-
▼
|
|
34
|
-
┌─────────────────┐
|
|
35
|
-
│ Query Expansion │ ← (currently stubbed, planned)
|
|
36
|
-
│ (optional) │ generates 2-3 query variants
|
|
37
|
-
└────────┬────────┘
|
|
38
|
-
│
|
|
39
|
-
┌────┴────┐
|
|
40
|
-
▼ ▼
|
|
41
|
-
┌────────┐ ┌──────────┐
|
|
42
|
-
│ BM25 │ │ Vector │
|
|
43
|
-
│ (FTS5) │ │ (Qdrant │
|
|
44
|
-
│ │ │ or │
|
|
45
|
-
│ │ │ sqlite- │
|
|
46
|
-
│ │ │ vec) │
|
|
47
|
-
└───┬────┘ └────┬─────┘
|
|
48
|
-
│ │
|
|
49
|
-
▼ ▼
|
|
50
|
-
┌─────────────────┐
|
|
51
|
-
│ RRF Fusion │ ← k=60, original query 2× weight
|
|
52
|
-
│ │
|
|
53
|
-
└────────┬────────┘
|
|
54
|
-
│
|
|
55
|
-
▼
|
|
56
|
-
┌─────────────────┐
|
|
57
|
-
│ PageRank Boost │ ← Centrality from file dependency graph
|
|
58
|
-
│ │ weight: 0.1 (default)
|
|
59
|
-
└────────┬────────┘
|
|
60
|
-
│
|
|
61
|
-
▼
|
|
62
|
-
┌─────────────────┐
|
|
63
|
-
│ Supersede │ ← 0.3× demotion for replaced documents
|
|
64
|
-
│ Demotion │
|
|
65
|
-
└────────┬────────┘
|
|
66
|
-
│
|
|
67
|
-
▼
|
|
68
|
-
┌─────────────────┐
|
|
69
|
-
│ Neural Reranking│ ← VoyageAI rerank-2.5-lite
|
|
70
|
-
│ (optional) │
|
|
71
|
-
└────────┬────────┘
|
|
72
|
-
│
|
|
73
|
-
▼
|
|
74
|
-
┌─────────────────┐
|
|
75
|
-
│ Position-Aware │ ← top 3: 75/25, 4-10: 60/40, 11+: 40/60
|
|
76
|
-
│ Blending │ (RRF weight / rerank weight)
|
|
77
|
-
└────────┬────────┘
|
|
78
|
-
│
|
|
79
|
-
▼
|
|
80
|
-
Final Results
|
|
21
|
+
# Or build from source
|
|
22
|
+
CGO_ENABLED=0 go build -o nano-brain ./cmd/nano-brain
|
|
81
23
|
```
|
|
82
24
|
|
|
83
|
-
###
|
|
25
|
+
### Start
|
|
84
26
|
|
|
85
|
-
```
|
|
86
|
-
Memory Write
|
|
87
|
-
│
|
|
88
|
-
▼
|
|
89
|
-
┌─────────────────┐
|
|
90
|
-
│ Save to File │ → ~/.nano-brain/memory/
|
|
91
|
-
│ Hash + DB Insert │ → documents + content tables
|
|
92
|
-
│ FTS5 Index │ → documents_fts (auto-trigger)
|
|
93
|
-
└────────┬────────┘
|
|
94
|
-
│
|
|
95
|
-
┌────┴────┐
|
|
96
|
-
▼ ▼
|
|
97
|
-
┌────────┐ ┌──────────┐
|
|
98
|
-
│Keyword │ │ Async │ (fire-and-forget)
|
|
99
|
-
│Categorize│ │ Processes│
|
|
100
|
-
│auto:* │ │ │
|
|
101
|
-
└────────┘ ├──────────┤
|
|
102
|
-
│ LLM │ → llm:* tags
|
|
103
|
-
│ Categorize│
|
|
104
|
-
├──────────┤
|
|
105
|
-
│ Entity │ → knowledge graph
|
|
106
|
-
│ Extract │
|
|
107
|
-
└──────────┘
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Search Pipeline (3 Tiers)
|
|
111
|
-
|
|
112
|
-
**`memory_search`** — BM25 only (fast, exact keyword matching)
|
|
113
|
-
|
|
114
|
-
**`memory_vsearch`** — Vector only (semantic similarity via embeddings)
|
|
115
|
-
|
|
116
|
-
**`memory_query`** — Full hybrid pipeline with 6 ranking signals:
|
|
117
|
-
|
|
118
|
-
1. **BM25 full-text scoring** — SQLite FTS5 with porter stemming
|
|
119
|
-
2. **Vector cosine similarity** — Qdrant or sqlite-vec embeddings
|
|
120
|
-
3. **RRF fusion** — k=60, original query weighted 2×
|
|
121
|
-
4. **PageRank centrality boost** — from file dependency graph (weight: 0.1)
|
|
122
|
-
5. **Supersede demotion** — 0.3× penalty for replaced documents
|
|
123
|
-
6. **VoyageAI neural reranking** — rerank-2.5-lite with position-aware blending:
|
|
124
|
-
- Top 3 results: 75% RRF / 25% rerank
|
|
125
|
-
- Ranks 4-10: 60% RRF / 40% rerank
|
|
126
|
-
- Ranks 11+: 40% RRF / 60% rerank
|
|
127
|
-
|
|
128
|
-
Query expansion generates 2-3 query variants before search. The pipeline supports it, but no expansion provider is currently active.
|
|
129
|
-
|
|
130
|
-
## Code Intelligence
|
|
131
|
-
|
|
132
|
-
Built on Tree-sitter AST parsing for TypeScript, JavaScript, and Python:
|
|
133
|
-
|
|
134
|
-
**`code_context`** — 360° view of a code symbol:
|
|
135
|
-
- Direct callers and callees
|
|
136
|
-
- Transitive call flows (upstream/downstream)
|
|
137
|
-
- File location, definition, and references
|
|
138
|
-
- Centrality score (PageRank) and cluster membership
|
|
139
|
-
|
|
140
|
-
**`code_impact`** — Change impact analysis:
|
|
141
|
-
- Upstream dependencies (what calls this?)
|
|
142
|
-
- Downstream dependencies (what does this call?)
|
|
143
|
-
- BFS traversal with configurable depth
|
|
144
|
-
- Risk assessment for refactoring
|
|
145
|
-
|
|
146
|
-
**`code_detect_changes`** — Map git diff to affected symbols:
|
|
147
|
-
- Parses `git diff` output
|
|
148
|
-
- Identifies modified symbols via Tree-sitter
|
|
149
|
-
- Returns symbol names, types, and file locations
|
|
150
|
-
- Scope: `staged`, `unstaged`, or `all`
|
|
151
|
-
|
|
152
|
-
**`memory_focus`** — File dependency context:
|
|
153
|
-
- Import/export graph for a file
|
|
154
|
-
- Centrality score (PageRank)
|
|
155
|
-
- Cluster membership (Louvain algorithm)
|
|
156
|
-
- Direct dependencies and dependents
|
|
157
|
-
|
|
158
|
-
**`memory_graph_stats`** — Dependency graph overview:
|
|
159
|
-
- Total files, symbols, edges
|
|
160
|
-
- Cycle detection
|
|
161
|
-
- Clustering coefficient
|
|
162
|
-
- Top central files
|
|
163
|
-
|
|
164
|
-
**Symbol tracking** — Cross-repo symbol queries:
|
|
165
|
-
- Redis keys, PubSub channels
|
|
166
|
-
- MySQL tables, columns
|
|
167
|
-
- API endpoints (Express, FastAPI)
|
|
168
|
-
- Bull/BullMQ queues
|
|
169
|
-
- GraphQL types, queries, mutations
|
|
170
|
-
|
|
171
|
-
## Data Ingestion
|
|
172
|
-
|
|
173
|
-
All data sources are indexed automatically:
|
|
174
|
-
|
|
175
|
-
**Session harvesting** — Converts OpenCode JSON sessions into searchable markdown:
|
|
176
|
-
- Polls `~/.opencode/sessions/` every 2 minutes
|
|
177
|
-
- Extracts user queries, assistant responses, tool calls
|
|
178
|
-
- Incremental append (hash-based deduplication)
|
|
179
|
-
|
|
180
|
-
**File watching** — Monitors collections for changes:
|
|
181
|
-
- Chokidar watches configured directories
|
|
182
|
-
- Dirty-flag tracking for incremental updates
|
|
183
|
-
- Reindexes every 5 minutes if changes detected
|
|
184
|
-
|
|
185
|
-
**Codebase indexing** — Tree-sitter AST → symbol graph:
|
|
186
|
-
- Parses TS/JS/Python files
|
|
187
|
-
- Extracts functions, classes, methods, variables
|
|
188
|
-
- Builds call graph (caller → callee edges)
|
|
189
|
-
- Computes PageRank centrality
|
|
190
|
-
- Detects clusters via Louvain algorithm
|
|
191
|
-
- Identifies call flows (entry points → leaf functions)
|
|
192
|
-
|
|
193
|
-
**Incremental behavior**:
|
|
194
|
-
- Hash-based file skipping (SHA-256 content addressing)
|
|
195
|
-
- Adaptive embedding backoff (exponential retry)
|
|
196
|
-
- Batch processing for large codebases
|
|
197
|
-
|
|
198
|
-
## Background Jobs
|
|
199
|
-
|
|
200
|
-
nano-brain runs 9 background jobs to keep your memory fresh and intelligent:
|
|
201
|
-
|
|
202
|
-
| Job | Interval | What It Does |
|
|
203
|
-
|-----|----------|-------------|
|
|
204
|
-
| File reindex | 5 min | Watch collections, reindex changed files |
|
|
205
|
-
| Session harvest | 2 min | Convert OpenCode sessions → searchable markdown |
|
|
206
|
-
| Embedding | 60s (adaptive) | Generate vector embeddings for new docs |
|
|
207
|
-
| Learning cycle | 10 min | Thompson Sampling + preference weight updates |
|
|
208
|
-
| Consolidation | 1 hour | LLM summarizes related memories |
|
|
209
|
-
| Importance | 30 min | Rescore document importance from usage |
|
|
210
|
-
| Sequence analysis | 30 min | Detect query patterns for proactive suggestions |
|
|
211
|
-
| Pruning (soft) | 6 hours | Soft-delete contradicted/orphan entities |
|
|
212
|
-
| Pruning (hard) | 7 days | Permanently delete old soft-deleted entities |
|
|
213
|
-
|
|
214
|
-
## Chunking Strategy
|
|
215
|
-
|
|
216
|
-
Heading-aware markdown chunking that respects document structure:
|
|
217
|
-
|
|
218
|
-
- **Target size:** 900 tokens (~3600 characters)
|
|
219
|
-
- **Overlap:** 15% between chunks (~540 characters)
|
|
220
|
-
- **Respects boundaries:** Code fences, headings, paragraphs
|
|
221
|
-
- **Break point scoring:** h1=100, h2=90, h3=80, code-fence=80, hr=60, blank-line=40
|
|
222
|
-
- **Content-addressed storage:** SHA-256 hash deduplication
|
|
223
|
-
|
|
224
|
-
## Storage & Infrastructure
|
|
225
|
-
|
|
226
|
-
**SQLite** (via better-sqlite3):
|
|
227
|
-
- `documents` — metadata, content, embeddings
|
|
228
|
-
- `chunks` — heading-aware markdown chunks (900 tokens, 15% overlap)
|
|
229
|
-
- `fts_index` — FTS5 virtual table with porter stemming
|
|
230
|
-
- `vec_index` — sqlite-vec extension (cosine distance)
|
|
231
|
-
- `symbols` — code symbols (functions, classes, variables)
|
|
232
|
-
- `call_edges` — caller → callee relationships
|
|
233
|
-
- `file_deps` — import/export graph
|
|
234
|
-
- `clusters` — Louvain clustering results
|
|
235
|
-
- `flows` — detected call flows (entry → leaf)
|
|
236
|
-
|
|
237
|
-
**Qdrant** (optional, production vector store):
|
|
238
|
-
- Included in `nano-brain docker start` compose stack, or managed standalone via `qdrant up/down/status` commands
|
|
239
|
-
- Automatic migration from sqlite-vec
|
|
240
|
-
- Verification and cleanup tools
|
|
241
|
-
|
|
242
|
-
**Embedding providers**:
|
|
243
|
-
- **VoyageAI** — voyage-code-3 (1024 dims, code-optimized)
|
|
244
|
-
- **Ollama** — local models (nomic-embed-text, etc.)
|
|
245
|
-
- **OpenAI-compatible** — Azure, LM Studio, custom endpoints
|
|
246
|
-
|
|
247
|
-
**Reranking**:
|
|
248
|
-
- **VoyageAI** — rerank-2.5-lite (neural reranking)
|
|
249
|
-
|
|
250
|
-
**Storage management**:
|
|
251
|
-
- Per-workspace SQLite databases (isolated)
|
|
252
|
-
- Content-addressed storage (SHA-256 deduplication)
|
|
253
|
-
- Retention policies (maxSize budget, auto-cleanup)
|
|
254
|
-
- Disk space checks before indexing
|
|
255
|
-
|
|
256
|
-
## Database Schema
|
|
257
|
-
|
|
258
|
-
nano-brain uses 18 SQLite tables organized into 5 functional groups:
|
|
259
|
-
|
|
260
|
-
| Table | Purpose |
|
|
261
|
-
|-------|---------|
|
|
262
|
-
| **Core Documents** | |
|
|
263
|
-
| `documents` | Document metadata, content, embeddings |
|
|
264
|
-
| `chunks` | Heading-aware markdown chunks (900 tokens, 15% overlap) |
|
|
265
|
-
| `content` | Raw content storage (content-addressed) |
|
|
266
|
-
| **Search Indexes** | |
|
|
267
|
-
| `documents_fts` | FTS5 full-text search index (porter stemming) |
|
|
268
|
-
| `vec_index` | sqlite-vec vector index (cosine distance) |
|
|
269
|
-
| **Code Intelligence** | |
|
|
270
|
-
| `symbols` | Code symbols (functions, classes, variables) |
|
|
271
|
-
| `call_edges` | Caller → callee relationships |
|
|
272
|
-
| `file_deps` | Import/export graph |
|
|
273
|
-
| `clusters` | Louvain clustering results |
|
|
274
|
-
| `flows` | Detected call flows (entry → leaf) |
|
|
275
|
-
| **Knowledge Graph** | |
|
|
276
|
-
| `entities` | LLM-extracted entities (people, concepts, tools) |
|
|
277
|
-
| `relationships` | Entity-to-entity connections |
|
|
278
|
-
| **Learning & Intelligence** | |
|
|
279
|
-
| `telemetry` | Search queries, results, expand feedback |
|
|
280
|
-
| `bandit_variants` | Thompson Sampling search parameter tuning |
|
|
281
|
-
| `config_versions` | Search config version history |
|
|
282
|
-
| `consolidations` | LLM-generated memory summaries |
|
|
283
|
-
| `query_sequences` | Query pattern detection for proactive suggestions |
|
|
284
|
-
| `category_preferences` | Per-workspace category weights from expand patterns |
|
|
285
|
-
|
|
286
|
-
## Database Reliability & Corruption Recovery
|
|
287
|
-
|
|
288
|
-
**Why corruption happens**:
|
|
289
|
-
SQLite databases can become corrupted due to:
|
|
290
|
-
- Unexpected process termination during write operations
|
|
291
|
-
- Filesystem crashes or power loss during WAL (Write-Ahead Log) checkpoint
|
|
292
|
-
- Disk I/O errors or hardware faults
|
|
293
|
-
- Rare race conditions in concurrent access (even with better-sqlite3 serialization)
|
|
294
|
-
|
|
295
|
-
**Automatic corruption detection**:
|
|
296
|
-
nano-brain automatically detects database corruption on startup via `PRAGMA integrity_check`:
|
|
297
|
-
- Runs before any database operations in `createStore()`
|
|
298
|
-
- Checks database file integrity without modifying data
|
|
299
|
-
- Takes 50-500ms depending on database size
|
|
300
|
-
|
|
301
|
-
**Automatic recovery**:
|
|
302
|
-
When corruption is detected:
|
|
303
|
-
1. **Backup corrupted file** — Renamed to `.corrupted.{ISO-timestamp}` for forensics/recovery
|
|
304
|
-
2. **Clear WAL/SHM files** — Removes Write-Ahead Log and shared memory files
|
|
305
|
-
3. **Initialize fresh database** — Creates clean SQLite database from scratch
|
|
306
|
-
4. **Verify fresh database** — Runs integrity check to confirm recovery succeeded
|
|
307
|
-
5. **Emit metric** — `database_corruption_detected` counter for monitoring/alerting
|
|
308
|
-
|
|
309
|
-
**Why this works**:
|
|
310
|
-
The database is a **cache/index** — all data is re-derivable from source files. Recovery involves:
|
|
311
|
-
- Session harvesting (re-ingests from session logs)
|
|
312
|
-
- Codebase reindexing (rescan source files)
|
|
313
|
-
- Memory re-embedding (regenerates vectors)
|
|
314
|
-
- Call graph rebuilding (reparses symbols)
|
|
315
|
-
|
|
316
|
-
**Automatic restart with launchd**:
|
|
317
|
-
On macOS, nano-brain runs as a launchd service (`com.tamlh.nano-brain`):
|
|
318
|
-
- If corruption causes a fatal error, process exits
|
|
319
|
-
- launchd automatically restarts it after 10-second throttle
|
|
320
|
-
- On restart, `checkAndRecoverDB()` detects corruption and recovers
|
|
321
|
-
- Service comes back online automatically with fresh database
|
|
322
|
-
|
|
323
|
-
**Installation (macOS)**:
|
|
324
27
|
```bash
|
|
325
|
-
#
|
|
326
|
-
|
|
28
|
+
# Start PostgreSQL
|
|
29
|
+
docker run -d --name nanobrain-pg -p 5432:5432 \
|
|
30
|
+
-e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \
|
|
31
|
+
pgvector/pgvector:pg17
|
|
327
32
|
|
|
328
|
-
#
|
|
329
|
-
|
|
33
|
+
# Start nano-brain
|
|
34
|
+
nano-brain serve -d
|
|
330
35
|
|
|
331
|
-
#
|
|
332
|
-
|
|
36
|
+
# Register your project
|
|
37
|
+
nano-brain init --root=/path/to/your/project
|
|
333
38
|
```
|
|
39
|
+
---
|
|
334
40
|
|
|
335
|
-
|
|
336
|
-
Check for corruption metrics in your monitoring/alerting system:
|
|
337
|
-
- Counter: `database_corruption_detected`
|
|
338
|
-
- Alert threshold: > 3 events per 24 hours (indicates underlying hardware/filesystem issue)
|
|
41
|
+
## Why Star This Project?
|
|
339
42
|
|
|
340
|
-
**
|
|
341
|
-
If corruption happens frequently:
|
|
342
|
-
1. Check system logs for disk I/O errors: `log stream --predicate 'eventMessage contains[c] "I/O error"'`
|
|
343
|
-
2. Verify filesystem health: `diskutil verifyVolume /` (macOS)
|
|
344
|
-
3. Check disk space: `df -h ~/.nano-brain/`
|
|
345
|
-
4. Review database size: `ls -lh ~/.nano-brain/index.db`
|
|
346
|
-
5. Consider moving database to a different drive if corruption persists
|
|
43
|
+
**If you've ever wished your AI agent stopped flying blind in your codebase.**
|
|
347
44
|
|
|
348
|
-
**
|
|
349
|
-
Corrupted backups are kept for analysis:
|
|
350
|
-
- Located at: `~/.nano-brain/index.db.corrupted.{ISO-timestamp}`
|
|
351
|
-
- Last 5 backups are kept by default; older ones are auto-cleaned
|
|
352
|
-
- File size indicates when corruption occurred (if truncated vs intact)
|
|
45
|
+
Most memory tools optimize for conversation recall. nano-brain optimizes for **agent comprehension** — the ability to understand codebases, trace dependencies, and predict the blast radius of changes.
|
|
353
46
|
|
|
354
|
-
|
|
47
|
+
nano-brain is:
|
|
355
48
|
|
|
356
|
-
|
|
49
|
+
- **Agent-oriented** — Built around how agents actually work: impact analysis before edits, call chain tracing, symbol lookup. Not a document store with MCP slapped on top.
|
|
50
|
+
- **Self-hosted** — Your data stays on your server. No cloud dependency.
|
|
51
|
+
- **Works everywhere** — OpenCode, Claude Code, Cursor, any MCP client.
|
|
52
|
+
- **Actually useful** — Not a toy demo. Production-ready with 16 MCP tools, hybrid search, code intelligence, and agent-oriented benchmarks.
|
|
53
|
+
- **Built for developers** — Go binary, PostgreSQL, zero magic. You can read the code.
|
|
54
|
+
- **Beating competitors** — P@5 of 80% vs LlamaIndex's 55% and Qdrant's 27% on real-world queries.
|
|
357
55
|
|
|
358
|
-
|
|
359
|
-
|------|-------------|
|
|
360
|
-
| `memory_search` | BM25 keyword search (fast, exact matching) |
|
|
361
|
-
| `memory_vsearch` | Semantic vector search (embeddings) |
|
|
362
|
-
| `memory_query` | Full hybrid search (BM25 + vector + RRF + reranking) |
|
|
363
|
-
| `memory_get` | Retrieve document by path or docid (#abc123) |
|
|
364
|
-
| `memory_multi_get` | Batch retrieve by glob pattern |
|
|
56
|
+
Star it if you want agents that understand your code, not just search it.
|
|
365
57
|
|
|
366
|
-
|
|
58
|
+
---
|
|
367
59
|
|
|
368
|
-
|
|
369
|
-
|------|-------------|
|
|
370
|
-
| `memory_write` | Write to daily log (supports tags, supersedes) |
|
|
371
|
-
| `memory_tags` | List all tags with document counts |
|
|
372
|
-
| `memory_status` | Index health, collections, model status, graph stats |
|
|
373
|
-
| `memory_update` | Trigger reindex of all collections |
|
|
374
|
-
| `memory_consolidate` | Trigger LLM memory consolidation |
|
|
375
|
-
| `memory_suggestions` | Proactive next-query predictions based on patterns |
|
|
60
|
+
## What It Does
|
|
376
61
|
|
|
377
|
-
|
|
62
|
+
nano-brain is an **agent-oriented infrastructure layer** that sits between your AI agent and your codebase.
|
|
378
63
|
|
|
379
|
-
|
|
380
|
-
|------|-------------|
|
|
381
|
-
| `code_context` | 360° view of a code symbol (callers, callees, flows, centrality) |
|
|
382
|
-
| `code_impact` | Change impact analysis (upstream/downstream BFS) |
|
|
383
|
-
| `code_detect_changes` | Map git diff to affected symbols (staged/unstaged/all) |
|
|
384
|
-
| `memory_index_codebase` | Index codebase files in current workspace (Tree-sitter AST) |
|
|
64
|
+
It solves two problems agents have:
|
|
385
65
|
|
|
386
|
-
|
|
66
|
+
1. **Session amnesia** — Agents forget everything when the session ends. nano-brain persists context across sessions via harvesting, indexing, and retrieval.
|
|
67
|
+
2. **Codebase blindness** — Agents can't trace dependencies, measure blast radius, or understand control flow. nano-brain builds a live code graph and exposes it via 16 MCP tools.
|
|
387
68
|
|
|
388
|
-
|
|
389
|
-
|------|-------------|
|
|
390
|
-
| `memory_focus` | File dependency context (imports/exports, centrality, cluster) |
|
|
391
|
-
| `memory_graph_stats` | Dependency graph overview (files, symbols, edges, cycles) |
|
|
392
|
-
| `memory_symbols` | Cross-repo symbol query (Redis, MySQL, API endpoints, queues) |
|
|
393
|
-
| `memory_impact` | Cross-repo impact analysis (writers vs readers) |
|
|
394
|
-
| `memory_graph_query` | BFS traversal from entity through knowledge graph |
|
|
395
|
-
| `memory_related` | Find related memories via entity graph connections |
|
|
396
|
-
| `memory_timeline` | Temporal view of entity changes over time |
|
|
69
|
+
**Why MCP?** Because agents don't read docs. They call tools. Every capability is a tool call — no REST API ceremony, no JSON parsing, no manual file reading.
|
|
397
70
|
|
|
398
|
-
|
|
71
|
+
### How agents use it
|
|
399
72
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
73
|
+
| Agent needs to... | Tool | What it returns |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| Understand a feature | `memory_query` | Hybrid search results with context |
|
|
76
|
+
| Check what breaks before editing | `memory_impact` | Blast radius — all dependent files |
|
|
77
|
+
| Trace an execution path | `memory_trace` | Call chain from entry point |
|
|
78
|
+
| Find a function definition | `memory_symbols` | Symbol location + kind |
|
|
79
|
+
| Recall a past decision | `memory_query` | Past session context |
|
|
80
|
+
| Save a discovery | `memory_write` | Persisted for future sessions |
|
|
81
|
+
|
|
82
|
+
---
|
|
403
83
|
|
|
404
|
-
|
|
405
|
-
npx nano-brain init --root=/path/to/your/project
|
|
84
|
+
## Architecture
|
|
406
85
|
|
|
407
|
-
|
|
408
|
-
|
|
86
|
+
```mermaid
|
|
87
|
+
graph LR
|
|
88
|
+
A[Your AI Agent] -->|MCP Protocol| B[nano-brain]
|
|
89
|
+
B --> C[PostgreSQL + pgvector]
|
|
90
|
+
B --> D[Session Harvesting]
|
|
91
|
+
B --> E[Code Intelligence]
|
|
92
|
+
B --> F[Hybrid Search]
|
|
93
|
+
|
|
94
|
+
D --> D1[OpenCode Sessions]
|
|
95
|
+
D --> D2[Claude Code Sessions]
|
|
96
|
+
|
|
97
|
+
E --> E1[Symbol Graph]
|
|
98
|
+
E --> E2[Flow Diagrams]
|
|
99
|
+
E --> E3[Impact Analysis]
|
|
100
|
+
|
|
101
|
+
F --> F1[BM25 Full-Text]
|
|
102
|
+
F --> F2[Vector Similarity]
|
|
103
|
+
F --> F3[RRF Fusion]
|
|
409
104
|
```
|
|
410
105
|
|
|
411
|
-
|
|
106
|
+
---
|
|
412
107
|
|
|
413
|
-
|
|
108
|
+
## Agent-Oriented Design
|
|
414
109
|
|
|
415
|
-
|
|
416
|
-
# Start nano-brain + Qdrant containers
|
|
417
|
-
npx nano-brain docker start
|
|
110
|
+
nano-brain isn't a memory tool with MCP bolted on. It's designed from the ground up around **how agents actually behave**.
|
|
418
111
|
|
|
419
|
-
|
|
420
|
-
npx nano-brain docker status
|
|
112
|
+
### The agent workflow loop
|
|
421
113
|
|
|
422
|
-
|
|
423
|
-
|
|
114
|
+
```
|
|
115
|
+
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
116
|
+
│ Agent │────▶│ memory_query │────▶│ Context │
|
|
117
|
+
│ receives │ │ /impact/trace│ │ window │
|
|
118
|
+
│ task │ │ │ │ filled │
|
|
119
|
+
└─────────────┘ └──────────────┘ └──────┬──────┘
|
|
120
|
+
│
|
|
121
|
+
┌──────▼──────┐
|
|
122
|
+
│ Agent │
|
|
123
|
+
│ implements │
|
|
124
|
+
│ change │
|
|
125
|
+
└──────┬──────┘
|
|
126
|
+
│
|
|
127
|
+
┌──────▼──────┐
|
|
128
|
+
│ memory_write │
|
|
129
|
+
│ (persist) │
|
|
130
|
+
└─────────────┘
|
|
424
131
|
```
|
|
425
132
|
|
|
426
|
-
|
|
133
|
+
### Why agent behavior matters
|
|
427
134
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
135
|
+
| Human workflow | Agent workflow | nano-brain response |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| Opens file, reads it | `memory_get` or `memory_search` | Returns structured content, not raw bytes |
|
|
138
|
+
| Traces call chain manually | `memory_trace` | Returns function-by-function chain with line numbers |
|
|
139
|
+
| Greps for callers | `memory_graph(direction="in")` | Returns all callers in one call |
|
|
140
|
+
| Thinks "what breaks?" | `memory_impact` | Returns full blast radius in <50ms |
|
|
141
|
+
| Remembers past decisions | `memory_query` | Returns cross-session context |
|
|
432
142
|
|
|
433
|
-
|
|
143
|
+
### The 50ms rule
|
|
434
144
|
|
|
435
|
-
|
|
436
|
-
|----------|--------|-------------|
|
|
437
|
-
| `/health` | GET | Health check |
|
|
438
|
-
| `/api/status` | GET | Index health, collections, model status |
|
|
439
|
-
| `/api/query` | POST | Hybrid search (body: `{query, tags, scope, limit}`) |
|
|
440
|
-
| `/api/search` | POST | BM25 keyword search (body: `{query, limit}`) |
|
|
441
|
-
| `/api/write` | POST | Write memory (body: `{content, tags, supersedes}`) |
|
|
442
|
-
| `/api/reindex` | POST | Trigger reindex (body: `{root}`) |
|
|
443
|
-
| `/mcp` | — | MCP endpoint (for AI agent integration) |
|
|
444
|
-
| `/sse` | — | SSE transport (for MCP remote clients) |
|
|
145
|
+
At 50ms latency, agents run impact analysis on every edit. At 500ms, they skip it. nano-brain is designed for the 50ms world — every code intelligence tool call is sub-50ms, making it practical for agents to use them on every operation.
|
|
445
146
|
|
|
446
|
-
###
|
|
147
|
+
### What agents actually need
|
|
447
148
|
|
|
448
|
-
|
|
149
|
+
Research from 15+ production code intelligence tools shows:
|
|
449
150
|
|
|
450
|
-
**
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
"mcp": {
|
|
454
|
-
"nano-brain": {
|
|
455
|
-
"type": "remote",
|
|
456
|
-
"url": "http://host.docker.internal:3100/mcp",
|
|
457
|
-
"enabled": true
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
```
|
|
151
|
+
1. **Impact analysis is #1** — "What breaks if I change this?" is the most common agent query
|
|
152
|
+
2. **Call chains > control flow** — Agents trace across files (inter-procedural), not within functions (intra-procedural)
|
|
153
|
+
3. **Component composition > internal logic** — For frontend frameworks, "who uses this component?" matters more than "what does the template do?"
|
|
462
154
|
|
|
463
|
-
|
|
464
|
-
```bash
|
|
465
|
-
npx nano-brain docker start # Start nano-brain + Qdrant containers
|
|
466
|
-
npx nano-brain docker status # Check if running
|
|
467
|
-
npx nano-brain docker stop # Stop containers
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
**Local mode (stdio, for development):**
|
|
471
|
-
```json
|
|
472
|
-
{
|
|
473
|
-
"mcp": {
|
|
474
|
-
"nano-brain": {
|
|
475
|
-
"type": "local",
|
|
476
|
-
"command": ["npx", "nano-brain", "mcp"],
|
|
477
|
-
"enabled": true
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
```
|
|
155
|
+
nano-brain optimizes for exactly these three patterns.
|
|
482
156
|
|
|
483
|
-
|
|
484
|
-
```json
|
|
485
|
-
{
|
|
486
|
-
"mcpServers": {
|
|
487
|
-
"nano-brain": {
|
|
488
|
-
"command": "npx",
|
|
489
|
-
"args": ["mcp-remote", "http://localhost:3100/sse"]
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
```
|
|
157
|
+
---
|
|
494
158
|
|
|
495
|
-
##
|
|
159
|
+
## Key Features
|
|
496
160
|
|
|
497
|
-
|
|
161
|
+
### Hybrid Search
|
|
498
162
|
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
sessions:
|
|
507
|
-
path: ~/.nano-brain/sessions
|
|
508
|
-
pattern: "**/*.md"
|
|
509
|
-
update: auto
|
|
510
|
-
|
|
511
|
-
# Vector store (qdrant or sqlite-vec)
|
|
512
|
-
vector:
|
|
513
|
-
provider: qdrant
|
|
514
|
-
url: http://localhost:6333
|
|
515
|
-
collection: nano_brain
|
|
516
|
-
# OR: provider: sqlite-vec (embedded, no external service)
|
|
517
|
-
|
|
518
|
-
# Embedding provider
|
|
519
|
-
embedding:
|
|
520
|
-
provider: openai # 'ollama' or 'openai' (OpenAI-compatible)
|
|
521
|
-
url: https://api.voyageai.com # VoyageAI, Azure, LM Studio, etc.
|
|
522
|
-
model: voyage-code-3
|
|
523
|
-
apiKey: ${VOYAGE_API_KEY}
|
|
524
|
-
dimensions: 1024 # Output dimensions (default: 1024); omit to use model default
|
|
525
|
-
# OR: provider: ollama, url: http://localhost:11434, model: nomic-embed-text
|
|
526
|
-
|
|
527
|
-
# Reranker (uses embedding.apiKey if not set separately)
|
|
528
|
-
reranker:
|
|
529
|
-
model: rerank-2.5-lite
|
|
530
|
-
# apiKey: ${VOYAGE_API_KEY} # optional, falls back to embedding.apiKey
|
|
531
|
-
|
|
532
|
-
# Codebase indexing
|
|
533
|
-
codebase:
|
|
534
|
-
enabled: true
|
|
535
|
-
languages: [typescript, javascript, python]
|
|
536
|
-
exclude: [node_modules, dist, build, .git]
|
|
537
|
-
maxFileSize: 1048576 # 1MB
|
|
538
|
-
|
|
539
|
-
# File watcher
|
|
540
|
-
watcher:
|
|
541
|
-
enabled: true
|
|
542
|
-
debounce: 300 # ms
|
|
543
|
-
reindexInterval: 300 # seconds (5 minutes)
|
|
544
|
-
|
|
545
|
-
# Search configuration
|
|
546
|
-
search:
|
|
547
|
-
rrf_k: 60
|
|
548
|
-
top_k: 30
|
|
549
|
-
expansion:
|
|
550
|
-
enabled: true
|
|
551
|
-
weight: 1
|
|
552
|
-
reranking:
|
|
553
|
-
enabled: true
|
|
554
|
-
blending:
|
|
555
|
-
top3:
|
|
556
|
-
rrf: 0.75
|
|
557
|
-
rerank: 0.25
|
|
558
|
-
mid:
|
|
559
|
-
rrf: 0.60
|
|
560
|
-
rerank: 0.40
|
|
561
|
-
tail:
|
|
562
|
-
rrf: 0.40
|
|
563
|
-
rerank: 0.60
|
|
564
|
-
centrality_weight: 0.1
|
|
565
|
-
supersede_demotion: 0.3
|
|
566
|
-
|
|
567
|
-
# Polling intervals
|
|
568
|
-
intervals:
|
|
569
|
-
sessionHarvest: 120 # seconds (2 minutes)
|
|
570
|
-
healthCheck: 60 # seconds
|
|
571
|
-
|
|
572
|
-
# Storage management
|
|
573
|
-
storage:
|
|
574
|
-
maxSize: 10737418240 # 10GB
|
|
575
|
-
retention:
|
|
576
|
-
sessions: 90 # days
|
|
577
|
-
logs: 30 # days
|
|
578
|
-
|
|
579
|
-
# Workspaces
|
|
580
|
-
workspaces:
|
|
581
|
-
isolation: true # Per-workspace SQLite databases
|
|
582
|
-
defaultScope: current # or 'all' for cross-workspace search
|
|
583
|
-
|
|
584
|
-
# Entity pruning (Memory Intelligence v2)
|
|
585
|
-
pruning:
|
|
586
|
-
enabled: true
|
|
587
|
-
interval_ms: 21600000 # 6 hours
|
|
588
|
-
contradicted_ttl_days: 30
|
|
589
|
-
orphan_ttl_days: 90
|
|
590
|
-
batch_size: 100
|
|
591
|
-
hard_delete_after_days: 30
|
|
592
|
-
|
|
593
|
-
# LLM categorization (Memory Intelligence v2)
|
|
594
|
-
categorization:
|
|
595
|
-
llm_enabled: true
|
|
596
|
-
confidence_threshold: 0.6
|
|
597
|
-
max_content_length: 2000
|
|
598
|
-
|
|
599
|
-
# Preference learning (Memory Intelligence v2)
|
|
600
|
-
preferences:
|
|
601
|
-
enabled: true
|
|
602
|
-
min_queries: 20
|
|
603
|
-
weight_min: 0.5
|
|
604
|
-
weight_max: 2.0
|
|
605
|
-
baseline_expand_rate: 0.1
|
|
606
|
-
|
|
607
|
-
# Logging
|
|
608
|
-
logging:
|
|
609
|
-
level: info # debug, info, warn, error
|
|
610
|
-
file: ~/.nano-brain/logs/nano-brain.log
|
|
611
|
-
maxSize: 10485760 # 10MB
|
|
612
|
-
maxFiles: 5
|
|
163
|
+
```mermaid
|
|
164
|
+
graph LR
|
|
165
|
+
Q[Query] --> BM25[BM25 Full-Text]
|
|
166
|
+
Q --> Vector[Vector Similarity]
|
|
167
|
+
BM25 --> RRF[RRF Fusion]
|
|
168
|
+
Vector --> RRF
|
|
169
|
+
RRF --> Results[Ranked Results]
|
|
613
170
|
```
|
|
614
171
|
|
|
615
|
-
|
|
616
|
-
```
|
|
617
|
-
~/.nano-brain/
|
|
618
|
-
├── config.yml # Configuration
|
|
619
|
-
├── data/ # SQLite databases (per-workspace)
|
|
620
|
-
├── memory/ # Curated notes
|
|
621
|
-
├── sessions/ # Harvested sessions
|
|
622
|
-
└── logs/ # Application logs
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
## CLI Commands (27 Total)
|
|
172
|
+
BM25 full-text + pgvector HNSW cosine similarity + Reciprocal Rank Fusion + recency decay.
|
|
626
173
|
|
|
627
|
-
###
|
|
174
|
+
### Code Intelligence
|
|
628
175
|
|
|
629
|
-
```
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
176
|
+
```mermaid
|
|
177
|
+
graph TD
|
|
178
|
+
A[Entry Point] --> B[Function Call]
|
|
179
|
+
B --> C[Method Call]
|
|
180
|
+
B --> D[Database Query]
|
|
181
|
+
C --> E[External Service]
|
|
182
|
+
D --> F[Redis Cache]
|
|
633
183
|
```
|
|
634
184
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
nano-brain mcp --http --port=3100 --host=0.0.0.0 # Start MCP server (HTTP/SSE)
|
|
640
|
-
```
|
|
185
|
+
- **Symbol extraction** — Functions, types, interfaces, constants
|
|
186
|
+
- **Call chain tracing** — Follow execution paths across files
|
|
187
|
+
- **Impact analysis** — "What breaks if I change this?"
|
|
188
|
+
- **Flow diagrams** — Mermaid flowcharts and sequence diagrams
|
|
641
189
|
|
|
642
|
-
###
|
|
190
|
+
### Session Harvesting
|
|
643
191
|
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
192
|
+
```mermaid
|
|
193
|
+
graph LR
|
|
194
|
+
S1[OpenCode DB] --> H[Harvester]
|
|
195
|
+
S2[Claude Code JSONL] --> H
|
|
196
|
+
H --> L[LLM Summarizer]
|
|
197
|
+
L --> I[Indexer]
|
|
198
|
+
I --> DB[PostgreSQL]
|
|
650
199
|
```
|
|
651
200
|
|
|
652
|
-
|
|
201
|
+
Auto-ingest from OpenCode and Claude Code sessions. Map-reduce LLM summarization. Incremental harvest with dedup.
|
|
653
202
|
|
|
654
|
-
|
|
655
|
-
nano-brain docker start # Start nano-brain + Qdrant via docker compose
|
|
656
|
-
nano-brain docker status # Check container status
|
|
657
|
-
nano-brain docker stop # Stop containers
|
|
658
|
-
```
|
|
203
|
+
### 16 MCP Tools
|
|
659
204
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
205
|
+
| Tool | Description |
|
|
206
|
+
|------|-------------|
|
|
207
|
+
| `memory_query` | Hybrid search — default first tool for broad questions |
|
|
208
|
+
| `memory_search` | BM25 keyword search for exact text/errors |
|
|
209
|
+
| `memory_vsearch` | Vector similarity for fuzzy concepts |
|
|
210
|
+
| `memory_get` | Get document by path or ID |
|
|
211
|
+
| `memory_write` | Write/update document |
|
|
212
|
+
| `memory_graph` | One-hop callers/callees/imports |
|
|
213
|
+
| `memory_trace` | Downstream call chain trace |
|
|
214
|
+
| `memory_impact` | Pre-change blast radius analysis |
|
|
215
|
+
| `memory_symbols` | Symbol search (functions, types, interfaces) |
|
|
216
|
+
| `memory_flow` | HTTP route execution flow |
|
|
217
|
+
| `memory_flowchart` | Function-level control-flow graph |
|
|
218
|
+
| `memory_workspaces_resolve` | Resolve path to workspace hash |
|
|
219
|
+
| `memory_tags` | List tags with counts |
|
|
220
|
+
| `memory_status` | Server and queue health |
|
|
221
|
+
| `memory_update` | Trigger re-embedding |
|
|
222
|
+
| `memory_wake_up` | Session-start workspace briefing |
|
|
663
223
|
|
|
664
|
-
|
|
665
|
-
- `NANO_BRAIN_APP` — Path to nano-brain source (default: current directory)
|
|
666
|
-
- `NANO_BRAIN_HOME` — Path to data directory (default: `~/.nano-brain`)
|
|
667
|
-
- `NANO_BRAIN_WORKSPACE` — Path to your project workspace to index as codebase (mounted read-only, passed as `--root`)
|
|
224
|
+
---
|
|
668
225
|
|
|
669
|
-
|
|
226
|
+
## Quick Start
|
|
670
227
|
|
|
671
|
-
|
|
672
|
-
nano-brain search "query" # BM25 keyword search
|
|
673
|
-
nano-brain vsearch "query" # Vector semantic search
|
|
674
|
-
nano-brain query "query" # Hybrid search (BM25 + vector + reranking)
|
|
675
|
-
nano-brain query "query" --tags=bug,fix # Filter by tags
|
|
676
|
-
nano-brain query "query" --scope=all # Cross-workspace search
|
|
677
|
-
```
|
|
228
|
+
### Prerequisites
|
|
678
229
|
|
|
679
|
-
|
|
230
|
+
- **Go 1.23+** OR pre-built binary
|
|
231
|
+
- **PostgreSQL 17** with **pgvector 0.8.2**
|
|
232
|
+
- **Ollama** (for embeddings) or any OpenAI-compatible provider
|
|
680
233
|
|
|
681
|
-
|
|
682
|
-
nano-brain write "content" # Write to daily log
|
|
683
|
-
nano-brain write "content" --tags=decision,architecture
|
|
684
|
-
nano-brain write "content" --supersedes=abc123 # Mark as replacement
|
|
685
|
-
nano-brain get <path> # Retrieve document by path
|
|
686
|
-
nano-brain get "#abc123" # Retrieve by docid
|
|
687
|
-
nano-brain tags # List all tags with counts
|
|
688
|
-
```
|
|
234
|
+
### Configure Your AI Agent
|
|
689
235
|
|
|
690
|
-
|
|
236
|
+
Add to your MCP client config (Claude Code, OpenCode, Cursor, etc.):
|
|
691
237
|
|
|
692
|
-
```
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
nano-brain
|
|
696
|
-
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"mcp": {
|
|
241
|
+
"nano-brain": {
|
|
242
|
+
"type": "http",
|
|
243
|
+
"url": "http://localhost:3100/mcp"
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
697
247
|
```
|
|
698
248
|
|
|
699
|
-
|
|
249
|
+
---
|
|
700
250
|
|
|
701
|
-
|
|
702
|
-
nano-brain collection add <name> <path> # Add collection
|
|
703
|
-
nano-brain collection remove <name> # Remove collection
|
|
704
|
-
nano-brain collection list # List collections
|
|
705
|
-
```
|
|
251
|
+
## Demo
|
|
706
252
|
|
|
707
|
-
###
|
|
253
|
+
### Query Your Codebase
|
|
708
254
|
|
|
709
255
|
```bash
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
256
|
+
# Search for authentication patterns
|
|
257
|
+
curl -X POST http://localhost:3100/api/v1/query \
|
|
258
|
+
-H "Content-Type: application/json" \
|
|
259
|
+
-d '{"workspace": "abc123", "query": "how does authentication work"}'
|
|
714
260
|
```
|
|
715
261
|
|
|
716
|
-
###
|
|
717
|
-
|
|
718
|
-
> **Note:** If using `nano-brain docker start`, Qdrant is already included in the compose stack. These commands manage a standalone Qdrant container separately.
|
|
262
|
+
### Trace Call Chains
|
|
719
263
|
|
|
720
264
|
```bash
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
nano-brain qdrant verify # Verify Qdrant data integrity
|
|
726
|
-
nano-brain qdrant activate # Switch to Qdrant (update config)
|
|
727
|
-
nano-brain qdrant cleanup # Remove orphaned vectors
|
|
265
|
+
# Trace from entry point
|
|
266
|
+
curl -X POST http://localhost:3100/api/v1/graph/trace \
|
|
267
|
+
-H "Content-Type: application/json" \
|
|
268
|
+
-d '{"workspace": "abc123", "node": "main.go::main", "max_depth": 5}'
|
|
728
269
|
```
|
|
729
270
|
|
|
730
|
-
###
|
|
271
|
+
### Analyze Impact
|
|
731
272
|
|
|
732
273
|
```bash
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
274
|
+
# What breaks if I change this file?
|
|
275
|
+
curl -X POST http://localhost:3100/api/v1/graph/impact \
|
|
276
|
+
-H "Content-Type: application/json" \
|
|
277
|
+
-d '{"workspace": "abc123", "node": "src/auth/login.ts", "max_depth": 2}'
|
|
736
278
|
```
|
|
737
279
|
|
|
738
|
-
###
|
|
280
|
+
### Generate Flow Diagrams
|
|
739
281
|
|
|
740
282
|
```bash
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
283
|
+
# Get flow diagram for a controller
|
|
284
|
+
curl -X POST http://localhost:3100/api/v1/graph/flow \
|
|
285
|
+
-H "Content-Type: application/json" \
|
|
286
|
+
-d '{"workspace": "abc123", "entry": "POST /users"}'
|
|
745
287
|
```
|
|
746
288
|
|
|
747
|
-
|
|
289
|
+
Returns Mermaid flowchart:
|
|
748
290
|
|
|
749
|
-
```
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
nano-brain logs path # Print log directory path
|
|
291
|
+
```mermaid
|
|
292
|
+
flowchart LR
|
|
293
|
+
POST_/users["POST /users"]
|
|
294
|
+
POST_/users --> UsersController#create
|
|
295
|
+
UsersController#create --> User.create
|
|
296
|
+
UsersController#create --> Mailer.welcome
|
|
756
297
|
```
|
|
757
298
|
|
|
758
|
-
|
|
299
|
+
---
|
|
759
300
|
|
|
760
|
-
|
|
761
|
-
src/
|
|
762
|
-
├── index.ts # CLI entry point
|
|
763
|
-
├── server.ts # MCP server (22+ tools, stdio/HTTP/SSE)
|
|
764
|
-
├── store.ts # SQLite storage (FTS5 + sqlite-vec)
|
|
765
|
-
├── storage.ts # Storage management (retention, disk space)
|
|
766
|
-
├── vector-store.ts # Vector store abstraction (Qdrant + sqlite-vec)
|
|
767
|
-
├── search.ts # Hybrid search pipeline (RRF, reranking, blending)
|
|
768
|
-
├── chunker.ts # Heading-aware markdown chunking
|
|
769
|
-
├── collections.ts # YAML config, collection scanning
|
|
770
|
-
├── embeddings.ts # Embedding providers (VoyageAI, Ollama, OpenAI-compatible)
|
|
771
|
-
├── reranker.ts # VoyageAI reranker
|
|
772
|
-
├── expansion.ts # Query expansion (interface only, no active provider)
|
|
773
|
-
├── harvester.ts # OpenCode session → markdown converter
|
|
774
|
-
├── watcher.ts # File watcher (chokidar, dirty flags)
|
|
775
|
-
├── codebase.ts # Codebase indexing orchestrator
|
|
776
|
-
├── treesitter.ts # Tree-sitter AST parsing
|
|
777
|
-
├── symbols.ts # Symbol extraction (functions, classes, variables)
|
|
778
|
-
├── graph.ts # File dependency graph (imports/exports)
|
|
779
|
-
├── symbol-graph.ts # Symbol call graph (caller → callee)
|
|
780
|
-
├── flow-detection.ts # Call flow detection (entry → leaf)
|
|
781
|
-
├── types.ts # TypeScript interfaces
|
|
782
|
-
└── providers/ # Vector store implementations
|
|
783
|
-
├── qdrant.ts # Qdrant vector store
|
|
784
|
-
└── sqlite-vec.ts # sqlite-vec vector store
|
|
785
|
-
bin/
|
|
786
|
-
└── cli.js # CLI wrapper
|
|
787
|
-
|
|
788
|
-
test/
|
|
789
|
-
└── *.test.ts # 760+ tests (vitest)
|
|
790
|
-
SKILL.md # AI agent routing instructions (auto-loaded by OpenCode)
|
|
791
|
-
AGENTS_SNIPPET.md # Optional project-level AGENTS.md managed block
|
|
792
|
-
```
|
|
301
|
+
## Use Cases
|
|
793
302
|
|
|
794
|
-
|
|
303
|
+
### Agent-assisted refactoring
|
|
304
|
+
Before refactoring, your agent calls `memory_impact` on the target function. Gets the full blast radius. Decides whether to split the change. After refactoring, runs affected tests only — not the full suite.
|
|
795
305
|
|
|
796
|
-
-
|
|
797
|
-
|
|
798
|
-
- **Qdrant** for production vector store (optional)
|
|
799
|
-
- **Tree-sitter** for AST parsing (TS, JS, Python)
|
|
800
|
-
- **@modelcontextprotocol/sdk** for MCP server (stdio/HTTP/SSE transports)
|
|
801
|
-
- **chokidar** for file watching
|
|
802
|
-
- **vitest** for testing (760+ tests)
|
|
306
|
+
### Multi-session feature development
|
|
307
|
+
Session 1: Agent explores the codebase, discovers patterns. `memory_write` saves findings. Session 2: Agent recalls session 1's discoveries via `memory_query`. No context lost between sessions.
|
|
803
308
|
|
|
804
|
-
|
|
309
|
+
### Legacy codebase onboarding
|
|
310
|
+
Index a 5-year-old codebase. Your agent can now answer "what does this function do?", "why does this class exist?", "if I change this file, what else breaks?" — without reading every file.
|
|
805
311
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
- **Ollama** — nomic-embed-text, mxbai-embed-large, etc. (local, free)
|
|
809
|
-
- **OpenAI-compatible** — Azure OpenAI, LM Studio, custom endpoints
|
|
312
|
+
### Cross-service debugging
|
|
313
|
+
Agent traces a bug from frontend to backend. `memory_trace` follows the call chain across services. `memory_graph` shows which microservices depend on the failing endpoint.
|
|
810
314
|
|
|
811
|
-
|
|
812
|
-
|
|
315
|
+
### Team knowledge sharing
|
|
316
|
+
One server, whole team. Every developer's AI agent connects to the same PostgreSQL. Decisions, architecture notes, code intelligence — instantly shared. New hires get full context from day one.
|
|
813
317
|
|
|
814
|
-
|
|
815
|
-
- Pipeline support exists but no active provider. The interface is ready for future integration.
|
|
318
|
+
---
|
|
816
319
|
|
|
817
|
-
##
|
|
320
|
+
## Performance
|
|
818
321
|
|
|
819
|
-
|
|
820
|
-
|---|---|---|---|---|---|---|
|
|
821
|
-
| **Search** | Hybrid (BM25 + vector + 6 ranking signals) | Vector only | Graph traversal + vector | Semantic + BM25 | Agent-managed | Text file read |
|
|
822
|
-
| **Storage** | SQLite + Qdrant (optional) | PostgreSQL + Qdrant | Neo4j | SQLite | PostgreSQL / SQLite | Flat text files |
|
|
823
|
-
| **MCP Tools** | 22+ | 4-9 | 9-10 | 12 | 7 | 0 |
|
|
824
|
-
| **Code Intelligence** | Yes (Tree-sitter AST, symbol graph, impact analysis) | No | No | No | No | No |
|
|
825
|
-
| **Codebase Indexing** | Yes (AST → symbols → call graph → flows) | No | No | No | No | No |
|
|
826
|
-
| **Session Recall** | Yes (auto-harvests past sessions) | No | No | No | No | Limited (CLAUDE.md) |
|
|
827
|
-
| **Query Expansion** | Pipeline ready (no active provider) | No | No | No | No | No |
|
|
828
|
-
| **Neural Reranking** | Yes (VoyageAI rerank-2.5-lite) | No | No | No | No | No |
|
|
829
|
-
| **Local-First** | Yes (Ollama + sqlite-vec) | Requires OpenAI API key | Requires Docker + Neo4j | Yes | Yes | Yes |
|
|
830
|
-
| **Cloud Option** | Yes (VoyageAI, OpenAI-compatible) | Cloud API (OpenAI) | Cloud API | Local ONNX | Cloud API | None |
|
|
831
|
-
| **Privacy** | 100% local option available | Cloud API calls | Cloud or self-host | 100% local | Self-host or cloud | Local files |
|
|
832
|
-
| **Dependencies** | SQLite + embedding API (+ optional Qdrant) | Docker + PostgreSQL + Qdrant + OpenAI key | Docker + Neo4j | SQLite + ONNX | PostgreSQL | None |
|
|
833
|
-
| **Pricing** | Free (open source, MIT) | Free tier / Pro $249/mo | Free self-host / Cloud $25-475/mo | Free (Apache-2.0) | Free (Apache-2.0) | Free (with Claude) |
|
|
834
|
-
| **GitHub Stars** | New | ~47K | ~23K | ~25 | ~21K | N/A |
|
|
322
|
+
### Search Quality vs Competitors
|
|
835
323
|
|
|
836
|
-
|
|
324
|
+
| Metric | nano-brain | LlamaIndex | Qdrant/Mem0 | Cognee | GraphRAG | Zep |
|
|
325
|
+
|--------|------------|------------|-------------|--------|----------|-----|
|
|
326
|
+
| P@5 | **80%** | 55% | 27% | — | — | — |
|
|
327
|
+
| MRR | **95%** | — | — | — | — | — |
|
|
328
|
+
| Latency | **42ms** | — | — | — | — | — |
|
|
329
|
+
| Code Intelligence | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
330
|
+
| Symbol Graph | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
331
|
+
| Impact Analysis | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
332
|
+
| Flow Diagrams | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
837
333
|
|
|
838
|
-
|
|
839
|
-
- **Code intelligence** — Tree-sitter AST parsing, symbol graph, call flow detection, impact analysis
|
|
840
|
-
- **Codebase indexing** — index your source files with structural boundary detection, not just conversations
|
|
841
|
-
- **Session recall** — automatically harvests and indexes past AI coding sessions
|
|
842
|
-
- **Flexible deployment** — 100% local (Ollama + sqlite-vec) or cloud (VoyageAI + Qdrant)
|
|
843
|
-
- **Privacy-first** — local processing option, your code never leaves your machine
|
|
334
|
+
Tested on 60 domain-specific queries across 3 workspaces. nano-brain is the **only** solution with code intelligence — competitors focus on conversation memory and document retrieval.
|
|
844
335
|
|
|
845
|
-
###
|
|
336
|
+
### Competitive Landscape
|
|
846
337
|
|
|
847
|
-
|
|
848
|
-
-
|
|
849
|
-
-
|
|
850
|
-
-
|
|
338
|
+
**What competitors offer:**
|
|
339
|
+
- **Mem0 / Zep** — Conversation memory, temporal ranking, chat history recall
|
|
340
|
+
- **Cognee / GraphRAG** — Document-level knowledge graphs, multi-hop reasoning
|
|
341
|
+
- **LlamaIndex** — Flexible RAG pipelines, document retrieval
|
|
851
342
|
|
|
852
|
-
|
|
343
|
+
**What nano-brain adds (agent-oriented):**
|
|
344
|
+
- **Impact analysis** — "What breaks if I change this?" — the #1 question agents ask. Pre-computed blast radius in <50ms.
|
|
345
|
+
- **Call chain tracing** — Follow execution paths across files. Agent gets a structured trace, not raw source.
|
|
346
|
+
- **Symbol graph** — Find definitions, callers, callees. `memory_symbols` + `memory_graph`.
|
|
347
|
+
- **Agent-oriented benchmarks** — Measures how well agents find context for domain tasks — not just search precision in isolation.
|
|
853
348
|
|
|
854
|
-
|
|
349
|
+
**The difference:** Competitors optimize for "did the agent find the right document?" nano-brain optimizes for "did the agent understand the codebase well enough to make the right change?"
|
|
855
350
|
|
|
856
|
-
|
|
857
|
-
- **Save context after completing work** — persist key decisions and debugging insights
|
|
858
|
-
- **Route queries to the right search tool** — BM25 for exact terms, vector for concepts, hybrid for best quality
|
|
859
|
-
- **Use code intelligence** — understand symbol relationships, assess change impact, detect affected code
|
|
351
|
+
At 50ms latency, agents run impact analysis on every edit. At 500ms, they skip it. nano-brain is designed for the 50ms world.
|
|
860
352
|
|
|
861
|
-
###
|
|
353
|
+
### Agent-Oriented Capability Benchmarks
|
|
862
354
|
|
|
863
|
-
|
|
355
|
+
nano-brain is built for agents. These benchmarks measure how well agents can **find relevant context for real-world domain tasks** using nano-brain's MCP tools — not just search quality in isolation.
|
|
864
356
|
|
|
865
|
-
|
|
357
|
+
Each benchmark runs a deterministic agent workflow:
|
|
358
|
+
1. **query_question** — natural-language domain question
|
|
359
|
+
2. **query_input** — optimized search query
|
|
360
|
+
3. **symbols_identifiers** — symbol lookup for known identifiers
|
|
866
361
|
|
|
867
|
-
|
|
362
|
+
This mimics how a real agent explores a codebase: broad understanding first, then targeted retrieval.
|
|
868
363
|
|
|
869
|
-
|
|
870
|
-
npx nano-brain init --root=/path/to/project
|
|
871
|
-
```
|
|
872
|
-
|
|
873
|
-
This adds a managed block to your project's `AGENTS.md` with quick reference tables for CLI commands and MCP tools (if available).
|
|
364
|
+
#### Scores
|
|
874
365
|
|
|
875
|
-
|
|
366
|
+
| Workspace | Domain | Overall | Multi-tool | Search-QA | Symbol-Lookup |
|
|
367
|
+
|-----------|--------|---------|------------|-----------|---------------|
|
|
368
|
+
| **nano-brain** | Go daemon | **1.000** | 1.000 | 1.000 | 1.000 |
|
|
369
|
+
| **TypeScript** | CS2 item trading | **0.885** | 1.000 | 0.817 | 1.000 |
|
|
370
|
+
| **Rails** | CS2 item trading | **0.795** | 1.000 | 0.726 | 0.667 |
|
|
876
371
|
|
|
877
|
-
|
|
372
|
+
**What this means:**
|
|
373
|
+
- **Multi-tool 1.000** — When agents combine search + symbols, they find every expected context item
|
|
374
|
+
- **Overall 0.885** — TypeScript workspace: agent finds 88.5% of expected domain artifacts
|
|
375
|
+
- **Fixed vs Agent** — Agent workflow improves recall by 15-40% over single-tool queries
|
|
376
|
+
- **Unique capability** — No competitor offers agent-oriented benchmarks or code intelligence
|
|
878
377
|
|
|
879
|
-
|
|
378
|
+
#### How to Run
|
|
880
379
|
|
|
881
|
-
|
|
380
|
+
```bash
|
|
381
|
+
# TypeScript workspace (CS2 item trading domain)
|
|
382
|
+
NANO_BRAIN_URL=http://localhost:3100 \
|
|
383
|
+
NANO_BRAIN_WORKSPACE=<your-workspace-hash> \
|
|
384
|
+
go test -v -tags=capbench -run TestCapabilityBenchmark \
|
|
385
|
+
./benchmarks/typescript/capability/
|
|
882
386
|
|
|
883
|
-
|
|
387
|
+
# Rails workspace (CS2 item trading domain)
|
|
388
|
+
NANO_BRAIN_URL=http://localhost:3100 \
|
|
389
|
+
NANO_BRAIN_WORKSPACE=<your-workspace-hash> \
|
|
390
|
+
go test -v -tags=capbench -run TestCapabilityBenchmark \
|
|
391
|
+
./benchmarks/rails/capability/
|
|
884
392
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
learning:
|
|
891
|
-
enabled: true # Enable adaptive search tuning
|
|
892
|
-
update_interval_ms: 600000 # Cold-path update interval (10 min)
|
|
893
|
-
|
|
894
|
-
consolidation:
|
|
895
|
-
enabled: true # Enable memory consolidation
|
|
896
|
-
interval_ms: 3600000 # Consolidation interval (60 min)
|
|
897
|
-
model: gpt-4o-mini # LLM model for consolidation
|
|
898
|
-
endpoint: https://api.openai.com/v1 # OpenAI-compatible endpoint
|
|
899
|
-
apiKey: sk-... # API key (not required for Ollama)
|
|
900
|
-
provider: openai # 'openai' (default) or 'ollama'
|
|
901
|
-
|
|
902
|
-
extraction:
|
|
903
|
-
enabled: true # Enable fact extraction from sessions
|
|
904
|
-
model: gpt-4o-mini # LLM model for extraction
|
|
905
|
-
endpoint: https://api.openai.com/v1
|
|
906
|
-
apiKey: sk-...
|
|
907
|
-
maxFactsPerSession: 20 # Max facts to extract per session
|
|
908
|
-
|
|
909
|
-
importance:
|
|
910
|
-
enabled: true # Enable importance scoring
|
|
911
|
-
weight: 0.1 # Importance boost weight
|
|
912
|
-
decay_half_life_days: 30
|
|
913
|
-
|
|
914
|
-
intents:
|
|
915
|
-
enabled: true # Enable query intent classification
|
|
393
|
+
# nano-brain itself (Go daemon)
|
|
394
|
+
NANO_BRAIN_URL=http://localhost:3100 \
|
|
395
|
+
NANO_BRAIN_WORKSPACE=nano-brain \
|
|
396
|
+
go test -v -tags=capbench -run TestCapabilityBenchmark \
|
|
397
|
+
./benchmarks/capability/
|
|
916
398
|
```
|
|
917
399
|
|
|
918
|
-
|
|
400
|
+
#### Task Categories
|
|
919
401
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
402
|
+
| Category | What It Tests | Tools Used |
|
|
403
|
+
|----------|---------------|------------|
|
|
404
|
+
| **search-qa** | Domain concept retrieval via search | `query_question`, `query_input` |
|
|
405
|
+
| **symbol-lookup** | Known identifier resolution | `query_input`, `symbols_identifiers` |
|
|
406
|
+
| **multi-tool** | Cross-tool workflow (search → symbols) | All three tools in sequence |
|
|
925
407
|
|
|
926
|
-
|
|
408
|
+
See individual benchmark READMEs for full task breakdowns:
|
|
409
|
+
- [`benchmarks/typescript/capability/README.md`](benchmarks/typescript/capability/README.md)
|
|
410
|
+
- [`benchmarks/rails/capability/README.md`](benchmarks/rails/capability/README.md)
|
|
411
|
+
- [`benchmarks/capability/README.md`](benchmarks/capability/README.md)
|
|
927
412
|
|
|
928
|
-
|
|
929
|
-
- `nano-brain consolidate` — Trigger a manual consolidation cycle
|
|
413
|
+
---
|
|
930
414
|
|
|
931
|
-
|
|
415
|
+
## Ruby / Rails Support
|
|
932
416
|
|
|
933
|
-
-
|
|
934
|
-
- `memory_consolidation_status` — View consolidation queue stats and recent logs
|
|
935
|
-
- `memory_importance` — View document importance scores
|
|
936
|
-
- `memory_status` — View learning system status (telemetry records, bandit variants, config version)
|
|
417
|
+
nano-brain supports Ruby and Ruby on Rails code intelligence:
|
|
937
418
|
|
|
938
|
-
|
|
419
|
+
- **Rails routes** — `resources`, `get`/`post`/`patch`/`put`/`delete`, `namespace`
|
|
420
|
+
- **Control-flow graphs** — `if`/`else`, loops, `begin`/`rescue`, method defs
|
|
421
|
+
- **Cross-file resolution** — Class→file index, resolver, reconcile edges
|
|
422
|
+
- **Flow diagrams** — Controller→service→model chains (20-34 nodes)
|
|
939
423
|
|
|
940
|
-
|
|
424
|
+
Example flow for a Rails controller action:
|
|
941
425
|
|
|
942
|
-
|
|
426
|
+
```mermaid
|
|
427
|
+
flowchart LR
|
|
428
|
+
POST_/users["POST /users"]
|
|
429
|
+
POST_/users --> UsersController#create
|
|
430
|
+
UsersController#create --> User.create
|
|
431
|
+
UsersController#create --> Mailer.welcome
|
|
432
|
+
```
|
|
943
433
|
|
|
944
|
-
|
|
434
|
+
---
|
|
945
435
|
|
|
946
|
-
|
|
947
|
-
- Background job runs every 6 hours
|
|
948
|
-
- Soft-deletes contradicted entities after 30 days (when newer information supersedes them)
|
|
949
|
-
- Soft-deletes orphan entities after 90 days (entities with no relationships)
|
|
950
|
-
- Hard-deletes soft-deleted entities after 30-day retention period
|
|
951
|
-
- Processes in batches of 100 to avoid SQLite lock contention
|
|
436
|
+
## Tech Stack
|
|
952
437
|
|
|
953
|
-
**
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
438
|
+
- **Go 1.23** — Single static binary (`CGO_ENABLED=0`)
|
|
439
|
+
- **PostgreSQL 17** — Full-text search (tsvector/tsquery)
|
|
440
|
+
- **pgvector 0.8.2** — HNSW vector indexing
|
|
441
|
+
- **Echo v4** — HTTP framework
|
|
442
|
+
- **sqlc** — Type-safe SQL code generation
|
|
443
|
+
- **goose v3** — Database migrations
|
|
444
|
+
- **zerolog** — Structured JSON logging
|
|
445
|
+
- **koanf** — YAML + env configuration
|
|
446
|
+
- **fsnotify** — File system watching
|
|
447
|
+
|
|
448
|
+
---
|
|
963
449
|
|
|
964
|
-
|
|
450
|
+
## Configuration
|
|
965
451
|
|
|
966
|
-
|
|
452
|
+
Config file: `~/.nano-brain/config.yml`
|
|
967
453
|
|
|
968
|
-
|
|
454
|
+
```yaml
|
|
455
|
+
server:
|
|
456
|
+
host: localhost
|
|
457
|
+
port: 3100
|
|
969
458
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
- Uses the same LLM provider configured for consolidation (same endpoint/model/apiKey)
|
|
973
|
-
- Adds tags prefixed with `llm:` (e.g., `llm:architecture-decision`, `llm:debugging-insight`)
|
|
974
|
-
- Only processes documents under 2000 characters (configurable)
|
|
975
|
-
- Requires confidence threshold of 0.6 or higher (configurable)
|
|
459
|
+
database:
|
|
460
|
+
url: postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev
|
|
976
461
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
4. `llm:pattern` — Reusable code patterns, best practices
|
|
982
|
-
5. `llm:preference` — User preferences, workflow choices
|
|
983
|
-
6. `llm:context` — Background information, explanations
|
|
984
|
-
7. `llm:workflow` — Process documentation, how-to guides
|
|
462
|
+
embedding:
|
|
463
|
+
provider: ollama
|
|
464
|
+
url: http://localhost:11434
|
|
465
|
+
model: nomic-embed-text
|
|
985
466
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
confidence_threshold: 0.6 # Minimum confidence to apply a category
|
|
991
|
-
max_content_length: 2000 # Skip documents longer than this
|
|
467
|
+
search:
|
|
468
|
+
rrf_k: 60
|
|
469
|
+
recency_weight: 0.3
|
|
470
|
+
limit: 20
|
|
992
471
|
```
|
|
993
472
|
|
|
994
|
-
|
|
473
|
+
See [Configuration](docs/CONFIGURATION.md) for full options.
|
|
995
474
|
|
|
996
|
-
|
|
475
|
+
---
|
|
997
476
|
|
|
998
|
-
|
|
477
|
+
## Documentation
|
|
999
478
|
|
|
1000
|
-
|
|
1001
|
-
-
|
|
1002
|
-
-
|
|
1003
|
-
-
|
|
1004
|
-
-
|
|
1005
|
-
-
|
|
479
|
+
- [Getting Started](docs/GETTING_STARTED.md) — Step-by-step setup guide
|
|
480
|
+
- [Configuration](docs/CONFIGURATION.md) — All config options
|
|
481
|
+
- [REST API](docs/API.md) — HTTP endpoints
|
|
482
|
+
- [CLI Commands](docs/CLI.md) — Command reference
|
|
483
|
+
- [MCP Tools](docs/MCP.md) — Tool documentation
|
|
484
|
+
- [Architecture](docs/ARCHITECTURE.md) — System design
|
|
485
|
+
- [Changelog](CHANGELOG.md) — What's new
|
|
486
|
+
- [Roadmap](docs/ROADMAP.md) — What's planned
|
|
487
|
+
- [Feature Showcase](docs/FEATURES.md) — Visual examples
|
|
1006
488
|
|
|
1007
|
-
|
|
489
|
+
---
|
|
1008
490
|
|
|
1009
|
-
|
|
1010
|
-
```yaml
|
|
1011
|
-
preferences:
|
|
1012
|
-
enabled: true
|
|
1013
|
-
min_queries: 20 # Minimum queries before personalization kicks in
|
|
1014
|
-
weight_min: 0.5 # Minimum category weight (demotion)
|
|
1015
|
-
weight_max: 2.0 # Maximum category weight (boost)
|
|
1016
|
-
baseline_expand_rate: 0.1 # Expected expand rate (10%)
|
|
1017
|
-
```
|
|
491
|
+
## Contributing
|
|
1018
492
|
|
|
1019
|
-
|
|
493
|
+
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
1020
494
|
|
|
1021
|
-
|
|
495
|
+
### Development Setup
|
|
1022
496
|
|
|
1023
|
-
|
|
497
|
+
```bash
|
|
498
|
+
# Clone the repo
|
|
499
|
+
git clone https://github.com/nano-step/nano-brain.git
|
|
500
|
+
cd nano-brain
|
|
501
|
+
|
|
502
|
+
# Build
|
|
503
|
+
CGO_ENABLED=0 go build -o nano-brain ./cmd/nano-brain
|
|
1024
504
|
|
|
1025
|
-
|
|
505
|
+
# Run tests
|
|
506
|
+
go test -race -short ./...
|
|
1026
507
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
4. **Predictions**: When you ask about topic A, nano-brain predicts you'll need topic B next
|
|
508
|
+
# Run integration tests (requires PostgreSQL)
|
|
509
|
+
go test -race -tags=integration ./...
|
|
510
|
+
```
|
|
1031
511
|
|
|
1032
|
-
###
|
|
512
|
+
### Project Structure
|
|
1033
513
|
|
|
1034
|
-
```
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
514
|
+
```
|
|
515
|
+
nano-brain/
|
|
516
|
+
├── cmd/nano-brain/ # CLI dispatcher + server startup
|
|
517
|
+
├── internal/
|
|
518
|
+
│ ├── config/ # Configuration management
|
|
519
|
+
│ ├── server/ # HTTP server + handlers
|
|
520
|
+
│ ├── storage/ # PostgreSQL + sqlc
|
|
521
|
+
│ ├── search/ # Hybrid search pipeline
|
|
522
|
+
│ ├── embed/ # Embedding queue
|
|
523
|
+
│ ├── watcher/ # File system watcher
|
|
524
|
+
│ ├── harvest/ # Session harvesting
|
|
525
|
+
│ ├── mcp/ # MCP protocol tools
|
|
526
|
+
│ ├── graph/ # Code intelligence
|
|
527
|
+
│ └── ...
|
|
528
|
+
├── migrations/ # Database migrations
|
|
529
|
+
└── benchmarks/ # Performance benchmarks
|
|
1043
530
|
```
|
|
1044
531
|
|
|
1045
|
-
|
|
532
|
+
---
|
|
1046
533
|
|
|
1047
|
-
|
|
1048
|
-
- `context` (optional): Current query or topic
|
|
1049
|
-
- `workspace` (optional): Workspace path
|
|
1050
|
-
- `limit` (optional): Max suggestions (default 3)
|
|
534
|
+
## Community
|
|
1051
535
|
|
|
1052
|
-
|
|
536
|
+
- [GitHub Discussions](https://github.com/nano-step/nano-brain/discussions) — Ask questions, share ideas
|
|
537
|
+
- [Discord](https://discord.gg/nano-brain) — Real-time chat
|
|
538
|
+
- [Twitter](https://twitter.com/nano_brain) — Updates and announcements
|
|
1053
539
|
|
|
1054
|
-
|
|
540
|
+
---
|
|
1055
541
|
|
|
1056
|
-
|
|
542
|
+
## License
|
|
1057
543
|
|
|
1058
|
-
|
|
544
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
1059
545
|
|
|
1060
|
-
|
|
546
|
+
---
|
|
1061
547
|
|
|
1062
|
-
##
|
|
548
|
+
## Acknowledgments
|
|
1063
549
|
|
|
1064
|
-
|
|
550
|
+
Built with:
|
|
551
|
+
- [Go](https://go.dev/) — Fast, statically typed language
|
|
552
|
+
- [PostgreSQL](https://www.postgresql.org/) — The world's most advanced open source database
|
|
553
|
+
- [pgvector](https://github.com/pgvector/pgvector) — Open-source vector similarity search
|
|
554
|
+
- [Echo](https://echo.labstack.com/) — High performance, extensible, minimalist Go web framework
|
|
555
|
+
- [sqlc](https://sqlc.dev/) — Generate type-safe code from SQL
|
|
556
|
+
- [goose](https://github.com/pressly/goose) — Database migration tool
|
|
557
|
+
- [zerolog](https://github.com/rs/zerolog) — Zero allocation JSON logger
|
|
558
|
+
- [koanf](https://github.com/knadh/koanf) — Configuration manager
|
|
559
|
+
- [fsnotify](https://github.com/fsnotify/fsnotify) — Cross-platform file system notifications
|