opencode-rag-plugin 1.1.0 → 1.2.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/ReadMe.md +463 -424
- package/dist/__tests__/chunker/c.test.d.ts +1 -0
- package/dist/__tests__/chunker/c.test.js +82 -0
- package/dist/__tests__/chunker/c.test.js.map +1 -0
- package/dist/__tests__/chunker/cpp.test.d.ts +1 -0
- package/dist/__tests__/chunker/cpp.test.js +96 -0
- package/dist/__tests__/chunker/cpp.test.js.map +1 -0
- package/dist/__tests__/chunker/csharp.test.d.ts +1 -0
- package/dist/__tests__/chunker/csharp.test.js +85 -0
- package/dist/__tests__/chunker/csharp.test.js.map +1 -0
- package/dist/__tests__/chunker/css.test.d.ts +1 -0
- package/dist/__tests__/chunker/css.test.js +64 -0
- package/dist/__tests__/chunker/css.test.js.map +1 -0
- package/dist/__tests__/chunker/factory.test.d.ts +1 -0
- package/dist/__tests__/chunker/factory.test.js +202 -0
- package/dist/__tests__/chunker/factory.test.js.map +1 -0
- package/dist/__tests__/chunker/fallback.test.d.ts +1 -0
- package/dist/__tests__/chunker/fallback.test.js +67 -0
- package/dist/__tests__/chunker/fallback.test.js.map +1 -0
- package/dist/__tests__/chunker/go.test.d.ts +1 -0
- package/dist/__tests__/chunker/go.test.js +90 -0
- package/dist/__tests__/chunker/go.test.js.map +1 -0
- package/dist/__tests__/chunker/grammar.test.d.ts +1 -0
- package/dist/__tests__/chunker/grammar.test.js +108 -0
- package/dist/__tests__/chunker/grammar.test.js.map +1 -0
- package/dist/__tests__/chunker/html.test.d.ts +1 -0
- package/dist/__tests__/chunker/html.test.js +64 -0
- package/dist/__tests__/chunker/html.test.js.map +1 -0
- package/dist/__tests__/chunker/java.test.d.ts +1 -0
- package/dist/__tests__/chunker/java.test.js +83 -0
- package/dist/__tests__/chunker/java.test.js.map +1 -0
- package/dist/__tests__/chunker/javascript.test.d.ts +1 -0
- package/dist/__tests__/chunker/javascript.test.js +88 -0
- package/dist/__tests__/chunker/javascript.test.js.map +1 -0
- package/dist/__tests__/chunker/json.test.d.ts +1 -0
- package/dist/__tests__/chunker/json.test.js +54 -0
- package/dist/__tests__/chunker/json.test.js.map +1 -0
- package/dist/__tests__/chunker/kotlin.test.d.ts +1 -0
- package/dist/__tests__/chunker/kotlin.test.js +42 -0
- package/dist/__tests__/chunker/kotlin.test.js.map +1 -0
- package/dist/__tests__/chunker/markdown.test.d.ts +1 -0
- package/dist/__tests__/chunker/markdown.test.js +76 -0
- package/dist/__tests__/chunker/markdown.test.js.map +1 -0
- package/dist/__tests__/chunker/python.test.d.ts +1 -0
- package/dist/__tests__/chunker/python.test.js +81 -0
- package/dist/__tests__/chunker/python.test.js.map +1 -0
- package/dist/__tests__/chunker/razor.test.d.ts +1 -0
- package/dist/__tests__/chunker/razor.test.js +73 -0
- package/dist/__tests__/chunker/razor.test.js.map +1 -0
- package/dist/__tests__/chunker/register.test.d.ts +1 -0
- package/dist/__tests__/chunker/register.test.js +93 -0
- package/dist/__tests__/chunker/register.test.js.map +1 -0
- package/dist/__tests__/chunker/ruby.test.d.ts +1 -0
- package/dist/__tests__/chunker/ruby.test.js +40 -0
- package/dist/__tests__/chunker/ruby.test.js.map +1 -0
- package/dist/__tests__/chunker/rust.test.d.ts +1 -0
- package/dist/__tests__/chunker/rust.test.js +42 -0
- package/dist/__tests__/chunker/rust.test.js.map +1 -0
- package/dist/__tests__/chunker/sln.test.d.ts +1 -0
- package/dist/__tests__/chunker/sln.test.js +45 -0
- package/dist/__tests__/chunker/sln.test.js.map +1 -0
- package/dist/__tests__/chunker/swift.test.d.ts +1 -0
- package/dist/__tests__/chunker/swift.test.js +49 -0
- package/dist/__tests__/chunker/swift.test.js.map +1 -0
- package/dist/__tests__/chunker/typescript.test.d.ts +1 -0
- package/dist/__tests__/chunker/typescript.test.js +92 -0
- package/dist/__tests__/chunker/typescript.test.js.map +1 -0
- package/dist/__tests__/chunker/uuid.test.d.ts +1 -0
- package/dist/__tests__/chunker/uuid.test.js +19 -0
- package/dist/__tests__/chunker/uuid.test.js.map +1 -0
- package/dist/__tests__/chunker/xml.test.d.ts +1 -0
- package/dist/__tests__/chunker/xml.test.js +50 -0
- package/dist/__tests__/chunker/xml.test.js.map +1 -0
- package/dist/__tests__/core/config.test.d.ts +1 -0
- package/dist/__tests__/core/config.test.js +75 -0
- package/dist/__tests__/core/config.test.js.map +1 -0
- package/dist/__tests__/core/fileLogger.test.d.ts +1 -0
- package/dist/__tests__/core/fileLogger.test.js +34 -0
- package/dist/__tests__/core/fileLogger.test.js.map +1 -0
- package/dist/__tests__/core/manifest.test.d.ts +1 -0
- package/dist/__tests__/core/manifest.test.js +56 -0
- package/dist/__tests__/core/manifest.test.js.map +1 -0
- package/dist/__tests__/embedder/embedBatch.test.d.ts +1 -0
- package/dist/__tests__/embedder/embedBatch.test.js +88 -0
- package/dist/__tests__/embedder/embedBatch.test.js.map +1 -0
- package/dist/__tests__/embedder/factory.test.d.ts +1 -0
- package/dist/__tests__/embedder/factory.test.js +71 -0
- package/dist/__tests__/embedder/factory.test.js.map +1 -0
- package/dist/__tests__/embedder/ollama.test.d.ts +1 -0
- package/dist/__tests__/embedder/ollama.test.js +106 -0
- package/dist/__tests__/embedder/ollama.test.js.map +1 -0
- package/dist/__tests__/embedder/openai.test.d.ts +1 -0
- package/dist/__tests__/embedder/openai.test.js +94 -0
- package/dist/__tests__/embedder/openai.test.js.map +1 -0
- package/dist/__tests__/indexer/indexer.test.d.ts +1 -0
- package/dist/__tests__/indexer/indexer.test.js +176 -0
- package/dist/__tests__/indexer/indexer.test.js.map +1 -0
- package/dist/__tests__/plugin.test.d.ts +1 -0
- package/dist/__tests__/plugin.test.js +77 -0
- package/dist/__tests__/plugin.test.js.map +1 -0
- package/dist/__tests__/retriever/retriever.test.d.ts +1 -0
- package/dist/__tests__/retriever/retriever.test.js +97 -0
- package/dist/__tests__/retriever/retriever.test.js.map +1 -0
- package/dist/__tests__/vectorstore/lancedb.test.d.ts +1 -0
- package/dist/__tests__/vectorstore/lancedb.test.js +159 -0
- package/dist/__tests__/vectorstore/lancedb.test.js.map +1 -0
- package/dist/chunker/doc.d.ts +8 -0
- package/dist/chunker/doc.js +79 -0
- package/dist/chunker/doc.js.map +1 -0
- package/dist/chunker/docx.d.ts +8 -0
- package/dist/chunker/docx.js +78 -0
- package/dist/chunker/docx.js.map +1 -0
- package/dist/chunker/excel.d.ts +8 -0
- package/dist/chunker/excel.js +78 -0
- package/dist/chunker/excel.js.map +1 -0
- package/dist/chunker/factory.d.ts +1 -0
- package/dist/chunker/factory.js +9 -0
- package/dist/chunker/factory.js.map +1 -1
- package/dist/cli.js +272 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +6 -1
- package/dist/core/config.js.map +1 -1
- package/dist/indexer.js +18 -0
- package/dist/indexer.js.map +1 -1
- package/dist/opencode/create-read-tool.d.ts +30 -0
- package/dist/opencode/create-read-tool.js +248 -0
- package/dist/opencode/create-read-tool.js.map +1 -0
- package/dist/opencode/read-fallback.d.ts +21 -0
- package/dist/opencode/read-fallback.js +90 -0
- package/dist/opencode/read-fallback.js.map +1 -0
- package/dist/opencode/read-format.d.ts +40 -0
- package/dist/opencode/read-format.js +86 -0
- package/dist/opencode/read-format.js.map +1 -0
- package/dist/opencode/read-query.d.ts +26 -0
- package/dist/opencode/read-query.js +39 -0
- package/dist/opencode/read-query.js.map +1 -0
- package/dist/opencode/tool-args.d.ts +51 -0
- package/dist/opencode/tool-args.js +70 -0
- package/dist/opencode/tool-args.js.map +1 -0
- package/dist/plugin.js +1 -0
- package/dist/plugin.js.map +1 -1
- package/package.json +89 -82
package/ReadMe.md
CHANGED
|
@@ -1,424 +1,463 @@
|
|
|
1
|
-
# OpenCodeRAG
|
|
2
|
-
|
|
3
|
-
Local-first RAG plugin for OpenCode — semantic code search powered by
|
|
4
|
-
embeddings and vector similarity.
|
|
5
|
-
|
|
6
|
-
**Published on npm as [`opencode-rag-plugin`](https://www.npmjs.com/package/opencode-rag-plugin).**
|
|
7
|
-
|
|
8
|
-
## Features
|
|
9
|
-
|
|
10
|
-
- **AST-aware chunking** — splits code into functions, classes, methods using
|
|
11
|
-
tree-sitter for 16 languages, plus regex-based chunking for 4 markup/config/doc
|
|
12
|
-
formats (Markdown, Razor, .sln, LaTeX). Falls back to line-based chunking for
|
|
13
|
-
unrecognized formats.
|
|
14
|
-
- **Incremental indexing** — manifest-backed indexing skips unchanged files,
|
|
15
|
-
removes deleted entries, and updates only changed files.
|
|
16
|
-
- **Watch mode** — `index --watch` re-indexes on file changes with debounced,
|
|
17
|
-
serialized passes.
|
|
18
|
-
- **Pluggable chunkers** — add custom language chunkers via config or programmatic API.
|
|
19
|
-
- **Configurable embeddings** — Ollama (default) or OpenAI-compatible providers.
|
|
20
|
-
Batch embedding with configurable batch size.
|
|
21
|
-
- **Local vector store** — LanceDB with L2 distance scoring, memory mode for
|
|
22
|
-
testing.
|
|
23
|
-
- **CLI** — index, query, clear, status commands.
|
|
24
|
-
- **OpenCode plugin** — exposes a chunk retrieval tool and suggests relevant files after each user message via the `chat.message` hook.
|
|
25
|
-
|
|
26
|
-
## Architecture
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
Workspace Files
|
|
30
|
-
│
|
|
31
|
-
▼
|
|
32
|
-
┌──────────────┐
|
|
33
|
-
│ Chunker │ AST-based (tree-sitter) or line-based fallback
|
|
34
|
-
└──────┬───────┘
|
|
35
|
-
│ chunks
|
|
36
|
-
▼
|
|
37
|
-
┌──────────────┐
|
|
38
|
-
│ Embedder │ Ollama / OpenAI-compatible API
|
|
39
|
-
└──────┬───────┘
|
|
40
|
-
│ vectors
|
|
41
|
-
▼
|
|
42
|
-
┌──────────────┐
|
|
43
|
-
│ VectorStore │ LanceDB (local files or memory:// for tests)
|
|
44
|
-
└──────┬───────┘
|
|
45
|
-
│ + manifest.json
|
|
46
|
-
▼
|
|
47
|
-
┌──────────────┐
|
|
48
|
-
│ Indexer/Retr.│ incremental index or query/search
|
|
49
|
-
└──────┬───────┘
|
|
50
|
-
│ results
|
|
51
|
-
▼
|
|
52
|
-
LLM Context
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Tech Stack
|
|
56
|
-
|
|
57
|
-
| Layer | Technology |
|
|
58
|
-
| ----------- | --------------------------------------------------- |
|
|
59
|
-
| Runtime | Node.js v22 + tsx (ESM) |
|
|
60
|
-
| Language | TypeScript 5.8 |
|
|
61
|
-
| Chunking | web-tree-sitter (WASM) + tree-sitter-wasm grammars |
|
|
62
|
-
| Embeddings | Ollama / OpenAI-compatible (native fetch) |
|
|
63
|
-
| Vector DB | LanceDB (`@lancedb/lancedb`) |
|
|
64
|
-
| CLI | commander |
|
|
65
|
-
| Tests | Node built-in test runner (`node --test`) |
|
|
66
|
-
| Package mgr | npm (with `--legacy-peer-deps`) |
|
|
67
|
-
|
|
68
|
-
## Installation
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
opencode-rag
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
#
|
|
149
|
-
opencode-rag index
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
`
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
1
|
+
# OpenCodeRAG
|
|
2
|
+
|
|
3
|
+
Local-first RAG plugin for OpenCode — semantic code search powered by
|
|
4
|
+
embeddings and vector similarity.
|
|
5
|
+
|
|
6
|
+
**Published on npm as [`opencode-rag-plugin`](https://www.npmjs.com/package/opencode-rag-plugin).**
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **AST-aware chunking** — splits code into functions, classes, methods using
|
|
11
|
+
tree-sitter for 16 languages, plus regex-based chunking for 4 markup/config/doc
|
|
12
|
+
formats (Markdown, Razor, .sln, LaTeX). Falls back to line-based chunking for
|
|
13
|
+
unrecognized formats.
|
|
14
|
+
- **Incremental indexing** — manifest-backed indexing skips unchanged files,
|
|
15
|
+
removes deleted entries, and updates only changed files.
|
|
16
|
+
- **Watch mode** — `index --watch` re-indexes on file changes with debounced,
|
|
17
|
+
serialized passes.
|
|
18
|
+
- **Pluggable chunkers** — add custom language chunkers via config or programmatic API.
|
|
19
|
+
- **Configurable embeddings** — Ollama (default) or OpenAI-compatible providers.
|
|
20
|
+
Batch embedding with configurable batch size.
|
|
21
|
+
- **Local vector store** — LanceDB with L2 distance scoring, memory mode for
|
|
22
|
+
testing.
|
|
23
|
+
- **CLI** — index, query, clear, status commands.
|
|
24
|
+
- **OpenCode plugin** — exposes a chunk retrieval tool and suggests relevant files after each user message via the `chat.message` hook.
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Workspace Files
|
|
30
|
+
│
|
|
31
|
+
▼
|
|
32
|
+
┌──────────────┐
|
|
33
|
+
│ Chunker │ AST-based (tree-sitter) or line-based fallback
|
|
34
|
+
└──────┬───────┘
|
|
35
|
+
│ chunks
|
|
36
|
+
▼
|
|
37
|
+
┌──────────────┐
|
|
38
|
+
│ Embedder │ Ollama / OpenAI-compatible API
|
|
39
|
+
└──────┬───────┘
|
|
40
|
+
│ vectors
|
|
41
|
+
▼
|
|
42
|
+
┌──────────────┐
|
|
43
|
+
│ VectorStore │ LanceDB (local files or memory:// for tests)
|
|
44
|
+
└──────┬───────┘
|
|
45
|
+
│ + manifest.json
|
|
46
|
+
▼
|
|
47
|
+
┌──────────────┐
|
|
48
|
+
│ Indexer/Retr.│ incremental index or query/search
|
|
49
|
+
└──────┬───────┘
|
|
50
|
+
│ results
|
|
51
|
+
▼
|
|
52
|
+
LLM Context
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Tech Stack
|
|
56
|
+
|
|
57
|
+
| Layer | Technology |
|
|
58
|
+
| ----------- | --------------------------------------------------- |
|
|
59
|
+
| Runtime | Node.js v22 + tsx (ESM) |
|
|
60
|
+
| Language | TypeScript 5.8 |
|
|
61
|
+
| Chunking | web-tree-sitter (WASM) + tree-sitter-wasm grammars |
|
|
62
|
+
| Embeddings | Ollama / OpenAI-compatible (native fetch) |
|
|
63
|
+
| Vector DB | LanceDB (`@lancedb/lancedb`) |
|
|
64
|
+
| CLI | commander |
|
|
65
|
+
| Tests | Node built-in test runner (`node --test`) |
|
|
66
|
+
| Package mgr | npm (with `--legacy-peer-deps`) |
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
### Global installation (recommended)
|
|
71
|
+
|
|
72
|
+
Clone the repository and run the install script:
|
|
73
|
+
|
|
74
|
+
**Windows:**
|
|
75
|
+
```powershell
|
|
76
|
+
.\install.ps1
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Linux/macOS:**
|
|
80
|
+
```bash
|
|
81
|
+
./install.sh
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This will:
|
|
85
|
+
1. Build the plugin from source (`npm run build`)
|
|
86
|
+
2. Install it into OpenCode's runtime (`~/.opencode/node_modules/`)
|
|
87
|
+
3. Register it in the global OpenCode config (`~/.config/opencode/opencode.jsonc`)
|
|
88
|
+
|
|
89
|
+
After installation, restart OpenCode and the plugin is ready.
|
|
90
|
+
|
|
91
|
+
### Per-workspace setup
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cd your-workspace
|
|
95
|
+
opencode-rag init
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`opencode-rag init` bootstraps the current workspace by creating:
|
|
99
|
+
|
|
100
|
+
- `opencode-rag.json`
|
|
101
|
+
- `.opencode/.gitignore`
|
|
102
|
+
- `.opencode/opencode.json`
|
|
103
|
+
- `.opencode/package.json`
|
|
104
|
+
- `.opencode/plugins/rag-plugin.js` (workspace-local plugin fallback)
|
|
105
|
+
- `.opencode/node_modules/` with the workspace-local plugin dependencies
|
|
106
|
+
|
|
107
|
+
Add `--skip-install` if you only want the files without installing dependencies.
|
|
108
|
+
|
|
109
|
+
### Dependencies
|
|
110
|
+
|
|
111
|
+
### Dependencies
|
|
112
|
+
|
|
113
|
+
- **Node.js v22+** for native ESM and fetch support
|
|
114
|
+
- **apache-arrow** — peer dependency for LanceDB (auto-installed)
|
|
115
|
+
- **tree-sitter-wasm** — ships pre-built WASM grammars for all supported languages
|
|
116
|
+
|
|
117
|
+
## Configuration
|
|
118
|
+
|
|
119
|
+
Create `opencode-rag.json` in the project root (auto-detected) or pass via
|
|
120
|
+
`--config`. The repository's own [`opencode-rag.json`](./opencode-rag.json) serves
|
|
121
|
+
as a complete example with all available options.
|
|
122
|
+
|
|
123
|
+
Config files support partial overrides — missing keys fall back to defaults.
|
|
124
|
+
Deep merging is applied per section.
|
|
125
|
+
|
|
126
|
+
### Embedding Providers
|
|
127
|
+
|
|
128
|
+
| Provider | `baseUrl` example | Notes |
|
|
129
|
+
| -------- | --------------------------------- | ---------------------------- |
|
|
130
|
+
| ollama | `http://localhost:11434/api` | Default. No apiKey required. Proxy is disabled when `embedding.proxy.url` is empty. |
|
|
131
|
+
| openai | `https://api.openai.com/v1` | Requires apiKey. |
|
|
132
|
+
|
|
133
|
+
`embedding.timeoutMs` defaults to 30000 ms. Increase it if your local model has a slow cold start.
|
|
134
|
+
|
|
135
|
+
OpenAI provider sends all texts in a single request. Ollama sends one request
|
|
136
|
+
per request to `/api/embed`. Set `embedding.proxy.url` to use the standard
|
|
137
|
+
proxy-aware HTTP path instead of the direct socket path.
|
|
138
|
+
|
|
139
|
+
## Usage
|
|
140
|
+
|
|
141
|
+
This extension consists of two main interfaces:
|
|
142
|
+
1. **CLI** — for manual indexing and querying from the terminal
|
|
143
|
+
2. **OpenCode plugin** — for automatic retrieval and file suggestions within the chat interface
|
|
144
|
+
|
|
145
|
+
### CLI
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Index the workspace incrementally
|
|
149
|
+
opencode-rag index
|
|
150
|
+
|
|
151
|
+
# Force full re-index (clears existing data first)
|
|
152
|
+
opencode-rag index --force
|
|
153
|
+
|
|
154
|
+
# Watch workspace and incrementally re-index on changes
|
|
155
|
+
opencode-rag index --watch
|
|
156
|
+
|
|
157
|
+
# Semantic search
|
|
158
|
+
opencode-rag query "How is authentication handled?"
|
|
159
|
+
|
|
160
|
+
# Limit results
|
|
161
|
+
opencode-rag query "error handling" --top-k 5
|
|
162
|
+
|
|
163
|
+
# Show indexing stats
|
|
164
|
+
opencode-rag status
|
|
165
|
+
|
|
166
|
+
# Example output:
|
|
167
|
+
# Indexed chunks: 1247
|
|
168
|
+
# Store path: /home/user/project/.opencode/rag_db
|
|
169
|
+
# Embedding provider: ollama
|
|
170
|
+
# Embedding model: nomic-embed-text
|
|
171
|
+
# Manifest status: ok
|
|
172
|
+
# Manifest entries: 42
|
|
173
|
+
# Last indexed: 2026-05-28 10:45:02
|
|
174
|
+
# Up-to-date files: 42
|
|
175
|
+
# Pending files: 0
|
|
176
|
+
# Watch mode: off
|
|
177
|
+
|
|
178
|
+
# Clear all indexed data
|
|
179
|
+
opencode-rag clear
|
|
180
|
+
|
|
181
|
+
# Use custom config
|
|
182
|
+
opencode-rag index --config ./my-config.json
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`index` is incremental by default. A sidecar manifest is stored at
|
|
186
|
+
`<vectorStore.path>/manifest.json` and tracks file hashes, chunk counts, and the
|
|
187
|
+
last successful index timestamp. If the manifest is missing or corrupt while the
|
|
188
|
+
vector store already contains data, the next index pass clears and rebuilds the
|
|
189
|
+
store to avoid duplicates.
|
|
190
|
+
|
|
191
|
+
### Watch workflow
|
|
192
|
+
|
|
193
|
+
Start a watch session:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
opencode-rag index --watch
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The initial pass indexes the workspace, then watches for file changes. On each
|
|
200
|
+
`add`, `change`, `unlink`, or `unlinkDir` event, the watch debounces (300 ms)
|
|
201
|
+
and triggers a new incremental pass. If a pass is already running, the re-index
|
|
202
|
+
queues one follow-up pass and runs it as soon as the current pass finishes.
|
|
203
|
+
|
|
204
|
+
The watcher ignores excluded directories, the vector store path, and the
|
|
205
|
+
manifest file itself. Press `Ctrl+C` to stop.
|
|
206
|
+
|
|
207
|
+
### OpenCode Plugin
|
|
208
|
+
|
|
209
|
+
The plugin registers:
|
|
210
|
+
|
|
211
|
+
1. **`opencode-rag-context`** — a custom retrieval tool for chunk-level evidence
|
|
212
|
+
2. **`chat.message`** — after each user message, automatically retrieves relevant indexed files and appends a compact suggestion list to the message text
|
|
213
|
+
|
|
214
|
+
#### Chat Message File Suggestions
|
|
215
|
+
|
|
216
|
+
After you send a message, the plugin:
|
|
217
|
+
1. Extracts the user's message text
|
|
218
|
+
2. Runs semantic retrieval against the indexed workspace
|
|
219
|
+
3. Groups results by file, sorts by best chunk score, and formats a compact file list:
|
|
220
|
+
```
|
|
221
|
+
src/plugin.ts (typescript, lines 10-42)
|
|
222
|
+
src/core/config.ts (typescript, lines 66-145)
|
|
223
|
+
```
|
|
224
|
+
4. Appends the list (max 10 files) to your message text
|
|
225
|
+
|
|
226
|
+
Only file paths, language, and line ranges are shown — no scores or code snippets. This gives the agent lightweight hints about which files are relevant without inflating the context window.
|
|
227
|
+
|
|
228
|
+
**Config:**
|
|
229
|
+
|
|
230
|
+
| Option | Default | Description |
|
|
231
|
+
| ------ | ------- | ----------- |
|
|
232
|
+
| `openCode.overrideRead` | `false` | Set to `true` to restore the legacy RAG-backed `read` tool (deprecated) |
|
|
233
|
+
| `openCode.maxContextChunks` | `5` | Maximum chunks per retrieval (affects `opencode-rag-context` tool output) |
|
|
234
|
+
| `retrieval.topK` | `10` | Number of chunks fetched per query (controls chat.message file suggestion breadth) |
|
|
235
|
+
|
|
236
|
+
Errors during retrieval are silently caught — a failed search won't break the
|
|
237
|
+
chat.
|
|
238
|
+
|
|
239
|
+
#### Install from source
|
|
240
|
+
|
|
241
|
+
After cloning and installing dependencies:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# Option 1: Install globally via the install script (recommended)
|
|
245
|
+
./install.sh # Linux/macOS
|
|
246
|
+
.\install.ps1 # Windows
|
|
247
|
+
|
|
248
|
+
# Option 2: Build and pack manually, then register globally
|
|
249
|
+
npm run build
|
|
250
|
+
npm pack
|
|
251
|
+
npm install --prefix ~/.opencode/ opencode-rag-plugin-1.2.0.tgz
|
|
252
|
+
npm install --prefix ~/.config/opencode/ opencode-rag-plugin-1.2.0.tgz
|
|
253
|
+
# Add "opencode-rag-plugin" to the plugin array in ~/.config/opencode/opencode.jsonc
|
|
254
|
+
|
|
255
|
+
# Option 3: Bootstrap workspace only (uses npm version)
|
|
256
|
+
opencode-rag init
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The plugin auto-detects configuration from `opencode-rag.json` or
|
|
260
|
+
`.opencode/opencode-rag.json` or `.opencode/rag.json` in the project root.
|
|
261
|
+
|
|
262
|
+
`opencode-rag init` creates a workspace-local plugin file at `.opencode/plugins/rag-plugin.js`
|
|
263
|
+
that re-exports from `node_modules/`, serving as a fallback when global loading fails.
|
|
264
|
+
No `plugin` entry is required in `.opencode/opencode.json`.
|
|
265
|
+
|
|
266
|
+
Restart OpenCode after changing plugin files or plugin configuration.
|
|
267
|
+
|
|
268
|
+
### Logging
|
|
269
|
+
|
|
270
|
+
Logging is configured under the `logging` key:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"logging": {
|
|
275
|
+
"level": "info",
|
|
276
|
+
"logFilePath": "./.opencode/opencode-rag.log"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Option | Default | Description |
|
|
282
|
+
| ------------ | ------------------------------ | -------------------------------------------- |
|
|
283
|
+
| `level` | `"info"` | Log level: `"debug"`, `"info"`, or `"error"` |
|
|
284
|
+
| `logFilePath` | `"./.opencode/opencode-rag.log"` | Path to the log file (relative paths are resolved against the workspace directory) |
|
|
285
|
+
|
|
286
|
+
The resolved log file path also falls back to the `LOG_FILE_PATH` environment variable when the config value is not set. Config takes precedence over the env var when both are provided.
|
|
287
|
+
|
|
288
|
+
#### AGENTS.md hints for using the plugin
|
|
289
|
+
|
|
290
|
+
Add a section like this to the target workspace's `AGENTS.md` so the agent
|
|
291
|
+
knows how to use the plugin correctly:
|
|
292
|
+
|
|
293
|
+
```markdown
|
|
294
|
+
## OpenCodeRAG Plugin
|
|
295
|
+
|
|
296
|
+
This workspace has OpenCodeRAG installed for semantic code retrieval.
|
|
297
|
+
|
|
298
|
+
### `opencode-rag-context` tool
|
|
299
|
+
Before planning, editing, or answering, use this tool to retrieve relevant code
|
|
300
|
+
chunks with file paths, line ranges, and surrounding implementation.
|
|
301
|
+
- `query` (required) — narrow, specific search, e.g. `"authentication middleware setup"`
|
|
302
|
+
- `pathHints` (optional) — up to 10 path filters, e.g. `["src/auth/"]`
|
|
303
|
+
- `languageHints` (optional) — up to 10 language filters, e.g. `["typescript"]`
|
|
304
|
+
- `topK` (optional) — result count (1-25, default 10)
|
|
305
|
+
|
|
306
|
+
### File suggestions
|
|
307
|
+
After each user message, a `chat.message` hook appends up to 10 relevant file
|
|
308
|
+
suggestions to the message. Look for lines like
|
|
309
|
+
`src/file.ts (typescript, lines 10-42)` at the bottom of user input.
|
|
310
|
+
|
|
311
|
+
### Indexing
|
|
312
|
+
- The plugin auto-indexes changed files in the background (debounced 5s)
|
|
313
|
+
- If no results come back, the workspace may not be indexed yet —
|
|
314
|
+
run `opencode-rag index` from the terminal (or `npx opencode-rag-plugin`)
|
|
315
|
+
- Tiny files (under 1 KB), excluded extensions, and excluded directories
|
|
316
|
+
(`node_modules`, `.git`, `.opencode`, `dist`, etc.) are silently skipped
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The plugin registers itself in the system prompt via the
|
|
320
|
+
`experimental.chat.system.transform` hook, so compliant agents will see a
|
|
321
|
+
reminder about the `opencode-rag-context` tool in their system instructions.
|
|
322
|
+
|
|
323
|
+
## Data Model
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
interface Chunk {
|
|
327
|
+
id: string;
|
|
328
|
+
content: string;
|
|
329
|
+
embedding?: number[];
|
|
330
|
+
metadata: {
|
|
331
|
+
filePath: string;
|
|
332
|
+
startLine: number;
|
|
333
|
+
endLine: number;
|
|
334
|
+
language: string;
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
interface SearchResult {
|
|
339
|
+
chunk: Chunk;
|
|
340
|
+
score: number; // 1 / (1 + L2_distance), range [0, 1]
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Chunking
|
|
345
|
+
|
|
346
|
+
| Language | Strategy | Captures |
|
|
347
|
+
| ---------- | ------------------------------ | ----------------------------------------- |
|
|
348
|
+
| TypeScript | AST (tree-sitter) | functions, methods, classes, interfaces |
|
|
349
|
+
| Python | AST (tree-sitter) | functions, classes, decorated definitions |
|
|
350
|
+
| Java | AST (tree-sitter) | methods, classes, interfaces, enums |
|
|
351
|
+
| Go | AST (tree-sitter) | functions, methods, type declarations |
|
|
352
|
+
| C | AST (tree-sitter) | functions, structs, enums, unions, typedefs |
|
|
353
|
+
| C++ | AST (tree-sitter) | functions, classes, structs, enums, namespaces, templates |
|
|
354
|
+
| C# | AST (tree-sitter) | classes, interfaces, structs, enums, methods, namespaces, records |
|
|
355
|
+
| JavaScript | AST (tree-sitter) | functions, classes, arrow functions, exports |
|
|
356
|
+
| JSON | AST (tree-sitter) | key-value pairs |
|
|
357
|
+
| XML | AST (tree-sitter) | elements (1 chunk per root element) |
|
|
358
|
+
| HTML | AST (tree-sitter) | `<script>` / `<style>` blocks |
|
|
359
|
+
| CSS | AST (tree-sitter) | rule sets, at-rules, media, keyframes |
|
|
360
|
+
| Razor | Regex (brace matching) | `@code` / `@functions` blocks, template regions |
|
|
361
|
+
| Markdown | Regex heading split | h1/h2 sections + trailing content |
|
|
362
|
+
| Solution | Regex (section boundary) | project entries and global sections |
|
|
363
|
+
| Rust | AST (tree-sitter) | functions, structs, enums, traits, impl blocks, modules, types |
|
|
364
|
+
| Ruby | AST (tree-sitter) | methods, classes, modules, singleton methods |
|
|
365
|
+
| Kotlin | AST (tree-sitter) | functions, classes, interfaces, objects, properties |
|
|
366
|
+
| Swift | AST (tree-sitter) | functions, classes, structs, enums, protocols, extensions, variables |
|
|
367
|
+
| LaTeX | Regex section split | chapter/section/subsection/subsubsection boundaries |
|
|
368
|
+
| PDF | Paragraph-based (text extraction) | groups small paragraphs, splits oversized |
|
|
369
|
+
| Word (docx) | Paragraph-based (text extraction) | extracts raw text via mammoth, groups small paragraphs, splits oversized |
|
|
370
|
+
| Word (doc) | Paragraph-based (text extraction) | extracts raw text via word-extractor, groups small paragraphs, splits oversized |
|
|
371
|
+
| Excel (xls/xlsx) | Row-batch (text extraction) | extracts CSV per sheet via @e965/xlsx, splits by sheet then by row batches |
|
|
372
|
+
| (other) | Line-based (100 lines/chunk) | raw text blocks |
|
|
373
|
+
|
|
374
|
+
Custom chunkers can be added without modifying the project source code. Two
|
|
375
|
+
registration paths are supported:
|
|
376
|
+
|
|
377
|
+
### Config file
|
|
378
|
+
|
|
379
|
+
Add a `chunkers` array to `opencode-rag.json`:
|
|
380
|
+
|
|
381
|
+
```json
|
|
382
|
+
{
|
|
383
|
+
"chunkers": [
|
|
384
|
+
{ "module": "./path/to/rust-chunker.js", "extensions": [".rs"] }
|
|
385
|
+
]
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
The module path is resolved relative to the config file. The loaded module must
|
|
390
|
+
export (as default or named) an object implementing the `Chunker` interface:
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
interface Chunker {
|
|
394
|
+
readonly language: string;
|
|
395
|
+
readonly fileExtensions?: string[];
|
|
396
|
+
chunk(filePath: string, content: string): Promise<Chunk[]>;
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Programmatic
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
import { registerChunker } from "opencode-rag-plugin/library";
|
|
404
|
+
registerChunker(myChunker, [".rs"]);
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
The optional second argument overrides the chunker's `fileExtensions`. If a
|
|
408
|
+
built-in chunker already covers the requested extension, the new registration is
|
|
409
|
+
skipped and a warning is emitted.
|
|
410
|
+
|
|
411
|
+
## Vector Store
|
|
412
|
+
|
|
413
|
+
LanceDB stores chunks in a `chunks` table with columns: `id`, `content`,
|
|
414
|
+
`embedding` (vector), `filePath`, `startLine`, `endLine`, `language`.
|
|
415
|
+
|
|
416
|
+
- **Disk mode**: files in `vectorStore.path` (default `.opencode/rag_db`)
|
|
417
|
+
- **Memory mode**: `memory://` URI — for tests only, data lost on close
|
|
418
|
+
- **Manifest sidecar**: `manifest.json` in the store directory tracks indexed
|
|
419
|
+
files for incremental updates
|
|
420
|
+
- Schema is auto-inferred from a seed row on first table creation
|
|
421
|
+
- L2 distance search, score = `1 / (1 + distance)`
|
|
422
|
+
- Stored file paths are normalized to absolute forward-slash paths
|
|
423
|
+
|
|
424
|
+
## Development
|
|
425
|
+
|
|
426
|
+
```bash
|
|
427
|
+
# TypeScript typecheck
|
|
428
|
+
npm run typecheck
|
|
429
|
+
|
|
430
|
+
# Run all tests
|
|
431
|
+
npm test
|
|
432
|
+
|
|
433
|
+
# Run specific test file
|
|
434
|
+
node --import tsx --test src/__tests__/chunker/fallback.test.ts
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Project structure:
|
|
438
|
+
```
|
|
439
|
+
src/
|
|
440
|
+
core/ — interfaces.ts, config.ts
|
|
441
|
+
chunker/ — grammar.ts, base.ts, language chunkers, fallback.ts, factory.ts, uuid.ts
|
|
442
|
+
embedder/ — ollama.ts, openai.ts, factory.ts
|
|
443
|
+
vectorstore/ — lancedb.ts
|
|
444
|
+
retriever/ — retriever.ts
|
|
445
|
+
types/ — opencode-plugin.d.ts
|
|
446
|
+
indexer.ts — incremental indexing + watch scheduling
|
|
447
|
+
watcher.ts — background indexer (chokidar + debounced scheduler + periodic timer)
|
|
448
|
+
cli.ts, plugin.ts, plugin-entry.ts, index.ts
|
|
449
|
+
__tests__/ — mirrors the module structure
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Test framework is Node's built-in runner (`node:test`) with `tsx` for TypeScript
|
|
453
|
+
imports. No test library dependencies.
|
|
454
|
+
|
|
455
|
+
## Limitations
|
|
456
|
+
|
|
457
|
+
- Embedding model dimension is auto-probed at startup; falls back to 384 if probing fails.
|
|
458
|
+
- 21 built-in chunkers (AST for 16, regex for 4, PDF text for 1) + configurable fallback
|
|
459
|
+
|
|
460
|
+
## Privacy
|
|
461
|
+
|
|
462
|
+
All processing is local. Embeddings are generated via local Ollama by default.
|
|
463
|
+
No data leaves the machine unless configured to use a remote embedding API.
|