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.
- package/CONTRIBUTING.md +36 -0
- package/README.ko.md +58 -365
- package/README.md +56 -363
- package/SKILL.md +7 -0
- package/dist/args.js +9 -1
- package/dist/code-index/extractors/light-languages.js +285 -0
- package/dist/code-index/extractors/registry.js +12 -0
- package/dist/code-index/extractors/shared.js +18 -1
- package/dist/code-index/extractors/typescript.js +30 -16
- package/dist/code-index/index-health.js +4 -3
- package/dist/code-index/modes.js +193 -33
- package/dist/code-index/native-helper-matrix.js +99 -0
- package/dist/code-index/native-helper.js +292 -0
- package/dist/code-index/schema.js +72 -13
- package/dist/code-index/search.js +1 -1
- package/dist/code-index-file-policy.js +9 -1
- package/dist/code-index.js +363 -12
- package/dist/init-project-wiki.js +14 -0
- package/dist/install-skill.js +22 -2
- package/dist/native/darwin-arm64/project-librarian-indexer +0 -0
- package/dist/native/darwin-x64/project-librarian-indexer +0 -0
- package/dist/native/linux-arm64/project-librarian-indexer +0 -0
- package/dist/native/linux-arm64-musl/project-librarian-indexer +0 -0
- package/dist/native/linux-x64/project-librarian-indexer +0 -0
- package/dist/native/linux-x64-musl/project-librarian-indexer +0 -0
- package/dist/native/project-librarian-indexer-manifest.json +70 -0
- package/dist/native/win32-arm64/project-librarian-indexer.exe +0 -0
- package/dist/native/win32-x64/project-librarian-indexer.exe +0 -0
- package/docs/README.md +11 -0
- package/docs/benchmarks.md +64 -0
- package/docs/cli-reference.md +61 -0
- package/docs/code-evidence.md +93 -0
- package/docs/ko/README.md +13 -0
- package/docs/ko/benchmarks.md +64 -0
- package/docs/ko/cli-reference.md +61 -0
- package/docs/ko/code-evidence.md +93 -0
- package/docs/ko/maintainer.md +76 -0
- package/docs/ko/usage.md +168 -0
- package/docs/maintainer.md +76 -0
- package/docs/usage.md +176 -0
- 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 = "
|
|
15
|
-
function
|
|
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.
|
|
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
|
}
|