edhindex 1.0.1 → 1.0.2
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 +178 -51
- package/package.json +27 -2
package/README.md
CHANGED
|
@@ -1,69 +1,210 @@
|
|
|
1
1
|
# EDHIndex
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/edhindex)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Local-first hybrid code search engine with Knowledge Graph — zero telemetry, fully offline.
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
npm link # makes "edhindex" available globally
|
|
8
|
+
npm install -g edhindex
|
|
9
|
+
# or
|
|
10
|
+
npx edhindex <command>
|
|
12
11
|
```
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
## Quick start
|
|
15
14
|
|
|
16
15
|
```sh
|
|
17
16
|
cd ~/your-project
|
|
18
|
-
|
|
19
|
-
edhindex start
|
|
17
|
+
edhinit index # initialize index (pick your model + MCP client)
|
|
18
|
+
edhindex start # build index + start MCP server + watch for changes
|
|
20
19
|
```
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
Then ask any MCP client (OpenCode, Claude Code, Cline, Cursor, etc.) to search your codebase.
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
|
29
|
-
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Supported file types
|
|
26
|
+
|
|
27
|
+
| Language | Extensions | Symbols indexed |
|
|
28
|
+
|----------|-----------|----------------|
|
|
29
|
+
| TypeScript | `.ts`, `.tsx`, `.mts`, `.cts` | functions, methods, classes, interfaces, enums |
|
|
30
|
+
| JavaScript | `.js`, `.jsx`, `.mjs`, `.cjs` | functions, methods, classes |
|
|
31
|
+
| Python | `.py`, `.pyw` | functions, classes |
|
|
32
|
+
| Go | `.go` | functions, methods |
|
|
33
|
+
|
|
34
|
+
All files are parsed with tree-sitter for accurate symbol extraction, imports, and exports. Unsupported file extensions are silently skipped. Files larger than 10 MB are also skipped.
|
|
35
|
+
|
|
36
|
+
## What gets ignored
|
|
37
|
+
|
|
38
|
+
EDHIndex uses three layers of filtering. **Every file must pass all three** to be indexed.
|
|
39
|
+
|
|
40
|
+
### Layer 1: Default ignore patterns
|
|
41
|
+
|
|
42
|
+
Directories and files ignored by default (no need for a `.edhindexignore`):
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
Directories: node_modules, .git, dist, build, coverage, .next,
|
|
46
|
+
out, vendor, bin, obj, target, tmp, .cache, .turbo,
|
|
47
|
+
.edhindex
|
|
48
|
+
|
|
49
|
+
Binaries: *.exe, *.dll, *.so, *.dylib, *.bin, *.wasm
|
|
50
|
+
*.o, *.a, *.lib
|
|
51
|
+
|
|
52
|
+
Images/Media: *.png, *.jpg, *.jpeg, *.gif, *.svg, *.ico, *.webp,
|
|
53
|
+
*.bmp, *.tiff
|
|
54
|
+
|
|
55
|
+
Docs/Archives: *.pdf, *.doc, *.docx, *.xls, *.xlsx, *.ppt, *.pptx
|
|
56
|
+
*.zip, *.tar, *.gz, *.bz2, *.7z, *.rar
|
|
57
|
+
|
|
58
|
+
Audio/Video: *.mp3, *.wav, *.flac, *.ogg
|
|
59
|
+
*.mp4, *.avi, *.mov, *.wmv, *.flv, *.mkv
|
|
60
|
+
|
|
61
|
+
Generated/Minified: *.min.js, *.min.css
|
|
62
|
+
package-lock.json, yarn.lock, pnpm-lock.yaml
|
|
63
|
+
|
|
64
|
+
Language artifacts: *.pyc, *.class, *.jar, *.war
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Layer 2: `.edhindexignore`
|
|
68
|
+
|
|
69
|
+
Add a `.edhindexignore` file at your project root with additional glob patterns. Supports `#` comments and `!` negation (to re-include a pattern).
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
```
|
|
73
|
+
# ignore generated code
|
|
74
|
+
src/generated/
|
|
75
|
+
*.generated.ts
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Layer 3: Binary + size gate
|
|
79
|
+
|
|
80
|
+
Files are checked against a blocklist of binary/media/archive extensions and must be under 10 MB.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Indexing modes
|
|
85
|
+
|
|
86
|
+
EDHIndex has **three indexing strategies** that work together:
|
|
87
|
+
|
|
88
|
+
### 1. Full index
|
|
89
|
+
|
|
90
|
+
Scans **every file** from scratch. Runs when no index exists yet, or when the embedding model or chunk schema changes. The full pipeline:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
File → tree-sitter parse → extract symbols → chunk (~512 tokens) →
|
|
94
|
+
→ SQLite metadata + FTS5 (keyword) → LanceDB vectors (semantic) → Graph (SQLite)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 2. Incremental index
|
|
98
|
+
|
|
99
|
+
Compares file hashes against the previous index. Only **added, modified, or removed** files are re-processed. Used by `edhindex index` when an existing compatible index is found.
|
|
100
|
+
|
|
101
|
+
### 3. Live file watcher
|
|
102
|
+
|
|
103
|
+
When `edhindex start` runs (and `watch: true` in config, which is the default), chokidar watches the filesystem. On every save — removes old chunks for the file, re-parses, re-indexes. Debounced at 300ms.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Search pipeline
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
User query
|
|
111
|
+
↓
|
|
112
|
+
┌────────────────┐
|
|
113
|
+
│ Keyword (BM25) │── SQLite FTS5 → top 30
|
|
114
|
+
└────────────────┘
|
|
115
|
+
┌────────────────┐
|
|
116
|
+
│ Vector (ANN) │── transformers.js → LanceDB → top 30
|
|
117
|
+
└────────────────┘
|
|
118
|
+
↓
|
|
119
|
+
┌────────────────┐
|
|
120
|
+
│ Deduplicate │── max score for duplicates
|
|
121
|
+
└────────────────┘
|
|
122
|
+
↓
|
|
123
|
+
┌────────────────┐
|
|
124
|
+
│ Reranker │── cross-encoder → final top N
|
|
125
|
+
└────────────────┘
|
|
126
|
+
↓
|
|
127
|
+
Results with matchType: keyword | vector | hybrid
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
- **Keyword**: SQLite FTS5 with BM25 scoring (porter + unicode61 tokenizer)
|
|
131
|
+
- **Semantic**: `@huggingface/transformers` embeddings → LanceDB ANN search
|
|
132
|
+
- **Hybrid**: top 30 BM25 + top 30 vectors → deduplicate → rerank → top 10
|
|
133
|
+
- **Reranker**: `Xenova/ms-marco-MiniLM-L-6-v2` cross-encoder (configurable via `edhindex config`)
|
|
134
|
+
|
|
135
|
+
### Embedding model tiers
|
|
136
|
+
|
|
137
|
+
| Tier | Model | Dimensions | Download size |
|
|
138
|
+
|------|-------|-----------|--------------|
|
|
139
|
+
| `light` | all-MiniLM-L6-v2 | 384 | ~46 MB |
|
|
140
|
+
| `balanced` (default) | bge-base-en-v1.5 | 768 | ~109 MB |
|
|
141
|
+
| `max` | bge-m3 | 1024 | ~1.1 GB |
|
|
142
|
+
|
|
143
|
+
Switch with `edhindex config model <tier>`.
|
|
144
|
+
|
|
145
|
+
---
|
|
39
146
|
|
|
40
147
|
## Knowledge Graph
|
|
41
148
|
|
|
42
|
-
|
|
149
|
+
Every symbol becomes a node. Imports, exports, and hierarchy become edges. Four graph modes (switch in the UI):
|
|
150
|
+
|
|
151
|
+
| View | Description |
|
|
152
|
+
|------|-------------|
|
|
153
|
+
| **Force** | Physics-based node layout |
|
|
154
|
+
| **Hierarchy** | Directory tree structure |
|
|
155
|
+
| **Circle** | Circular arrangement |
|
|
156
|
+
| **Grid** | Grid layout |
|
|
157
|
+
|
|
158
|
+
### Commands
|
|
43
159
|
|
|
44
160
|
```
|
|
45
|
-
edhindex kg --
|
|
46
|
-
edhindex kg --
|
|
47
|
-
|
|
161
|
+
edhindex kg --rebuild Build the knowledge graph from the index
|
|
162
|
+
edhindex kg --stats Node/edge counts by type
|
|
163
|
+
edhindex kg --serve Open interactive browser at localhost
|
|
164
|
+
edhindex kg --write Write standalone HTML → .edhindex/knowledge-graph.html
|
|
48
165
|
```
|
|
49
166
|
|
|
50
|
-
|
|
167
|
+
Built on tree-sitter + SQLite + Cytoscape.js — all local, no telemetry, no cloud.
|
|
168
|
+
|
|
169
|
+
### Node/edge types
|
|
170
|
+
|
|
171
|
+
**Node kinds**: `workspace`, `folder`, `file`, `module`, `class`, `interface`, `enum`, `function`, `method`, `variable`, `import`, `export`
|
|
172
|
+
|
|
173
|
+
**Edge kinds**: `contains`, `imports`, `exports`, `inherits`, `implements`, `calls`, `references`, `defines`, `belongs_to`
|
|
51
174
|
|
|
52
|
-
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Commands
|
|
178
|
+
|
|
179
|
+
| Command | What it does |
|
|
180
|
+
|---------|-------------|
|
|
181
|
+
| `edhindex init` | Initialize `.edhindex/` — pick model + MCP client |
|
|
182
|
+
| `edhindex start` | Full build + MCP server + file watcher |
|
|
183
|
+
| `edhindex index` | Just build/update the index (no server) |
|
|
184
|
+
| `edhindex search <query>` | CLI hybrid search |
|
|
185
|
+
| `edhindex status` | Index stats |
|
|
186
|
+
| `edhindex config` | View/update settings |
|
|
187
|
+
| `edhindex models` | List available embedding models |
|
|
188
|
+
| `edhindex kg ...` | Knowledge graph operations |
|
|
189
|
+
| `edhindex graph` | Static SVG dependency graph |
|
|
190
|
+
| `edhindex doctor` | Diagnostics (10 checks) |
|
|
191
|
+
| `edhindex reset` | Delete the entire `.edhindex/` |
|
|
192
|
+
|
|
193
|
+
---
|
|
53
194
|
|
|
54
195
|
## MCP Tools
|
|
55
196
|
|
|
56
|
-
When `edhindex start` is running, any MCP client
|
|
197
|
+
When `edhindex start` is running, any MCP client can call:
|
|
57
198
|
|
|
58
199
|
| Tool | What it does |
|
|
59
|
-
|
|
60
|
-
| `search_codebase` | Hybrid search
|
|
200
|
+
|------|-------------|
|
|
201
|
+
| `search_codebase` | Hybrid search with file/language filters |
|
|
61
202
|
| `get_graph` | Full knowledge graph (nodes + edges) |
|
|
62
|
-
| `get_node` | Node details
|
|
203
|
+
| `get_node` | Node details + neighbors |
|
|
63
204
|
| `search_graph` | Search nodes by name |
|
|
64
205
|
| `get_graph_stats` | Graph statistics |
|
|
65
206
|
|
|
66
|
-
|
|
207
|
+
### Client setup
|
|
67
208
|
|
|
68
209
|
During `edhindex init`, pick your MCP client and the config file is created automatically:
|
|
69
210
|
|
|
@@ -76,25 +217,11 @@ During `edhindex init`, pick your MCP client and the config file is created auto
|
|
|
76
217
|
- **GitHub Copilot** → `.vscode/settings.json`
|
|
77
218
|
- **Continue** → `.continue/config.json`
|
|
78
219
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
Source code → Tree-sitter → Chunks → SQLite (metadata + FTS5)
|
|
83
|
-
→ LanceDB (vectors)
|
|
84
|
-
→ Graph (SQLite)
|
|
85
|
-
↓
|
|
86
|
-
MCP Server ← Search Engine ← Hybrid Rerank
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
- **Keyword search**: SQLite FTS5 (BM25)
|
|
90
|
-
- **Semantic search**: transformers.js embeddings → LanceDB vector search
|
|
91
|
-
- **Hybrid**: Top 30 BM25 + top 30 vectors → deduplicate → rerank → top 10
|
|
92
|
-
- **Knowledge Graph**: Symbols, files, folders, imports/exports, hierarchy
|
|
220
|
+
---
|
|
93
221
|
|
|
94
222
|
## Requirements
|
|
95
223
|
|
|
96
224
|
- Node.js 18+
|
|
97
|
-
- npm
|
|
98
225
|
|
|
99
226
|
## License
|
|
100
227
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edhindex",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Local-first hybrid code search engine with MCP",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Local-first hybrid code search engine with knowledge graph — BM25 + vector + rerank, tree-sitter parsing, MCP server",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"code-search",
|
|
7
|
+
"code-index",
|
|
8
|
+
"semantic-search",
|
|
9
|
+
"hybrid-search",
|
|
10
|
+
"knowledge-graph",
|
|
11
|
+
"mcp",
|
|
12
|
+
"tree-sitter",
|
|
13
|
+
"codebase-search",
|
|
14
|
+
"local-first",
|
|
15
|
+
"offline"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/krishnasfdcc-a11y/edhIndex.git"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/krishnasfdcc-a11y/edhIndex#readme",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/krishnasfdcc-a11y/edhIndex/issues"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "edhdev (https://github.com/krishnasfdcc-a11y)",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
},
|
|
5
30
|
"type": "module",
|
|
6
31
|
"bin": {
|
|
7
32
|
"edhindex": "dist/cli/index.js"
|