@comfanion/usethis_search 3.0.0-dev.4 → 3.0.0-dev.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comfanion/usethis_search",
3
- "version": "3.0.0-dev.4",
3
+ "version": "3.0.0-dev.5",
4
4
  "description": "OpenCode plugin: semantic search with graph-based context (v3: graph relations, 1-hop context, LSP + regex analyzers)",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -68,14 +68,33 @@ Use this instead of the standard Read tool for better context awareness.`,
68
68
  console.log(`[read-interceptor] Intercepted Read("${relPath}")`)
69
69
  }
70
70
 
71
- const indexer = await new CodebaseIndexer(projectRoot, "code").init()
72
- const results = await indexer.search(relPath, 20, false, {})
73
- const fileChunks = results.filter(r => r.file === relPath)
74
- await indexer.unloadModel()
71
+ // Resilient search: if vector index is corrupted or unavailable, fall back gracefully
72
+ let fileChunks: any[] = []
73
+ let allRelated: any[] = []
74
+ let searchFailed = false
75
75
 
76
- const allRelated = fileChunks
77
- .flatMap(c => c.relatedContext || [])
78
- .filter((r, i, arr) => arr.findIndex(x => x.chunk_id === r.chunk_id) === i)
76
+ try {
77
+ const indexer = await new CodebaseIndexer(projectRoot, "code").init()
78
+ try {
79
+ const results = await indexer.search(relPath, 20, false, {})
80
+ fileChunks = results.filter((r: any) => r.file === relPath)
81
+
82
+ allRelated = fileChunks
83
+ .flatMap((c: any) => c.relatedContext || [])
84
+ .filter((r: any, i: number, arr: any[]) => arr.findIndex((x: any) => x.chunk_id === r.chunk_id) === i)
85
+ } catch (searchErr: any) {
86
+ if (DEBUG) {
87
+ console.log(`[read-interceptor] Search failed for "${relPath}": ${searchErr.message}`)
88
+ }
89
+ searchFailed = true
90
+ }
91
+ await indexer.unloadModel()
92
+ } catch (initErr: any) {
93
+ if (DEBUG) {
94
+ console.log(`[read-interceptor] Indexer init failed: ${initErr.message}`)
95
+ }
96
+ searchFailed = true
97
+ }
79
98
 
80
99
  const durationMs = Date.now() - startTime
81
100
  const fallback = fileChunks.length === 0
@@ -93,12 +112,15 @@ Use this instead of the standard Read tool for better context awareness.`,
93
112
 
94
113
  if (DEBUG) {
95
114
  console.log(
96
- `[read-interceptor] ${relPath}: ${fileChunks.length} chunks, ${allRelated.length} related, ${durationMs}ms${fallback ? " (fallback)" : ""}`
115
+ `[read-interceptor] ${relPath}: ${fileChunks.length} chunks, ${allRelated.length} related, ${durationMs}ms${fallback ? " (fallback)" : ""}${searchFailed ? " (search error)" : ""}`
97
116
  )
98
117
  }
99
118
 
100
119
  if (fallback) {
101
- return `File "${relPath}" not indexed. Use original Read tool or run codeindex({ action: "reindex", index: "code" })`
120
+ const reason = searchFailed
121
+ ? `Search index unavailable (possibly corrupted). Run codeindex({ action: "reindex", index: "code" }) to rebuild.`
122
+ : `File "${relPath}" not indexed. Use original Read tool or run codeindex({ action: "reindex", index: "code" })`
123
+ return reason
102
124
  }
103
125
 
104
126
  let output = `## ${relPath}\n\n`
@@ -603,7 +603,13 @@ class CodebaseIndexer {
603
603
  if (!tables.includes(tableName)) return null;
604
604
 
605
605
  const table = await this.db.openTable(tableName);
606
- const allRows = await table.search([0]).limit(100000).execute();
606
+ let allRows;
607
+ try {
608
+ allRows = await table.search([0]).limit(100000).execute();
609
+ } catch (e) {
610
+ if (DEBUG) console.log("[vectorizer] BM25 index build failed (corrupted table?):", e.message);
611
+ return null;
612
+ }
607
613
 
608
614
  if (allRows.length === 0) return null;
609
615
 
@@ -643,7 +649,14 @@ class CodebaseIndexer {
643
649
  (options.tags && options.tags.length > 0);
644
650
  const isHybrid = HYBRID_CONFIG.enabled || options.hybrid;
645
651
  const fetchLimit = (hasFilters || isHybrid) ? Math.max(limit * 3, 50) : limit;
646
- let results = await table.search(queryEmbedding).limit(fetchLimit).execute();
652
+ let results;
653
+ try {
654
+ results = await table.search(queryEmbedding).limit(fetchLimit).execute();
655
+ } catch (e) {
656
+ // LanceDB schema error (e.g. missing vector column) — index is corrupted
657
+ if (DEBUG) console.log("[vectorizer] Vector search failed (corrupted index?):", e.message);
658
+ return [];
659
+ }
647
660
 
648
661
  // ── Hybrid search ───────────────────────────────────────────────────────
649
662
  if (HYBRID_CONFIG.enabled || options.hybrid) {
@@ -833,7 +846,13 @@ class CodebaseIndexer {
833
846
  if (!tables.includes(tableName)) return null;
834
847
 
835
848
  const table = await this.db.openTable(tableName);
836
- const rows = await table.search([0]).limit(100000).execute();
849
+ let rows;
850
+ try {
851
+ rows = await table.search([0]).limit(100000).execute();
852
+ } catch (e) {
853
+ if (DEBUG) console.log("[vectorizer] Chunk cache build failed (corrupted table?):", e.message);
854
+ return null;
855
+ }
837
856
  this._chunkCache = new Map();
838
857
  for (const row of rows) {
839
858
  if (row.chunk_id) {