project-librarian 0.5.4 → 0.5.6
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 +57 -360
- package/README.md +56 -359
- package/dist/args.js +6 -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/modes.js +136 -32
- package/dist/code-index/native-helper-matrix.js +99 -0
- package/dist/code-index/native-helper.js +292 -0
- package/dist/code-index/ownership.js +8 -6
- package/dist/code-index/schema.js +72 -13
- package/dist/code-index/search.js +1 -1
- package/dist/code-index-db.js +20 -12
- package/dist/code-index-file-policy.js +17 -11
- package/dist/code-index.js +365 -13
- package/dist/hooks.js +5 -5
- package/dist/init-project-wiki.js +7 -1
- package/dist/install-skill.js +99 -6
- package/dist/mcp-server.js +4 -4
- package/dist/migration.js +27 -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/dist/templates.js +4 -3
- package/dist/workspace.js +137 -10
- package/docs/README.md +11 -0
- package/docs/benchmarks.md +64 -0
- package/docs/cli-reference.md +60 -0
- package/docs/code-evidence.md +87 -0
- package/docs/ko/README.md +13 -0
- package/docs/ko/benchmarks.md +64 -0
- package/docs/ko/cli-reference.md +60 -0
- package/docs/ko/code-evidence.md +87 -0
- package/docs/ko/maintainer.md +76 -0
- package/docs/ko/usage.md +167 -0
- package/docs/maintainer.md +76 -0
- package/docs/usage.md +175 -0
- package/package.json +13 -2
package/dist/code-index/modes.js
CHANGED
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resolveCodeIndexEngine = resolveCodeIndexEngine;
|
|
36
37
|
exports.runCodeIndexMode = runCodeIndexMode;
|
|
37
38
|
exports.runCodeQueryMode = runCodeQueryMode;
|
|
38
39
|
exports.runCodeReportMode = runCodeReportMode;
|
|
@@ -70,17 +71,75 @@ function requireCompatibleDatabase(database, runtime) {
|
|
|
70
71
|
].join("\n"));
|
|
71
72
|
}
|
|
72
73
|
}
|
|
74
|
+
function elapsedMs(started) {
|
|
75
|
+
return Number(process.hrtime.bigint() - started) / 1_000_000;
|
|
76
|
+
}
|
|
77
|
+
function measurePhase(timings, key, fn) {
|
|
78
|
+
const started = process.hrtime.bigint();
|
|
79
|
+
try {
|
|
80
|
+
return fn();
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
timings[key] = Number(((timings[key] ?? 0) + elapsedMs(started)).toFixed(3));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function emitCodeIndexPhaseTimings(timings) {
|
|
87
|
+
if (process.env.PROJECT_LIBRARIAN_CODE_INDEX_TIMINGS !== "1")
|
|
88
|
+
return;
|
|
89
|
+
console.error(`code_index_phase_timings ${JSON.stringify(timings)}`);
|
|
90
|
+
}
|
|
91
|
+
function configureBulkWriteConnection(database) {
|
|
92
|
+
database.exec(`
|
|
93
|
+
PRAGMA synchronous = OFF;
|
|
94
|
+
PRAGMA temp_store = MEMORY;
|
|
95
|
+
PRAGMA cache_size = -20000;
|
|
96
|
+
`);
|
|
97
|
+
}
|
|
98
|
+
function shouldUseNativeIncrementalForAuto(requestedEngine, runtime, staleFileCount) {
|
|
99
|
+
if (requestedEngine !== "auto" || !args_1.codeIndexIncrementalMode)
|
|
100
|
+
return false;
|
|
101
|
+
if (staleFileCount <= 0 || !runtime.nativeCodeIndexAvailable())
|
|
102
|
+
return false;
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
function resolveCodeIndexEngine(requestedEngine, context, shouldUseNativeAuto, incrementalMode = args_1.codeIndexIncrementalMode) {
|
|
106
|
+
if (requestedEngine !== "auto")
|
|
107
|
+
return requestedEngine;
|
|
108
|
+
if (incrementalMode)
|
|
109
|
+
return "typescript";
|
|
110
|
+
return shouldUseNativeAuto(context) ? "native-rust" : "typescript";
|
|
111
|
+
}
|
|
73
112
|
function runCodeIndexMode(runtime) {
|
|
113
|
+
const totalStarted = process.hrtime.bigint();
|
|
114
|
+
const phaseTimings = {};
|
|
74
115
|
const databasePath = runtime.codeEvidenceDatabasePath();
|
|
75
116
|
const scopes = runtime.codeScopes();
|
|
76
117
|
const parserMode = runtime.selectedCodeParserMode();
|
|
118
|
+
const requestedEngine = runtime.selectedCodeIndexEngine();
|
|
77
119
|
// Scale gate before ANY write or database work: below the measured threshold
|
|
78
120
|
// the build halts with the evidence-citing warning unless --acknowledge-small-repo
|
|
79
121
|
// was passed (2026-06-12 scale-aware guidance decision).
|
|
80
|
-
const discoveredFiles = (0, code_index_file_policy_1.discoverCodeFiles)(scopes);
|
|
122
|
+
const discoveredFiles = measurePhase(phaseTimings, "discover_files_ms", () => (0, code_index_file_policy_1.discoverCodeFiles)(scopes));
|
|
81
123
|
const scaleGate = (0, code_index_file_policy_1.smallRepoCodeIndexGate)(discoveredFiles.length, args_1.acknowledgeSmallRepoMode);
|
|
82
124
|
if (!scaleGate.proceed)
|
|
83
125
|
runtime.fail(scaleGate.warning);
|
|
126
|
+
const engineSelectionContext = runtime.codeIndexEngineSelectionContext(discoveredFiles, parserMode);
|
|
127
|
+
const engine = resolveCodeIndexEngine(requestedEngine, engineSelectionContext, runtime.shouldUseNativeCodeIndexAuto);
|
|
128
|
+
if (engine === "native-rust") {
|
|
129
|
+
if (!args_1.codeIndexIncrementalMode) {
|
|
130
|
+
try {
|
|
131
|
+
measurePhase(phaseTimings, "native_helper_ms", () => runtime.runNativeCodeIndexMode({ databasePath, discoveredFiles, parserMode, requestedEngine, scopes }));
|
|
132
|
+
phaseTimings.total_ms = Number(elapsedMs(totalStarted).toFixed(3));
|
|
133
|
+
emitCodeIndexPhaseTimings(phaseTimings);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
phaseTimings.total_ms = Number(elapsedMs(totalStarted).toFixed(3));
|
|
138
|
+
emitCodeIndexPhaseTimings(phaseTimings);
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
84
143
|
const existingIndex = fs.existsSync(databasePath.absolutePath);
|
|
85
144
|
if (args_1.codeIndexIncrementalMode && !existingIndex) {
|
|
86
145
|
runtime.fail(`--incremental requires an existing compatible code evidence index: ${databasePath.relativePath}`);
|
|
@@ -88,27 +147,30 @@ function runCodeIndexMode(runtime) {
|
|
|
88
147
|
let incremental = false;
|
|
89
148
|
if (existingIndex && !args_1.codeIndexFullMode) {
|
|
90
149
|
let compatibility = { compatible: false, reason: "compatibility was not checked" };
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
150
|
+
measurePhase(phaseTimings, "compatibility_ms", () => {
|
|
151
|
+
const existingDatabase = runtime.openDatabase(databasePath.absolutePath);
|
|
152
|
+
try {
|
|
153
|
+
compatibility = (0, schema_1.incrementalCompatibility)(existingDatabase, scopes, parserMode);
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
existingDatabase.close();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
98
159
|
incremental = !args_1.codeIndexFullMode && compatibility.compatible;
|
|
99
160
|
if (args_1.codeIndexIncrementalMode && !compatibility.compatible)
|
|
100
161
|
runtime.fail(`--incremental cannot update ${databasePath.relativePath}: ${compatibility.reason}`);
|
|
101
162
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
163
|
+
measurePhase(phaseTimings, "prepare_output_ms", () => {
|
|
164
|
+
runtime.prepareOutputPath();
|
|
165
|
+
if (!incremental)
|
|
166
|
+
runtime.removeDatabaseFiles(databasePath.absolutePath);
|
|
167
|
+
});
|
|
168
|
+
let database = runtime.openDatabase(databasePath.absolutePath);
|
|
106
169
|
try {
|
|
107
170
|
if (!incremental)
|
|
108
|
-
(0, schema_1.setupDatabase)(database);
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
let reindexedFiles;
|
|
171
|
+
(0, schema_1.setupDatabase)(database, { secondaryIndexes: false });
|
|
172
|
+
const currentFingerprints = measurePhase(phaseTimings, "fingerprints_ms", () => discoveredFiles.map((filePath) => runtime.readCodeFileFingerprint(filePath)));
|
|
173
|
+
let reindexedFingerprints;
|
|
112
174
|
let deletedPaths;
|
|
113
175
|
let indexedPaths = new Set();
|
|
114
176
|
let unchangedFiles = 0;
|
|
@@ -122,45 +184,87 @@ function runCodeIndexMode(runtime) {
|
|
|
122
184
|
}]));
|
|
123
185
|
const currentPaths = new Set(currentFingerprints.map((file) => file.path));
|
|
124
186
|
deletedPaths = indexedRows.map((row) => String(row.path)).filter((filePath) => !currentPaths.has(filePath));
|
|
125
|
-
|
|
187
|
+
reindexedFingerprints = [];
|
|
126
188
|
for (const file of currentFingerprints) {
|
|
127
189
|
const existing = indexed.get(file.path);
|
|
128
190
|
if (existing && existing.mtimeMs === file.mtimeMs && existing.size === file.size) {
|
|
129
191
|
unchangedFiles += 1;
|
|
130
192
|
continue;
|
|
131
193
|
}
|
|
132
|
-
|
|
194
|
+
reindexedFingerprints.push(file);
|
|
133
195
|
}
|
|
134
196
|
}
|
|
135
197
|
else {
|
|
136
198
|
deletedPaths = [];
|
|
137
|
-
|
|
199
|
+
reindexedFingerprints = currentFingerprints;
|
|
138
200
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
201
|
+
const nativeIncrementalRequested = engine === "native-rust"
|
|
202
|
+
|| shouldUseNativeIncrementalForAuto(requestedEngine, runtime, reindexedFingerprints.length + deletedPaths.length);
|
|
203
|
+
if (nativeIncrementalRequested) {
|
|
204
|
+
if (!runtime.nativeCodeIndexAvailable()) {
|
|
205
|
+
runtime.fail("--code-index-engine native-rust --incremental requires PROJECT_LIBRARIAN_NATIVE_INDEXER or a packaged native helper.");
|
|
206
|
+
}
|
|
207
|
+
if (!runtime.nativeCodeIndexIncrementalEligible(reindexedFingerprints, parserMode)) {
|
|
208
|
+
if (engine === "native-rust") {
|
|
209
|
+
runtime.fail("--code-index-engine native-rust --incremental only supports native-eligible parser profiles; use --code-index-engine typescript for this incremental update.");
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
database.close();
|
|
214
|
+
database = undefined;
|
|
215
|
+
measurePhase(phaseTimings, "native_helper_ms", () => runtime.runNativeCodeIndexIncrementalMode({
|
|
216
|
+
databasePath,
|
|
217
|
+
deletedPaths,
|
|
218
|
+
discoveredFiles,
|
|
219
|
+
parserMode,
|
|
220
|
+
requestedEngine,
|
|
221
|
+
reindexedFiles: reindexedFingerprints,
|
|
222
|
+
scopes,
|
|
223
|
+
unchangedFiles,
|
|
224
|
+
}));
|
|
225
|
+
phaseTimings.total_ms = Number(elapsedMs(totalStarted).toFixed(3));
|
|
226
|
+
emitCodeIndexPhaseTimings(phaseTimings);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
149
229
|
}
|
|
150
|
-
|
|
230
|
+
const reindexedFiles = measurePhase(phaseTimings, "read_files_ms", () => reindexedFingerprints.map((file) => runtime.readCodeFile(file.path, parserMode, file)));
|
|
231
|
+
const activeDatabase = database;
|
|
232
|
+
const statements = (0, schema_1.createIndexStatements)(activeDatabase);
|
|
233
|
+
measurePhase(phaseTimings, "sqlite_write_ms", () => {
|
|
234
|
+
configureBulkWriteConnection(activeDatabase);
|
|
235
|
+
activeDatabase.exec("BEGIN");
|
|
236
|
+
if (!incremental)
|
|
237
|
+
statements.insertMeta.run("created_at", new Date().toISOString());
|
|
238
|
+
(0, schema_1.writeIndexMetadata)(scopes, parserMode, statements);
|
|
239
|
+
for (const filePath of deletedPaths)
|
|
240
|
+
(0, schema_1.removeIndexedFile)(filePath, statements);
|
|
241
|
+
for (const file of reindexedFiles) {
|
|
242
|
+
if (incremental && indexedPaths.has(file.path))
|
|
243
|
+
(0, schema_1.removeIndexedFile)(file.path, statements);
|
|
244
|
+
runtime.indexCodeFile(file, statements);
|
|
245
|
+
}
|
|
246
|
+
if (!incremental)
|
|
247
|
+
(0, schema_1.createSecondaryIndexes)(activeDatabase);
|
|
248
|
+
activeDatabase.exec("COMMIT");
|
|
249
|
+
});
|
|
250
|
+
phaseTimings.total_ms = Number(elapsedMs(totalStarted).toFixed(3));
|
|
151
251
|
console.log("Project wiki code evidence index complete.");
|
|
152
252
|
console.log(`database: ${databasePath.relativePath}`);
|
|
153
253
|
console.log(`mode: ${incremental ? "incremental" : "full"}`);
|
|
254
|
+
console.log(`engine: ${engine}`);
|
|
255
|
+
if (requestedEngine === "auto")
|
|
256
|
+
console.log("engine_selection: auto");
|
|
154
257
|
console.log(`parser_mode: ${parserMode}`);
|
|
155
258
|
console.log(`scopes: ${scopes.join(", ")}`);
|
|
156
259
|
console.log(`files: ${currentFingerprints.length}`);
|
|
157
260
|
console.log(`reindexed_files: ${reindexedFiles.length}`);
|
|
158
261
|
console.log(`deleted_files: ${deletedPaths.length}`);
|
|
159
262
|
console.log(`unchanged_files: ${unchangedFiles}`);
|
|
263
|
+
emitCodeIndexPhaseTimings(phaseTimings);
|
|
160
264
|
}
|
|
161
265
|
catch (error) {
|
|
162
266
|
try {
|
|
163
|
-
database
|
|
267
|
+
database?.exec("ROLLBACK");
|
|
164
268
|
}
|
|
165
269
|
catch {
|
|
166
270
|
// Ignore rollback failures after setup errors.
|
|
@@ -168,7 +272,7 @@ function runCodeIndexMode(runtime) {
|
|
|
168
272
|
throw error;
|
|
169
273
|
}
|
|
170
274
|
finally {
|
|
171
|
-
database
|
|
275
|
+
database?.close();
|
|
172
276
|
}
|
|
173
277
|
}
|
|
174
278
|
function runCodeQueryMode(runtime) {
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.supportedNativeHelperTriples = exports.nativeCodeIndexHelperTargets = void 0;
|
|
4
|
+
exports.nativeCodeIndexHelperTargetForTriple = nativeCodeIndexHelperTargetForTriple;
|
|
5
|
+
exports.nativeCodeIndexHelperPlatformFromTriple = nativeCodeIndexHelperPlatformFromTriple;
|
|
6
|
+
exports.nativeCodeIndexHelperTripleForPlatform = nativeCodeIndexHelperTripleForPlatform;
|
|
7
|
+
exports.nativeCodeIndexHelperTargets = [
|
|
8
|
+
{
|
|
9
|
+
arch: "arm64",
|
|
10
|
+
architecture: "arm64",
|
|
11
|
+
format: "mach-o",
|
|
12
|
+
libc: "",
|
|
13
|
+
platform: "darwin",
|
|
14
|
+
runner: "macos-14",
|
|
15
|
+
rustTarget: "aarch64-apple-darwin",
|
|
16
|
+
triple: "darwin-arm64",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
arch: "x64",
|
|
20
|
+
architecture: "x64",
|
|
21
|
+
format: "mach-o",
|
|
22
|
+
libc: "",
|
|
23
|
+
platform: "darwin",
|
|
24
|
+
runner: "macos-15-intel",
|
|
25
|
+
rustTarget: "x86_64-apple-darwin",
|
|
26
|
+
triple: "darwin-x64",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
arch: "arm64",
|
|
30
|
+
architecture: "arm64",
|
|
31
|
+
format: "elf",
|
|
32
|
+
libc: "",
|
|
33
|
+
platform: "linux",
|
|
34
|
+
runner: "ubuntu-24.04-arm",
|
|
35
|
+
rustTarget: "aarch64-unknown-linux-gnu",
|
|
36
|
+
triple: "linux-arm64",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
arch: "arm64",
|
|
40
|
+
architecture: "arm64",
|
|
41
|
+
format: "elf",
|
|
42
|
+
libc: "musl",
|
|
43
|
+
platform: "linux",
|
|
44
|
+
runner: "ubuntu-24.04-arm",
|
|
45
|
+
rustTarget: "aarch64-unknown-linux-musl",
|
|
46
|
+
triple: "linux-arm64-musl",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
arch: "x64",
|
|
50
|
+
architecture: "x64",
|
|
51
|
+
format: "elf",
|
|
52
|
+
libc: "",
|
|
53
|
+
platform: "linux",
|
|
54
|
+
runner: "ubuntu-latest",
|
|
55
|
+
rustTarget: "x86_64-unknown-linux-gnu",
|
|
56
|
+
triple: "linux-x64",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
arch: "x64",
|
|
60
|
+
architecture: "x64",
|
|
61
|
+
format: "elf",
|
|
62
|
+
libc: "musl",
|
|
63
|
+
platform: "linux",
|
|
64
|
+
runner: "ubuntu-latest",
|
|
65
|
+
rustTarget: "x86_64-unknown-linux-musl",
|
|
66
|
+
triple: "linux-x64-musl",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
arch: "arm64",
|
|
70
|
+
architecture: "arm64",
|
|
71
|
+
format: "pe",
|
|
72
|
+
libc: "",
|
|
73
|
+
platform: "win32",
|
|
74
|
+
runner: "windows-11-arm",
|
|
75
|
+
rustTarget: "aarch64-pc-windows-msvc",
|
|
76
|
+
triple: "win32-arm64",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
arch: "x64",
|
|
80
|
+
architecture: "x64",
|
|
81
|
+
format: "pe",
|
|
82
|
+
libc: "",
|
|
83
|
+
platform: "win32",
|
|
84
|
+
runner: "windows-latest",
|
|
85
|
+
rustTarget: "x86_64-pc-windows-msvc",
|
|
86
|
+
triple: "win32-x64",
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
exports.supportedNativeHelperTriples = exports.nativeCodeIndexHelperTargets.map((target) => target.triple);
|
|
90
|
+
function nativeCodeIndexHelperTargetForTriple(triple) {
|
|
91
|
+
return exports.nativeCodeIndexHelperTargets.find((target) => target.triple === triple);
|
|
92
|
+
}
|
|
93
|
+
function nativeCodeIndexHelperPlatformFromTriple(triple) {
|
|
94
|
+
return nativeCodeIndexHelperTargetForTriple(triple)?.platform ?? String(triple).split("-")[0] ?? "";
|
|
95
|
+
}
|
|
96
|
+
function nativeCodeIndexHelperTripleForPlatform(platform, arch, libc = "") {
|
|
97
|
+
const normalizedLibc = platform === "linux" && libc === "musl" ? "musl" : "";
|
|
98
|
+
return exports.nativeCodeIndexHelperTargets.find((target) => (target.platform === platform && target.arch === arch && target.libc === normalizedLibc))?.triple ?? `${platform}-${arch}`;
|
|
99
|
+
}
|
|
@@ -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
|
+
}
|