@nano-step/nano-brain 2026.1.14 → 2026.5.25-beta.26

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.
Files changed (95) hide show
  1. package/README.md +228 -245
  2. package/npm/postinstall.js +89 -0
  3. package/npm/run.js +22 -0
  4. package/package.json +24 -28
  5. package/.opencode/command/nano-brain-init.md +0 -13
  6. package/.opencode/command/nano-brain-reindex.md +0 -11
  7. package/.opencode/command/nano-brain-status.md +0 -12
  8. package/AGENTS.md +0 -41
  9. package/AGENTS_SNIPPET.md +0 -44
  10. package/CHANGELOG.md +0 -186
  11. package/SKILL.md +0 -109
  12. package/bin/cli.js +0 -29
  13. package/commands/nano-brain-init.md +0 -36
  14. package/commands/nano-brain-reindex.md +0 -31
  15. package/commands/nano-brain-status.md +0 -32
  16. package/index.html +0 -929
  17. package/nano-brain +0 -4
  18. package/opencode-mcp.json +0 -9
  19. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/.openspec.yaml +0 -2
  20. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/design.md +0 -68
  21. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/proposal.md +0 -27
  22. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/specs/mcp-integration-testing/spec.md +0 -50
  23. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/specs/mcp-server/spec.md +0 -40
  24. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/specs/search-pipeline/spec.md +0 -29
  25. package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/tasks.md +0 -37
  26. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/.openspec.yaml +0 -2
  27. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/design.md +0 -111
  28. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/proposal.md +0 -30
  29. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/specs/mcp-server/spec.md +0 -33
  30. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/specs/storage-limits/spec.md +0 -90
  31. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/specs/workspace-scoping/spec.md +0 -66
  32. package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/tasks.md +0 -199
  33. package/openspec/changes/codebase-indexing/.openspec.yaml +0 -2
  34. package/openspec/changes/codebase-indexing/design.md +0 -169
  35. package/openspec/changes/codebase-indexing/proposal.md +0 -30
  36. package/openspec/changes/codebase-indexing/specs/codebase-collection/spec.md +0 -187
  37. package/openspec/changes/codebase-indexing/specs/mcp-server/spec.md +0 -36
  38. package/openspec/changes/codebase-indexing/tasks.md +0 -56
  39. package/openspec/changes/fix-session-harvest-workspace-scoping/.openspec.yaml +0 -2
  40. package/openspec/changes/fix-session-harvest-workspace-scoping/design.md +0 -84
  41. package/openspec/changes/fix-session-harvest-workspace-scoping/proposal.md +0 -26
  42. package/openspec/changes/fix-session-harvest-workspace-scoping/specs/workspace-scoping/spec.md +0 -65
  43. package/openspec/changes/fix-session-harvest-workspace-scoping/tasks.md +0 -33
  44. package/openspec/changes/performance-and-search-quality/.openspec.yaml +0 -2
  45. package/openspec/changes/performance-and-search-quality/proposal.md +0 -37
  46. package/openspec/specs/mcp-integration-testing/spec.md +0 -50
  47. package/openspec/specs/mcp-server/spec.md +0 -75
  48. package/openspec/specs/search-pipeline/spec.md +0 -29
  49. package/openspec/specs/storage-limits/spec.md +0 -94
  50. package/openspec/specs/workspace-scoping/spec.md +0 -70
  51. package/site/build.js +0 -66
  52. package/site/partials/_api.html +0 -83
  53. package/site/partials/_compare.html +0 -100
  54. package/site/partials/_config.html +0 -23
  55. package/site/partials/_features.html +0 -43
  56. package/site/partials/_footer.html +0 -6
  57. package/site/partials/_hero.html +0 -9
  58. package/site/partials/_how-it-works.html +0 -26
  59. package/site/partials/_models.html +0 -18
  60. package/site/partials/_quick-start.html +0 -15
  61. package/site/partials/_stats.html +0 -1
  62. package/site/partials/_tech-stack.html +0 -13
  63. package/site/script.js +0 -12
  64. package/site/shell.html +0 -44
  65. package/site/styles.css +0 -548
  66. package/src/chunker.ts +0 -427
  67. package/src/codebase.ts +0 -425
  68. package/src/collections.ts +0 -217
  69. package/src/embeddings.ts +0 -325
  70. package/src/expansion.ts +0 -79
  71. package/src/harvester.ts +0 -306
  72. package/src/index.ts +0 -778
  73. package/src/reranker.ts +0 -103
  74. package/src/search.ts +0 -294
  75. package/src/server.ts +0 -876
  76. package/src/storage.ts +0 -221
  77. package/src/store.ts +0 -653
  78. package/src/types.ts +0 -215
  79. package/src/watcher.ts +0 -389
  80. package/test/chunker.test.ts +0 -479
  81. package/test/cli.test.ts +0 -309
  82. package/test/codebase-chunker.test.ts +0 -446
  83. package/test/codebase.test.ts +0 -678
  84. package/test/collections.test.ts +0 -571
  85. package/test/harvester.test.ts +0 -636
  86. package/test/integration.test.ts +0 -219
  87. package/test/llm.test.ts +0 -322
  88. package/test/search.test.ts +0 -572
  89. package/test/server.test.ts +0 -541
  90. package/test/storage.test.ts +0 -302
  91. package/test/store.test.ts +0 -530
  92. package/test/watcher.test.ts +0 -717
  93. package/test/workspace.test.ts +0 -239
  94. package/tsconfig.json +0 -19
  95. package/vitest.config.ts +0 -16
package/README.md CHANGED
@@ -1,297 +1,280 @@
1
1
  # nano-brain
2
2
 
3
- Persistent memory system for AI coding agents. Hybrid search (BM25 + vector + LLM reranking) across past sessions, codebase, curated notes, and daily logs.
3
+ **Persistent memory and code intelligence for AI coding agents.**
4
+
5
+ [![Go 1.23](https://img.shields.io/badge/Go-1.23-00ADD8?logo=go)](https://go.dev/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ [![GitHub](https://img.shields.io/badge/GitHub-nano--step%2Fnano--brain-181717?logo=github)](https://github.com/nano-step/nano-brain)
4
8
 
5
9
  ## What It Does
6
10
 
7
- An MCP server that gives AI coding agents persistent memory across sessions. Indexes markdown documents, past sessions, and daily logs into a searchable SQLite database with FTS5 and vector embeddings. Provides 10 MCP tools for search, retrieval, and memory management using a sophisticated hybrid search pipeline with query expansion, RRF fusion, and neural reranking.
11
+ nano-brain is a persistent memory server for AI coding agents that solves session amnesia. It automatically ingests AI sessions, notes, and codebase files, indexes everything with hybrid search (BM25 + pgvector), and serves memories via MCP tools and REST API. Built in Go with PostgreSQL single static binary, zero CGO dependencies.
8
12
 
9
- Inspired by [QMD](https://github.com/tobi/qmd) and [OpenClaw](https://github.com/openclaw/openclaw).
13
+ ## Key Features
10
14
 
11
- ## Architecture
15
+ - **Hybrid search** — BM25 full-text + pgvector HNSW cosine similarity + RRF fusion + recency decay
16
+ - **9 MCP tools** — query, search, vsearch, get, write, tags, status, update, wake_up
17
+ - **Session harvesting** — auto-ingest OpenCode and Claude Code sessions
18
+ - **File watcher** — fsnotify-based directory monitoring with debounce
19
+ - **Content-addressed storage** — SHA-256 deduplication
20
+ - **Heading-aware markdown chunking**
21
+ - **Multi-workspace isolation** with per-workspace data
22
+ - **Config hot-reload** — `POST /api/reload-config`
23
+ - **V1 migration** — import from SQLite (pure Go, no CGO)
24
+ - **Benchmarking suite** — generate, run, compare, stress
25
+ - **Search telemetry** — local-only, 90-day retention, non-blocking
12
26
 
13
- ```
14
- User Query
15
-
16
-
17
- ┌─────────────────┐
18
- │ Query Expansion │ ← qmd-query-expansion-1.7B (GGUF)
19
- │ (optional) │ generates 2-3 query variants
20
- └────────┬────────┘
21
-
22
- ┌────┴────┐
23
- ▼ ▼
24
- ┌────────┐ ┌──────────┐
25
- │ BM25 │ │ Vector │
26
- │ (FTS5) │ │(sqlite- │
27
- │ │ │ vec) │
28
- └───┬────┘ └────┬─────┘
29
- │ │
30
- ▼ ▼
31
- ┌─────────────────┐
32
- │ RRF Fusion │ ← k=60, original query 2× weight
33
- │ │
34
- └────────┬────────┘
35
-
36
-
37
- ┌─────────────────┐
38
- │ LLM Reranking │ ← bge-reranker-v2-m3 (GGUF)
39
- │ (optional) │
40
- └────────┬────────┘
41
-
42
-
43
- ┌─────────────────┐
44
- │ Position-Aware │ ← top 3: 75/25, 4-10: 60/40, 11+: 40/60
45
- │ Blending │ (RRF weight / rerank weight)
46
- └────────┬────────┘
47
-
48
-
49
- Final Results
50
- ```
27
+ ## Prerequisites
51
28
 
52
- ## How It Works
29
+ - **Go 1.23+** (building from source) OR pre-built binary
30
+ - **PostgreSQL 17** with **pgvector 0.8.2** extension
31
+ - **Embedding provider:** Ollama (default, local) or Voyage AI
53
32
 
54
- ### Storage Layer
33
+ ## Quick Start
55
34
 
56
- - **SQLite** via better-sqlite3 for document metadata and content
57
- - **FTS5** virtual table with porter stemming for BM25 full-text search
58
- - **sqlite-vec** extension for vector similarity search (cosine distance)
59
- - **Content-addressed storage** using SHA-256 hash deduplication
35
+ ### Option A: Via npx (no Go required)
60
36
 
61
- ### Chunking
37
+ ```bash
38
+ # Start PostgreSQL + pgvector
39
+ docker run -d --name nanobrain-pg -p 5432:5432 \
40
+ -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \
41
+ pgvector/pgvector:pg17
62
42
 
63
- Heading-aware markdown chunking that respects document structure:
43
+ # Start Ollama + pull embedding model
44
+ ollama pull nomic-embed-text
64
45
 
65
- - **Target size:** 900 tokens (~3600 characters)
66
- - **Overlap:** 15% between chunks (~540 characters)
67
- - **Respects boundaries:** Code fences, headings, paragraphs
68
- - **Break point scoring:** h1=100, h2=90, h3=80, code-fence=80, hr=60, blank-line=40
46
+ # Check prerequisites
47
+ npx @nano-step/nano-brain@beta doctor
69
48
 
70
- ### Search Pipeline (3 Tiers)
49
+ # Start server
50
+ npx @nano-step/nano-brain@beta
51
+ ```
71
52
 
72
- **`memory_search`** BM25 only (fast, exact keyword matching)
53
+ > **Also available as:** `npx nano-brain@beta` (unscoped alias)
54
+ >
55
+ > **Note:** Do NOT run `npx nano-brain` from the nano-brain source directory — npm will resolve the local package instead of the registry. Run from any other directory.
73
56
 
74
- **`memory_vsearch`** Vector only (semantic similarity via embeddings)
57
+ ### Option B: Build from source
75
58
 
76
- **`memory_query`** — Full hybrid pipeline:
77
- 1. Query expansion generates 2-3 variants (optional)
78
- 2. Parallel BM25 + vector search
79
- 3. RRF fusion (k=60, original query weighted 2×)
80
- 4. LLM reranking with bge-reranker-v2-m3 (optional)
81
- 5. Position-aware blending:
82
- - Top 3 results: 75% RRF / 25% rerank
83
- - Ranks 4-10: 60% RRF / 40% rerank
84
- - Ranks 11+: 40% RRF / 60% rerank
59
+ ```bash
60
+ # Build
61
+ CGO_ENABLED=0 go build -o nano-brain ./cmd/nano-brain
85
62
 
86
- ### Collections
63
+ # Start PostgreSQL + pgvector (example with Docker)
64
+ docker run -d --name nanobrain-pg -p 5432:5432 \
65
+ -e POSTGRES_USER=nanobrain -e POSTGRES_PASSWORD=nanobrain -e POSTGRES_DB=nanobrain_dev \
66
+ pgvector/pgvector:pg17
87
67
 
88
- - **YAML-configured** directories of markdown files
89
- - **Auto-indexing** via chokidar file watcher
90
- - **Incremental updates** using dirty-flag tracking
91
- - **Session harvesting** converts OpenCode JSON sessions into searchable markdown
68
+ # Start server
69
+ DATABASE_URL="postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev" ./nano-brain
92
70
 
93
- ## MCP Tools
71
+ # Register workspace
72
+ curl -X POST http://localhost:3100/api/v1/init \
73
+ -H "Content-Type: application/json" \
74
+ -d '{"root_path":"/path/to/project","name":"my-project"}'
94
75
 
95
- | Tool | Description |
96
- |------|-------------|
97
- | `memory_search` | BM25 keyword search (fast) |
98
- | `memory_vsearch` | Semantic vector search |
99
- | `memory_query` | Full hybrid search with expansion + reranking |
100
- | `memory_get` | Retrieve document by path or docid (#abc123) |
101
- | `memory_multi_get` | Batch retrieve by glob pattern |
102
- | `memory_write` | Write to daily log (tagged with workspace) |
103
- | `memory_status` | Index health, collections, model status |
104
- | `memory_index_codebase` | Index codebase files in current workspace |
105
- | `memory_update` | Trigger reindex of all collections |
106
-
107
- ## Installation
108
- ```bash
109
- npm install -g nano-brain
76
+ # Write a document
77
+ curl -X POST http://localhost:3100/api/v1/write \
78
+ -H "Content-Type: application/json" \
79
+ -d '{"workspace":"<hash>","source_path":"notes/decision.md","content":"# Decision\nUse PostgreSQL.","tags":["decision"]}'
80
+
81
+ # Search
82
+ curl -X POST http://localhost:3100/api/v1/query \
83
+ -H "Content-Type: application/json" \
84
+ -d '{"workspace":"<hash>","query":"database decision"}'
110
85
  ```
111
86
 
112
- ### Quick Start
87
+ ## Configuration
113
88
 
114
- ```bash
115
- # Initialize (creates config, indexes codebase, generates embeddings)
116
- npx nano-brain init --root=/path/to/your/project
89
+ Config file: `~/.nano-brain/config.yml`
117
90
 
118
- # Check everything is working
119
- npx nano-brain status
120
- ```
91
+ ```yaml
92
+ server:
93
+ host: localhost
94
+ port: 3100
121
95
 
122
- Add to your AI agent's MCP config (e.g. `~/.config/opencode/opencode.json`):
123
- ```json
124
- {
125
- "mcp": {
126
- "nano-brain": {
127
- "type": "local",
128
- "command": ["npx", "nano-brain", "mcp"],
129
- "enabled": true
130
- }
131
- }
132
- }
133
- ```
96
+ database:
97
+ url: postgres://nanobrain:nanobrain@localhost:5432/nanobrain_dev
134
98
 
135
- ## Configuration
136
- Create `~/.nano-brain/config.yml` (auto-generated by `init`):
137
- ```yaml
138
- collections:
139
- memory:
140
- path: ~/.nano-brain/memory
141
- pattern: "**/*.md"
142
- update: auto
143
- sessions:
144
- path: ~/.nano-brain/sessions
145
- pattern: "**/*.md"
146
- update: auto
147
-
148
- # Embedding configuration
149
99
  embedding:
150
- provider: ollama
151
- url: http://localhost:11434 # Auto-detected: localhost natively, host.docker.internal in Docker
100
+ provider: ollama # ollama or voyage
101
+ url: http://localhost:11434
152
102
  model: nomic-embed-text
103
+ dimension: 0 # auto-detect from provider
104
+ concurrency: 3
105
+
106
+ search:
107
+ rrf_k: 60
108
+ recency_weight: 0.3
109
+ recency_half_life_days: 180
110
+ limit: 20
111
+
112
+ harvester:
113
+ opencode:
114
+ session_dir: "" # e.g., ~/.local/share/opencode/storage
115
+ claudecode:
116
+ enabled: false
117
+ session_dir: ""
118
+
119
+ watcher:
120
+ debounce_ms: 2000
121
+ reindex_interval: 300
122
+
123
+ storage:
124
+ max_file_size: 314572800 # 300MB
125
+ max_size: 10737418240 # 10GB
126
+
127
+ telemetry:
128
+ retention_days: 90
129
+
130
+ logging:
131
+ level: info
132
+ file: "" # empty = stdout only
153
133
  ```
154
134
 
155
- **Collection options:**
156
- - `path` — Directory to index
157
- - `pattern` Glob pattern for files
158
- - `update` — `auto` (watch for changes) or `manual`
135
+ ### Environment Variables
136
+
137
+ | Variable | Description |
138
+ |----------|-------------|
139
+ | `DATABASE_URL` | PostgreSQL connection string |
140
+ | `VOYAGE_API_KEY` | Voyage AI API key |
141
+ | `OPENCODE_STORAGE_DIR` | OpenCode session directory |
142
+ | `NANO_BRAIN_*` | Override any config (e.g., `NANO_BRAIN_SERVER_PORT=3100`) |
143
+
144
+ ## REST API
145
+
146
+ ### Public Endpoints
147
+
148
+ | Method | Path | Description |
149
+ |--------|------|-------------|
150
+ | GET | `/health` | Health check |
151
+ | GET | `/api/status` | Server status with version, uptime, workspace stats |
152
+ | POST | `/api/v1/init` | Register workspace |
153
+ | GET | `/api/v1/workspaces` | List all workspaces (with doc counts) |
154
+ | GET | `/api/v1/wake-up` | Workspace briefing |
155
+ | POST | `/api/harvest` | Trigger session harvesting |
156
+ | POST | `/api/reload-config` | Hot-reload configuration |
157
+
158
+ ### Workspace-Scoped Endpoints
159
+
160
+ Workspace is passed in the JSON body for POST, query param for GET.
161
+
162
+ | Method | Path | Description |
163
+ |--------|------|-------------|
164
+ | POST | `/api/v1/write` | Write/update document |
165
+ | POST | `/api/v1/embed` | Trigger embedding |
166
+ | POST | `/api/v1/search` | BM25 keyword search |
167
+ | POST | `/api/v1/vsearch` | Vector similarity search |
168
+ | POST | `/api/v1/query` | Hybrid search (BM25 + vector + RRF + recency) |
169
+ | POST | `/api/v1/collections` | Add collection |
170
+ | GET | `/api/v1/collections` | List collections |
171
+ | PUT | `/api/v1/collections/:name` | Rename collection |
172
+ | DELETE | `/api/v1/collections/:name` | Remove collection |
173
+ | GET | `/api/v1/tags` | List tags with counts |
174
+ | POST | `/api/v1/reindex` | Queue reindex (202) |
175
+ | POST | `/api/v1/update` | Queue update (202) |
176
+ | POST | `/api/v1/wake-up` | Workspace briefing with session_dir |
177
+
178
+ ### MCP Endpoints
179
+
180
+ | Method | Path | Description |
181
+ |--------|------|-------------|
182
+ | GET/POST | `/mcp` | Streamable HTTP (MCP 2025-03-26) |
183
+ | GET/POST | `/sse` | SSE transport (legacy) |
184
+
185
+ ## CLI Commands
186
+
187
+ | Command | Description |
188
+ |---------|-------------|
189
+ | `nano-brain` (no args) | Start HTTP server (default: port 3100) |
190
+ | `nano-brain init --root=<path>` | Register workspace |
191
+ | `nano-brain write` | Write document via CLI |
192
+ | `nano-brain query` | Hybrid search |
193
+ | `nano-brain search` | BM25 keyword search |
194
+ | `nano-brain vsearch` | Vector similarity search |
195
+ | `nano-brain collection add\|remove\|list` | Manage collections |
196
+ | `nano-brain harvest` | Trigger session harvesting |
197
+ | `nano-brain bench generate\|run\|compare\|stress` | Benchmarking suite |
198
+ | `nano-brain db:migrate` | Run pending goose migrations |
199
+ | `nano-brain db:migrate --from-v1 <path>` | Import V1 SQLite data |
200
+ | `nano-brain logs [-n 50] [-f]` | Tail log file |
201
+ | `nano-brain docker start\|stop\|status` | Docker compose management |
202
+ | `nano-brain status [--json]` | Server status |
203
+ | `nano-brain doctor [--json]` | Check prerequisites (config, PostgreSQL, pgvector, Ollama, model) |
159
204
 
160
- **Embedding options:**
161
- - `provider` — `ollama` (default)
162
- - `url` — Ollama API URL (auto-detected during `init`)
163
- - `model` — Embedding model name (default: `nomic-embed-text`)
205
+ ## MCP Tools
164
206
 
165
- **Data directory layout (`~/.nano-brain/`):**
166
- ```
167
- ~/.nano-brain/
168
- ├── config.yml # Configuration
169
- ├── data/ # SQLite databases (per-workspace)
170
- ├── models/ # Embedding model cache
171
- ├── memory/ # Curated notes
172
- └── sessions/ # Harvested sessions
173
- ```
207
+ nano-brain exposes 9 tools via MCP (Model Context Protocol):
174
208
 
175
- ## CLI Usage
209
+ | Tool | Description |
210
+ |------|-------------|
211
+ | `memory_query` | Hybrid search (BM25 + vector + RRF + recency) |
212
+ | `memory_search` | BM25 keyword search |
213
+ | `memory_vsearch` | Vector similarity search |
214
+ | `memory_get` | Get document by path |
215
+ | `memory_write` | Write/update document |
216
+ | `memory_tags` | List tags with counts |
217
+ | `memory_status` | Server and embedding status |
218
+ | `memory_update` | Trigger re-embedding |
219
+ | `memory_wake_up` | Workspace briefing |
220
+
221
+ ### MCP Configuration
176
222
 
177
- ```bash
178
- # Setup
179
- nano-brain init # Full initialization (config, index, embed, AGENTS.md)
180
- nano-brain init --root=/path # Initialize for specific project
181
- # MCP server
182
- nano-brain mcp # Start MCP server (stdio)
183
- nano-brain mcp --http # Start MCP server (HTTP, port 8282)
184
- # Index management
185
- nano-brain status # Show index health
186
- nano-brain update # Reindex all collections
187
- # Search
188
- nano-brain search "query" # BM25 search
189
- nano-brain vsearch "query" # Vector search
190
- nano-brain query "query" # Hybrid search
191
- # Collections
192
- nano-brain collection add <name> <path> # Add collection
193
- nano-brain collection remove <name> # Remove collection
194
- nano-brain collection list # List collections
223
+ ```json
224
+ {
225
+ "mcp": {
226
+ "nano-brain": {
227
+ "type": "remote",
228
+ "url": "http://localhost:3100/mcp"
229
+ }
230
+ }
231
+ }
195
232
  ```
196
233
 
197
- ## Project Structure
234
+ ## Search Pipeline
198
235
 
199
236
  ```
200
- src/
201
- ├── index.ts # CLI entry point
202
- ├── server.ts # MCP server (10 tools, stdio/HTTP)
203
- ├── store.ts # SQLite storage (FTS5 + sqlite-vec)
204
- ├── search.ts # Hybrid search pipeline (RRF, reranking, blending)
205
- ├── chunker.ts # Heading-aware markdown chunking
206
- ├── collections.ts # YAML config, collection scanning
207
- ├── embeddings.ts # Embedding providers (Ollama API + GGUF fallback)
208
- ├── reranker.ts # GGUF reranker model (bge-reranker-v2-m3)
209
- ├── expansion.ts # GGUF query expansion (qmd-query-expansion-1.7B)
210
- ├── harvester.ts # OpenCode session → markdown converter
211
- ├── watcher.ts # File watcher (chokidar, dirty flags)
212
- └── types.ts # TypeScript interfaces
213
- bin/
214
- └── cli.js # CLI wrapper
215
-
216
- test/
217
- └── *.test.ts # 428 tests (vitest)
218
- SKILL.md # AI agent routing instructions (auto-loaded by OpenCode)
219
- AGENTS_SNIPPET.md # Optional project-level AGENTS.md managed block
237
+ Query --> BM25 (ts_rank_cd) ---+
238
+ +--> RRF Fusion (k=60) --> Recency Decay --> Results
239
+ Query --> Vector (HNSW cos) ---+
220
240
  ```
221
241
 
222
- ## Tech Stack
223
-
224
- - **TypeScript + Node.js** (via tsx)
225
- - **better-sqlite3** + **sqlite-vec** for storage
226
- - **@modelcontextprotocol/sdk** for MCP server
227
- - **node-llama-cpp** for GGUF model inference
228
- - **chokidar** for file watching
229
- - **vitest** for testing (428 tests)
230
-
231
- ## Models
232
-
233
- All models are GGUF format, loaded on-demand:
234
-
235
- - **Embeddings:** nomic-embed-text-v1.5 (~270MB)
236
- - **Reranker:** bge-reranker-v2-m3 (~1.1GB)
237
- - **Query Expansion:** qmd-query-expansion-1.7B (~1GB)
242
+ - **BM25:** `websearch_to_tsquery` + `ts_rank_cd` on PostgreSQL tsvector
243
+ - **Vector:** pgvector HNSW index with cosine distance
244
+ - **RRF:** Reciprocal Rank Fusion (k=60), scores normalized to [0,1]
245
+ - **Recency:** exponential half-life decay (default 180 days, weight 0.3)
238
246
 
239
- Models are downloaded automatically on first use to `~/.nano-brain/models/`.
240
-
241
- ## How nano-brain Compares
242
-
243
- | | nano-brain | Mem0 / OpenMemory | Zep / Graphiti | OMEGA | Letta (MemGPT) | Claude Native |
244
- |---|---|---|---|---|---|---|
245
- | **Search** | Hybrid (BM25 + vector + LLM reranking) | Vector only | Graph traversal + vector | Semantic + BM25 | Agent-managed | Text file read |
246
- | **Storage** | SQLite (single file) | PostgreSQL + Qdrant | Neo4j | SQLite | PostgreSQL / SQLite | Flat text files |
247
- | **MCP Tools** | 10 | 4-9 | 9-10 | 12 | 7 | 0 |
248
- | **Local-First** | Yes (zero cloud) | Requires OpenAI API key | Requires Docker + Neo4j | Yes | Yes | Yes |
249
- | **AI Models** | Local GGUF (nomic-embed, bge-reranker) | Cloud API (OpenAI) | Cloud API | Local ONNX | Cloud API | None |
250
- | **Codebase Indexing** | Yes (structural boundary detection) | No | No | No | No | No |
251
- | **Session Recall** | Yes (auto-harvests past sessions) | No | No | No | No | Limited (CLAUDE.md) |
252
- | **Query Expansion** | Yes (local LLM) | No | No | No | No | No |
253
- | **LLM Reranking** | Yes (bge-reranker-v2-m3) | No | No | No | No | No |
254
- | **Privacy** | 100% local, no data leaves machine | Cloud API calls | Cloud or self-host | 100% local | Self-host or cloud | Local files |
255
- | **Dependencies** | SQLite + GGUF models (~1.5GB) | Docker + PostgreSQL + Qdrant + OpenAI key | Docker + Neo4j | SQLite + ONNX | PostgreSQL | None |
256
- | **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) |
257
- | **GitHub Stars** | New | ~47K | ~23K | ~25 | ~21K | N/A |
258
-
259
- ### Where nano-brain shines
260
-
261
- - **Hybrid search pipeline** — the only MCP memory server with BM25 + vector + query expansion + LLM reranking in a single pipeline
262
- - **Codebase indexing** — index your source files with structural boundary detection, not just conversations
263
- - **Session recall** — automatically harvests and indexes past AI coding sessions
264
- - **Zero dependencies** — single SQLite file, local GGUF models, no Docker/PostgreSQL/Neo4j/API keys
265
- - **Privacy** — 100% local processing, your code and conversations never leave your machine
266
-
267
- ### Consider alternatives if
268
-
269
- - You need a knowledge graph with temporal reasoning (Zep/Graphiti)
270
- - You want a full agent framework, not just memory (Letta)
271
- - You need cloud-hosted memory shared across teams (Mem0 Cloud)
272
- - You only need basic session notes (Claude native memory)
273
-
274
- ## AI Agent Integration
275
-
276
- nano-brain ships with a SKILL.md that teaches AI agents when and how to use memory tools. When loaded as an OpenCode skill, agents automatically:
277
-
278
- - **Check memory before starting work** — recall past decisions, patterns, and context
279
- - **Save context after completing work** — persist key decisions and debugging insights
280
- - **Route queries to the right search tool** — BM25 for exact terms, vector for concepts, hybrid for best quality
281
-
282
- ### SKILL.md (Auto-loaded)
283
-
284
- The skill file at `SKILL.md` provides routing rules, trigger phrases, tool selection guides, and integration patterns. It's automatically loaded when any agent references the `nano-brain` skill.
247
+ ## Architecture
285
248
 
286
- ### AGENTS_SNIPPET.md (Optional, project-level)
249
+ - 15 internal packages: config, server, handlers, storage, sqlc, embed, search, watcher, harvest, mcp, migrate, telemetry, health, bench
250
+ - 7 goose SQL migrations (embedded)
251
+ - Constructor injection (no DI framework)
252
+ - errgroup + context for goroutine lifecycle
253
+ - Echo v4 middleware: workspace extraction, content-type enforcement, version header
287
254
 
288
- For project-level integration, `AGENTS_SNIPPET.md` provides a managed block that can be injected into a project's `AGENTS.md`:
255
+ ## Migration from V1
289
256
 
290
257
  ```bash
291
- npx nano-brain init --root=/path/to/project
258
+ # Import V1 SQLite data to PostgreSQL
259
+ nano-brain db:migrate --from-v1 /path/to/old/index.db
260
+
261
+ # Idempotent — safe to run multiple times
262
+ # Uses content-addressed SHA-256 hashing
263
+ # Pure Go SQLite reader (modernc.org/sqlite, no CGO)
292
264
  ```
293
265
 
294
- See [SKILL.md](./SKILL.md) for full routing rules and [AGENTS_SNIPPET.md](./AGENTS_SNIPPET.md) for the project-level snippet.
266
+ ## Tech Stack
267
+
268
+ - **Go 1.23** — compiled to single static binary (`CGO_ENABLED=0`)
269
+ - **PostgreSQL 17** — relational storage + full-text search (tsvector/tsquery)
270
+ - **pgvector 0.8.2** — HNSW vector indexing
271
+ - **Echo v4** — HTTP framework
272
+ - **sqlc** — type-safe SQL code generation
273
+ - **goose v3** — database migrations
274
+ - **zerolog** — structured JSON logging
275
+ - **koanf** — YAML + env configuration
276
+ - **fsnotify** — file system watching
277
+ - **modernc.org/sqlite** — V1 migration reader (pure Go)
295
278
 
296
279
  ## License
297
280
 
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const https = require("https");
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const os = require("os");
8
+ const { execSync } = require("child_process");
9
+
10
+ const VERSION = require("../package.json").version;
11
+ const REPO = "nano-step/nano-brain";
12
+
13
+ const PLATFORM_MAP = {
14
+ darwin: "darwin",
15
+ linux: "linux",
16
+ };
17
+ const ARCH_MAP = {
18
+ arm64: "arm64",
19
+ x64: "amd64",
20
+ };
21
+
22
+ function getPlatformKey() {
23
+ const platform = PLATFORM_MAP[os.platform()];
24
+ const arch = ARCH_MAP[os.arch()];
25
+ if (!platform || !arch) {
26
+ console.error(`Unsupported platform: ${os.platform()}-${os.arch()}`);
27
+ console.error("Build from source: CGO_ENABLED=0 go build -o nano-brain ./cmd/nano-brain");
28
+ process.exit(0);
29
+ }
30
+ return `${platform}-${arch}`;
31
+ }
32
+
33
+ function download(url, dest) {
34
+ return new Promise((resolve, reject) => {
35
+ const file = fs.createWriteStream(dest);
36
+ https.get(url, (res) => {
37
+ if (res.statusCode === 301 || res.statusCode === 302) {
38
+ file.close();
39
+ fs.unlinkSync(dest);
40
+ return download(res.headers.location, dest).then(resolve).catch(reject);
41
+ }
42
+ if (res.statusCode !== 200) {
43
+ file.close();
44
+ fs.unlinkSync(dest);
45
+ return reject(new Error(`Download failed: HTTP ${res.statusCode}`));
46
+ }
47
+ res.pipe(file);
48
+ file.on("finish", () => {
49
+ file.close(resolve);
50
+ });
51
+ }).on("error", (err) => {
52
+ fs.unlinkSync(dest);
53
+ reject(err);
54
+ });
55
+ });
56
+ }
57
+
58
+ async function main() {
59
+ const platformKey = getPlatformKey();
60
+ const binName = os.platform() === "win32" ? "nano-brain.exe" : "nano-brain";
61
+ const binPath = path.join(__dirname, binName);
62
+
63
+ if (fs.existsSync(binPath)) {
64
+ try {
65
+ const output = execSync(`"${binPath}" version --json`, { timeout: 5000 }).toString();
66
+ if (output.includes(VERSION)) {
67
+ console.log(`nano-brain v${VERSION} already installed.`);
68
+ return;
69
+ }
70
+ } catch {
71
+ // Wrong version or can't run — redownload
72
+ }
73
+ }
74
+
75
+ const url = `https://github.com/${REPO}/releases/download/v${VERSION}/nano-brain-${platformKey}`;
76
+ console.log(`Downloading nano-brain v${VERSION} for ${platformKey}...`);
77
+
78
+ try {
79
+ await download(url, binPath);
80
+ fs.chmodSync(binPath, 0o755);
81
+ console.log(`nano-brain v${VERSION} installed successfully.`);
82
+ } catch (err) {
83
+ console.error(`Failed to download binary: ${err.message}`);
84
+ console.error("Build from source: CGO_ENABLED=0 go build -o npm/nano-brain ./cmd/nano-brain");
85
+ process.exit(0);
86
+ }
87
+ }
88
+
89
+ main();
package/npm/run.js ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const { execFileSync } = require("child_process");
5
+ const path = require("path");
6
+ const fs = require("fs");
7
+ const os = require("os");
8
+
9
+ const binName = os.platform() === "win32" ? "nano-brain.exe" : "nano-brain";
10
+ const binPath = path.join(__dirname, binName);
11
+
12
+ if (!fs.existsSync(binPath)) {
13
+ console.error("nano-brain binary not found. Run: npx nano-brain (it will download automatically)");
14
+ console.error("Or build from source: CGO_ENABLED=0 go build -o npm/nano-brain ./cmd/nano-brain");
15
+ process.exit(1);
16
+ }
17
+
18
+ try {
19
+ execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
20
+ } catch (e) {
21
+ process.exit(e.status || 1);
22
+ }