nano-brain 2026.1.0
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/AGENTS_SNIPPET.md +36 -0
- package/CHANGELOG.md +68 -0
- package/README.md +281 -0
- package/SKILL.md +153 -0
- package/bin/cli.js +18 -0
- package/index.html +929 -0
- package/nano-brain +4 -0
- package/opencode-mcp.json +9 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/.openspec.yaml +2 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/design.md +68 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/proposal.md +27 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/specs/mcp-integration-testing/spec.md +50 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/specs/mcp-server/spec.md +40 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/specs/search-pipeline/spec.md +29 -0
- package/openspec/changes/archive/2026-02-16-fix-mcp-server-bugs/tasks.md +37 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/.openspec.yaml +2 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/design.md +111 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/proposal.md +30 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/specs/mcp-server/spec.md +33 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/specs/storage-limits/spec.md +90 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/specs/workspace-scoping/spec.md +66 -0
- package/openspec/changes/archive/2026-02-23-workspace-scoped-memory-and-storage-limits/tasks.md +199 -0
- package/openspec/changes/codebase-indexing/.openspec.yaml +2 -0
- package/openspec/changes/codebase-indexing/design.md +169 -0
- package/openspec/changes/codebase-indexing/proposal.md +30 -0
- package/openspec/changes/codebase-indexing/specs/codebase-collection/spec.md +187 -0
- package/openspec/changes/codebase-indexing/specs/mcp-server/spec.md +36 -0
- package/openspec/changes/codebase-indexing/tasks.md +56 -0
- package/openspec/specs/mcp-integration-testing/spec.md +50 -0
- package/openspec/specs/mcp-server/spec.md +75 -0
- package/openspec/specs/search-pipeline/spec.md +29 -0
- package/openspec/specs/storage-limits/spec.md +94 -0
- package/openspec/specs/workspace-scoping/spec.md +70 -0
- package/package.json +34 -0
- package/site/build.js +66 -0
- package/site/partials/_api.html +83 -0
- package/site/partials/_compare.html +100 -0
- package/site/partials/_config.html +23 -0
- package/site/partials/_features.html +43 -0
- package/site/partials/_footer.html +6 -0
- package/site/partials/_hero.html +9 -0
- package/site/partials/_how-it-works.html +26 -0
- package/site/partials/_models.html +18 -0
- package/site/partials/_quick-start.html +15 -0
- package/site/partials/_stats.html +1 -0
- package/site/partials/_tech-stack.html +13 -0
- package/site/script.js +12 -0
- package/site/shell.html +44 -0
- package/site/styles.css +548 -0
- package/src/chunker.ts +427 -0
- package/src/codebase.ts +331 -0
- package/src/collections.ts +192 -0
- package/src/embeddings.ts +293 -0
- package/src/expansion.ts +79 -0
- package/src/harvester.ts +306 -0
- package/src/index.ts +503 -0
- package/src/reranker.ts +103 -0
- package/src/search.ts +294 -0
- package/src/server.ts +664 -0
- package/src/storage.ts +221 -0
- package/src/store.ts +623 -0
- package/src/types.ts +202 -0
- package/src/watcher.ts +384 -0
- package/test/chunker.test.ts +479 -0
- package/test/cli.test.ts +309 -0
- package/test/codebase-chunker.test.ts +446 -0
- package/test/codebase.test.ts +678 -0
- package/test/collections.test.ts +571 -0
- package/test/harvester.test.ts +636 -0
- package/test/integration.test.ts +150 -0
- package/test/llm.test.ts +322 -0
- package/test/search.test.ts +572 -0
- package/test/server.test.ts +541 -0
- package/test/storage.test.ts +302 -0
- package/test/store.test.ts +465 -0
- package/test/watcher.test.ts +656 -0
- package/test/workspace.test.ts +239 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!-- OPENCODE-MEMORY:START -->
|
|
2
|
+
<!-- Managed block - do not edit manually. Updated by: npx nano-brain init -->
|
|
3
|
+
|
|
4
|
+
## Memory System (nano-brain)
|
|
5
|
+
|
|
6
|
+
This project uses **nano-brain** for persistent context across sessions.
|
|
7
|
+
|
|
8
|
+
### Quick Reference
|
|
9
|
+
|
|
10
|
+
| I want to... | Command |
|
|
11
|
+
|--------------|---------|
|
|
12
|
+
| Recall past work on a topic | `memory_query("topic")` |
|
|
13
|
+
| Find exact error/function name | `memory_search("exact term")` |
|
|
14
|
+
| Explore a concept semantically | `memory_vsearch("concept")` |
|
|
15
|
+
| Save a decision for future sessions | `memory_write("decision context")` |
|
|
16
|
+
| Check index health | `memory_status` |
|
|
17
|
+
|
|
18
|
+
### Session Workflow
|
|
19
|
+
|
|
20
|
+
**Start of session:** Check memory for relevant past context before exploring the codebase.
|
|
21
|
+
```
|
|
22
|
+
memory_query("what have we done regarding {current task topic}")
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**End of session:** Save key decisions, patterns discovered, and debugging insights.
|
|
26
|
+
```
|
|
27
|
+
memory_write("## Summary\n- Decision: ...\n- Why: ...\n- Files: ...")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### When to Search Memory vs Codebase
|
|
31
|
+
|
|
32
|
+
- **"Have we done this before?"** → `memory_query` (searches past sessions)
|
|
33
|
+
- **"Where is this in the code?"** → grep / ast-grep (searches current files)
|
|
34
|
+
- **"How does this concept work here?"** → Both (memory for past context + grep for current code)
|
|
35
|
+
|
|
36
|
+
<!-- OPENCODE-MEMORY:END -->
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2026.1.0] - 2026-02-23
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **AI agent routing instructions (SKILL.md)**: Enhanced SKILL.md with trigger phrases, when-to-use rules, tool selection guide, collection filtering, and integration patterns for orchestrator and subagent workflows. Agents now auto-route to memory for recall, past decisions, cross-session context, and repeated patterns.
|
|
8
|
+
- **AGENTS_SNIPPET.md**: Optional managed block for project-level AGENTS.md installation. Provides quick reference table, session workflow (start/end), and memory vs codebase search guidance. Designed for `npx nano-brain init` injection.
|
|
9
|
+
- **`memory_index_codebase` documented**: Added to SKILL.md, README, and site API reference.
|
|
10
|
+
- **`workspace` parameter documented**: Added to search tool docs showing workspace scoping.
|
|
11
|
+
|
|
12
|
+
## [0.3.0] - 2026-02-23
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Codebase indexing**: Opt-in source code indexing via `codebase: { enabled: true }` in config.yml. Indexes source files from the current workspace into the search pipeline for semantic code search.
|
|
17
|
+
- **Source code chunker**: Line-based chunking with structural boundary detection (function/class/type definitions, import blocks). Same 900-token target and 15% overlap as markdown chunker. Metadata headers (`File:`, `Language:`, `Lines:`) prepended to each chunk.
|
|
18
|
+
- **Project type auto-detection**: Detects project type from marker files (package.json, pyproject.toml, go.mod, Cargo.toml, etc.) and selects appropriate file extensions to index. Falls back to all common extensions.
|
|
19
|
+
- **Exclude pattern merging**: Combines exclude patterns from three sources: config `codebase.exclude`, `.gitignore`, and built-in defaults (node_modules, .git, dist, build, etc.).
|
|
20
|
+
- **Codebase storage budget**: Independent `codebase.maxSize` (default 2GB) limits codebase storage separately from session storage. Indexing stops when budget is exceeded. Storage usage reported in `memory_status`.
|
|
21
|
+
- **Max file size guard**: Skips files larger than `codebase.maxFileSize` (default 5MB) to avoid indexing generated/minified files.
|
|
22
|
+
- **`memory_index_codebase` MCP tool**: On-demand full codebase scan and index with summary stats (files scanned, indexed, skipped, storage usage).
|
|
23
|
+
- **Codebase stats in `memory_status`**: Shows enabled state, document count, storage used/limit, resolved extensions, and exclude pattern count.
|
|
24
|
+
- **Watcher integration**: File watcher monitors workspace directory for source code changes with exclude patterns, triggering incremental reindex.
|
|
25
|
+
- **`getCollectionStorageSize()`**: New Store method to query per-collection storage usage.
|
|
26
|
+
- **118 new tests**: `codebase.test.ts` (68 tests), `codebase-chunker.test.ts` (50 tests). Total: 428 tests.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Increased vitest worker heap size to 8GB to prevent OOM during test runs with large test suites.
|
|
31
|
+
|
|
32
|
+
## [0.2.0] - 2026-02-23
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- **Workspace scoping**: Search results are now scoped to the current workspace by default. Each workspace is identified by a SHA-256 hash of its directory path, matching the harvester convention. Cross-workspace search is available via `workspace: "all"` parameter.
|
|
37
|
+
- **Storage limits**: Configurable `maxSize` (default 2GB), `retention` (default 90d), and `minFreeDisk` (default 100MB) in `config.yml` under a `storage` section. Human-readable values like `500MB`, `30d`, `1y` are supported.
|
|
38
|
+
- **Disk safety guard**: Checks available disk space via `fs.statfsSync()` before writes. Skips harvest/reindex/embed when disk is critically low.
|
|
39
|
+
- **Retention-based eviction**: Automatically deletes harvested session markdown older than the retention period during each harvest cycle.
|
|
40
|
+
- **Size-based eviction**: If total storage exceeds `maxSize` after retention eviction, deletes oldest sessions until under limit. Original OpenCode session JSON is never touched.
|
|
41
|
+
- **Orphan embedding cleanup**: Removes embedding vectors for deleted documents every 10 harvest cycles.
|
|
42
|
+
- **Incremental harvesting**: Tracks session file mtimes in `.harvest-state.json` to skip unchanged files, reducing harvest time from O(all) to O(changed).
|
|
43
|
+
- **`workspace` parameter** on `memory_search`, `memory_vsearch`, and `memory_query` MCP tools. Omit for current workspace, `"all"` for cross-workspace.
|
|
44
|
+
- **Per-workspace stats** in `memory_status` output showing document counts per workspace hash.
|
|
45
|
+
- **45 new tests**: `workspace.test.ts` (18), `storage.test.ts` (27), plus integration tests in `server.test.ts` and `watcher.test.ts`. Total: 310 tests.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- Switched embedding model from EmbeddingGemma-300M (384d) to **nomic-embed-text-v1.5** (768d) for better search quality.
|
|
50
|
+
- Switched reranker from Qwen3-Reranker-0.6B to **bge-reranker-v2-m3** (8192 context) for improved reranking.
|
|
51
|
+
- Updated prompt format to nomic `search_query:`/`search_document:` convention.
|
|
52
|
+
- `documents` table now has a `project_hash` column with automatic migration and backfill on first startup.
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- Crash when session JSON has undefined `slug` field (now falls back to session id).
|
|
57
|
+
|
|
58
|
+
## [0.1.0] - 2026-02-16
|
|
59
|
+
|
|
60
|
+
### Added
|
|
61
|
+
|
|
62
|
+
- Initial release with hybrid search (BM25 + vector + LLM reranking).
|
|
63
|
+
- 8 MCP tools: `memory_search`, `memory_vsearch`, `memory_query`, `memory_get`, `memory_multi_get`, `memory_write`, `memory_status`, `memory_update`.
|
|
64
|
+
- SQLite storage with FTS5 and sqlite-vec.
|
|
65
|
+
- Heading-aware markdown chunking.
|
|
66
|
+
- YAML-configured collections with auto-indexing via chokidar.
|
|
67
|
+
- OpenCode session harvesting (JSON to markdown).
|
|
68
|
+
- GGUF model inference via node-llama-cpp.
|
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# nano-brain
|
|
2
|
+
|
|
3
|
+
Persistent memory system for AI coding agents. Hybrid search (BM25 + vector + LLM reranking) across past sessions, codebase, curated notes, and daily logs.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
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.
|
|
8
|
+
|
|
9
|
+
Inspired by [QMD](https://github.com/tobi/qmd) and [OpenClaw](https://github.com/openclaw/openclaw).
|
|
10
|
+
|
|
11
|
+
## Architecture
|
|
12
|
+
|
|
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
|
+
```
|
|
51
|
+
|
|
52
|
+
## How It Works
|
|
53
|
+
|
|
54
|
+
### Storage Layer
|
|
55
|
+
|
|
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
|
|
60
|
+
|
|
61
|
+
### Chunking
|
|
62
|
+
|
|
63
|
+
Heading-aware markdown chunking that respects document structure:
|
|
64
|
+
|
|
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
|
|
69
|
+
|
|
70
|
+
### Search Pipeline (3 Tiers)
|
|
71
|
+
|
|
72
|
+
**`memory_search`** — BM25 only (fast, exact keyword matching)
|
|
73
|
+
|
|
74
|
+
**`memory_vsearch`** — Vector only (semantic similarity via embeddings)
|
|
75
|
+
|
|
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
|
|
85
|
+
|
|
86
|
+
### Collections
|
|
87
|
+
|
|
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
|
|
92
|
+
|
|
93
|
+
## MCP Tools
|
|
94
|
+
|
|
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 or MEMORY.md |
|
|
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
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Clone and install
|
|
111
|
+
git clone <repo-url>
|
|
112
|
+
cd nano-brain
|
|
113
|
+
npm install
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Add to OpenCode config (`~/.config/opencode/opencode.json`):
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"mcp": {
|
|
121
|
+
"nano-brain": {
|
|
122
|
+
"type": "local",
|
|
123
|
+
"command": ["node", "/path/to/nano-brain/bin/cli.js", "mcp"],
|
|
124
|
+
"enabled": true
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
Create `~/.config/nano-brain/config.yml`:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
collections:
|
|
136
|
+
memory:
|
|
137
|
+
path: ~/.nano-brain
|
|
138
|
+
pattern: "**/*.md"
|
|
139
|
+
update: auto
|
|
140
|
+
|
|
141
|
+
project-docs:
|
|
142
|
+
path: /path/to/project/docs
|
|
143
|
+
pattern: "**/*.md"
|
|
144
|
+
update: auto
|
|
145
|
+
|
|
146
|
+
sessions:
|
|
147
|
+
path: ~/.local/share/opencode/sessions
|
|
148
|
+
pattern: "**/*.json"
|
|
149
|
+
update: auto
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Collection options:**
|
|
153
|
+
- `path` — Directory to index
|
|
154
|
+
- `pattern` — Glob pattern for files
|
|
155
|
+
- `update` — `auto` (watch for changes) or `manual`
|
|
156
|
+
|
|
157
|
+
## CLI Usage
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# MCP server
|
|
161
|
+
nano-brain mcp # Start MCP server (stdio)
|
|
162
|
+
nano-brain mcp --http # Start MCP server (HTTP, port 8282)
|
|
163
|
+
|
|
164
|
+
# Index management
|
|
165
|
+
nano-brain status # Show index health
|
|
166
|
+
nano-brain update # Reindex all collections
|
|
167
|
+
|
|
168
|
+
# Search
|
|
169
|
+
nano-brain search "query" # BM25 search
|
|
170
|
+
nano-brain vsearch "query" # Vector search
|
|
171
|
+
nano-brain query "query" # Hybrid search
|
|
172
|
+
|
|
173
|
+
# Collections
|
|
174
|
+
nano-brain collection add <name> <path> # Add collection
|
|
175
|
+
nano-brain collection remove <name> # Remove collection
|
|
176
|
+
nano-brain collection list # List collections
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Project Structure
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
src/
|
|
183
|
+
├── index.ts # CLI entry point
|
|
184
|
+
├── server.ts # MCP server (10 tools, stdio/HTTP)
|
|
185
|
+
├── store.ts # SQLite storage (FTS5 + sqlite-vec)
|
|
186
|
+
├── search.ts # Hybrid search pipeline (RRF, reranking, blending)
|
|
187
|
+
├── chunker.ts # Heading-aware markdown chunking
|
|
188
|
+
├── collections.ts # YAML config, collection scanning
|
|
189
|
+
├── embeddings.ts # GGUF embedding model (nomic-embed-text-v1.5)
|
|
190
|
+
├── reranker.ts # GGUF reranker model (bge-reranker-v2-m3)
|
|
191
|
+
├── expansion.ts # GGUF query expansion (qmd-query-expansion-1.7B)
|
|
192
|
+
├── harvester.ts # OpenCode session → markdown converter
|
|
193
|
+
├── watcher.ts # File watcher (chokidar, dirty flags)
|
|
194
|
+
└── types.ts # TypeScript interfaces
|
|
195
|
+
bin/
|
|
196
|
+
└── cli.js # CLI wrapper
|
|
197
|
+
|
|
198
|
+
test/
|
|
199
|
+
└── *.test.ts # 428 tests (vitest)
|
|
200
|
+
SKILL.md # AI agent routing instructions (auto-loaded by OpenCode)
|
|
201
|
+
AGENTS_SNIPPET.md # Optional project-level AGENTS.md managed block
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Tech Stack
|
|
205
|
+
|
|
206
|
+
- **TypeScript + Node.js** (via tsx)
|
|
207
|
+
- **better-sqlite3** + **sqlite-vec** for storage
|
|
208
|
+
- **@modelcontextprotocol/sdk** for MCP server
|
|
209
|
+
- **node-llama-cpp** for GGUF model inference
|
|
210
|
+
- **chokidar** for file watching
|
|
211
|
+
- **vitest** for testing (428 tests)
|
|
212
|
+
|
|
213
|
+
## Models
|
|
214
|
+
|
|
215
|
+
All models are GGUF format, loaded on-demand:
|
|
216
|
+
|
|
217
|
+
- **Embeddings:** nomic-embed-text-v1.5 (~270MB)
|
|
218
|
+
- **Reranker:** bge-reranker-v2-m3 (~1.1GB)
|
|
219
|
+
- **Query Expansion:** qmd-query-expansion-1.7B (~1GB)
|
|
220
|
+
|
|
221
|
+
Models are downloaded automatically on first use to `~/.cache/nano-brain/models/`.
|
|
222
|
+
|
|
223
|
+
## How nano-brain Compares
|
|
224
|
+
|
|
225
|
+
| | nano-brain | Mem0 / OpenMemory | Zep / Graphiti | OMEGA | Letta (MemGPT) | Claude Native |
|
|
226
|
+
|---|---|---|---|---|---|---|
|
|
227
|
+
| **Search** | Hybrid (BM25 + vector + LLM reranking) | Vector only | Graph traversal + vector | Semantic + BM25 | Agent-managed | Text file read |
|
|
228
|
+
| **Storage** | SQLite (single file) | PostgreSQL + Qdrant | Neo4j | SQLite | PostgreSQL / SQLite | Flat text files |
|
|
229
|
+
| **MCP Tools** | 10 | 4-9 | 9-10 | 12 | 7 | 0 |
|
|
230
|
+
| **Local-First** | Yes (zero cloud) | Requires OpenAI API key | Requires Docker + Neo4j | Yes | Yes | Yes |
|
|
231
|
+
| **AI Models** | Local GGUF (nomic-embed, bge-reranker) | Cloud API (OpenAI) | Cloud API | Local ONNX | Cloud API | None |
|
|
232
|
+
| **Codebase Indexing** | Yes (structural boundary detection) | No | No | No | No | No |
|
|
233
|
+
| **Session Recall** | Yes (auto-harvests past sessions) | No | No | No | No | Limited (CLAUDE.md) |
|
|
234
|
+
| **Query Expansion** | Yes (local LLM) | No | No | No | No | No |
|
|
235
|
+
| **LLM Reranking** | Yes (bge-reranker-v2-m3) | No | No | No | No | No |
|
|
236
|
+
| **Privacy** | 100% local, no data leaves machine | Cloud API calls | Cloud or self-host | 100% local | Self-host or cloud | Local files |
|
|
237
|
+
| **Dependencies** | SQLite + GGUF models (~1.5GB) | Docker + PostgreSQL + Qdrant + OpenAI key | Docker + Neo4j | SQLite + ONNX | PostgreSQL | None |
|
|
238
|
+
| **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) |
|
|
239
|
+
| **GitHub Stars** | New | ~47K | ~23K | ~25 | ~21K | N/A |
|
|
240
|
+
|
|
241
|
+
### Where nano-brain shines
|
|
242
|
+
|
|
243
|
+
- **Hybrid search pipeline** — the only MCP memory server with BM25 + vector + query expansion + LLM reranking in a single pipeline
|
|
244
|
+
- **Codebase indexing** — index your source files with structural boundary detection, not just conversations
|
|
245
|
+
- **Session recall** — automatically harvests and indexes past AI coding sessions
|
|
246
|
+
- **Zero dependencies** — single SQLite file, local GGUF models, no Docker/PostgreSQL/Neo4j/API keys
|
|
247
|
+
- **Privacy** — 100% local processing, your code and conversations never leave your machine
|
|
248
|
+
|
|
249
|
+
### Consider alternatives if
|
|
250
|
+
|
|
251
|
+
- You need a knowledge graph with temporal reasoning (Zep/Graphiti)
|
|
252
|
+
- You want a full agent framework, not just memory (Letta)
|
|
253
|
+
- You need cloud-hosted memory shared across teams (Mem0 Cloud)
|
|
254
|
+
- You only need basic session notes (Claude native memory)
|
|
255
|
+
|
|
256
|
+
## AI Agent Integration
|
|
257
|
+
|
|
258
|
+
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:
|
|
259
|
+
|
|
260
|
+
- **Check memory before starting work** — recall past decisions, patterns, and context
|
|
261
|
+
- **Save context after completing work** — persist key decisions and debugging insights
|
|
262
|
+
- **Route queries to the right search tool** — BM25 for exact terms, vector for concepts, hybrid for best quality
|
|
263
|
+
|
|
264
|
+
### SKILL.md (Auto-loaded)
|
|
265
|
+
|
|
266
|
+
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.
|
|
267
|
+
|
|
268
|
+
### AGENTS_SNIPPET.md (Optional, project-level)
|
|
269
|
+
|
|
270
|
+
For project-level integration, `AGENTS_SNIPPET.md` provides a managed block that can be injected into a project's `AGENTS.md`:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# Future: npx nano-brain init
|
|
274
|
+
# For now: copy the managed block from AGENTS_SNIPPET.md into your project's AGENTS.md
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
See [SKILL.md](./SKILL.md) for full routing rules and [AGENTS_SNIPPET.md](./AGENTS_SNIPPET.md) for the project-level snippet.
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# nano-brain
|
|
2
|
+
|
|
3
|
+
Persistent memory system for OpenCode. Hybrid search across past sessions, codebase, curated notes, and daily logs.
|
|
4
|
+
|
|
5
|
+
## When to Use (Routing Rules)
|
|
6
|
+
|
|
7
|
+
### ALWAYS use memory BEFORE starting work when:
|
|
8
|
+
|
|
9
|
+
- **Resuming or continuing work** — "continue", "pick up where we left off", "what were we doing"
|
|
10
|
+
- **Referencing past decisions** — "we decided", "last time", "previously", "remember when"
|
|
11
|
+
- **Cross-session context** — "what did we do about X", "how did we solve Y before"
|
|
12
|
+
- **Unfamiliar codebase area** — search memory for past exploration sessions before re-exploring
|
|
13
|
+
- **Repeated patterns** — "same as before", "like we did for X", "follow the same approach"
|
|
14
|
+
|
|
15
|
+
### ALWAYS use memory AFTER completing work:
|
|
16
|
+
|
|
17
|
+
- **Save key decisions** — architecture choices, tradeoffs, rejected alternatives
|
|
18
|
+
- **Save implementation patterns** — reusable approaches discovered during work
|
|
19
|
+
- **Save debugging insights** — root causes, non-obvious fixes, gotchas
|
|
20
|
+
- **Save project context** — domain knowledge, business rules, conventions learned
|
|
21
|
+
|
|
22
|
+
### Trigger Phrases (auto-route to memory)
|
|
23
|
+
|
|
24
|
+
| Phrase | Action |
|
|
25
|
+
|--------|--------|
|
|
26
|
+
| "what did we...", "have we ever...", "did we already..." | `memory_query` → recall past work |
|
|
27
|
+
| "remember", "last time", "before", "previously" | `memory_query` → find past context |
|
|
28
|
+
| "save this", "remember this", "note that" | `memory_write` → persist to memory |
|
|
29
|
+
| "what's the status of memory", "is memory indexed" | `memory_status` → check health |
|
|
30
|
+
| Starting a new feature in a known area | `memory_query` → find past sessions in that area |
|
|
31
|
+
| Debugging a recurring issue | `memory_search` → find past fixes |
|
|
32
|
+
|
|
33
|
+
## Tool Selection Guide
|
|
34
|
+
|
|
35
|
+
### Which search tool to use:
|
|
36
|
+
|
|
37
|
+
| Scenario | Tool | Why |
|
|
38
|
+
|----------|------|-----|
|
|
39
|
+
| Exact function/variable name, error message | `memory_search` (BM25) | Fast exact keyword matching |
|
|
40
|
+
| Conceptual question ("how does X work") | `memory_vsearch` (semantic) | Understands meaning, not just keywords |
|
|
41
|
+
| Complex question, best quality needed | `memory_query` (hybrid) | BM25 + vector + LLM reranking |
|
|
42
|
+
| Retrieve a specific known document | `memory_get` | Direct fetch by path or docid |
|
|
43
|
+
| Save a decision or insight | `memory_write` | Persist to daily log or MEMORY.md |
|
|
44
|
+
|
|
45
|
+
### Search strategy for best results:
|
|
46
|
+
|
|
47
|
+
1. **Start with `memory_query`** for complex/conceptual questions (best quality)
|
|
48
|
+
2. **Use `memory_search`** for exact terms — function names, error codes, specific strings
|
|
49
|
+
3. **Use `memory_vsearch`** when you want semantic similarity without reranking overhead
|
|
50
|
+
4. **Combine with native tools** — memory excels at recall and semantic search; grep/ast-grep excel at precise code pattern matching
|
|
51
|
+
|
|
52
|
+
### Collection filtering:
|
|
53
|
+
|
|
54
|
+
- `collection: "codebase"` — search only indexed source files
|
|
55
|
+
- `collection: "sessions-{project}"` — search only past sessions for a specific project
|
|
56
|
+
- `collection: "curated"` — search only manually saved notes
|
|
57
|
+
- Omit `collection` — search everything (recommended default)
|
|
58
|
+
|
|
59
|
+
## Available Tools
|
|
60
|
+
|
|
61
|
+
### memory_search
|
|
62
|
+
BM25 keyword search. Fast, exact matching.
|
|
63
|
+
- query: Search query (required)
|
|
64
|
+
- limit: Max results (default: 10)
|
|
65
|
+
- collection: Filter by collection
|
|
66
|
+
|
|
67
|
+
### memory_vsearch
|
|
68
|
+
Semantic vector search using embeddings.
|
|
69
|
+
- query: Search query (required)
|
|
70
|
+
- limit: Max results (default: 10)
|
|
71
|
+
- collection: Filter by collection
|
|
72
|
+
|
|
73
|
+
### memory_query
|
|
74
|
+
Full hybrid search with query expansion, RRF fusion, and LLM reranking. Best quality.
|
|
75
|
+
- query: Search query (required)
|
|
76
|
+
- limit: Max results (default: 10)
|
|
77
|
+
- collection: Filter by collection
|
|
78
|
+
- minScore: Minimum score threshold
|
|
79
|
+
|
|
80
|
+
### memory_get
|
|
81
|
+
Retrieve a document by path or docid.
|
|
82
|
+
- id: Document path or #docid (required)
|
|
83
|
+
- fromLine: Start line number
|
|
84
|
+
- maxLines: Number of lines to return
|
|
85
|
+
|
|
86
|
+
### memory_multi_get
|
|
87
|
+
Batch retrieve documents by glob pattern or comma-separated list.
|
|
88
|
+
- pattern: Glob pattern or comma-separated docids/paths (required)
|
|
89
|
+
- maxBytes: Maximum total bytes to return (default: 50000)
|
|
90
|
+
|
|
91
|
+
### memory_write
|
|
92
|
+
Write content to daily log or MEMORY.md.
|
|
93
|
+
- content: Content to write (required)
|
|
94
|
+
- target: "daily" for daily log, "memory" for MEMORY.md (default: "daily")
|
|
95
|
+
|
|
96
|
+
### memory_status
|
|
97
|
+
Show index health, collection info, and model status.
|
|
98
|
+
|
|
99
|
+
### memory_index_codebase
|
|
100
|
+
Index codebase files in the current workspace.
|
|
101
|
+
- root: Workspace root path (optional, defaults to current workspace)
|
|
102
|
+
|
|
103
|
+
### memory_update
|
|
104
|
+
Trigger immediate reindex of all collections.
|
|
105
|
+
|
|
106
|
+
## Integration with Agent Workflow
|
|
107
|
+
|
|
108
|
+
### As an orchestrator (Sisyphus):
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
# Before starting any non-trivial task, check memory:
|
|
112
|
+
memory_query("what have we done regarding {topic}")
|
|
113
|
+
|
|
114
|
+
# After completing significant work, save context:
|
|
115
|
+
memory_write("## {date} - {topic}\n- Decision: ...\n- Reason: ...\n- Files changed: ...")
|
|
116
|
+
|
|
117
|
+
# When delegating to subagents, include memory context:
|
|
118
|
+
task(category="...", load_skills=["nano-brain"], prompt="... CONTEXT from memory: ...")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### As a subagent:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
# If the task involves an area you're unfamiliar with:
|
|
125
|
+
memory_query("{area} implementation patterns")
|
|
126
|
+
|
|
127
|
+
# If debugging and the fix isn't obvious:
|
|
128
|
+
memory_search("{error message or symptom}")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Memory vs Native Tools
|
|
132
|
+
|
|
133
|
+
| Capability | nano-brain | Native (grep/glob/ast-grep) |
|
|
134
|
+
|-----------|----------------|---------------------------|
|
|
135
|
+
| Past session recall | ✅ Searches all past sessions | ❌ session_search is basic text match |
|
|
136
|
+
| Semantic understanding | ✅ "notification workflow" finds related concepts | ❌ Literal pattern matching only |
|
|
137
|
+
| Cross-project knowledge | ✅ Searches across all indexed workspaces | ❌ Scoped to current directory |
|
|
138
|
+
| Exact code patterns | ⚠️ BM25 works, but less precise | ✅ ast-grep, grep are superior |
|
|
139
|
+
| Structural code search | ❌ Not AST-aware | ✅ ast-grep matches code structure |
|
|
140
|
+
| Curated knowledge | ✅ MEMORY.md + daily logs | ❌ No equivalent |
|
|
141
|
+
|
|
142
|
+
**They are complementary.** Use memory for recall + semantics, native tools for precise code matching.
|
|
143
|
+
|
|
144
|
+
## First-Time Setup
|
|
145
|
+
|
|
146
|
+
If memory is not yet indexed for a workspace:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
memory_status # Check current state
|
|
150
|
+
memory_index_codebase root="/path/to/ws" # Index codebase files
|
|
151
|
+
memory_update # Trigger reindex of sessions + curated
|
|
152
|
+
memory_status # Verify completion
|
|
153
|
+
```
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const entry = join(__dirname, '..', 'src', 'index.ts');
|
|
11
|
+
const tsxBin = join(__dirname, '..', 'node_modules', '.bin', 'tsx');
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
execFileSync(tsxBin, [entry, ...args], { stdio: 'inherit' });
|
|
16
|
+
} catch (err) {
|
|
17
|
+
process.exit(err.status || 1);
|
|
18
|
+
}
|