opencode-rag-plugin 1.19.3 → 1.19.4

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/dist/api.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { type IndexRunStats } from "./indexer.js";
6
6
  import { type WorkspaceFile } from "./content/reader.js";
7
- import type { SearchResult } from "./core/interfaces.js";
7
+ import { type SearchResult } from "./core/interfaces.js";
8
8
  /** Options controlling a semantic search query. */
9
9
  export interface SearchOptions {
10
10
  /** Working directory to resolve relative paths against. */
package/dist/api.js CHANGED
@@ -7,6 +7,7 @@ import { retrieve } from "./retriever/retriever.js";
7
7
  import { optimizeContext, DEFAULT_CONTEXT_OPTIMIZATION } from "./retriever/context-optimizer.js";
8
8
  import { runIndexPass } from "./indexer.js";
9
9
  import { scanWorkspaceFiles } from "./content/reader.js";
10
+ import { CODE_SEARCH_FILTER } from "./core/interfaces.js";
10
11
  import { destroyAllPooledConnections } from "./embedder/http.js";
11
12
  /**
12
13
  * Format a list of search results into a human-readable markdown block.
@@ -55,6 +56,7 @@ export async function search(query, options = {}) {
55
56
  filter: {
56
57
  pathPatterns: options.pathHints,
57
58
  languages: options.languageHints,
59
+ kinds: CODE_SEARCH_FILTER.kinds,
58
60
  },
59
61
  });
60
62
  const optCfg = ctx.config.retrieval.contextOptimization ?? DEFAULT_CONTEXT_OPTIMIZATION;
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import path from "node:path";
8
8
  import pc from "picocolors";
9
+ import { CODE_SEARCH_FILTER } from "../../core/interfaces.js";
9
10
  import { retrieve } from "../../retriever/retriever.js";
10
11
  import { c, resolveCliContext, cleanupContext, logCliError, logCliInfo, formatDuration } from "../format.js";
11
12
  import { optimizeContext, DEFAULT_CONTEXT_OPTIMIZATION } from "../../retriever/context-optimizer.js";
@@ -54,6 +55,7 @@ export function registerQueryCommand(program) {
54
55
  hybridEnabled: hybridCfg?.enabled,
55
56
  queryPrefix: config.embedding.queryPrefix,
56
57
  explain: options.explain ?? false,
58
+ filter: CODE_SEARCH_FILTER,
57
59
  });
58
60
  const optCfg = config.retrieval.contextOptimization ?? DEFAULT_CONTEXT_OPTIMIZATION;
59
61
  const results = optimizeContext(rawResults, { topK, config: optCfg });
@@ -56,17 +56,17 @@ export async function walkFiles(dir, extensions, excludeDirs, excludeFiles, root
56
56
  return results;
57
57
  }
58
58
  async function dispatchExtraction(filePath, buffer, imageVisionProvider, imagePrompt, resizeMaxDimension) {
59
- const lower = filePath.toLowerCase();
60
- if (pdfExtractor.PDF_EXTENSIONS.has(lower)) {
59
+ const ext = path.extname(filePath).toLowerCase();
60
+ if (pdfExtractor.PDF_EXTENSIONS.has(ext)) {
61
61
  return pdfExtractor.extract(filePath, buffer);
62
62
  }
63
- if (docxExtractor.DOCX_EXTENSIONS.has(lower)) {
63
+ if (docxExtractor.DOCX_EXTENSIONS.has(ext)) {
64
64
  return docxExtractor.extract(filePath, buffer);
65
65
  }
66
- if (docExtractor.DOC_EXTENSIONS.has(lower)) {
66
+ if (docExtractor.DOC_EXTENSIONS.has(ext)) {
67
67
  return docExtractor.extract(filePath, buffer);
68
68
  }
69
- if (excelExtractor.EXCEL_EXTENSIONS.has(lower)) {
69
+ if (excelExtractor.EXCEL_EXTENSIONS.has(ext)) {
70
70
  return excelExtractor.extract(filePath, buffer);
71
71
  }
72
72
  if (imageVisionProvider && imageExtractor.isImageFile(filePath)) {
@@ -164,10 +164,11 @@ export async function scanWorkspaceFiles(cwd, config, logger, manifest, filterPa
164
164
  }
165
165
  }
166
166
  const isImage = imageVisionProvider !== null && imageExtractor.isImageFile(filePath);
167
- const isBinary = pdfExtractor.PDF_EXTENSIONS.has(filePath.toLowerCase()) ||
168
- docxExtractor.DOCX_EXTENSIONS.has(filePath.toLowerCase()) ||
169
- docExtractor.DOC_EXTENSIONS.has(filePath.toLowerCase()) ||
170
- excelExtractor.EXCEL_EXTENSIONS.has(filePath.toLowerCase()) ||
167
+ const ext = path.extname(filePath).toLowerCase();
168
+ const isBinary = pdfExtractor.PDF_EXTENSIONS.has(ext) ||
169
+ docxExtractor.DOCX_EXTENSIONS.has(ext) ||
170
+ docExtractor.DOC_EXTENSIONS.has(ext) ||
171
+ excelExtractor.EXCEL_EXTENSIONS.has(ext) ||
171
172
  isImage;
172
173
  logger?.info(`Reading: ${filePath}`);
173
174
  const buffer = isBinary ? await fs.readFile(filePath) : Buffer.alloc(0);
@@ -201,6 +201,14 @@ export interface MetadataFilter {
201
201
  /** Synthetic kind filters (e.g. ["quirk"]). */
202
202
  kinds?: string[];
203
203
  }
204
+ /**
205
+ * Filter for general code/document retrieval that excludes quirk memory
206
+ * chunks. Regular indexed chunks store `kind: ""`, quirk chunks `kind: "quirk"`.
207
+ * All code-search paths (search_semantic, hotkey injection, CLI query, web UI,
208
+ * read-tool context) must pass this so quirks never surface as code results —
209
+ * quirks are only reachable through recall_quirks / the quirk CLI.
210
+ */
211
+ export declare const CODE_SEARCH_FILTER: MetadataFilter;
204
212
  /** Callback interface for reporting indexing progress to the UI or CLI. */
205
213
  export interface IndexProgress {
206
214
  /** Set the total number of files to be indexed. */
@@ -2,5 +2,12 @@
2
2
  * @fileoverview Core type definitions for the OpenCodeRAG pipeline: Chunk, SearchResult,
3
3
  * Chunker, EmbeddingProvider, VectorStore, KeywordIndex, and related interfaces.
4
4
  */
5
- export {};
5
+ /**
6
+ * Filter for general code/document retrieval that excludes quirk memory
7
+ * chunks. Regular indexed chunks store `kind: ""`, quirk chunks `kind: "quirk"`.
8
+ * All code-search paths (search_semantic, hotkey injection, CLI query, web UI,
9
+ * read-tool context) must pass this so quirks never surface as code results —
10
+ * quirks are only reachable through recall_quirks / the quirk CLI.
11
+ */
12
+ export const CODE_SEARCH_FILTER = { kinds: [""] };
6
13
  //# sourceMappingURL=interfaces.js.map
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Handler implementations for all MCP tools: semantic search, file skeleton, symbol usage lookup, and image description.
3
3
  */
4
- import type { EmbeddingProvider, VectorStore, KeywordIndex, SearchResult } from "../core/interfaces.js";
4
+ import { type EmbeddingProvider, type VectorStore, type KeywordIndex, type SearchResult } from "../core/interfaces.js";
5
5
  import type { RagConfig } from "../core/config.js";
6
6
  import { type ImageVisionProvider } from "../chunker/image.js";
7
7
  import { retrieve } from "../retriever/retriever.js";
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @fileoverview Handler implementations for all MCP tools: semantic search, file skeleton, symbol usage lookup, and image description.
3
+ */
4
+ import { CODE_SEARCH_FILTER } from "../core/interfaces.js";
1
5
  import { SUPPORTED_IMAGE_EXTENSIONS } from "../chunker/image.js";
2
6
  import { retrieve } from "../retriever/retriever.js";
3
7
  import { optimizeContext, DEFAULT_CONTEXT_OPTIMIZATION } from "../retriever/context-optimizer.js";
@@ -178,6 +182,7 @@ export async function handleSearchSemantic(params, embedder, store, cfg, keyword
178
182
  keywordWeight: cfg.retrieval.hybridSearch?.keywordWeight,
179
183
  hybridEnabled: cfg.retrieval.hybridSearch?.enabled,
180
184
  queryPrefix: cfg.embedding.queryPrefix,
185
+ filter: CODE_SEARCH_FILTER,
181
186
  };
182
187
  const rawResults = await retrieveFn_(query, embedder, store, retrieveOpts);
183
188
  if (rawResults.length === 0) {
@@ -256,7 +261,7 @@ export async function handleFindUsages(params, embedder, store, cfg, keywordInde
256
261
  const symbolName = params.symbolName.trim();
257
262
  const topK = params.topK ?? 30;
258
263
  const kwResults = keywordIndex
259
- ? keywordIndex.search(symbolName, topK)
264
+ ? keywordIndex.search(symbolName, topK, CODE_SEARCH_FILTER)
260
265
  : [];
261
266
  const count = await store.count();
262
267
  const vsResults = count > 0
@@ -265,6 +270,7 @@ export async function handleFindUsages(params, embedder, store, cfg, keywordInde
265
270
  minScore: 0,
266
271
  keywordIndex: undefined,
267
272
  queryPrefix: cfg.embedding.queryPrefix,
273
+ filter: CODE_SEARCH_FILTER,
268
274
  })
269
275
  : [];
270
276
  const seen = new Set();
@@ -2,7 +2,7 @@
2
2
  * @fileoverview Creates the RAG-backed read tool that returns full file contents with supplementary semantic context.
3
3
  */
4
4
  import { tool } from "@opencode-ai/plugin/tool";
5
- import type { EmbeddingProvider, KeywordIndex, VectorStore, SearchResult } from "../core/interfaces.js";
5
+ import { type EmbeddingProvider, type KeywordIndex, type VectorStore, type SearchResult } from "../core/interfaces.js";
6
6
  import type { RagConfig } from "../core/config.js";
7
7
  export interface RagReadToolOptions {
8
8
  /** Workspace root directory. */
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import fs from "node:fs/promises";
5
5
  import { tool } from "@opencode-ai/plugin/tool";
6
+ import { CODE_SEARCH_FILTER } from "../core/interfaces.js";
6
7
  import { retrieve } from "../retriever/retriever.js";
7
8
  import { normalizeReadArgs, resolveWorkspacePath } from "./tool-args.js";
8
9
  import { buildReadQuery } from "./read-query.js";
@@ -63,7 +64,7 @@ export function createRagReadTool(options) {
63
64
  }
64
65
  else {
65
66
  const retrievalQuery = buildSessionQuery(messageText, resolvedPath, normalized);
66
- rawResults = await retrieve(retrievalQuery, embedder, store, { topK: retrievalTopK, keywordIndex, hybridEnabled: config.retrieval.hybridSearch?.enabled, queryPrefix: config.embedding.queryPrefix });
67
+ rawResults = await retrieve(retrievalQuery, embedder, store, { topK: retrievalTopK, keywordIndex, hybridEnabled: config.retrieval.hybridSearch?.enabled, queryPrefix: config.embedding.queryPrefix, filter: CODE_SEARCH_FILTER });
67
68
  const maxSize = options.maxSessionCacheSize ?? 50;
68
69
  if (!sessionRetrievalCache.has(sessionID) && sessionRetrievalCache.size >= maxSize) {
69
70
  const oldest = sessionRetrievalCache.keys().next().value;
@@ -80,7 +81,7 @@ export function createRagReadTool(options) {
80
81
  startLine: normalized.startLine,
81
82
  endLine: normalized.endLine,
82
83
  });
83
- rawResults = await retrieve(retrievalQuery, embedder, store, { topK: retrievalTopK, keywordIndex, hybridEnabled: config.retrieval.hybridSearch?.enabled, queryPrefix: config.embedding.queryPrefix });
84
+ rawResults = await retrieve(retrievalQuery, embedder, store, { topK: retrievalTopK, keywordIndex, hybridEnabled: config.retrieval.hybridSearch?.enabled, queryPrefix: config.embedding.queryPrefix, filter: CODE_SEARCH_FILTER });
84
85
  }
85
86
  // Collect related files from raw results (before filtering)
86
87
  relatedFiles = collectRelatedFiles(rawResults, resolvedPath, readRelatedFilesMax);
@@ -2,7 +2,7 @@
2
2
  * @fileoverview Factory functions for OpenCode autonomous-agent tools (file skeleton, find usages, describe image).
3
3
  */
4
4
  import type { ToolDefinition } from "@opencode-ai/plugin";
5
- import type { EmbeddingProvider, VectorStore, KeywordIndex } from "../core/interfaces.js";
5
+ import { type EmbeddingProvider, type VectorStore, type KeywordIndex } from "../core/interfaces.js";
6
6
  import type { RagConfig } from "../core/config.js";
7
7
  import { type ImageVisionProvider } from "../chunker/image.js";
8
8
  import { retrieve } from "../retriever/retriever.js";
@@ -13,6 +13,7 @@
13
13
  * These complement the general-purpose search_semantic tool.
14
14
  */
15
15
  import { tool } from "@opencode-ai/plugin/tool";
16
+ import { CODE_SEARCH_FILTER } from "../core/interfaces.js";
16
17
  import { SUPPORTED_IMAGE_EXTENSIONS, createImageVisionProvider, getMimeType } from "../chunker/image.js";
17
18
  import { resizeImage } from "../content/image.js";
18
19
  import { retrieve } from "../retriever/retriever.js";
@@ -362,7 +363,7 @@ export function createFindUsagesTool(options) {
362
363
  async function searchViaKeywordIndex(symbol, topK) {
363
364
  if (!keywordIndex)
364
365
  return [];
365
- return keywordIndex.search(symbol, topK);
366
+ return keywordIndex.search(symbol, topK, CODE_SEARCH_FILTER);
366
367
  }
367
368
  async function searchViaVectorStore(symbol, topK) {
368
369
  const count = await store.count();
@@ -373,6 +374,7 @@ export function createFindUsagesTool(options) {
373
374
  minScore: 0,
374
375
  keywordIndex: undefined,
375
376
  queryPrefix: cfg.embedding.queryPrefix,
377
+ filter: CODE_SEARCH_FILTER,
376
378
  });
377
379
  }
378
380
  function escapeRegex(s) {
package/dist/plugin.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * automatic context injection and documentation mode.
5
5
  */
6
6
  import type { Plugin, Hooks } from "@opencode-ai/plugin";
7
- import type { EmbeddingProvider, DescriptionProvider, KeywordIndex, VectorStore } from "./core/interfaces.js";
7
+ import { type EmbeddingProvider, type DescriptionProvider, type KeywordIndex, type VectorStore } from "./core/interfaces.js";
8
8
  import { type RagConfig } from "./core/config.js";
9
9
  import { createEmbedder } from "./embedder/factory.js";
10
10
  import { retrieve } from "./retriever/retriever.js";
package/dist/plugin.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * automatic context injection and documentation mode.
5
5
  */
6
6
  import { tool } from "@opencode-ai/plugin/tool";
7
+ import { CODE_SEARCH_FILTER } from "./core/interfaces.js";
7
8
  import { loadConfig, findConfigFile, DEFAULT_CONFIG, resolveLogConfig, persistProbedDimension } from "./core/config.js";
8
9
  import { createEmbedder } from "./embedder/factory.js";
9
10
  import { createDescriptionProvider } from "./describer/factory.js";
@@ -1189,6 +1190,8 @@ export function createRagHooks(options) {
1189
1190
  keywordIndex,
1190
1191
  keywordWeight: hybridCfg?.keywordWeight,
1191
1192
  queryPrefix: effectiveCfg.embedding.queryPrefix,
1193
+ // Never surface quirk chunks in hotkey file lists / chunk injections.
1194
+ filter: CODE_SEARCH_FILTER,
1192
1195
  });
1193
1196
  const retrievalTimeMs = Date.now() - retrievalStart;
1194
1197
  if (results.length > 0) {
package/dist/web/api.d.ts CHANGED
@@ -5,7 +5,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
5
5
  import { LanceDbStore } from "../vectorstore/lancedb.js";
6
6
  import { KeywordIndex } from "../retriever/keyword-index.js";
7
7
  import type { RagConfig } from "../core/config.js";
8
- import type { EmbeddingProvider } from "../core/interfaces.js";
8
+ import { type EmbeddingProvider } from "../core/interfaces.js";
9
9
  /** Internal shape for a JSON API response: an HTTP status code and a serialisable body. */
10
10
  interface ApiResponse {
11
11
  status: number;
package/dist/web/api.js CHANGED
@@ -5,6 +5,7 @@ import { listSessions, getSession, deleteSession, compareSessions, validateSessi
5
5
  import { analyzeTokenUsage, compareTokenAnalyses, projectTokenSavings } from "../eval/token-analysis.js";
6
6
  import { listQuirks, lintQuirks, removeQuirk } from "../quirks/quirk-store.js";
7
7
  import { retrieve } from "../retriever/retriever.js";
8
+ import { CODE_SEARCH_FILTER } from "../core/interfaces.js";
8
9
  const FILE_MIME_TYPES = {
9
10
  ".png": "image/png",
10
11
  ".jpg": "image/jpeg",
@@ -297,7 +298,7 @@ async function handleSearch(keywordIndex, params) {
297
298
  if (!query.trim()) {
298
299
  return { status: 200, body: { results: [] } };
299
300
  }
300
- const results = keywordIndex.search(query, topK);
301
+ const results = keywordIndex.search(query, topK, CODE_SEARCH_FILTER);
301
302
  return {
302
303
  status: 200,
303
304
  body: {
@@ -355,6 +356,7 @@ async function handleRetrieve(store, keywordIndex, getEmbedder, cfg, params) {
355
356
  filter: {
356
357
  pathPatterns: pathFilter ? pathFilter.split(",").map((s) => s.trim()).filter(Boolean) : undefined,
357
358
  languages: langFilter ? langFilter.split(",").map((s) => s.trim()).filter(Boolean) : undefined,
359
+ kinds: CODE_SEARCH_FILTER.kinds,
358
360
  },
359
361
  });
360
362
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-rag-plugin",
3
- "version": "1.19.3",
3
+ "version": "1.19.4",
4
4
  "description": "OpenCode plugin for local-first RAG-based semantic code search",
5
5
  "type": "module",
6
6
  "main": "./dist/plugin-entry.js",