@neuralsea/workspace-indexer 0.3.3 → 0.3.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/dist/{chunk-IXKSW7IX.js → chunk-FUUQXFJQ.js} +146 -9
- package/dist/cli.cjs +146 -9
- package/dist/cli.js +1 -1
- package/dist/index.cjs +146 -9
- package/dist/index.d.cts +71 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2271,10 +2271,24 @@ var Neo4jGraphStore = class {
|
|
|
2271
2271
|
this.driver = driver;
|
|
2272
2272
|
this.cfg = cfg;
|
|
2273
2273
|
this.labelPrefix = cfg.labelPrefix ?? "Petri";
|
|
2274
|
+
this.emitProgress = cfg.emit ?? null;
|
|
2274
2275
|
}
|
|
2275
2276
|
id = "neo4j";
|
|
2276
2277
|
labelPrefix;
|
|
2277
2278
|
schemaVersionLatest = 2;
|
|
2279
|
+
emitProgress;
|
|
2280
|
+
opStart(op, args) {
|
|
2281
|
+
try {
|
|
2282
|
+
this.emitProgress?.({ type: "graph/neo4j/op/start", op, repoId: args?.repoId, path: args?.path });
|
|
2283
|
+
} catch {
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
opDone(op, startedAt, args) {
|
|
2287
|
+
try {
|
|
2288
|
+
this.emitProgress?.({ type: "graph/neo4j/op/done", op, repoId: args?.repoId, path: args?.path, ms: Date.now() - startedAt });
|
|
2289
|
+
} catch {
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2278
2292
|
labels() {
|
|
2279
2293
|
return {
|
|
2280
2294
|
Repo: lp(this.labelPrefix, "Repo"),
|
|
@@ -2285,6 +2299,8 @@ var Neo4jGraphStore = class {
|
|
|
2285
2299
|
};
|
|
2286
2300
|
}
|
|
2287
2301
|
async init() {
|
|
2302
|
+
const startedAt = Date.now();
|
|
2303
|
+
this.opStart("init");
|
|
2288
2304
|
const { Schema } = this.labels();
|
|
2289
2305
|
await runSession(this.driver, this.cfg.database, async (s) => {
|
|
2290
2306
|
await s.run(
|
|
@@ -2295,6 +2311,7 @@ var Neo4jGraphStore = class {
|
|
|
2295
2311
|
);
|
|
2296
2312
|
});
|
|
2297
2313
|
await this.runMigrations().catch(() => void 0);
|
|
2314
|
+
this.opDone("init", startedAt);
|
|
2298
2315
|
}
|
|
2299
2316
|
async getSchemaVersion() {
|
|
2300
2317
|
const { Schema } = this.labels();
|
|
@@ -2318,6 +2335,8 @@ var Neo4jGraphStore = class {
|
|
|
2318
2335
|
});
|
|
2319
2336
|
}
|
|
2320
2337
|
async runMigrations() {
|
|
2338
|
+
const startedAt = Date.now();
|
|
2339
|
+
this.opStart("migrations");
|
|
2321
2340
|
const { Repo, File, Symbol: Symbol2, External } = this.labels();
|
|
2322
2341
|
let v = await this.getSchemaVersion();
|
|
2323
2342
|
if (v < 1) {
|
|
@@ -2358,8 +2377,11 @@ var Neo4jGraphStore = class {
|
|
|
2358
2377
|
if (v !== this.schemaVersionLatest) {
|
|
2359
2378
|
await this.setSchemaVersion(this.schemaVersionLatest);
|
|
2360
2379
|
}
|
|
2380
|
+
this.opDone("migrations", startedAt);
|
|
2361
2381
|
}
|
|
2362
2382
|
async setRepoHead(args) {
|
|
2383
|
+
const startedAt = Date.now();
|
|
2384
|
+
this.opStart("setRepoHead", { repoId: args.repoId });
|
|
2363
2385
|
const { Repo, File, Symbol: Symbol2, External } = this.labels();
|
|
2364
2386
|
const { repoId, repoRoot, commit, branch } = args;
|
|
2365
2387
|
await runSession(this.driver, this.cfg.database, async (s) => {
|
|
@@ -2390,15 +2412,21 @@ var Neo4jGraphStore = class {
|
|
|
2390
2412
|
await s.run(`MATCH (r:${Repo} {repo_id:$repoId}) SET r.commit=$commit`, { repoId, commit });
|
|
2391
2413
|
}
|
|
2392
2414
|
});
|
|
2415
|
+
this.opDone("setRepoHead", startedAt, { repoId: args.repoId });
|
|
2393
2416
|
}
|
|
2394
2417
|
async deleteFile(args) {
|
|
2418
|
+
const startedAt = Date.now();
|
|
2419
|
+
this.opStart("deleteFile", { repoId: args.repoId, path: args.path });
|
|
2395
2420
|
const { File, Symbol: Symbol2 } = this.labels();
|
|
2396
2421
|
await runSession(this.driver, this.cfg.database, async (s) => {
|
|
2397
2422
|
await s.run(`MATCH (s:${Symbol2} {repo_id:$repoId, path:$path}) DETACH DELETE s`, args);
|
|
2398
2423
|
await s.run(`MATCH (f:${File} {repo_id:$repoId, path:$path}) DETACH DELETE f`, args);
|
|
2399
2424
|
});
|
|
2425
|
+
this.opDone("deleteFile", startedAt, { repoId: args.repoId, path: args.path });
|
|
2400
2426
|
}
|
|
2401
2427
|
async replaceOutgoingSymbolEdgesFromFile(args) {
|
|
2428
|
+
const startedAt = Date.now();
|
|
2429
|
+
this.opStart("replaceOutgoingSymbolEdgesFromFile", { repoId: args.repoId, path: args.fromPath });
|
|
2402
2430
|
const { Symbol: Symbol2 } = this.labels();
|
|
2403
2431
|
const kinds = args.edges.length > 0 ? Array.from(new Set(args.edges.map((e) => e.kind))) : ["definition", "reference", "implementation", "typeDefinition"];
|
|
2404
2432
|
const keep = args.edges.map((e) => `${e.fromId}|${e.kind}|${e.toId}`);
|
|
@@ -2430,8 +2458,11 @@ var Neo4jGraphStore = class {
|
|
|
2430
2458
|
{ repoId: args.repoId, fromPath: args.fromPath, kinds, keep }
|
|
2431
2459
|
).catch(() => void 0);
|
|
2432
2460
|
});
|
|
2461
|
+
this.opDone("replaceOutgoingSymbolEdgesFromFile", startedAt, { repoId: args.repoId, path: args.fromPath });
|
|
2433
2462
|
}
|
|
2434
2463
|
async replaceFileGraph(update) {
|
|
2464
|
+
const startedAt = Date.now();
|
|
2465
|
+
this.opStart("replaceFileGraph", { repoId: update.repoId, path: update.path });
|
|
2435
2466
|
const { Repo, File, Symbol: Symbol2, External } = this.labels();
|
|
2436
2467
|
const symbols = update.symbols.map((s) => ({
|
|
2437
2468
|
id: s.id,
|
|
@@ -2543,8 +2574,11 @@ var Neo4jGraphStore = class {
|
|
|
2543
2574
|
}
|
|
2544
2575
|
}
|
|
2545
2576
|
});
|
|
2577
|
+
this.opDone("replaceFileGraph", startedAt, { repoId: update.repoId, path: update.path });
|
|
2546
2578
|
}
|
|
2547
2579
|
async replaceRepoLinks(args) {
|
|
2580
|
+
const startedAt = Date.now();
|
|
2581
|
+
this.opStart("replaceRepoLinks");
|
|
2548
2582
|
const { Repo } = this.labels();
|
|
2549
2583
|
const byFrom = /* @__PURE__ */ new Map();
|
|
2550
2584
|
for (const l of args.links) {
|
|
@@ -2575,8 +2609,11 @@ var Neo4jGraphStore = class {
|
|
|
2575
2609
|
).catch(() => void 0);
|
|
2576
2610
|
});
|
|
2577
2611
|
}
|
|
2612
|
+
this.opDone("replaceRepoLinks", startedAt);
|
|
2578
2613
|
}
|
|
2579
2614
|
async neighborFiles(args) {
|
|
2615
|
+
const startedAt = Date.now();
|
|
2616
|
+
this.opStart("neighborFiles");
|
|
2580
2617
|
const { File, Symbol: Symbol2 } = this.labels();
|
|
2581
2618
|
const limit = args.limit ?? 20;
|
|
2582
2619
|
const kinds = args.kinds && args.kinds.length > 0 ? args.kinds : null;
|
|
@@ -2600,9 +2637,12 @@ var Neo4jGraphStore = class {
|
|
|
2600
2637
|
rows.push({ repoId, path: p, weight: Number.isFinite(w) ? w : 0 });
|
|
2601
2638
|
}
|
|
2602
2639
|
});
|
|
2640
|
+
this.opDone("neighborFiles", startedAt);
|
|
2603
2641
|
return rows;
|
|
2604
2642
|
}
|
|
2605
2643
|
async shortestFilePath(args) {
|
|
2644
|
+
const startedAt = Date.now();
|
|
2645
|
+
this.opStart("shortestFilePath");
|
|
2606
2646
|
const { File } = this.labels();
|
|
2607
2647
|
const maxRels = args.maxRels ?? 16;
|
|
2608
2648
|
let out = null;
|
|
@@ -2618,9 +2658,12 @@ var Neo4jGraphStore = class {
|
|
|
2618
2658
|
if (!Array.isArray(files)) return;
|
|
2619
2659
|
out = files.map((x) => ({ repoId: String(x.repoId), path: String(x.path) }));
|
|
2620
2660
|
});
|
|
2661
|
+
this.opDone("shortestFilePath", startedAt);
|
|
2621
2662
|
return out;
|
|
2622
2663
|
}
|
|
2623
2664
|
async extractFileSubgraph(args) {
|
|
2665
|
+
const startedAt = Date.now();
|
|
2666
|
+
this.opStart("extractFileSubgraph");
|
|
2624
2667
|
const { File, Symbol: Symbol2 } = this.labels();
|
|
2625
2668
|
const limitEdges = args.limitEdges ?? 200;
|
|
2626
2669
|
const nodes = /* @__PURE__ */ new Map();
|
|
@@ -2642,6 +2685,7 @@ var Neo4jGraphStore = class {
|
|
|
2642
2685
|
edges.push({ from, to, kind });
|
|
2643
2686
|
}
|
|
2644
2687
|
});
|
|
2688
|
+
this.opDone("extractFileSubgraph", startedAt);
|
|
2645
2689
|
return { nodes: Array.from(nodes.values()), edges };
|
|
2646
2690
|
}
|
|
2647
2691
|
async close() {
|
|
@@ -3408,6 +3452,16 @@ var RepoFileIndexer = class {
|
|
|
3408
3452
|
return;
|
|
3409
3453
|
}
|
|
3410
3454
|
this.emit({ type: "repo/index/file/start", repoRoot: this.repoRoot, path: posixRelPath });
|
|
3455
|
+
const stage = (stageName, stageStartedAt) => {
|
|
3456
|
+
this.emit({
|
|
3457
|
+
type: "repo/index/file/stage",
|
|
3458
|
+
repoRoot: this.repoRoot,
|
|
3459
|
+
path: posixRelPath,
|
|
3460
|
+
stage: stageName,
|
|
3461
|
+
ms: Date.now() - stageStartedAt
|
|
3462
|
+
});
|
|
3463
|
+
};
|
|
3464
|
+
const readStartedAt = Date.now();
|
|
3411
3465
|
const abs = import_node_path14.default.join(this.repoRoot, fromPosixPath(posixRelPath));
|
|
3412
3466
|
let stat;
|
|
3413
3467
|
try {
|
|
@@ -3431,16 +3485,20 @@ var RepoFileIndexer = class {
|
|
|
3431
3485
|
}
|
|
3432
3486
|
const raw = buf.toString("utf8");
|
|
3433
3487
|
const redacted = this.applyRedactions(raw);
|
|
3488
|
+
stage("read", readStartedAt);
|
|
3434
3489
|
const fileHash = sha256Hex(redacted);
|
|
3435
3490
|
const prev = this.store.getFileHash(posixRelPath);
|
|
3436
3491
|
if (prev === fileHash) {
|
|
3437
3492
|
this.emit({ type: "repo/index/file/skip", repoRoot: this.repoRoot, path: posixRelPath, reason: "unchanged" });
|
|
3438
3493
|
return;
|
|
3439
3494
|
}
|
|
3495
|
+
const chunkStartedAt = Date.now();
|
|
3440
3496
|
const { language, chunks } = chunkSource(posixRelPath, redacted, this.config.chunk);
|
|
3497
|
+
stage("chunk", chunkStartedAt);
|
|
3441
3498
|
let imports = [];
|
|
3442
3499
|
let exports2 = [];
|
|
3443
3500
|
if (language === "typescript" || language === "javascript") {
|
|
3501
|
+
const relationsStartedAt = Date.now();
|
|
3444
3502
|
const rel = extractTsRelations(posixRelPath, redacted);
|
|
3445
3503
|
imports = rel.imports;
|
|
3446
3504
|
exports2 = rel.exports;
|
|
@@ -3448,12 +3506,14 @@ var RepoFileIndexer = class {
|
|
|
3448
3506
|
this.store.setEdges(posixRelPath, "export", rel.exports);
|
|
3449
3507
|
this.workspaceStore?.setEdges(this.repoId, posixRelPath, "import", rel.imports);
|
|
3450
3508
|
this.workspaceStore?.setEdges(this.repoId, posixRelPath, "export", rel.exports);
|
|
3509
|
+
stage("relations", relationsStartedAt);
|
|
3451
3510
|
} else {
|
|
3452
3511
|
this.store.setEdges(posixRelPath, "import", []);
|
|
3453
3512
|
this.store.setEdges(posixRelPath, "export", []);
|
|
3454
3513
|
this.workspaceStore?.setEdges(this.repoId, posixRelPath, "import", []);
|
|
3455
3514
|
this.workspaceStore?.setEdges(this.repoId, posixRelPath, "export", []);
|
|
3456
3515
|
}
|
|
3516
|
+
const synopsisStartedAt = Date.now();
|
|
3457
3517
|
const synopsisText = buildSynopsis(posixRelPath, language, redacted);
|
|
3458
3518
|
const synopsis = synopsisText.trim() ? [
|
|
3459
3519
|
{
|
|
@@ -3478,14 +3538,29 @@ var RepoFileIndexer = class {
|
|
|
3478
3538
|
}
|
|
3479
3539
|
] : [];
|
|
3480
3540
|
const combined = [...synopsis, ...headerChunk, ...chunks.map((c) => ({ ...c, kind: "chunk" }))];
|
|
3541
|
+
stage("synopsis", synopsisStartedAt);
|
|
3542
|
+
const embedStartedAt = Date.now();
|
|
3481
3543
|
const embedTexts = [];
|
|
3482
3544
|
const embedPlan = [];
|
|
3483
3545
|
const embeddings = combined.map(() => null);
|
|
3546
|
+
let cached2 = 0;
|
|
3484
3547
|
for (let i = 0; i < combined.length; i++) {
|
|
3485
3548
|
const ch = combined[i];
|
|
3486
|
-
const
|
|
3487
|
-
if (
|
|
3488
|
-
embeddings[i] =
|
|
3549
|
+
const cachedEmb = this.embeddingCache.get(this.embedder.id, ch.contentHash);
|
|
3550
|
+
if (cachedEmb) {
|
|
3551
|
+
embeddings[i] = cachedEmb;
|
|
3552
|
+
cached2++;
|
|
3553
|
+
this.emit({
|
|
3554
|
+
type: "repo/index/file/embed/chunk",
|
|
3555
|
+
repoRoot: this.repoRoot,
|
|
3556
|
+
path: posixRelPath,
|
|
3557
|
+
chunkIndex: i,
|
|
3558
|
+
chunksTotal: combined.length,
|
|
3559
|
+
kind: ch.kind,
|
|
3560
|
+
startLine: ch.startLine,
|
|
3561
|
+
endLine: ch.endLine,
|
|
3562
|
+
cached: true
|
|
3563
|
+
});
|
|
3489
3564
|
continue;
|
|
3490
3565
|
}
|
|
3491
3566
|
embedTexts.push(
|
|
@@ -3497,7 +3572,7 @@ lines:${ch.startLine}-${ch.endLine}
|
|
|
3497
3572
|
---
|
|
3498
3573
|
${ch.text}`
|
|
3499
3574
|
);
|
|
3500
|
-
embedPlan.push({ chunkIdx: i, contentHash: ch.contentHash });
|
|
3575
|
+
embedPlan.push({ chunkIdx: i, contentHash: ch.contentHash, kind: ch.kind, startLine: ch.startLine, endLine: ch.endLine });
|
|
3501
3576
|
}
|
|
3502
3577
|
const batchSize = this.config.embed.batchSize;
|
|
3503
3578
|
for (let start = 0; start < embedTexts.length; start += batchSize) {
|
|
@@ -3515,13 +3590,35 @@ ${ch.text}`
|
|
|
3515
3590
|
const plan = embedPlan[start + j];
|
|
3516
3591
|
embeddings[plan.chunkIdx] = vecs[j];
|
|
3517
3592
|
this.embeddingCache.put(this.embedder.id, plan.contentHash, vecs[j]);
|
|
3593
|
+
this.emit({
|
|
3594
|
+
type: "repo/index/file/embed/chunk",
|
|
3595
|
+
repoRoot: this.repoRoot,
|
|
3596
|
+
path: posixRelPath,
|
|
3597
|
+
chunkIndex: plan.chunkIdx,
|
|
3598
|
+
chunksTotal: combined.length,
|
|
3599
|
+
kind: plan.kind,
|
|
3600
|
+
startLine: plan.startLine,
|
|
3601
|
+
endLine: plan.endLine,
|
|
3602
|
+
cached: false
|
|
3603
|
+
});
|
|
3518
3604
|
}
|
|
3519
3605
|
}
|
|
3606
|
+
this.emit({
|
|
3607
|
+
type: "repo/index/file/embed/done",
|
|
3608
|
+
repoRoot: this.repoRoot,
|
|
3609
|
+
path: posixRelPath,
|
|
3610
|
+
chunks: combined.length,
|
|
3611
|
+
cached: cached2,
|
|
3612
|
+
computed: embedTexts.length,
|
|
3613
|
+
ms: Date.now() - embedStartedAt
|
|
3614
|
+
});
|
|
3615
|
+
stage("embed", embedStartedAt);
|
|
3520
3616
|
const fileMtime = stat.mtimeMs;
|
|
3521
3617
|
const ftsMode = this.config.storage.ftsMode;
|
|
3522
3618
|
const storeText = this.config.storage.storeText;
|
|
3523
3619
|
const oldChunkIds = this.store.listChunksForFile(posixRelPath).map((r) => r.id);
|
|
3524
3620
|
const points = [];
|
|
3621
|
+
const storeStartedAt = Date.now();
|
|
3525
3622
|
const rows = combined.map((ch, i) => {
|
|
3526
3623
|
const id = sha256Hex(
|
|
3527
3624
|
`${this.repoId}:${posixRelPath}:${ch.kind}:${ch.startLine}:${ch.endLine}:${ch.contentHash}`
|
|
@@ -3549,7 +3646,22 @@ ${ch.text}`
|
|
|
3549
3646
|
this.store.replaceChunksForFile(posixRelPath, rows);
|
|
3550
3647
|
this.workspaceStore?.upsertFile(this.repoId, posixRelPath, fileHash, fileMtime, language, stat.size);
|
|
3551
3648
|
this.workspaceStore?.replaceChunksForFile(this.repoId, this.repoRoot, posixRelPath, rows);
|
|
3649
|
+
stage("store", storeStartedAt);
|
|
3650
|
+
const symbolsStartedAt = Date.now();
|
|
3651
|
+
if (this.symbolGraphProvider && this.symbolGraphProvider.supports(language)) {
|
|
3652
|
+
this.emit({ type: "repo/index/file/symbols/start", repoRoot: this.repoRoot, path: posixRelPath, providerId: this.symbolGraphProvider.id });
|
|
3653
|
+
}
|
|
3552
3654
|
const symbolOut = await this.indexSymbolsIfEnabled(posixRelPath, language, redacted, fileHash);
|
|
3655
|
+
this.emit({
|
|
3656
|
+
type: "repo/index/file/symbols",
|
|
3657
|
+
repoRoot: this.repoRoot,
|
|
3658
|
+
path: posixRelPath,
|
|
3659
|
+
symbols: symbolOut?.symbols?.length ?? 0,
|
|
3660
|
+
edges: symbolOut?.edges?.length ?? 0,
|
|
3661
|
+
ms: Date.now() - symbolsStartedAt
|
|
3662
|
+
});
|
|
3663
|
+
stage("symbols", symbolsStartedAt);
|
|
3664
|
+
const graphStartedAt = Date.now();
|
|
3553
3665
|
const head = this.getHead();
|
|
3554
3666
|
if (this.graphStore && head) {
|
|
3555
3667
|
await this.graphStore.replaceFileGraph({
|
|
@@ -3565,7 +3677,10 @@ ${ch.text}`
|
|
|
3565
3677
|
symbolEdges: (symbolOut?.edges ?? []).map((e) => ({ fromId: e.fromId, toId: e.toId, kind: e.kind }))
|
|
3566
3678
|
}).catch(() => void 0);
|
|
3567
3679
|
}
|
|
3680
|
+
stage("graph", graphStartedAt);
|
|
3681
|
+
const vectorStartedAt = Date.now();
|
|
3568
3682
|
await this.ensureVectorUpToDate(points, oldChunkIds);
|
|
3683
|
+
stage("vector", vectorStartedAt);
|
|
3569
3684
|
this.emit({
|
|
3570
3685
|
type: "repo/index/file/done",
|
|
3571
3686
|
repoRoot: this.repoRoot,
|
|
@@ -4176,28 +4291,46 @@ var RepoIndexer = class {
|
|
|
4176
4291
|
const uniq3 = Array.from(new Set(posixPaths)).slice(0, maxFiles);
|
|
4177
4292
|
for (const p of uniq3) {
|
|
4178
4293
|
if (opts?.signal?.aborted) return;
|
|
4294
|
+
const startedAt = Date.now();
|
|
4295
|
+
this.emitProgress({ type: "repo/symbolGraph/expand/start", repoRoot: this.repoRoot, path: p });
|
|
4179
4296
|
const abs = import_node_path17.default.join(this.repoRoot, p.split("/").join(import_node_path17.default.sep));
|
|
4180
4297
|
let text = "";
|
|
4181
4298
|
try {
|
|
4182
4299
|
text = import_node_fs12.default.readFileSync(abs, "utf8");
|
|
4183
4300
|
} catch {
|
|
4301
|
+
this.emitProgress({ type: "repo/symbolGraph/expand/done", repoRoot: this.repoRoot, path: p, edges: 0, ms: Date.now() - startedAt });
|
|
4184
4302
|
continue;
|
|
4185
4303
|
}
|
|
4186
4304
|
const contentHash = this.store.getFileHash(p) ?? void 0;
|
|
4187
4305
|
const lang = languageFromPath(p);
|
|
4188
4306
|
const edges = await provider.expandDocumentEdges({ repoRoot: this.repoRoot, path: p, language: lang, text, contentHash }, { signal: opts?.signal }).catch(() => []);
|
|
4189
4307
|
const normalized = (Array.isArray(edges) ? edges : []).map((e) => ({
|
|
4190
|
-
fromId: e
|
|
4191
|
-
toId: e
|
|
4192
|
-
kind: e
|
|
4193
|
-
toPath: String(e
|
|
4308
|
+
fromId: String(e?.fromId ?? ""),
|
|
4309
|
+
toId: String(e?.toId ?? ""),
|
|
4310
|
+
kind: String(e?.kind ?? ""),
|
|
4311
|
+
toPath: String(e?.toPath ?? "")
|
|
4194
4312
|
}));
|
|
4313
|
+
const byKind = {};
|
|
4314
|
+
for (const e of normalized) {
|
|
4315
|
+
const kind = e.kind;
|
|
4316
|
+
if (kind === "definition" || kind === "reference" || kind === "implementation" || kind === "typeDefinition") {
|
|
4317
|
+
byKind[kind] = (byKind[kind] ?? 0) + 1;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4195
4320
|
this.workspaceStore.replaceSymbolEdgesFromFile(this.repoId, p, normalized);
|
|
4196
4321
|
await this.graphStore?.replaceOutgoingSymbolEdgesFromFile?.({
|
|
4197
4322
|
repoId: this.repoId,
|
|
4198
4323
|
fromPath: p,
|
|
4199
4324
|
edges: normalized.map((e) => ({ fromId: e.fromId, toId: e.toId, kind: e.kind, toPath: e.toPath }))
|
|
4200
4325
|
}).catch(() => void 0);
|
|
4326
|
+
this.emitProgress({
|
|
4327
|
+
type: "repo/symbolGraph/expand/done",
|
|
4328
|
+
repoRoot: this.repoRoot,
|
|
4329
|
+
path: p,
|
|
4330
|
+
edges: normalized.length,
|
|
4331
|
+
byKind,
|
|
4332
|
+
ms: Date.now() - startedAt
|
|
4333
|
+
});
|
|
4201
4334
|
}
|
|
4202
4335
|
}
|
|
4203
4336
|
async watch() {
|
|
@@ -4587,7 +4720,8 @@ var WorkspaceIndexer = class {
|
|
|
4587
4720
|
user: n.user,
|
|
4588
4721
|
password: n.password,
|
|
4589
4722
|
database: n.database,
|
|
4590
|
-
labelPrefix: n.labelPrefix
|
|
4723
|
+
labelPrefix: n.labelPrefix,
|
|
4724
|
+
emit: (e) => this.emitProgress(e)
|
|
4591
4725
|
});
|
|
4592
4726
|
} catch (e) {
|
|
4593
4727
|
this.emitProgress({
|
|
@@ -4784,11 +4918,14 @@ var WorkspaceIndexer = class {
|
|
|
4784
4918
|
if (seeds.length >= 4) break;
|
|
4785
4919
|
}
|
|
4786
4920
|
if (seeds.length > 0) {
|
|
4921
|
+
const gs = Date.now();
|
|
4922
|
+
this.emitProgress({ type: "workspace/retrieve/graph/start", workspaceRoot: this.workspaceRoot, seeds: seeds.length });
|
|
4787
4923
|
graphNeighborFiles = await this.graphStore.neighborFiles({
|
|
4788
4924
|
seeds,
|
|
4789
4925
|
limit: profile.name === "architecture" ? 16 : 10,
|
|
4790
4926
|
kinds: ["definition", "reference", "implementation", "typeDefinition"]
|
|
4791
4927
|
});
|
|
4928
|
+
this.emitProgress({ type: "workspace/retrieve/graph/done", workspaceRoot: this.workspaceRoot, neighbors: graphNeighborFiles.length, ms: Date.now() - gs });
|
|
4792
4929
|
}
|
|
4793
4930
|
}
|
|
4794
4931
|
} catch {
|
package/dist/index.d.cts
CHANGED
|
@@ -253,6 +253,15 @@ type IndexerProgressEvent = {
|
|
|
253
253
|
lexical: number;
|
|
254
254
|
merged: number;
|
|
255
255
|
};
|
|
256
|
+
} | {
|
|
257
|
+
type: "workspace/retrieve/graph/start";
|
|
258
|
+
workspaceRoot: string;
|
|
259
|
+
seeds: number;
|
|
260
|
+
} | {
|
|
261
|
+
type: "workspace/retrieve/graph/done";
|
|
262
|
+
workspaceRoot: string;
|
|
263
|
+
ms: number;
|
|
264
|
+
neighbors: number;
|
|
256
265
|
} | {
|
|
257
266
|
type: "repo/open";
|
|
258
267
|
repoRoot: string;
|
|
@@ -267,11 +276,47 @@ type IndexerProgressEvent = {
|
|
|
267
276
|
type: "repo/index/file/start";
|
|
268
277
|
repoRoot: string;
|
|
269
278
|
path: string;
|
|
279
|
+
} | {
|
|
280
|
+
type: "repo/index/file/stage";
|
|
281
|
+
repoRoot: string;
|
|
282
|
+
path: string;
|
|
283
|
+
stage: "read" | "chunk" | "relations" | "synopsis" | "embed" | "store" | "symbols" | "graph" | "vector";
|
|
284
|
+
ms?: number;
|
|
270
285
|
} | {
|
|
271
286
|
type: "repo/index/file/skip";
|
|
272
287
|
repoRoot: string;
|
|
273
288
|
path: string;
|
|
274
289
|
reason: string;
|
|
290
|
+
} | {
|
|
291
|
+
type: "repo/index/file/embed/chunk";
|
|
292
|
+
repoRoot: string;
|
|
293
|
+
path: string;
|
|
294
|
+
chunkIndex: number;
|
|
295
|
+
chunksTotal: number;
|
|
296
|
+
kind: "chunk" | "synopsis";
|
|
297
|
+
startLine: number;
|
|
298
|
+
endLine: number;
|
|
299
|
+
cached: boolean;
|
|
300
|
+
} | {
|
|
301
|
+
type: "repo/index/file/embed/done";
|
|
302
|
+
repoRoot: string;
|
|
303
|
+
path: string;
|
|
304
|
+
chunks: number;
|
|
305
|
+
cached: number;
|
|
306
|
+
computed: number;
|
|
307
|
+
ms: number;
|
|
308
|
+
} | {
|
|
309
|
+
type: "repo/index/file/symbols/start";
|
|
310
|
+
repoRoot: string;
|
|
311
|
+
path: string;
|
|
312
|
+
providerId: string;
|
|
313
|
+
} | {
|
|
314
|
+
type: "repo/index/file/symbols";
|
|
315
|
+
repoRoot: string;
|
|
316
|
+
path: string;
|
|
317
|
+
symbols: number;
|
|
318
|
+
edges: number;
|
|
319
|
+
ms: number;
|
|
275
320
|
} | {
|
|
276
321
|
type: "repo/index/file/done";
|
|
277
322
|
repoRoot: string;
|
|
@@ -306,6 +351,17 @@ type IndexerProgressEvent = {
|
|
|
306
351
|
type: "repo/vector/flush";
|
|
307
352
|
repoRoot: string;
|
|
308
353
|
kind: string;
|
|
354
|
+
} | {
|
|
355
|
+
type: "repo/symbolGraph/expand/start";
|
|
356
|
+
repoRoot: string;
|
|
357
|
+
path: string;
|
|
358
|
+
} | {
|
|
359
|
+
type: "repo/symbolGraph/expand/done";
|
|
360
|
+
repoRoot: string;
|
|
361
|
+
path: string;
|
|
362
|
+
edges: number;
|
|
363
|
+
byKind?: Partial<Record<"definition" | "reference" | "implementation" | "typeDefinition", number>>;
|
|
364
|
+
ms: number;
|
|
309
365
|
} | {
|
|
310
366
|
type: "repo/watch/start";
|
|
311
367
|
repoRoot: string;
|
|
@@ -319,6 +375,17 @@ type IndexerProgressEvent = {
|
|
|
319
375
|
repoRoot: string;
|
|
320
376
|
fileCount: number;
|
|
321
377
|
ms: number;
|
|
378
|
+
} | {
|
|
379
|
+
type: "graph/neo4j/op/start";
|
|
380
|
+
op: string;
|
|
381
|
+
repoId?: string;
|
|
382
|
+
path?: string;
|
|
383
|
+
} | {
|
|
384
|
+
type: "graph/neo4j/op/done";
|
|
385
|
+
op: string;
|
|
386
|
+
repoId?: string;
|
|
387
|
+
path?: string;
|
|
388
|
+
ms: number;
|
|
322
389
|
} | {
|
|
323
390
|
type: "error";
|
|
324
391
|
scope: "workspace" | "repo";
|
|
@@ -984,6 +1051,7 @@ type Neo4jConfig = {
|
|
|
984
1051
|
password: string;
|
|
985
1052
|
database?: string;
|
|
986
1053
|
labelPrefix?: string;
|
|
1054
|
+
emit?: (e: IndexerProgressEvent) => void;
|
|
987
1055
|
};
|
|
988
1056
|
declare class Neo4jGraphStore implements GraphStore {
|
|
989
1057
|
private driver;
|
|
@@ -991,7 +1059,10 @@ declare class Neo4jGraphStore implements GraphStore {
|
|
|
991
1059
|
id: string;
|
|
992
1060
|
private labelPrefix;
|
|
993
1061
|
private schemaVersionLatest;
|
|
1062
|
+
private emitProgress;
|
|
994
1063
|
constructor(driver: Neo4jLikeDriver, cfg: Neo4jConfig);
|
|
1064
|
+
private opStart;
|
|
1065
|
+
private opDone;
|
|
995
1066
|
private labels;
|
|
996
1067
|
init(): Promise<void>;
|
|
997
1068
|
private getSchemaVersion;
|
package/dist/index.d.ts
CHANGED
|
@@ -253,6 +253,15 @@ type IndexerProgressEvent = {
|
|
|
253
253
|
lexical: number;
|
|
254
254
|
merged: number;
|
|
255
255
|
};
|
|
256
|
+
} | {
|
|
257
|
+
type: "workspace/retrieve/graph/start";
|
|
258
|
+
workspaceRoot: string;
|
|
259
|
+
seeds: number;
|
|
260
|
+
} | {
|
|
261
|
+
type: "workspace/retrieve/graph/done";
|
|
262
|
+
workspaceRoot: string;
|
|
263
|
+
ms: number;
|
|
264
|
+
neighbors: number;
|
|
256
265
|
} | {
|
|
257
266
|
type: "repo/open";
|
|
258
267
|
repoRoot: string;
|
|
@@ -267,11 +276,47 @@ type IndexerProgressEvent = {
|
|
|
267
276
|
type: "repo/index/file/start";
|
|
268
277
|
repoRoot: string;
|
|
269
278
|
path: string;
|
|
279
|
+
} | {
|
|
280
|
+
type: "repo/index/file/stage";
|
|
281
|
+
repoRoot: string;
|
|
282
|
+
path: string;
|
|
283
|
+
stage: "read" | "chunk" | "relations" | "synopsis" | "embed" | "store" | "symbols" | "graph" | "vector";
|
|
284
|
+
ms?: number;
|
|
270
285
|
} | {
|
|
271
286
|
type: "repo/index/file/skip";
|
|
272
287
|
repoRoot: string;
|
|
273
288
|
path: string;
|
|
274
289
|
reason: string;
|
|
290
|
+
} | {
|
|
291
|
+
type: "repo/index/file/embed/chunk";
|
|
292
|
+
repoRoot: string;
|
|
293
|
+
path: string;
|
|
294
|
+
chunkIndex: number;
|
|
295
|
+
chunksTotal: number;
|
|
296
|
+
kind: "chunk" | "synopsis";
|
|
297
|
+
startLine: number;
|
|
298
|
+
endLine: number;
|
|
299
|
+
cached: boolean;
|
|
300
|
+
} | {
|
|
301
|
+
type: "repo/index/file/embed/done";
|
|
302
|
+
repoRoot: string;
|
|
303
|
+
path: string;
|
|
304
|
+
chunks: number;
|
|
305
|
+
cached: number;
|
|
306
|
+
computed: number;
|
|
307
|
+
ms: number;
|
|
308
|
+
} | {
|
|
309
|
+
type: "repo/index/file/symbols/start";
|
|
310
|
+
repoRoot: string;
|
|
311
|
+
path: string;
|
|
312
|
+
providerId: string;
|
|
313
|
+
} | {
|
|
314
|
+
type: "repo/index/file/symbols";
|
|
315
|
+
repoRoot: string;
|
|
316
|
+
path: string;
|
|
317
|
+
symbols: number;
|
|
318
|
+
edges: number;
|
|
319
|
+
ms: number;
|
|
275
320
|
} | {
|
|
276
321
|
type: "repo/index/file/done";
|
|
277
322
|
repoRoot: string;
|
|
@@ -306,6 +351,17 @@ type IndexerProgressEvent = {
|
|
|
306
351
|
type: "repo/vector/flush";
|
|
307
352
|
repoRoot: string;
|
|
308
353
|
kind: string;
|
|
354
|
+
} | {
|
|
355
|
+
type: "repo/symbolGraph/expand/start";
|
|
356
|
+
repoRoot: string;
|
|
357
|
+
path: string;
|
|
358
|
+
} | {
|
|
359
|
+
type: "repo/symbolGraph/expand/done";
|
|
360
|
+
repoRoot: string;
|
|
361
|
+
path: string;
|
|
362
|
+
edges: number;
|
|
363
|
+
byKind?: Partial<Record<"definition" | "reference" | "implementation" | "typeDefinition", number>>;
|
|
364
|
+
ms: number;
|
|
309
365
|
} | {
|
|
310
366
|
type: "repo/watch/start";
|
|
311
367
|
repoRoot: string;
|
|
@@ -319,6 +375,17 @@ type IndexerProgressEvent = {
|
|
|
319
375
|
repoRoot: string;
|
|
320
376
|
fileCount: number;
|
|
321
377
|
ms: number;
|
|
378
|
+
} | {
|
|
379
|
+
type: "graph/neo4j/op/start";
|
|
380
|
+
op: string;
|
|
381
|
+
repoId?: string;
|
|
382
|
+
path?: string;
|
|
383
|
+
} | {
|
|
384
|
+
type: "graph/neo4j/op/done";
|
|
385
|
+
op: string;
|
|
386
|
+
repoId?: string;
|
|
387
|
+
path?: string;
|
|
388
|
+
ms: number;
|
|
322
389
|
} | {
|
|
323
390
|
type: "error";
|
|
324
391
|
scope: "workspace" | "repo";
|
|
@@ -984,6 +1051,7 @@ type Neo4jConfig = {
|
|
|
984
1051
|
password: string;
|
|
985
1052
|
database?: string;
|
|
986
1053
|
labelPrefix?: string;
|
|
1054
|
+
emit?: (e: IndexerProgressEvent) => void;
|
|
987
1055
|
};
|
|
988
1056
|
declare class Neo4jGraphStore implements GraphStore {
|
|
989
1057
|
private driver;
|
|
@@ -991,7 +1059,10 @@ declare class Neo4jGraphStore implements GraphStore {
|
|
|
991
1059
|
id: string;
|
|
992
1060
|
private labelPrefix;
|
|
993
1061
|
private schemaVersionLatest;
|
|
1062
|
+
private emitProgress;
|
|
994
1063
|
constructor(driver: Neo4jLikeDriver, cfg: Neo4jConfig);
|
|
1064
|
+
private opStart;
|
|
1065
|
+
private opDone;
|
|
995
1066
|
private labels;
|
|
996
1067
|
init(): Promise<void>;
|
|
997
1068
|
private getSchemaVersion;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuralsea/workspace-indexer",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Local-first multi-repo workspace indexer (semantic embeddings + git-aware incremental updates + hybrid retrieval profiles) for AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|