project-librarian 0.5.5 → 0.5.7

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.
Files changed (41) hide show
  1. package/CONTRIBUTING.md +36 -0
  2. package/README.ko.md +58 -365
  3. package/README.md +56 -363
  4. package/SKILL.md +7 -0
  5. package/dist/args.js +9 -1
  6. package/dist/code-index/extractors/light-languages.js +285 -0
  7. package/dist/code-index/extractors/registry.js +12 -0
  8. package/dist/code-index/extractors/shared.js +18 -1
  9. package/dist/code-index/extractors/typescript.js +30 -16
  10. package/dist/code-index/index-health.js +4 -3
  11. package/dist/code-index/modes.js +193 -33
  12. package/dist/code-index/native-helper-matrix.js +99 -0
  13. package/dist/code-index/native-helper.js +292 -0
  14. package/dist/code-index/schema.js +72 -13
  15. package/dist/code-index/search.js +1 -1
  16. package/dist/code-index-file-policy.js +9 -1
  17. package/dist/code-index.js +363 -12
  18. package/dist/init-project-wiki.js +14 -0
  19. package/dist/install-skill.js +22 -2
  20. package/dist/native/darwin-arm64/project-librarian-indexer +0 -0
  21. package/dist/native/darwin-x64/project-librarian-indexer +0 -0
  22. package/dist/native/linux-arm64/project-librarian-indexer +0 -0
  23. package/dist/native/linux-arm64-musl/project-librarian-indexer +0 -0
  24. package/dist/native/linux-x64/project-librarian-indexer +0 -0
  25. package/dist/native/linux-x64-musl/project-librarian-indexer +0 -0
  26. package/dist/native/project-librarian-indexer-manifest.json +70 -0
  27. package/dist/native/win32-arm64/project-librarian-indexer.exe +0 -0
  28. package/dist/native/win32-x64/project-librarian-indexer.exe +0 -0
  29. package/docs/README.md +11 -0
  30. package/docs/benchmarks.md +64 -0
  31. package/docs/cli-reference.md +61 -0
  32. package/docs/code-evidence.md +93 -0
  33. package/docs/ko/README.md +13 -0
  34. package/docs/ko/benchmarks.md +64 -0
  35. package/docs/ko/cli-reference.md +61 -0
  36. package/docs/ko/code-evidence.md +93 -0
  37. package/docs/ko/maintainer.md +76 -0
  38. package/docs/ko/usage.md +168 -0
  39. package/docs/maintainer.md +76 -0
  40. package/docs/usage.md +176 -0
  41. package/package.json +11 -1
@@ -0,0 +1,292 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.nativeCodeIndexHelperPlatformTriple = nativeCodeIndexHelperPlatformTriple;
37
+ exports.nativeCodeIndexHelperBinaryName = nativeCodeIndexHelperBinaryName;
38
+ exports.packagedNativeCodeIndexHelperPath = packagedNativeCodeIndexHelperPath;
39
+ exports.requireNativeCodeIndexHelperPath = requireNativeCodeIndexHelperPath;
40
+ exports.nativeCodeIndexHelperAvailability = nativeCodeIndexHelperAvailability;
41
+ exports.nativeCodeIndexHelperAvailable = nativeCodeIndexHelperAvailable;
42
+ exports.buildNativeCodeIndexJob = buildNativeCodeIndexJob;
43
+ exports.runNativeCodeIndexHelper = runNativeCodeIndexHelper;
44
+ exports.runNativeCodeIndexRowsHelper = runNativeCodeIndexRowsHelper;
45
+ const childProcess = __importStar(require("node:child_process"));
46
+ const fs = __importStar(require("node:fs"));
47
+ const os = __importStar(require("node:os"));
48
+ const path = __importStar(require("node:path"));
49
+ const native_helper_matrix_1 = require("./native-helper-matrix");
50
+ const workspace_1 = require("../workspace");
51
+ const supportedNativeHelperTripleSet = new Set(native_helper_matrix_1.supportedNativeHelperTriples);
52
+ function nativeCodeIndexLinuxLibcVariant(platform = process.platform) {
53
+ if (platform !== "linux")
54
+ return "";
55
+ const report = process.report;
56
+ if (!report || typeof report.getReport !== "function")
57
+ return "";
58
+ try {
59
+ return report.getReport().header?.glibcVersionRuntime ? "glibc" : "musl";
60
+ }
61
+ catch {
62
+ return "";
63
+ }
64
+ }
65
+ function nativeCodeIndexHelperPlatformTriple(platform = process.platform, arch = process.arch, libc = nativeCodeIndexLinuxLibcVariant(platform)) {
66
+ return (0, native_helper_matrix_1.nativeCodeIndexHelperTripleForPlatform)(platform, arch, libc);
67
+ }
68
+ function nativeCodeIndexHelperBinaryName(platform = process.platform) {
69
+ return platform === "win32" ? "project-librarian-indexer.exe" : "project-librarian-indexer";
70
+ }
71
+ function nativeCodeIndexHelperPackageRoot(options = {}) {
72
+ return path.resolve(options.packageRoot ?? path.join(__dirname, ".."));
73
+ }
74
+ function packagedNativeCodeIndexHelperPath(options = {}) {
75
+ const platform = options.platform ?? process.platform;
76
+ const arch = options.arch ?? process.arch;
77
+ return path.join(nativeCodeIndexHelperPackageRoot(options), "native", nativeCodeIndexHelperPlatformTriple(platform, arch, options.libc), nativeCodeIndexHelperBinaryName(platform));
78
+ }
79
+ function configuredHelperPath(options = {}) {
80
+ const optionPath = (options.helperPath ?? "").trim();
81
+ if (optionPath)
82
+ return { helperPath: optionPath, source: "option" };
83
+ const envPath = ((options.env ?? process.env).PROJECT_LIBRARIAN_NATIVE_INDEXER ?? "").trim();
84
+ if (envPath)
85
+ return { helperPath: envPath, source: "environment" };
86
+ return { helperPath: "", source: "missing" };
87
+ }
88
+ function helperPathLabel(source) {
89
+ if (source === "option")
90
+ return "native helper path";
91
+ if (source === "environment")
92
+ return "PROJECT_LIBRARIAN_NATIVE_INDEXER";
93
+ return "packaged native helper";
94
+ }
95
+ function requireUsableHelperPath(helperPath, source) {
96
+ const label = helperPathLabel(source);
97
+ if (!path.isAbsolute(helperPath)) {
98
+ throw new Error(`${label} must be an absolute path: ${helperPath}`);
99
+ }
100
+ const resolved = path.resolve(helperPath);
101
+ if (!fs.existsSync(resolved)) {
102
+ throw new Error(`${label} does not exist: ${resolved}`);
103
+ }
104
+ const stat = fs.statSync(resolved);
105
+ if (!stat.isFile()) {
106
+ throw new Error(`${label} must point to an executable file: ${resolved}`);
107
+ }
108
+ fs.accessSync(resolved, fs.constants.X_OK);
109
+ return resolved;
110
+ }
111
+ function requireNativeCodeIndexHelperPath(options = {}) {
112
+ const availability = nativeCodeIndexHelperAvailability(options);
113
+ if (availability.available)
114
+ return availability.helperPath;
115
+ throw new Error(availability.reason);
116
+ }
117
+ function nativeCodeIndexHelperAvailability(options = {}) {
118
+ const platform = options.platform ?? process.platform;
119
+ const arch = options.arch ?? process.arch;
120
+ const platformTriple = nativeCodeIndexHelperPlatformTriple(platform, arch, options.libc);
121
+ const packagedHelperPath = packagedNativeCodeIndexHelperPath({ ...options, arch, platform });
122
+ const configured = configuredHelperPath(options);
123
+ if (configured.helperPath) {
124
+ try {
125
+ return {
126
+ available: true,
127
+ helperPath: requireUsableHelperPath(configured.helperPath, configured.source),
128
+ packagedHelperPath,
129
+ platformTriple,
130
+ reason: "",
131
+ source: configured.source,
132
+ };
133
+ }
134
+ catch (error) {
135
+ return {
136
+ available: false,
137
+ helperPath: "",
138
+ packagedHelperPath,
139
+ platformTriple,
140
+ reason: error instanceof Error ? error.message : String(error),
141
+ source: configured.source,
142
+ };
143
+ }
144
+ }
145
+ if (!supportedNativeHelperTripleSet.has(platformTriple)) {
146
+ return {
147
+ available: false,
148
+ helperPath: "",
149
+ packagedHelperPath,
150
+ platformTriple,
151
+ reason: `packaged native code index helper does not support this platform: ${platformTriple}; set PROJECT_LIBRARIAN_NATIVE_INDEXER to a compatible helper path`,
152
+ source: "missing",
153
+ };
154
+ }
155
+ if (fs.existsSync(packagedHelperPath)) {
156
+ try {
157
+ return {
158
+ available: true,
159
+ helperPath: requireUsableHelperPath(packagedHelperPath, "packaged"),
160
+ packagedHelperPath,
161
+ platformTriple,
162
+ reason: "",
163
+ source: "packaged",
164
+ };
165
+ }
166
+ catch (error) {
167
+ return {
168
+ available: false,
169
+ helperPath: "",
170
+ packagedHelperPath,
171
+ platformTriple,
172
+ reason: error instanceof Error ? error.message : String(error),
173
+ source: "packaged",
174
+ };
175
+ }
176
+ }
177
+ return {
178
+ available: false,
179
+ helperPath: "",
180
+ packagedHelperPath,
181
+ platformTriple,
182
+ reason: `--code-index-engine native-rust requires PROJECT_LIBRARIAN_NATIVE_INDEXER or a packaged native helper at ${packagedHelperPath}`,
183
+ source: "missing",
184
+ };
185
+ }
186
+ function nativeCodeIndexHelperAvailable(options = {}) {
187
+ return nativeCodeIndexHelperAvailability(options).available;
188
+ }
189
+ function writeJobManifest(job) {
190
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "project-librarian-native-indexer-"));
191
+ const manifestPath = path.join(tmpDir, "job.json");
192
+ fs.writeFileSync(manifestPath, `${JSON.stringify(job)}\n`);
193
+ return manifestPath;
194
+ }
195
+ function buildNativeCodeIndexJob(input) {
196
+ const { mode = "full", ...rest } = input;
197
+ return {
198
+ abi_version: 1,
199
+ engine: "native-rust",
200
+ mode,
201
+ project_root: (0, workspace_1.normalizePath)(workspace_1.root),
202
+ ...rest,
203
+ };
204
+ }
205
+ function validateNativeCodeIndexSummary(job, summary) {
206
+ if (summary.engine !== job.engine) {
207
+ throw new Error(`native code index helper summary engine mismatch: expected ${job.engine}, got ${summary.engine ?? "(missing)"}`);
208
+ }
209
+ if (summary.schema_version !== job.schema_version) {
210
+ throw new Error(`native code index helper summary schema mismatch: expected ${job.schema_version}, got ${summary.schema_version ?? "(missing)"}`);
211
+ }
212
+ if (summary.mode !== job.mode) {
213
+ throw new Error(`native code index helper summary mode mismatch: expected ${job.mode}, got ${summary.mode ?? "(missing)"}`);
214
+ }
215
+ const database = summary.database ?? summary.database_path ?? "";
216
+ if (path.resolve(database) !== path.resolve(job.database_path)) {
217
+ throw new Error(`native code index helper summary database mismatch: expected ${job.database_path}, got ${database || "(missing)"}`);
218
+ }
219
+ if (!Number.isInteger(summary.files) || (summary.files ?? -1) < 0) {
220
+ throw new Error("native code index helper summary files must be a non-negative integer");
221
+ }
222
+ if (summary.native_files !== undefined && summary.native_files !== job.files.length) {
223
+ throw new Error(`native code index helper summary native_files mismatch: expected ${job.files.length}, got ${summary.native_files}`);
224
+ }
225
+ if ((summary.unsupported_profiles ?? []).length > 0) {
226
+ throw new Error(`native code index helper reported unsupported profiles: ${(summary.unsupported_profiles ?? []).join(", ")}`);
227
+ }
228
+ return summary;
229
+ }
230
+ function runNativeCodeIndexHelper(job, options = {}) {
231
+ const helperPath = requireNativeCodeIndexHelperPath(options);
232
+ const manifestPath = writeJobManifest(job);
233
+ try {
234
+ const result = childProcess.spawnSync(helperPath, ["--manifest", manifestPath], {
235
+ cwd: workspace_1.root,
236
+ encoding: "utf8",
237
+ stdio: ["ignore", "pipe", "pipe"],
238
+ });
239
+ if (result.status !== 0) {
240
+ const detail = (result.stderr || result.stdout || "").trim();
241
+ throw new Error(`native code index helper failed (${result.status ?? "signal"}): ${detail || helperPath}`);
242
+ }
243
+ let summary;
244
+ try {
245
+ summary = JSON.parse(result.stdout || "{}");
246
+ }
247
+ catch (error) {
248
+ const message = error instanceof Error ? error.message : String(error);
249
+ throw new Error(`native code index helper returned invalid JSON: ${message}`);
250
+ }
251
+ return validateNativeCodeIndexSummary(job, summary);
252
+ }
253
+ finally {
254
+ fs.rmSync(path.dirname(manifestPath), { recursive: true, force: true });
255
+ }
256
+ }
257
+ function validateNativeRows(value) {
258
+ if (typeof value !== "object" || value === null) {
259
+ throw new Error("native code index helper row stream must be an object");
260
+ }
261
+ const rows = value;
262
+ for (const key of ["configs", "edges", "files", "imports", "routes", "symbols"]) {
263
+ if (!Array.isArray(rows[key])) {
264
+ throw new Error(`native code index helper row stream missing array: ${key}`);
265
+ }
266
+ }
267
+ return rows;
268
+ }
269
+ function runNativeCodeIndexRowsHelper(job, options = {}) {
270
+ if (job.output_mode !== "row-stream") {
271
+ throw new Error("native row helper requires output_mode row-stream");
272
+ }
273
+ if (!job.rows_path) {
274
+ throw new Error("native row helper requires rows_path");
275
+ }
276
+ const summary = runNativeCodeIndexHelper(job, options);
277
+ let rowsJson = "";
278
+ try {
279
+ rowsJson = fs.readFileSync(job.rows_path, "utf8");
280
+ }
281
+ catch (error) {
282
+ const message = error instanceof Error ? error.message : String(error);
283
+ throw new Error(`native code index helper did not write rows: ${message}`);
284
+ }
285
+ try {
286
+ return { rows: validateNativeRows(JSON.parse(rowsJson)), summary };
287
+ }
288
+ catch (error) {
289
+ const message = error instanceof Error ? error.message : String(error);
290
+ throw new Error(`native code index helper returned invalid row stream: ${message}`);
291
+ }
292
+ }
@@ -1,6 +1,41 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.codeIndexSchemaVersion = void 0;
37
+ exports.fileFtsRowid = fileFtsRowid;
38
+ exports.createSecondaryIndexes = createSecondaryIndexes;
4
39
  exports.setupDatabase = setupDatabase;
5
40
  exports.createIndexStatements = createIndexStatements;
6
41
  exports.removeIndexedFile = removeIndexedFile;
@@ -10,14 +45,44 @@ exports.indexedScopes = indexedScopes;
10
45
  exports.indexedParserMode = indexedParserMode;
11
46
  exports.incrementalCompatibility = incrementalCompatibility;
12
47
  exports.codeIndexSnapshot = codeIndexSnapshot;
48
+ const crypto = __importStar(require("node:crypto"));
13
49
  const workspace_1 = require("../workspace");
14
- exports.codeIndexSchemaVersion = "4";
15
- function setupDatabase(database) {
50
+ exports.codeIndexSchemaVersion = "5";
51
+ function stableFtsRowid(parts) {
52
+ const hash = crypto.createHash("sha256");
53
+ for (const part of parts) {
54
+ hash.update(part);
55
+ hash.update("\0");
56
+ }
57
+ const digest = hash.digest();
58
+ let value = 0;
59
+ for (let index = 0; index < 6; index += 1)
60
+ value = value * 256 + digest[index];
61
+ return value + 1;
62
+ }
63
+ function fileFtsRowid(filePath) {
64
+ return stableFtsRowid(["file", filePath]);
65
+ }
66
+ const secondaryIndexSql = `
67
+ CREATE INDEX idx_symbols_file ON symbols(file_path);
68
+ CREATE INDEX idx_symbols_name ON symbols(name);
69
+ CREATE INDEX idx_imports_from ON imports(from_file);
70
+ CREATE INDEX idx_routes_path ON routes(route);
71
+ CREATE INDEX idx_configs_file ON configs(file_path);
72
+ CREATE INDEX idx_edges_source ON edges(source_kind, source);
73
+ CREATE INDEX idx_edges_target ON edges(target_kind, target);
74
+ CREATE INDEX idx_edges_kind ON edges(kind);
75
+ `;
76
+ function createSecondaryIndexes(database) {
77
+ database.exec(secondaryIndexSql);
78
+ }
79
+ function setupDatabase(database, options = {}) {
16
80
  database.exec(`
17
81
  PRAGMA journal_mode = WAL;
18
82
  CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);
19
83
  CREATE TABLE files (
20
84
  path TEXT PRIMARY KEY,
85
+ fts_rowid INTEGER NOT NULL UNIQUE,
21
86
  language TEXT NOT NULL,
22
87
  profile TEXT NOT NULL,
23
88
  kind TEXT NOT NULL,
@@ -71,30 +136,24 @@ function setupDatabase(database) {
71
136
  );
72
137
  CREATE VIRTUAL TABLE files_fts USING fts5(path, language, profile, content);
73
138
  CREATE VIRTUAL TABLE symbols_fts USING fts5(name, kind, file_path, signature);
74
- CREATE INDEX idx_symbols_file ON symbols(file_path);
75
- CREATE INDEX idx_symbols_name ON symbols(name);
76
- CREATE INDEX idx_imports_from ON imports(from_file);
77
- CREATE INDEX idx_routes_path ON routes(route);
78
- CREATE INDEX idx_configs_file ON configs(file_path);
79
- CREATE INDEX idx_edges_source ON edges(source_kind, source);
80
- CREATE INDEX idx_edges_target ON edges(target_kind, target);
81
- CREATE INDEX idx_edges_kind ON edges(kind);
82
139
  `);
140
+ if (options.secondaryIndexes ?? true)
141
+ createSecondaryIndexes(database);
83
142
  }
84
143
  function createIndexStatements(database) {
85
144
  return {
86
145
  deleteConfig: database.prepare("DELETE FROM configs WHERE file_path = ?"),
87
146
  deleteEdge: database.prepare("DELETE FROM edges WHERE file_path = ?"),
88
147
  deleteFile: database.prepare("DELETE FROM files WHERE path = ?"),
89
- deleteFileFts: database.prepare("DELETE FROM files_fts WHERE path = ?"),
148
+ deleteFileFts: database.prepare("DELETE FROM files_fts WHERE rowid = (SELECT fts_rowid FROM files WHERE path = ?)"),
90
149
  deleteImport: database.prepare("DELETE FROM imports WHERE from_file = ?"),
91
150
  deleteRoute: database.prepare("DELETE FROM routes WHERE file_path = ?"),
92
151
  deleteSymbol: database.prepare("DELETE FROM symbols WHERE file_path = ?"),
93
152
  deleteSymbolFts: database.prepare("DELETE FROM symbols_fts WHERE file_path = ?"),
94
153
  insertConfig: database.prepare("INSERT INTO configs (key, value, file_path, line) VALUES (?, ?, ?, ?)"),
95
154
  insertEdge: database.prepare("INSERT INTO edges (kind, source_kind, source, target_kind, target, file_path, line, evidence) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"),
96
- insertFile: database.prepare("INSERT INTO files (path, language, profile, kind, bytes, lines, hash, mtime_ms, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"),
97
- insertFileFts: database.prepare("INSERT INTO files_fts (path, language, profile, content) VALUES (?, ?, ?, ?)"),
155
+ insertFile: database.prepare("INSERT INTO files (path, fts_rowid, language, profile, kind, bytes, lines, hash, mtime_ms, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
156
+ insertFileFts: database.prepare("INSERT INTO files_fts (rowid, path, language, profile, content) VALUES (?, ?, ?, ?, ?)"),
98
157
  insertImport: database.prepare("INSERT INTO imports (from_file, to_ref, imported, line, raw) VALUES (?, ?, ?, ?, ?)"),
99
158
  insertMeta: database.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES (?, ?)"),
100
159
  insertRoute: database.prepare("INSERT INTO routes (method, route, file_path, line, handler) VALUES (?, ?, ?, ?, ?)"),
@@ -82,7 +82,7 @@ function searchFiles(database, term, limit = 25) {
82
82
  const ftsRows = database.prepare(`
83
83
  SELECT files.path, files.language, files.profile, files.lines, files.bytes
84
84
  FROM files_fts
85
- JOIN files ON files.path = files_fts.path
85
+ JOIN files ON files.fts_rowid = files_fts.rowid
86
86
  WHERE files_fts MATCH ?
87
87
  ORDER BY bm25(files_fts, 8.0, 1.0, 1.0, 0.25), files.path
88
88
  LIMIT ?
@@ -38,6 +38,7 @@ exports.fileLanguage = fileLanguage;
38
38
  exports.isJavaScriptLike = isJavaScriptLike;
39
39
  exports.shouldIndexFile = shouldIndexFile;
40
40
  exports.isIgnoredCodePath = isIgnoredCodePath;
41
+ exports.cachedDiscoveredCodeFileStat = cachedDiscoveredCodeFileStat;
41
42
  exports.discoverCodeFiles = discoverCodeFiles;
42
43
  exports.smallRepoCodeIndexGate = smallRepoCodeIndexGate;
43
44
  const childProcess = __importStar(require("node:child_process"));
@@ -76,6 +77,7 @@ const languageByExtension = {
76
77
  };
77
78
  const configExtensions = new Set([".json", ".yaml", ".yml", ".toml"]);
78
79
  exports.maxIndexedBytes = 1024 * 1024;
80
+ const discoveredCodeFileStats = new Map();
79
81
  function fileLanguage(relativePath) {
80
82
  if (path.basename(relativePath) === ".env.example")
81
83
  return "config";
@@ -170,7 +172,11 @@ function gitTrackedAndUnignoredFiles(scopes) {
170
172
  function indexableFileStat(file) {
171
173
  return (0, workspace_1.containedProjectFileStat)(file);
172
174
  }
175
+ function cachedDiscoveredCodeFileStat(relativePath) {
176
+ return discoveredCodeFileStats.get(relativePath);
177
+ }
173
178
  function discoverCodeFiles(scopes) {
179
+ discoveredCodeFileStats.clear();
174
180
  const gitFiles = gitTrackedAndUnignoredFiles(scopes);
175
181
  const candidates = gitFiles ?? scopes.flatMap((scope) => walkCodeFiles(scope));
176
182
  const files = [];
@@ -178,8 +184,10 @@ function discoverCodeFiles(scopes) {
178
184
  if (isIgnoredCodePath(file) || !shouldIndexFile(file))
179
185
  continue;
180
186
  const stat = indexableFileStat(file);
181
- if (stat && stat.size <= exports.maxIndexedBytes)
187
+ if (stat && stat.size <= exports.maxIndexedBytes) {
188
+ discoveredCodeFileStats.set(file, { absolutePath: (0, workspace_1.abs)(file), stat });
182
189
  files.push(file);
190
+ }
183
191
  }
184
192
  return files.sort();
185
193
  }