@inerrata-corporation/errata 2.0.21 → 2.0.22
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/consolidate-worker.mjs +443 -187
- package/errata.mjs +5927 -4472
- package/generalize-worker.mjs +17430 -0
- package/install.ps1 +1 -1
- package/package.json +2 -1
- package/pass-worker.mjs +3101 -2653
- package/resources/claude-mods/errata-minimap/.claude-plugin/plugin.json +2 -2
- package/resources/claude-mods/errata-minimap/hooks/bookcase.ts +450 -0
- package/resources/claude-mods/errata-minimap/hooks/chains.ts +427 -0
- package/resources/claude-mods/errata-minimap/hooks/graph.ts +349 -0
- package/resources/claude-mods/errata-minimap/hooks/minimap.ts +39 -351
- package/resources/claude-mods/errata-minimap/hooks/register.tsx +440 -148
- package/resources/claude-mods/errata-minimap/hooks/tags.ts +129 -0
- package/resources/claude-mods/errata-minimap/types/index.d.ts +42 -8
- package/resources/context-plugin/.codex-plugin/plugin.json +1 -1
- package/resources/context-plugin/SHA256SUMS +1 -1
package/consolidate-worker.mjs
CHANGED
|
@@ -594,6 +594,13 @@ function aliasRegex(alias) {
|
|
|
594
594
|
const body = escapeRe(alias).replace(/\\?\s+/g, "\\s+");
|
|
595
595
|
return new RegExp(`(?<![\\w-])${body}(?![\\w-])`, "i");
|
|
596
596
|
}
|
|
597
|
+
function withoutEntityMentions(text, entityId) {
|
|
598
|
+
let out = text;
|
|
599
|
+
for (const { entity, re } of COMPILED) {
|
|
600
|
+
if (entity.id === entityId) out = out.replace(new RegExp(re.source, "gi"), " ");
|
|
601
|
+
}
|
|
602
|
+
return out;
|
|
603
|
+
}
|
|
597
604
|
function prefilterEntities(text) {
|
|
598
605
|
const seen = /* @__PURE__ */ new Set();
|
|
599
606
|
const hits = [];
|
|
@@ -770,13 +777,19 @@ var init_concept_bag = __esm({
|
|
|
770
777
|
|
|
771
778
|
// ../../packages/shared/src/nlp/claim-id.ts
|
|
772
779
|
function claimStructure(text, scope) {
|
|
773
|
-
const
|
|
780
|
+
const extracted = prefilterEntities(text);
|
|
781
|
+
const entities = extracted.map((e) => e.id).sort();
|
|
774
782
|
const predicate = normalizePredicate(text);
|
|
775
783
|
const stance = detectStance(text);
|
|
776
784
|
const base = { entities, predicate, stance, scope: scope ?? {} };
|
|
777
|
-
if (predicate === ""
|
|
785
|
+
if (predicate === "" || entities.length === 0 || predicateIsTheEntity(text, extracted[0].id, entities.length)) {
|
|
786
|
+
base.raw = conceptBag(text);
|
|
787
|
+
}
|
|
778
788
|
return base;
|
|
779
789
|
}
|
|
790
|
+
function predicateIsTheEntity(text, entityId, entityCount) {
|
|
791
|
+
return entityCount === 1 && normalizePredicate(withoutEntityMentions(text, entityId)) === "";
|
|
792
|
+
}
|
|
780
793
|
function canonicalClaimId(text, scope) {
|
|
781
794
|
const s = claimStructure(text, scope);
|
|
782
795
|
return digest(
|
|
@@ -15242,6 +15255,36 @@ var init_history_evidence = __esm({
|
|
|
15242
15255
|
});
|
|
15243
15256
|
|
|
15244
15257
|
// ../../packages/shared/src/history-dependencies.ts
|
|
15258
|
+
function historyDependencyIdentity(raw) {
|
|
15259
|
+
const compact = compactDependencyIdentity(raw);
|
|
15260
|
+
if (compact !== void 0) return compact;
|
|
15261
|
+
const parsed = HistoryDependencyContextSchema.safeParse(raw);
|
|
15262
|
+
if (!parsed.success || !parsed.data.complete || parsed.data.conflict) return null;
|
|
15263
|
+
if (parsed.data.dependencies.some((d) => !exactHistoryDependencyVersion(d))) return null;
|
|
15264
|
+
return digest(parsed.data.dependencies.map((d) => [d.packageId, d.manifestId, d.side, d.declaredRange, d.resolvedVersion]).sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b))));
|
|
15265
|
+
}
|
|
15266
|
+
function exactHistoryDependencyVersion(d) {
|
|
15267
|
+
return d.resolvedVersion ?? (/^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(d.declaredRange ?? "") ? d.declaredRange : null);
|
|
15268
|
+
}
|
|
15269
|
+
function compactDependencyIdentity(raw) {
|
|
15270
|
+
if (!raw || typeof raw !== "object" || raw.compact !== true) return void 0;
|
|
15271
|
+
const identity = raw.identity;
|
|
15272
|
+
return typeof identity === "string" ? identity : null;
|
|
15273
|
+
}
|
|
15274
|
+
function compactHistoryQuality(quality) {
|
|
15275
|
+
const out = { ...quality };
|
|
15276
|
+
const context = quality["dependencyContext"];
|
|
15277
|
+
if (context !== void 0 && compactDependencyIdentity(context) === void 0) {
|
|
15278
|
+
const compact = { schemaVersion: "history-deps-1", compact: true, identity: historyDependencyIdentity(context) };
|
|
15279
|
+
out["dependencyContext"] = compact;
|
|
15280
|
+
}
|
|
15281
|
+
const evidence = quality["reconciliationEvidence"];
|
|
15282
|
+
if (evidence && typeof evidence === "object" && !Array.isArray(evidence)) {
|
|
15283
|
+
const build = evidence["build"];
|
|
15284
|
+
out["reconciliationEvidence"] = build === void 0 ? {} : { build };
|
|
15285
|
+
}
|
|
15286
|
+
return out;
|
|
15287
|
+
}
|
|
15245
15288
|
var version2, HistoryDependencySchema, HistoryDependencyContextSchema;
|
|
15246
15289
|
var init_history_dependencies = __esm({
|
|
15247
15290
|
"../../packages/shared/src/history-dependencies.ts"() {
|
|
@@ -15726,10 +15769,12 @@ var init_history_quality = __esm({
|
|
|
15726
15769
|
});
|
|
15727
15770
|
|
|
15728
15771
|
// ../../packages/shared/src/history-read.ts
|
|
15772
|
+
var CLOUD_ATTR_DUPLICATE_KEYS;
|
|
15729
15773
|
var init_history_read = __esm({
|
|
15730
15774
|
"../../packages/shared/src/history-read.ts"() {
|
|
15731
15775
|
"use strict";
|
|
15732
15776
|
init_history_dependencies();
|
|
15777
|
+
CLOUD_ATTR_DUPLICATE_KEYS = ["attrsJson", "embedding"];
|
|
15733
15778
|
}
|
|
15734
15779
|
});
|
|
15735
15780
|
|
|
@@ -16396,7 +16441,275 @@ function installEditPlaceholderRetirement(db) {
|
|
|
16396
16441
|
});
|
|
16397
16442
|
}
|
|
16398
16443
|
|
|
16444
|
+
// ../../packages/local-graph/src/cloud-attr-compaction.ts
|
|
16445
|
+
init_src2();
|
|
16446
|
+
var CLOUD_ATTR_COMPACTION_KEY = "cloud-attr-compaction-1";
|
|
16447
|
+
var DUPES = CLOUD_ATTR_DUPLICATE_KEYS.map((k) => `'${k}'`).join(",");
|
|
16448
|
+
function compacted(row) {
|
|
16449
|
+
const packed = `json_extract(${row}.attrs_json, '$.attrsJson')`;
|
|
16450
|
+
const nested = `CASE WHEN json_type(${row}.attrs_json, '$.attrsJson') = 'text' AND json_valid(${packed})
|
|
16451
|
+
AND json_type(${packed}) = 'object' THEN ${packed} ELSE '{}' END`;
|
|
16452
|
+
const value = `CASE WHEN type IN ('array','object') THEN json(value) WHEN type IN ('true','false') THEN json(type) ELSE value END`;
|
|
16453
|
+
return `(SELECT json_group_object(key, ${value}) FROM (
|
|
16454
|
+
SELECT key, value, type, min(pri) FROM (
|
|
16455
|
+
SELECT key, value, type, 0 AS pri FROM json_each(${row}.attrs_json)
|
|
16456
|
+
UNION ALL
|
|
16457
|
+
SELECT key, value, type, 1 AS pri FROM json_each(${nested})
|
|
16458
|
+
) WHERE key NOT IN (${DUPES}) GROUP BY key))`;
|
|
16459
|
+
}
|
|
16460
|
+
function dirty(row) {
|
|
16461
|
+
const has = CLOUD_ATTR_DUPLICATE_KEYS.map((k) => `json_type(${row}.attrs_json, '$.${k}') IS NOT NULL`).join(" OR ");
|
|
16462
|
+
return `json_extract(${row}.attrs_json, '$.source') = 'cloud' AND (${has})`;
|
|
16463
|
+
}
|
|
16464
|
+
function installCloudAttrCompaction(db) {
|
|
16465
|
+
if (db.prepare("SELECT value FROM store_meta WHERE key = ?").get(CLOUD_ATTR_COMPACTION_KEY)) return;
|
|
16466
|
+
db.transaction(() => {
|
|
16467
|
+
for (const operation of ["INSERT", "UPDATE"]) {
|
|
16468
|
+
db.exec(`CREATE TRIGGER IF NOT EXISTS cloud_attr_compact_${operation.toLowerCase()}
|
|
16469
|
+
AFTER ${operation} ON nodes WHEN ${dirty("NEW")}
|
|
16470
|
+
BEGIN UPDATE nodes SET attrs_json = ${compacted("nodes")} WHERE id = NEW.id; END;`);
|
|
16471
|
+
}
|
|
16472
|
+
db.exec(`UPDATE nodes SET attrs_json = ${compacted("nodes")} WHERE ${dirty("nodes")}`);
|
|
16473
|
+
db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(CLOUD_ATTR_COMPACTION_KEY, "installed");
|
|
16474
|
+
});
|
|
16475
|
+
}
|
|
16476
|
+
|
|
16477
|
+
// ../../packages/local-graph/src/history-attr-slim.ts
|
|
16478
|
+
init_src();
|
|
16479
|
+
var HISTORY_ATTR_SLIM_KEY = "history-attr-slim-1";
|
|
16480
|
+
var SLIM_BATCH = 500;
|
|
16481
|
+
function installHistoryAttrSlim(db) {
|
|
16482
|
+
if (db.prepare("SELECT value FROM store_meta WHERE key = ?").get(HISTORY_ATTR_SLIM_KEY)) return;
|
|
16483
|
+
const select = db.prepare(`SELECT rowid AS rid, json_extract(attrs_json, '$.historyQuality') AS q FROM nodes
|
|
16484
|
+
WHERE rowid > ? AND (json_type(attrs_json, '$.historyQuality.dependencyContext.dependencies') IS NOT NULL
|
|
16485
|
+
OR json_type(attrs_json, '$.historyQuality.reconciliationEvidence') = 'object')
|
|
16486
|
+
ORDER BY rowid LIMIT ${SLIM_BATCH}`);
|
|
16487
|
+
const write = db.prepare(`UPDATE nodes SET attrs_json = json_set(attrs_json, '$.historyQuality', json(?)) WHERE rowid = ?`);
|
|
16488
|
+
let after = 0;
|
|
16489
|
+
for (; ; ) {
|
|
16490
|
+
const rows = select.all(after);
|
|
16491
|
+
if (rows.length === 0) break;
|
|
16492
|
+
db.transaction(() => {
|
|
16493
|
+
for (const { rid, q } of rows) {
|
|
16494
|
+
if (!q) continue;
|
|
16495
|
+
let quality;
|
|
16496
|
+
try {
|
|
16497
|
+
quality = JSON.parse(q);
|
|
16498
|
+
} catch {
|
|
16499
|
+
continue;
|
|
16500
|
+
}
|
|
16501
|
+
if (!quality || typeof quality !== "object" || Array.isArray(quality)) continue;
|
|
16502
|
+
const slim = JSON.stringify(compactHistoryQuality(quality));
|
|
16503
|
+
if (slim !== q) write.run(slim, rid);
|
|
16504
|
+
}
|
|
16505
|
+
});
|
|
16506
|
+
after = rows[rows.length - 1].rid;
|
|
16507
|
+
}
|
|
16508
|
+
db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(HISTORY_ATTR_SLIM_KEY, "done");
|
|
16509
|
+
}
|
|
16510
|
+
|
|
16511
|
+
// ../../packages/math/src/constants.ts
|
|
16512
|
+
var NEMORI_DEDUP_COSINE = 0.88;
|
|
16513
|
+
|
|
16514
|
+
// ../../packages/math/src/triage.ts
|
|
16515
|
+
var TRIAGE_GLOBAL_BUCKET = "*";
|
|
16516
|
+
function triageContextBuckets(ctx) {
|
|
16517
|
+
const out = [];
|
|
16518
|
+
for (const s of ctx.stack ?? []) {
|
|
16519
|
+
const t = s.trim().toLowerCase();
|
|
16520
|
+
if (t) out.push(`stack:${t}`);
|
|
16521
|
+
}
|
|
16522
|
+
const domains = Array.isArray(ctx.domain) ? ctx.domain : typeof ctx.domain === "string" ? [ctx.domain] : [];
|
|
16523
|
+
for (const d of domains) {
|
|
16524
|
+
const t = d.trim().toLowerCase();
|
|
16525
|
+
if (t) out.push(`domain:${t}`);
|
|
16526
|
+
}
|
|
16527
|
+
return out;
|
|
16528
|
+
}
|
|
16529
|
+
|
|
16530
|
+
// ../../packages/math/src/relevance.ts
|
|
16531
|
+
function pageRankScale(ranks) {
|
|
16532
|
+
const positive = [...ranks].filter((r) => Number.isFinite(r) && r > 0).sort((a, b) => a - b);
|
|
16533
|
+
return positive.length ? Math.max(1e-9, positive[Math.floor((positive.length - 1) * 0.95)]) : 1;
|
|
16534
|
+
}
|
|
16535
|
+
|
|
16536
|
+
// ../../packages/math/src/leiden.ts
|
|
16537
|
+
function buildGraph(nodeIds, adj) {
|
|
16538
|
+
const nbr = /* @__PURE__ */ new Map();
|
|
16539
|
+
const deg = /* @__PURE__ */ new Map();
|
|
16540
|
+
const present = new Set(nodeIds);
|
|
16541
|
+
for (const id of nodeIds) {
|
|
16542
|
+
nbr.set(id, /* @__PURE__ */ new Map());
|
|
16543
|
+
deg.set(id, 0);
|
|
16544
|
+
}
|
|
16545
|
+
let m2 = 0;
|
|
16546
|
+
for (const id of nodeIds) {
|
|
16547
|
+
for (const { to, weight } of adj.get(id) ?? []) {
|
|
16548
|
+
if (!present.has(to)) continue;
|
|
16549
|
+
const row = nbr.get(id);
|
|
16550
|
+
row.set(to, (row.get(to) ?? 0) + weight);
|
|
16551
|
+
deg.set(id, (deg.get(id) ?? 0) + weight);
|
|
16552
|
+
m2 += weight;
|
|
16553
|
+
}
|
|
16554
|
+
}
|
|
16555
|
+
return { nbr, deg, m2 };
|
|
16556
|
+
}
|
|
16557
|
+
function localMoving(nodeIds, g) {
|
|
16558
|
+
const community = new Map(nodeIds.map((n) => [n, n]));
|
|
16559
|
+
const comTot = new Map(nodeIds.map((n) => [n, g.deg.get(n) ?? 0]));
|
|
16560
|
+
const order = [...nodeIds].sort();
|
|
16561
|
+
const m2 = g.m2 > 0 ? g.m2 : 1;
|
|
16562
|
+
let improved = true;
|
|
16563
|
+
let iter = 0;
|
|
16564
|
+
while (improved && iter < 100) {
|
|
16565
|
+
improved = false;
|
|
16566
|
+
iter++;
|
|
16567
|
+
for (const node of order) {
|
|
16568
|
+
const ci = community.get(node);
|
|
16569
|
+
const ki = g.deg.get(node) ?? 0;
|
|
16570
|
+
comTot.set(ci, (comTot.get(ci) ?? 0) - ki);
|
|
16571
|
+
const wToComm = /* @__PURE__ */ new Map();
|
|
16572
|
+
for (const [nb, w] of g.nbr.get(node) ?? []) {
|
|
16573
|
+
if (nb === node) continue;
|
|
16574
|
+
const c = community.get(nb);
|
|
16575
|
+
wToComm.set(c, (wToComm.get(c) ?? 0) + w);
|
|
16576
|
+
}
|
|
16577
|
+
let bestC = ci;
|
|
16578
|
+
let bestGain = (wToComm.get(ci) ?? 0) - (comTot.get(ci) ?? 0) * ki / m2;
|
|
16579
|
+
for (const [c, kiIn] of [...wToComm.entries()].sort(
|
|
16580
|
+
(a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0
|
|
16581
|
+
)) {
|
|
16582
|
+
const gain = kiIn - (comTot.get(c) ?? 0) * ki / m2;
|
|
16583
|
+
if (gain > bestGain) {
|
|
16584
|
+
bestGain = gain;
|
|
16585
|
+
bestC = c;
|
|
16586
|
+
}
|
|
16587
|
+
}
|
|
16588
|
+
community.set(node, bestC);
|
|
16589
|
+
comTot.set(bestC, (comTot.get(bestC) ?? 0) + ki);
|
|
16590
|
+
if (bestC !== ci) improved = true;
|
|
16591
|
+
}
|
|
16592
|
+
}
|
|
16593
|
+
return community;
|
|
16594
|
+
}
|
|
16595
|
+
function refineConnectivity(community, g) {
|
|
16596
|
+
const members = /* @__PURE__ */ new Map();
|
|
16597
|
+
for (const [id, c] of community) {
|
|
16598
|
+
const l = members.get(c) ?? [];
|
|
16599
|
+
l.push(id);
|
|
16600
|
+
members.set(c, l);
|
|
16601
|
+
}
|
|
16602
|
+
const refined = /* @__PURE__ */ new Map();
|
|
16603
|
+
for (const [, group] of members) {
|
|
16604
|
+
const inGroup = new Set(group);
|
|
16605
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16606
|
+
for (const start of [...group].sort()) {
|
|
16607
|
+
if (seen.has(start)) continue;
|
|
16608
|
+
const comp = [];
|
|
16609
|
+
const stack = [start];
|
|
16610
|
+
seen.add(start);
|
|
16611
|
+
while (stack.length) {
|
|
16612
|
+
const cur = stack.pop();
|
|
16613
|
+
comp.push(cur);
|
|
16614
|
+
for (const [nb] of g.nbr.get(cur) ?? []) {
|
|
16615
|
+
if (inGroup.has(nb) && !seen.has(nb)) {
|
|
16616
|
+
seen.add(nb);
|
|
16617
|
+
stack.push(nb);
|
|
16618
|
+
}
|
|
16619
|
+
}
|
|
16620
|
+
}
|
|
16621
|
+
const anchor = [...comp].sort()[0];
|
|
16622
|
+
for (const id of comp) refined.set(id, anchor);
|
|
16623
|
+
}
|
|
16624
|
+
}
|
|
16625
|
+
return refined;
|
|
16626
|
+
}
|
|
16627
|
+
function normalize(assignment) {
|
|
16628
|
+
const groups = /* @__PURE__ */ new Map();
|
|
16629
|
+
for (const [id, c] of assignment) {
|
|
16630
|
+
const l = groups.get(c) ?? [];
|
|
16631
|
+
l.push(id);
|
|
16632
|
+
groups.set(c, l);
|
|
16633
|
+
}
|
|
16634
|
+
const community = /* @__PURE__ */ new Map();
|
|
16635
|
+
for (const grp of groups.values()) {
|
|
16636
|
+
const anchor = [...grp].sort()[0];
|
|
16637
|
+
const cid = `community_${anchor}`;
|
|
16638
|
+
for (const m of grp) community.set(m, cid);
|
|
16639
|
+
}
|
|
16640
|
+
return { community, count: groups.size, iterations: 1 };
|
|
16641
|
+
}
|
|
16642
|
+
function causalComponents(nodeIds, pairs) {
|
|
16643
|
+
const parent = new Map(nodeIds.map((n) => [n, n]));
|
|
16644
|
+
const find = (x) => {
|
|
16645
|
+
let r = x;
|
|
16646
|
+
while (parent.get(r) !== r) r = parent.get(r);
|
|
16647
|
+
let c = x;
|
|
16648
|
+
while (parent.get(c) !== r) {
|
|
16649
|
+
const next = parent.get(c);
|
|
16650
|
+
parent.set(c, r);
|
|
16651
|
+
c = next;
|
|
16652
|
+
}
|
|
16653
|
+
return r;
|
|
16654
|
+
};
|
|
16655
|
+
for (const [a, b] of pairs) {
|
|
16656
|
+
const ra = find(a);
|
|
16657
|
+
const rb = find(b);
|
|
16658
|
+
if (ra !== rb) parent.set(ra < rb ? rb : ra, ra < rb ? ra : rb);
|
|
16659
|
+
}
|
|
16660
|
+
return find;
|
|
16661
|
+
}
|
|
16662
|
+
function detectCommunitiesLeiden(input, opts = {}) {
|
|
16663
|
+
const idSet = new Set(input.nodeIds);
|
|
16664
|
+
const protect = [...opts.protect ?? []].filter(
|
|
16665
|
+
([a, b]) => a !== b && idSet.has(a) && idSet.has(b)
|
|
16666
|
+
);
|
|
16667
|
+
if (protect.length === 0) {
|
|
16668
|
+
const g = buildGraph(input.nodeIds, input.adj);
|
|
16669
|
+
return normalize(refineConnectivity(localMoving(input.nodeIds, g), g));
|
|
16670
|
+
}
|
|
16671
|
+
const rep = causalComponents(input.nodeIds, protect);
|
|
16672
|
+
const superIds = [...new Set(input.nodeIds.map(rep))];
|
|
16673
|
+
const superAdj = /* @__PURE__ */ new Map();
|
|
16674
|
+
const acc = /* @__PURE__ */ new Map();
|
|
16675
|
+
for (const id of input.nodeIds) {
|
|
16676
|
+
const ra = rep(id);
|
|
16677
|
+
for (const { to, weight } of input.adj.get(id) ?? []) {
|
|
16678
|
+
if (!idSet.has(to)) continue;
|
|
16679
|
+
const rb = rep(to);
|
|
16680
|
+
if (ra === rb) continue;
|
|
16681
|
+
const row = acc.get(ra) ?? /* @__PURE__ */ new Map();
|
|
16682
|
+
row.set(rb, (row.get(rb) ?? 0) + weight);
|
|
16683
|
+
acc.set(ra, row);
|
|
16684
|
+
}
|
|
16685
|
+
}
|
|
16686
|
+
for (const [a, row] of acc) superAdj.set(a, [...row].map(([to, weight]) => ({ to, weight })));
|
|
16687
|
+
const sg = buildGraph(superIds, superAdj);
|
|
16688
|
+
const superComm = refineConnectivity(localMoving(superIds, sg), sg);
|
|
16689
|
+
const assignment = /* @__PURE__ */ new Map();
|
|
16690
|
+
for (const id of input.nodeIds) assignment.set(id, superComm.get(rep(id)) ?? rep(id));
|
|
16691
|
+
return normalize(assignment);
|
|
16692
|
+
}
|
|
16693
|
+
|
|
16694
|
+
// ../../packages/math/src/void-demand.ts
|
|
16695
|
+
var DEMAND_HOT = Math.log1p(10);
|
|
16696
|
+
var DEMAND_WARM = Math.log1p(5);
|
|
16697
|
+
|
|
16399
16698
|
// ../../packages/local-graph/src/store.ts
|
|
16699
|
+
var PAGE_RANK_SCALE_KEY = "pageRankScale.p95.v1";
|
|
16700
|
+
var TEXT_SEARCH_COLUMNS = `id, label, description, page_rank,
|
|
16701
|
+
json_object('test', json(CASE WHEN json_type(attrs_json, '$.test') = 'true' THEN 'true' ELSE 'false' END),
|
|
16702
|
+
'relPath', json_extract(attrs_json, '$.relPath'),
|
|
16703
|
+
'resolutionSuspect', json(CASE WHEN json_type(attrs_json, '$.resolutionSuspect') = 'true' THEN 'true' ELSE 'false' END),
|
|
16704
|
+
'resolvedAt', json_extract(attrs_json, '$.resolvedAt'),
|
|
16705
|
+
'refutedAt', json_extract(attrs_json, '$.refutedAt'),
|
|
16706
|
+
'refuteReasons', json_extract(attrs_json, '$.refuteReasons'),
|
|
16707
|
+
'reopenedFrom', json_extract(attrs_json, '$.reopenedFrom'),
|
|
16708
|
+
'resolvedAs', json_extract(attrs_json, '$.resolvedAs')) AS search_attrs`;
|
|
16709
|
+
function textSearchNode(row) {
|
|
16710
|
+
const attrs = JSON.parse(row.search_attrs);
|
|
16711
|
+
return { id: row.id, label: row.label, description: row.description, pageRank: row.page_rank, attrs };
|
|
16712
|
+
}
|
|
16400
16713
|
var LOCAL_RULE_OVERRIDES = {
|
|
16401
16714
|
ANCHORED_AT: {
|
|
16402
16715
|
from: EDGE_RULES["ANCHORED_AT"]?.from,
|
|
@@ -16540,6 +16853,9 @@ CREATE INDEX IF NOT EXISTS edges_session_evidence ON edges(id) WHERE ${SESSION_E
|
|
|
16540
16853
|
DROP INDEX IF EXISTS nodes_live_fingerprint;
|
|
16541
16854
|
DROP INDEX IF EXISTS nodes_instance_fingerprint;
|
|
16542
16855
|
CREATE INDEX IF NOT EXISTS nodes_instance_fingerprint_v2 ON nodes(label, last_updated_at, last_reinforced_at_seq, created_at_seq) WHERE valid_to IS NULL AND label IN ('Problem','Vulnerability','Solution','RootCause');
|
|
16856
|
+
-- Calibrate rank from a covering scalar index; the global page-rank index
|
|
16857
|
+
-- requires a table lookup per node to exclude frozen versions.
|
|
16858
|
+
CREATE INDEX IF NOT EXISTS nodes_live_page_rank ON nodes(valid_to, page_rank);
|
|
16543
16859
|
CREATE INDEX IF NOT EXISTS nodes_logical ON nodes(logical_id, version);
|
|
16544
16860
|
CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
16545
16861
|
-- Expression index on the per-node relPath (stored in attrs_json) so the
|
|
@@ -16552,6 +16868,16 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
16552
16868
|
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
16553
16869
|
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
16554
16870
|
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
16871
|
+
-- Problems by the command / checker / file that opened them. The generalizer
|
|
16872
|
+
-- looked these up per shell or tool EVENT by hydrating every Problem: ~12s of
|
|
16873
|
+
-- every minute of daemon main-thread time on a 3.4k-Problem store (2026-10-05).
|
|
16874
|
+
CREATE INDEX IF NOT EXISTS nodes_command_signature ON nodes(json_extract(attrs_json, '$.commandSignature')) WHERE valid_to IS NULL;
|
|
16875
|
+
CREATE INDEX IF NOT EXISTS nodes_diag_command ON nodes(json_extract(attrs_json, '$.diagCommand')) WHERE valid_to IS NULL;
|
|
16876
|
+
CREATE INDEX IF NOT EXISTS nodes_lsp_rel_path ON nodes(json_extract(attrs_json, '$.lspRelPath')) WHERE valid_to IS NULL;
|
|
16877
|
+
-- Local nodes by the cloud twin their upload receipt recorded. Every burst /
|
|
16878
|
+
-- search fusion folds the Network copy of the caller's own knowledge back onto
|
|
16879
|
+
-- the local node; unindexed, the reverse lookup was a ~300ms attrs scan per call.
|
|
16880
|
+
CREATE INDEX IF NOT EXISTS nodes_cloud_node_id ON nodes(json_extract(attrs_json, '$.cloudNodeId')) WHERE valid_to IS NULL;
|
|
16555
16881
|
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
16556
16882
|
-- tool response (the enrichment piggyback), so it must not parse every
|
|
16557
16883
|
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
@@ -16638,6 +16964,7 @@ var SqliteGraphStore = class {
|
|
|
16638
16964
|
* ALL upserts incl. code reindex) — this counter is the knowledge-arrival axis
|
|
16639
16965
|
* Δseq is measured over, so code reindex churn must NOT advance it. */
|
|
16640
16966
|
ingestSeq = 0;
|
|
16967
|
+
initialPageRankScale;
|
|
16641
16968
|
constructor(opts) {
|
|
16642
16969
|
this.db = openDatabase(opts.path);
|
|
16643
16970
|
this.db.exec(SCHEMA_SQL);
|
|
@@ -16654,6 +16981,8 @@ var SqliteGraphStore = class {
|
|
|
16654
16981
|
this.db.exec(TEMPORAL_INDEX_SQL);
|
|
16655
16982
|
installHistoryCacheFloor(this.db);
|
|
16656
16983
|
installEditPlaceholderRetirement(this.db);
|
|
16984
|
+
installCloudAttrCompaction(this.db);
|
|
16985
|
+
installHistoryAttrSlim(this.db);
|
|
16657
16986
|
if (!this.db.prepare("SELECT value FROM store_meta WHERE key = ?").get(SESSION_REPAIR_KEY)) {
|
|
16658
16987
|
this.db.transaction(() => {
|
|
16659
16988
|
this.repairSessionAliases();
|
|
@@ -16705,6 +17034,12 @@ var SqliteGraphStore = class {
|
|
|
16705
17034
|
setPageRank: this.db.prepare("UPDATE nodes SET page_rank = :v WHERE id = :id"),
|
|
16706
17035
|
setLandmark: this.db.prepare("UPDATE nodes SET is_landmark = :v WHERE id = :id"),
|
|
16707
17036
|
setCommunity: this.db.prepare("UPDATE nodes SET community = :v WHERE id = :id"),
|
|
17037
|
+
setLocalCommunity: this.db.prepare(`
|
|
17038
|
+
UPDATE nodes SET
|
|
17039
|
+
attrs_json = CASE WHEN :v IS NULL THEN json_remove(attrs_json, '$.localCommunity')
|
|
17040
|
+
ELSE json_set(attrs_json, '$.localCommunity', :v) END,
|
|
17041
|
+
community = CASE WHEN :col = 1 THEN :v ELSE community END
|
|
17042
|
+
WHERE id = :id`),
|
|
16708
17043
|
updateNode: this.db.prepare(`
|
|
16709
17044
|
UPDATE nodes SET
|
|
16710
17045
|
description = COALESCE(:description, description),
|
|
@@ -17025,6 +17360,36 @@ var SqliteGraphStore = class {
|
|
|
17025
17360
|
setLandmark(id, isLandmark) {
|
|
17026
17361
|
this.stmts.setLandmark.run({ id, v: isLandmark ? 1 : 0 });
|
|
17027
17362
|
}
|
|
17363
|
+
setLocalCommunity(id, community, column) {
|
|
17364
|
+
this.stmts.setLocalCommunity.run({ id, v: community, col: column ? 1 : 0 });
|
|
17365
|
+
}
|
|
17366
|
+
fieldStmts = /* @__PURE__ */ new Map();
|
|
17367
|
+
findNodeFieldsByLabel(label, attrKeys) {
|
|
17368
|
+
for (const k of attrKeys) if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(k)) throw new Error(`findNodeFieldsByLabel: bad attr key ${k}`);
|
|
17369
|
+
const cacheKey = attrKeys.join(",");
|
|
17370
|
+
let stmt = this.fieldStmts.get(cacheKey);
|
|
17371
|
+
if (!stmt) {
|
|
17372
|
+
const cols = attrKeys.map((k, i) => `, json_extract(attrs_json, '$.${k}') AS a${i}`).join("");
|
|
17373
|
+
stmt = this.db.prepare(
|
|
17374
|
+
`SELECT id, description, community, extraction_confidence${cols} FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
17375
|
+
);
|
|
17376
|
+
this.fieldStmts.set(cacheKey, stmt);
|
|
17377
|
+
}
|
|
17378
|
+
return stmt.all(label).map((r) => {
|
|
17379
|
+
const attrs = {};
|
|
17380
|
+
attrKeys.forEach((k, i) => {
|
|
17381
|
+
const v = r[`a${i}`];
|
|
17382
|
+
if (v !== null && v !== void 0) attrs[k] = v;
|
|
17383
|
+
});
|
|
17384
|
+
return {
|
|
17385
|
+
id: r["id"],
|
|
17386
|
+
description: r["description"] ?? "",
|
|
17387
|
+
community: r["community"] ?? null,
|
|
17388
|
+
extractionConfidence: r["extraction_confidence"],
|
|
17389
|
+
attrs
|
|
17390
|
+
};
|
|
17391
|
+
});
|
|
17392
|
+
}
|
|
17028
17393
|
setCommunity(id, community) {
|
|
17029
17394
|
this.stmts.setCommunity.run({ id, v: community });
|
|
17030
17395
|
}
|
|
@@ -17151,6 +17516,19 @@ var SqliteGraphStore = class {
|
|
|
17151
17516
|
* read attrs and never the vector. `findNodesByLabel` decodes every embedding
|
|
17152
17517
|
* blob; the liveness watch's coverage pass spent 3.4s of a 4.3s main-thread
|
|
17153
17518
|
* hold doing exactly that on a 227k-node store (2026-09-24). */
|
|
17519
|
+
findNodeStampsByLabel(label, attrKey) {
|
|
17520
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(attrKey)) throw new Error(`findNodeStampsByLabel: bad attr key ${attrKey}`);
|
|
17521
|
+
const rows = this.db.prepare(
|
|
17522
|
+
`SELECT id, created_at, created_at_seq, json_type(attrs_json, '$.${attrKey}') IS NOT NULL AS has
|
|
17523
|
+
FROM nodes WHERE label = ? AND valid_to IS NULL`
|
|
17524
|
+
).all(label);
|
|
17525
|
+
return rows.map((r) => ({
|
|
17526
|
+
id: r.id,
|
|
17527
|
+
createdAt: r.created_at,
|
|
17528
|
+
...r.created_at_seq != null ? { createdAtSeq: r.created_at_seq } : {},
|
|
17529
|
+
has: r.has === 1
|
|
17530
|
+
}));
|
|
17531
|
+
}
|
|
17154
17532
|
findNodeAttrsByLabel(label) {
|
|
17155
17533
|
const rows = this.stmts.attrsByLabel.all(label);
|
|
17156
17534
|
return rows.map((r) => ({
|
|
@@ -17257,6 +17635,34 @@ var SqliteGraphStore = class {
|
|
|
17257
17635
|
).all(...terms.map((t) => `%${t}%`), Math.max(1, limit));
|
|
17258
17636
|
return rows.map((r) => ({ node: rowToNode(r), matched: Number(r.matched) }));
|
|
17259
17637
|
}
|
|
17638
|
+
searchTextCandidates(terms) {
|
|
17639
|
+
if (terms.length === 0) return [];
|
|
17640
|
+
const rows = this.db.prepare(`WITH matches AS MATERIALIZED (
|
|
17641
|
+
SELECT n.id, COUNT(*) AS matched FROM nodes n INDEXED BY nodes_live_description, json_each(:terms) t
|
|
17642
|
+
WHERE n.valid_to IS NULL AND n.description LIKE '%' || t.value || '%'
|
|
17643
|
+
GROUP BY n.id
|
|
17644
|
+
) SELECT ${TEXT_SEARCH_COLUMNS}, matches.matched FROM nodes
|
|
17645
|
+
JOIN matches USING (id) ORDER BY page_rank DESC, last_updated_at DESC`).all({ terms: JSON.stringify(terms) });
|
|
17646
|
+
return rows.map((row) => ({ node: textSearchNode(row), matched: row.matched }));
|
|
17647
|
+
}
|
|
17648
|
+
getTextSearchNode(id) {
|
|
17649
|
+
const row = this.db.prepare(`SELECT ${TEXT_SEARCH_COLUMNS} FROM nodes WHERE id = ? AND valid_to IS NULL`).get(id);
|
|
17650
|
+
return row ? textSearchNode(row) : null;
|
|
17651
|
+
}
|
|
17652
|
+
readPageRankScale() {
|
|
17653
|
+
const rows = this.db.prepare("SELECT page_rank FROM nodes WHERE valid_to IS NULL AND page_rank > 0").all();
|
|
17654
|
+
return pageRankScale(rows.map((row) => row.page_rank));
|
|
17655
|
+
}
|
|
17656
|
+
pageRankScale() {
|
|
17657
|
+
const value = Number(this.getMeta(PAGE_RANK_SCALE_KEY));
|
|
17658
|
+
if (Number.isFinite(value) && value > 0) return value;
|
|
17659
|
+
return this.initialPageRankScale ??= this.readPageRankScale();
|
|
17660
|
+
}
|
|
17661
|
+
refreshPageRankScale() {
|
|
17662
|
+
const scale = this.readPageRankScale();
|
|
17663
|
+
this.setMeta(PAGE_RANK_SCALE_KEY, String(scale));
|
|
17664
|
+
return scale;
|
|
17665
|
+
}
|
|
17260
17666
|
typedEdgeStmt(sql) {
|
|
17261
17667
|
let stmt = this.typedEdgeStmts.get(sql);
|
|
17262
17668
|
if (!stmt) {
|
|
@@ -17491,6 +17897,19 @@ var SqliteGraphStore = class {
|
|
|
17491
17897
|
).get(attr, `%${marker}%`, limit);
|
|
17492
17898
|
return { count: Number(r.count), total: Number(r.total) };
|
|
17493
17899
|
}
|
|
17900
|
+
liveNodeIdsByCloudNodeId(cloudIds) {
|
|
17901
|
+
const out = /* @__PURE__ */ new Map();
|
|
17902
|
+
const CHUNK = 900;
|
|
17903
|
+
for (let i = 0; i < cloudIds.length; i += CHUNK) {
|
|
17904
|
+
const slice = cloudIds.slice(i, i + CHUNK);
|
|
17905
|
+
if (slice.length === 0) continue;
|
|
17906
|
+
const rows = this.db.prepare(
|
|
17907
|
+
`SELECT id, json_extract(attrs_json, '$.cloudNodeId') AS cloud FROM nodes INDEXED BY nodes_cloud_node_id WHERE json_extract(attrs_json, '$.cloudNodeId') IN (${slice.map(() => "?").join(",")}) AND valid_to IS NULL ORDER BY id`
|
|
17908
|
+
).all(...slice);
|
|
17909
|
+
for (const r of rows) out.set(r.cloud, [...out.get(r.cloud) ?? [], r.id]);
|
|
17910
|
+
}
|
|
17911
|
+
return out;
|
|
17912
|
+
}
|
|
17494
17913
|
liveNodeIds(ids) {
|
|
17495
17914
|
const live = /* @__PURE__ */ new Set();
|
|
17496
17915
|
const CHUNK = 900;
|
|
@@ -17552,7 +17971,10 @@ var SqliteGraphStore = class {
|
|
|
17552
17971
|
if (relPaths.length === 0) return [];
|
|
17553
17972
|
const placeholders = relPaths.map(() => "?").join(",");
|
|
17554
17973
|
const rows = this.db.prepare(
|
|
17555
|
-
|
|
17974
|
+
// INDEXED BY: unforced, the planner took nodes_live_page_rank and
|
|
17975
|
+
// json-parsed every live row — 11–25s per reindexed file pair on the
|
|
17976
|
+
// live store vs 7ms here (2026-10-08).
|
|
17977
|
+
`SELECT * FROM nodes INDEXED BY nodes_relpath WHERE valid_to IS NULL AND json_extract(attrs_json, '$.relPath') IN (${placeholders})`
|
|
17556
17978
|
).all(...relPaths);
|
|
17557
17979
|
return rows.map(rowToNode);
|
|
17558
17980
|
}
|
|
@@ -17802,183 +18224,6 @@ function percolate(l1, l2, opts) {
|
|
|
17802
18224
|
init_src();
|
|
17803
18225
|
init_src2();
|
|
17804
18226
|
|
|
17805
|
-
// ../../packages/math/src/constants.ts
|
|
17806
|
-
var NEMORI_DEDUP_COSINE = 0.88;
|
|
17807
|
-
|
|
17808
|
-
// ../../packages/math/src/triage.ts
|
|
17809
|
-
var TRIAGE_GLOBAL_BUCKET = "*";
|
|
17810
|
-
function triageContextBuckets(ctx) {
|
|
17811
|
-
const out = [];
|
|
17812
|
-
for (const s of ctx.stack ?? []) {
|
|
17813
|
-
const t = s.trim().toLowerCase();
|
|
17814
|
-
if (t) out.push(`stack:${t}`);
|
|
17815
|
-
}
|
|
17816
|
-
const domains = Array.isArray(ctx.domain) ? ctx.domain : typeof ctx.domain === "string" ? [ctx.domain] : [];
|
|
17817
|
-
for (const d of domains) {
|
|
17818
|
-
const t = d.trim().toLowerCase();
|
|
17819
|
-
if (t) out.push(`domain:${t}`);
|
|
17820
|
-
}
|
|
17821
|
-
return out;
|
|
17822
|
-
}
|
|
17823
|
-
|
|
17824
|
-
// ../../packages/math/src/leiden.ts
|
|
17825
|
-
function buildGraph(nodeIds, adj) {
|
|
17826
|
-
const nbr = /* @__PURE__ */ new Map();
|
|
17827
|
-
const deg = /* @__PURE__ */ new Map();
|
|
17828
|
-
const present = new Set(nodeIds);
|
|
17829
|
-
for (const id of nodeIds) {
|
|
17830
|
-
nbr.set(id, /* @__PURE__ */ new Map());
|
|
17831
|
-
deg.set(id, 0);
|
|
17832
|
-
}
|
|
17833
|
-
let m2 = 0;
|
|
17834
|
-
for (const id of nodeIds) {
|
|
17835
|
-
for (const { to, weight } of adj.get(id) ?? []) {
|
|
17836
|
-
if (!present.has(to)) continue;
|
|
17837
|
-
const row = nbr.get(id);
|
|
17838
|
-
row.set(to, (row.get(to) ?? 0) + weight);
|
|
17839
|
-
deg.set(id, (deg.get(id) ?? 0) + weight);
|
|
17840
|
-
m2 += weight;
|
|
17841
|
-
}
|
|
17842
|
-
}
|
|
17843
|
-
return { nbr, deg, m2 };
|
|
17844
|
-
}
|
|
17845
|
-
function localMoving(nodeIds, g) {
|
|
17846
|
-
const community = new Map(nodeIds.map((n) => [n, n]));
|
|
17847
|
-
const comTot = new Map(nodeIds.map((n) => [n, g.deg.get(n) ?? 0]));
|
|
17848
|
-
const order = [...nodeIds].sort();
|
|
17849
|
-
const m2 = g.m2 > 0 ? g.m2 : 1;
|
|
17850
|
-
let improved = true;
|
|
17851
|
-
let iter = 0;
|
|
17852
|
-
while (improved && iter < 100) {
|
|
17853
|
-
improved = false;
|
|
17854
|
-
iter++;
|
|
17855
|
-
for (const node of order) {
|
|
17856
|
-
const ci = community.get(node);
|
|
17857
|
-
const ki = g.deg.get(node) ?? 0;
|
|
17858
|
-
comTot.set(ci, (comTot.get(ci) ?? 0) - ki);
|
|
17859
|
-
const wToComm = /* @__PURE__ */ new Map();
|
|
17860
|
-
for (const [nb, w] of g.nbr.get(node) ?? []) {
|
|
17861
|
-
if (nb === node) continue;
|
|
17862
|
-
const c = community.get(nb);
|
|
17863
|
-
wToComm.set(c, (wToComm.get(c) ?? 0) + w);
|
|
17864
|
-
}
|
|
17865
|
-
let bestC = ci;
|
|
17866
|
-
let bestGain = (wToComm.get(ci) ?? 0) - (comTot.get(ci) ?? 0) * ki / m2;
|
|
17867
|
-
for (const [c, kiIn] of [...wToComm.entries()].sort(
|
|
17868
|
-
(a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0
|
|
17869
|
-
)) {
|
|
17870
|
-
const gain = kiIn - (comTot.get(c) ?? 0) * ki / m2;
|
|
17871
|
-
if (gain > bestGain) {
|
|
17872
|
-
bestGain = gain;
|
|
17873
|
-
bestC = c;
|
|
17874
|
-
}
|
|
17875
|
-
}
|
|
17876
|
-
community.set(node, bestC);
|
|
17877
|
-
comTot.set(bestC, (comTot.get(bestC) ?? 0) + ki);
|
|
17878
|
-
if (bestC !== ci) improved = true;
|
|
17879
|
-
}
|
|
17880
|
-
}
|
|
17881
|
-
return community;
|
|
17882
|
-
}
|
|
17883
|
-
function refineConnectivity(community, g) {
|
|
17884
|
-
const members = /* @__PURE__ */ new Map();
|
|
17885
|
-
for (const [id, c] of community) {
|
|
17886
|
-
const l = members.get(c) ?? [];
|
|
17887
|
-
l.push(id);
|
|
17888
|
-
members.set(c, l);
|
|
17889
|
-
}
|
|
17890
|
-
const refined = /* @__PURE__ */ new Map();
|
|
17891
|
-
for (const [, group] of members) {
|
|
17892
|
-
const inGroup = new Set(group);
|
|
17893
|
-
const seen = /* @__PURE__ */ new Set();
|
|
17894
|
-
for (const start of [...group].sort()) {
|
|
17895
|
-
if (seen.has(start)) continue;
|
|
17896
|
-
const comp = [];
|
|
17897
|
-
const stack = [start];
|
|
17898
|
-
seen.add(start);
|
|
17899
|
-
while (stack.length) {
|
|
17900
|
-
const cur = stack.pop();
|
|
17901
|
-
comp.push(cur);
|
|
17902
|
-
for (const [nb] of g.nbr.get(cur) ?? []) {
|
|
17903
|
-
if (inGroup.has(nb) && !seen.has(nb)) {
|
|
17904
|
-
seen.add(nb);
|
|
17905
|
-
stack.push(nb);
|
|
17906
|
-
}
|
|
17907
|
-
}
|
|
17908
|
-
}
|
|
17909
|
-
const anchor = [...comp].sort()[0];
|
|
17910
|
-
for (const id of comp) refined.set(id, anchor);
|
|
17911
|
-
}
|
|
17912
|
-
}
|
|
17913
|
-
return refined;
|
|
17914
|
-
}
|
|
17915
|
-
function normalize(assignment) {
|
|
17916
|
-
const groups = /* @__PURE__ */ new Map();
|
|
17917
|
-
for (const [id, c] of assignment) {
|
|
17918
|
-
const l = groups.get(c) ?? [];
|
|
17919
|
-
l.push(id);
|
|
17920
|
-
groups.set(c, l);
|
|
17921
|
-
}
|
|
17922
|
-
const community = /* @__PURE__ */ new Map();
|
|
17923
|
-
for (const grp of groups.values()) {
|
|
17924
|
-
const anchor = [...grp].sort()[0];
|
|
17925
|
-
const cid = `community_${anchor}`;
|
|
17926
|
-
for (const m of grp) community.set(m, cid);
|
|
17927
|
-
}
|
|
17928
|
-
return { community, count: groups.size, iterations: 1 };
|
|
17929
|
-
}
|
|
17930
|
-
function causalComponents(nodeIds, pairs) {
|
|
17931
|
-
const parent = new Map(nodeIds.map((n) => [n, n]));
|
|
17932
|
-
const find = (x) => {
|
|
17933
|
-
let r = x;
|
|
17934
|
-
while (parent.get(r) !== r) r = parent.get(r);
|
|
17935
|
-
let c = x;
|
|
17936
|
-
while (parent.get(c) !== r) {
|
|
17937
|
-
const next = parent.get(c);
|
|
17938
|
-
parent.set(c, r);
|
|
17939
|
-
c = next;
|
|
17940
|
-
}
|
|
17941
|
-
return r;
|
|
17942
|
-
};
|
|
17943
|
-
for (const [a, b] of pairs) {
|
|
17944
|
-
const ra = find(a);
|
|
17945
|
-
const rb = find(b);
|
|
17946
|
-
if (ra !== rb) parent.set(ra < rb ? rb : ra, ra < rb ? ra : rb);
|
|
17947
|
-
}
|
|
17948
|
-
return find;
|
|
17949
|
-
}
|
|
17950
|
-
function detectCommunitiesLeiden(input, opts = {}) {
|
|
17951
|
-
const idSet = new Set(input.nodeIds);
|
|
17952
|
-
const protect = [...opts.protect ?? []].filter(
|
|
17953
|
-
([a, b]) => a !== b && idSet.has(a) && idSet.has(b)
|
|
17954
|
-
);
|
|
17955
|
-
if (protect.length === 0) {
|
|
17956
|
-
const g = buildGraph(input.nodeIds, input.adj);
|
|
17957
|
-
return normalize(refineConnectivity(localMoving(input.nodeIds, g), g));
|
|
17958
|
-
}
|
|
17959
|
-
const rep = causalComponents(input.nodeIds, protect);
|
|
17960
|
-
const superIds = [...new Set(input.nodeIds.map(rep))];
|
|
17961
|
-
const superAdj = /* @__PURE__ */ new Map();
|
|
17962
|
-
const acc = /* @__PURE__ */ new Map();
|
|
17963
|
-
for (const id of input.nodeIds) {
|
|
17964
|
-
const ra = rep(id);
|
|
17965
|
-
for (const { to, weight } of input.adj.get(id) ?? []) {
|
|
17966
|
-
if (!idSet.has(to)) continue;
|
|
17967
|
-
const rb = rep(to);
|
|
17968
|
-
if (ra === rb) continue;
|
|
17969
|
-
const row = acc.get(ra) ?? /* @__PURE__ */ new Map();
|
|
17970
|
-
row.set(rb, (row.get(rb) ?? 0) + weight);
|
|
17971
|
-
acc.set(ra, row);
|
|
17972
|
-
}
|
|
17973
|
-
}
|
|
17974
|
-
for (const [a, row] of acc) superAdj.set(a, [...row].map(([to, weight]) => ({ to, weight })));
|
|
17975
|
-
const sg = buildGraph(superIds, superAdj);
|
|
17976
|
-
const superComm = refineConnectivity(localMoving(superIds, sg), sg);
|
|
17977
|
-
const assignment = /* @__PURE__ */ new Map();
|
|
17978
|
-
for (const id of input.nodeIds) assignment.set(id, superComm.get(rep(id)) ?? rep(id));
|
|
17979
|
-
return normalize(assignment);
|
|
17980
|
-
}
|
|
17981
|
-
|
|
17982
18227
|
// ../../packages/local-graph/src/triage.ts
|
|
17983
18228
|
init_src();
|
|
17984
18229
|
init_src();
|
|
@@ -19368,7 +19613,7 @@ var DOC_COMMENT_KINDS = /* @__PURE__ */ new Set(["docstring", "explanation"]);
|
|
|
19368
19613
|
var MAX_DOC_CHARS = 600;
|
|
19369
19614
|
function buildDocIndex(store) {
|
|
19370
19615
|
const byName = /* @__PURE__ */ new Map();
|
|
19371
|
-
for (const c of store.
|
|
19616
|
+
for (const c of store.findNodeFieldsByLabel("Comment", ["attachedTo", "kind", "text"])) {
|
|
19372
19617
|
const name = c.attrs["attachedTo"];
|
|
19373
19618
|
const kind = c.attrs["kind"];
|
|
19374
19619
|
if (typeof name !== "string" || !name) continue;
|
|
@@ -19384,7 +19629,7 @@ function buildSymbolLexicon(store) {
|
|
|
19384
19629
|
const docs = buildDocIndex(store);
|
|
19385
19630
|
const candidates = [];
|
|
19386
19631
|
for (const [label, kind] of SYMBOL_LABELS) {
|
|
19387
|
-
for (const n of store.
|
|
19632
|
+
for (const n of store.findNodeFieldsByLabel(label, ["qname"])) {
|
|
19388
19633
|
const qname = String(n.attrs["qname"] ?? "");
|
|
19389
19634
|
const doc = (n.description ? docs.get(n.description) : void 0) ?? (qname ? docs.get(qname) : void 0);
|
|
19390
19635
|
for (const name of [n.description, qname]) {
|
|
@@ -19490,7 +19735,7 @@ function buildFileLexicon(store) {
|
|
|
19490
19735
|
const basenameCount = /* @__PURE__ */ new Map();
|
|
19491
19736
|
const stemRelPaths = /* @__PURE__ */ new Map();
|
|
19492
19737
|
const entries = [];
|
|
19493
|
-
for (const n of store.
|
|
19738
|
+
for (const n of store.findNodeFieldsByLabel("File", ["relPath"])) {
|
|
19494
19739
|
const relPath = typeof n.attrs["relPath"] === "string" && n.attrs["relPath"].length > 0 ? n.attrs["relPath"] : n.description;
|
|
19495
19740
|
if (!relPath) continue;
|
|
19496
19741
|
const basename = relPath.split("/").pop();
|
|
@@ -19812,9 +20057,7 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19812
20057
|
collapsedEdges: 0
|
|
19813
20058
|
};
|
|
19814
20059
|
const sharedCauses = /* @__PURE__ */ new Map();
|
|
19815
|
-
const causalQueue = store.
|
|
19816
|
-
(n) => n.attrs["source"] !== "cloud" && n.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE && !ignored(n.description)
|
|
19817
|
-
).map((n) => n.id);
|
|
20060
|
+
const causalQueue = store.findNodeFieldsByLabel("Problem", ["source", "resolvedAs"]).filter((r) => r.attrs["source"] !== "cloud" && r.attrs["resolvedAs"] !== PROBLEM_RESOLUTION.FALSE_POSITIVE).map((r) => r.id).filter((id) => ignorePatterns.length === 0 || !ignored(store.getNode(id)?.description ?? ""));
|
|
19818
20061
|
const causalSeen = new Set(causalQueue);
|
|
19819
20062
|
for (let i = 0; i < causalQueue.length; i++) {
|
|
19820
20063
|
const id = causalQueue[i];
|
|
@@ -19830,7 +20073,20 @@ function buildInstanceIngest(store, profile, daemonVersion, ignorePatterns = [],
|
|
|
19830
20073
|
for (const label of INSTANCE_LABELS) {
|
|
19831
20074
|
const ref = [];
|
|
19832
20075
|
includedByLabel.set(label, ref);
|
|
19833
|
-
const
|
|
20076
|
+
const local = [];
|
|
20077
|
+
for (const row of store.findNodeFieldsByLabel(label, ["source", "privateFinding"])) {
|
|
20078
|
+
if (row.attrs["source"] !== "cloud") {
|
|
20079
|
+
const n = store.getNode(row.id);
|
|
20080
|
+
if (n) local.push(n);
|
|
20081
|
+
continue;
|
|
20082
|
+
}
|
|
20083
|
+
if (seen.has(row.id) || walked.has(row.id)) continue;
|
|
20084
|
+
walked.add(row.id);
|
|
20085
|
+
composition.candidates++;
|
|
20086
|
+
if ((row.attrs["privateFinding"] || label === "Vulnerability") && !opts.project) composition.privateTargetMissing++;
|
|
20087
|
+
else composition.cloudSourced++;
|
|
20088
|
+
}
|
|
20089
|
+
const population = label === "RootCause" && opts.sharedStore ? [...local, ...sharedCauses.values()] : local;
|
|
19834
20090
|
for (const n of population) {
|
|
19835
20091
|
if (seen.has(n.id)) continue;
|
|
19836
20092
|
if (walked.has(n.id)) continue;
|