(rootDir: string, relativePath: string)
| 89 | } |
| 90 | |
| 91 | async function buildSearchDocumentForFile(rootDir: string, relativePath: string): Promise<SearchDocument | null> { |
| 92 | const normalized = normalizeRelativePath(relativePath); |
| 93 | const fullPath = resolve(rootDir, normalized); |
| 94 | |
| 95 | if (isTextIndexCandidate(fullPath)) { |
| 96 | try { |
| 97 | if ((await stat(fullPath)).size > getMaxEmbedFileSize()) return null; |
| 98 | const raw = await readFile(fullPath, "utf-8"); |
| 99 | const content = raw.slice(0, MAX_TEXT_DOC_CHARS); |
| 100 | return { |
| 101 | path: normalized, |
| 102 | header: extractPlainTextHeader(content), |
| 103 | symbols: [], |
| 104 | content, |
| 105 | }; |
| 106 | } catch { |
| 107 | return null; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | if (!isSupportedFile(fullPath)) return null; |
| 112 | |
| 113 | try { |
| 114 | const analysis = await analyzeFile(fullPath); |
| 115 | const flatSymbols = flattenSymbols(analysis.symbols); |
| 116 | return { |
| 117 | path: normalized, |
| 118 | header: analysis.header, |
| 119 | symbols: flatSymbols.map((s) => s.name), |
| 120 | symbolEntries: flatSymbols.map((s) => ({ |
| 121 | name: s.name, |
| 122 | kind: s.kind, |
| 123 | line: s.line, |
| 124 | endLine: s.endLine, |
| 125 | signature: s.signature, |
| 126 | })), |
| 127 | content: flatSymbols.map((s) => s.signature).join(" "), |
| 128 | }; |
| 129 | } catch { |
| 130 | return null; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | async function buildIndex(rootDir: string): Promise<SearchIndex> { |
| 135 | if (cachedIndex && cachedRootDir === rootDir && Date.now() - lastIndexTime < INDEX_TTL_MS) { |
no test coverage detected