@inerrata-corporation/errata 2.0.21-dev.3918 → 2.0.21-dev.3930
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
CHANGED
|
@@ -16810,6 +16810,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
16810
16810
|
CREATE INDEX IF NOT EXISTS nodes_command_signature ON nodes(json_extract(attrs_json, '$.commandSignature')) WHERE valid_to IS NULL;
|
|
16811
16811
|
CREATE INDEX IF NOT EXISTS nodes_diag_command ON nodes(json_extract(attrs_json, '$.diagCommand')) WHERE valid_to IS NULL;
|
|
16812
16812
|
CREATE INDEX IF NOT EXISTS nodes_lsp_rel_path ON nodes(json_extract(attrs_json, '$.lspRelPath')) WHERE valid_to IS NULL;
|
|
16813
|
+
-- Local nodes by the cloud twin their upload receipt recorded. Every burst /
|
|
16814
|
+
-- search fusion folds the Network copy of the caller's own knowledge back onto
|
|
16815
|
+
-- the local node; unindexed, the reverse lookup was a ~300ms attrs scan per call.
|
|
16816
|
+
CREATE INDEX IF NOT EXISTS nodes_cloud_node_id ON nodes(json_extract(attrs_json, '$.cloudNodeId')) WHERE valid_to IS NULL;
|
|
16813
16817
|
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
16814
16818
|
-- tool response (the enrichment piggyback), so it must not parse every
|
|
16815
16819
|
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
@@ -17779,6 +17783,19 @@ var SqliteGraphStore = class {
|
|
|
17779
17783
|
).get(attr, `%${marker}%`, limit);
|
|
17780
17784
|
return { count: Number(r.count), total: Number(r.total) };
|
|
17781
17785
|
}
|
|
17786
|
+
liveNodeIdsByCloudNodeId(cloudIds) {
|
|
17787
|
+
const out = /* @__PURE__ */ new Map();
|
|
17788
|
+
const CHUNK = 900;
|
|
17789
|
+
for (let i = 0; i < cloudIds.length; i += CHUNK) {
|
|
17790
|
+
const slice = cloudIds.slice(i, i + CHUNK);
|
|
17791
|
+
if (slice.length === 0) continue;
|
|
17792
|
+
const rows = this.db.prepare(
|
|
17793
|
+
`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`
|
|
17794
|
+
).all(...slice);
|
|
17795
|
+
for (const r of rows) out.set(r.cloud, [...out.get(r.cloud) ?? [], r.id]);
|
|
17796
|
+
}
|
|
17797
|
+
return out;
|
|
17798
|
+
}
|
|
17782
17799
|
liveNodeIds(ids) {
|
|
17783
17800
|
const live = /* @__PURE__ */ new Set();
|
|
17784
17801
|
const CHUNK = 900;
|
|
@@ -17840,7 +17857,10 @@ var SqliteGraphStore = class {
|
|
|
17840
17857
|
if (relPaths.length === 0) return [];
|
|
17841
17858
|
const placeholders = relPaths.map(() => "?").join(",");
|
|
17842
17859
|
const rows = this.db.prepare(
|
|
17843
|
-
|
|
17860
|
+
// INDEXED BY: unforced, the planner took nodes_live_page_rank and
|
|
17861
|
+
// json-parsed every live row — 11–25s per reindexed file pair on the
|
|
17862
|
+
// live store vs 7ms here (2026-10-08).
|
|
17863
|
+
`SELECT * FROM nodes INDEXED BY nodes_relpath WHERE valid_to IS NULL AND json_extract(attrs_json, '$.relPath') IN (${placeholders})`
|
|
17844
17864
|
).all(...relPaths);
|
|
17845
17865
|
return rows.map(rowToNode);
|
|
17846
17866
|
}
|
package/errata.mjs
CHANGED
|
@@ -19568,6 +19568,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
19568
19568
|
CREATE INDEX IF NOT EXISTS nodes_command_signature ON nodes(json_extract(attrs_json, '$.commandSignature')) WHERE valid_to IS NULL;
|
|
19569
19569
|
CREATE INDEX IF NOT EXISTS nodes_diag_command ON nodes(json_extract(attrs_json, '$.diagCommand')) WHERE valid_to IS NULL;
|
|
19570
19570
|
CREATE INDEX IF NOT EXISTS nodes_lsp_rel_path ON nodes(json_extract(attrs_json, '$.lspRelPath')) WHERE valid_to IS NULL;
|
|
19571
|
+
-- Local nodes by the cloud twin their upload receipt recorded. Every burst /
|
|
19572
|
+
-- search fusion folds the Network copy of the caller's own knowledge back onto
|
|
19573
|
+
-- the local node; unindexed, the reverse lookup was a ~300ms attrs scan per call.
|
|
19574
|
+
CREATE INDEX IF NOT EXISTS nodes_cloud_node_id ON nodes(json_extract(attrs_json, '$.cloudNodeId')) WHERE valid_to IS NULL;
|
|
19571
19575
|
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
19572
19576
|
-- tool response (the enrichment piggyback), so it must not parse every
|
|
19573
19577
|
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
@@ -20480,6 +20484,19 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
|
|
|
20480
20484
|
).get(attr, `%${marker}%`, limit);
|
|
20481
20485
|
return { count: Number(r.count), total: Number(r.total) };
|
|
20482
20486
|
}
|
|
20487
|
+
liveNodeIdsByCloudNodeId(cloudIds) {
|
|
20488
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
20489
|
+
const CHUNK = 900;
|
|
20490
|
+
for (let i2 = 0; i2 < cloudIds.length; i2 += CHUNK) {
|
|
20491
|
+
const slice = cloudIds.slice(i2, i2 + CHUNK);
|
|
20492
|
+
if (slice.length === 0) continue;
|
|
20493
|
+
const rows = this.db.prepare(
|
|
20494
|
+
`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`
|
|
20495
|
+
).all(...slice);
|
|
20496
|
+
for (const r of rows) out2.set(r.cloud, [...out2.get(r.cloud) ?? [], r.id]);
|
|
20497
|
+
}
|
|
20498
|
+
return out2;
|
|
20499
|
+
}
|
|
20483
20500
|
liveNodeIds(ids) {
|
|
20484
20501
|
const live3 = /* @__PURE__ */ new Set();
|
|
20485
20502
|
const CHUNK = 900;
|
|
@@ -20541,7 +20558,10 @@ CREATE INDEX IF NOT EXISTS nodes_enrichment_pending ON nodes(json_extract(attrs_
|
|
|
20541
20558
|
if (relPaths.length === 0) return [];
|
|
20542
20559
|
const placeholders = relPaths.map(() => "?").join(",");
|
|
20543
20560
|
const rows = this.db.prepare(
|
|
20544
|
-
|
|
20561
|
+
// INDEXED BY: unforced, the planner took nodes_live_page_rank and
|
|
20562
|
+
// json-parsed every live row — 11–25s per reindexed file pair on the
|
|
20563
|
+
// live store vs 7ms here (2026-10-08).
|
|
20564
|
+
`SELECT * FROM nodes INDEXED BY nodes_relpath WHERE valid_to IS NULL AND json_extract(attrs_json, '$.relPath') IN (${placeholders})`
|
|
20545
20565
|
).all(...relPaths);
|
|
20546
20566
|
return rows.map(rowToNode);
|
|
20547
20567
|
}
|
|
@@ -34982,33 +35002,90 @@ function collectiveScore(hit, cap) {
|
|
|
34982
35002
|
function mergeDualBurst(local, cloud, opts = {}) {
|
|
34983
35003
|
const boost = opts.corroborationBoost ?? 0.15;
|
|
34984
35004
|
const cap = opts.collectiveScoreCap ?? 0.5;
|
|
34985
|
-
const
|
|
34986
|
-
const
|
|
35005
|
+
const twins = opts.twins;
|
|
35006
|
+
const cloudIdsOf = (id) => twins?.cloudIdsOf(id) ?? [];
|
|
35007
|
+
const seedSet = /* @__PURE__ */ new Set();
|
|
35008
|
+
if (opts.seedId) {
|
|
35009
|
+
seedSet.add(opts.seedId);
|
|
35010
|
+
for (const c of cloudIdsOf(opts.seedId)) seedSet.add(c);
|
|
35011
|
+
}
|
|
35012
|
+
const isSeedTwin = (id) => seedSet.has(id) || opts.seedId != null && twins?.localOf(id)?.id === opts.seedId;
|
|
34987
35013
|
const nodes = [];
|
|
35014
|
+
const byId = /* @__PURE__ */ new Map();
|
|
35015
|
+
const owner = /* @__PURE__ */ new Map();
|
|
34988
35016
|
let corroboratedCount = 0;
|
|
34989
|
-
|
|
34990
|
-
|
|
34991
|
-
|
|
34992
|
-
|
|
34993
|
-
|
|
35017
|
+
let collectiveCount = 0;
|
|
35018
|
+
const keptLocal = local.filter((l) => !isSeedTwin(l.id)).sort((a, b) => b.score - a.score);
|
|
35019
|
+
const recordedBy = /* @__PURE__ */ new Map();
|
|
35020
|
+
for (const l of keptLocal) {
|
|
35021
|
+
for (const c of cloudIdsOf(l.id)) if (c !== l.id && !recordedBy.has(c)) recordedBy.set(c, l.id);
|
|
35022
|
+
}
|
|
35023
|
+
const copies = [];
|
|
35024
|
+
for (const l of keptLocal) {
|
|
35025
|
+
if (recordedBy.has(l.id)) {
|
|
35026
|
+
copies.push(l);
|
|
35027
|
+
continue;
|
|
35028
|
+
}
|
|
35029
|
+
const n = {
|
|
34994
35030
|
id: l.id,
|
|
34995
35031
|
label: l.node.label,
|
|
34996
35032
|
name: l.node.description,
|
|
34997
|
-
score:
|
|
35033
|
+
score: l.score,
|
|
34998
35034
|
hops: l.hops,
|
|
34999
|
-
provenance:
|
|
35000
|
-
...twin?.usageCount != null ? { usageCount: twin.usageCount } : {},
|
|
35001
|
-
...twin?.rel ? { rel: twin.rel } : {},
|
|
35002
|
-
...twin?.community ? { community: twin.community } : {},
|
|
35035
|
+
provenance: "local",
|
|
35003
35036
|
why: l.components,
|
|
35004
35037
|
...l.via ? { via: l.via } : {}
|
|
35005
|
-
}
|
|
35038
|
+
};
|
|
35039
|
+
nodes.push(n);
|
|
35040
|
+
byId.set(n.id, n);
|
|
35041
|
+
for (const c of cloudIdsOf(l.id)) if (!owner.has(c)) owner.set(c, n);
|
|
35042
|
+
}
|
|
35043
|
+
for (const l of copies) {
|
|
35044
|
+
const host = byId.get(recordedBy.get(l.id));
|
|
35045
|
+
if (host) addTwin(host, l.id);
|
|
35006
35046
|
}
|
|
35007
|
-
let collectiveCount = 0;
|
|
35008
35047
|
for (const c of cloud) {
|
|
35009
|
-
if (
|
|
35048
|
+
if (isSeedTwin(c.id)) continue;
|
|
35049
|
+
const recorded = owner.get(c.id);
|
|
35050
|
+
if (recorded) {
|
|
35051
|
+
foldSelfUpload(recorded, c);
|
|
35052
|
+
continue;
|
|
35053
|
+
}
|
|
35054
|
+
const exact = byId.get(c.id);
|
|
35055
|
+
if (exact && exact.provenance !== "collective") {
|
|
35056
|
+
absorb(exact, c);
|
|
35057
|
+
continue;
|
|
35058
|
+
}
|
|
35059
|
+
const mine = twins?.localOf(c.id);
|
|
35060
|
+
if (mine && !isSeedTwin(mine.id)) {
|
|
35061
|
+
const existing = byId.get(mine.id);
|
|
35062
|
+
if (existing) {
|
|
35063
|
+
if (existing.provenance === "collective") {
|
|
35064
|
+
existing.provenance = "local";
|
|
35065
|
+
collectiveCount--;
|
|
35066
|
+
}
|
|
35067
|
+
owner.set(c.id, existing);
|
|
35068
|
+
absorb(existing, c);
|
|
35069
|
+
continue;
|
|
35070
|
+
}
|
|
35071
|
+
const n2 = {
|
|
35072
|
+
id: mine.id,
|
|
35073
|
+
label: mine.label,
|
|
35074
|
+
name: mine.description,
|
|
35075
|
+
score: collectiveScore(c, cap),
|
|
35076
|
+
hops: 1,
|
|
35077
|
+
provenance: "local"
|
|
35078
|
+
};
|
|
35079
|
+
nodes.push(n2);
|
|
35080
|
+
byId.set(n2.id, n2);
|
|
35081
|
+
for (const cid of cloudIdsOf(mine.id)) if (!owner.has(cid)) owner.set(cid, n2);
|
|
35082
|
+
owner.set(c.id, n2);
|
|
35083
|
+
absorb(n2, c);
|
|
35084
|
+
continue;
|
|
35085
|
+
}
|
|
35086
|
+
if (exact) continue;
|
|
35010
35087
|
collectiveCount++;
|
|
35011
|
-
|
|
35088
|
+
const n = {
|
|
35012
35089
|
id: c.id,
|
|
35013
35090
|
label: c.label,
|
|
35014
35091
|
name: c.description,
|
|
@@ -35020,10 +35097,53 @@ function mergeDualBurst(local, cloud, opts = {}) {
|
|
|
35020
35097
|
...c.rel ? { rel: c.rel } : {},
|
|
35021
35098
|
...c.community ? { community: c.community } : {},
|
|
35022
35099
|
...c.via ? { via: c.via } : {}
|
|
35023
|
-
}
|
|
35100
|
+
};
|
|
35101
|
+
nodes.push(n);
|
|
35102
|
+
byId.set(n.id, n);
|
|
35103
|
+
}
|
|
35104
|
+
for (const n of nodes) {
|
|
35105
|
+
if (!n.via) continue;
|
|
35106
|
+
const parent = canonicalId(n.via.parentId);
|
|
35107
|
+
if (parent === n.id) delete n.via;
|
|
35108
|
+
else if (parent !== n.via.parentId) n.via = { ...n.via, parentId: parent };
|
|
35024
35109
|
}
|
|
35025
35110
|
nodes.sort((a, b) => b.score - a.score);
|
|
35026
35111
|
return { nodes, collectiveCount, corroboratedCount };
|
|
35112
|
+
function canonicalId(id) {
|
|
35113
|
+
if (opts.seedId && isSeedTwin(id)) return opts.seedId;
|
|
35114
|
+
return owner.get(id)?.id ?? recordedBy.get(id) ?? twins?.localOf(id)?.id ?? id;
|
|
35115
|
+
}
|
|
35116
|
+
function absorb(n, c) {
|
|
35117
|
+
if (c.id === n.id && cloudIdsOf(n.id).length === 0) corroborate(n, c);
|
|
35118
|
+
else foldSelfUpload(n, c);
|
|
35119
|
+
}
|
|
35120
|
+
function corroborate(n, c) {
|
|
35121
|
+
if (n.provenance !== "corroborated") {
|
|
35122
|
+
corroboratedCount++;
|
|
35123
|
+
n.provenance = "corroborated";
|
|
35124
|
+
n.score = n.score * (1 + boost);
|
|
35125
|
+
delete n.uploaded;
|
|
35126
|
+
}
|
|
35127
|
+
attachCloudFields(n, c);
|
|
35128
|
+
}
|
|
35129
|
+
function foldSelfUpload(n, c) {
|
|
35130
|
+
addTwin(n, c.id);
|
|
35131
|
+
if ((c.usageCount ?? 0) >= 2) return corroborate(n, c);
|
|
35132
|
+
if (n.provenance === "local") n.uploaded = true;
|
|
35133
|
+
attachCloudFields(n, c);
|
|
35134
|
+
}
|
|
35135
|
+
function attachCloudFields(n, c) {
|
|
35136
|
+
if (c.usageCount != null && (n.usageCount ?? -1) < c.usageCount) n.usageCount = c.usageCount;
|
|
35137
|
+
if (c.rel && !n.rel) n.rel = c.rel;
|
|
35138
|
+
if (c.community && !n.community) n.community = c.community;
|
|
35139
|
+
const v = c.via;
|
|
35140
|
+
if (v && !n.via) n.via = v;
|
|
35141
|
+
}
|
|
35142
|
+
}
|
|
35143
|
+
function addTwin(n, id) {
|
|
35144
|
+
if (id === n.id) return;
|
|
35145
|
+
const t = n.twins ?? (n.twins = []);
|
|
35146
|
+
if (!t.includes(id)) t.push(id);
|
|
35027
35147
|
}
|
|
35028
35148
|
function packageNeighborhoodToCloudHits(pn) {
|
|
35029
35149
|
const mk = (rel) => (r) => ({
|
|
@@ -35078,6 +35198,69 @@ var init_dual_burst = __esm({
|
|
|
35078
35198
|
}
|
|
35079
35199
|
});
|
|
35080
35200
|
|
|
35201
|
+
// src/twin-index.ts
|
|
35202
|
+
function recordedCloudIds(n) {
|
|
35203
|
+
if (n.attrs["source"] === "cloud") return [];
|
|
35204
|
+
const ids = [];
|
|
35205
|
+
const add = (v) => {
|
|
35206
|
+
if (typeof v === "string" && v.length > 0 && v !== n.id && !ids.includes(v)) ids.push(v);
|
|
35207
|
+
};
|
|
35208
|
+
add(n.attrs["cloudNodeId"]);
|
|
35209
|
+
const receipts = n.attrs["instanceReceipts"];
|
|
35210
|
+
if (receipts && typeof receipts === "object" && !Array.isArray(receipts)) {
|
|
35211
|
+
for (const r of Object.values(receipts)) {
|
|
35212
|
+
if (r && typeof r === "object") add(r["cloudNodeId"]);
|
|
35213
|
+
}
|
|
35214
|
+
}
|
|
35215
|
+
return ids;
|
|
35216
|
+
}
|
|
35217
|
+
function localTwinOf(store, cloudId) {
|
|
35218
|
+
return localTwinsOf(store, [cloudId]).get(cloudId) ?? null;
|
|
35219
|
+
}
|
|
35220
|
+
function localTwinsOf(store, cloudIds) {
|
|
35221
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
35222
|
+
if (cloudIds.length === 0) return out2;
|
|
35223
|
+
for (const [cloudId, localIds] of store.liveNodeIdsByCloudNodeId(cloudIds)) {
|
|
35224
|
+
for (const id of localIds) {
|
|
35225
|
+
if (id === cloudId) continue;
|
|
35226
|
+
const n = store.getNode(id);
|
|
35227
|
+
if (!n || n.attrs["source"] === "cloud") continue;
|
|
35228
|
+
out2.set(cloudId, n);
|
|
35229
|
+
break;
|
|
35230
|
+
}
|
|
35231
|
+
}
|
|
35232
|
+
const rest2 = cloudIds.filter((id) => !out2.has(id));
|
|
35233
|
+
for (const id of rest2.length ? store.liveNodeIds(rest2) : []) {
|
|
35234
|
+
const n = store.getNode(id);
|
|
35235
|
+
if (n && recordedCloudIds(n).length > 0) out2.set(id, n);
|
|
35236
|
+
}
|
|
35237
|
+
return out2;
|
|
35238
|
+
}
|
|
35239
|
+
function storeTwinIndex(store, cloudIds) {
|
|
35240
|
+
const reverse = localTwinsOf(store, [...new Set(cloudIds)]);
|
|
35241
|
+
const forward = /* @__PURE__ */ new Map();
|
|
35242
|
+
return {
|
|
35243
|
+
cloudIdsOf(localId) {
|
|
35244
|
+
let ids = forward.get(localId);
|
|
35245
|
+
if (!ids) {
|
|
35246
|
+
const n = store.getNode(localId);
|
|
35247
|
+
ids = n ? recordedCloudIds(n) : [];
|
|
35248
|
+
forward.set(localId, ids);
|
|
35249
|
+
}
|
|
35250
|
+
return ids;
|
|
35251
|
+
},
|
|
35252
|
+
localOf(cloudId) {
|
|
35253
|
+
const n = reverse.get(cloudId);
|
|
35254
|
+
return n ? { id: n.id, label: n.label, description: n.description } : void 0;
|
|
35255
|
+
}
|
|
35256
|
+
};
|
|
35257
|
+
}
|
|
35258
|
+
var init_twin_index = __esm({
|
|
35259
|
+
"src/twin-index.ts"() {
|
|
35260
|
+
"use strict";
|
|
35261
|
+
}
|
|
35262
|
+
});
|
|
35263
|
+
|
|
35081
35264
|
// src/dual-augment.ts
|
|
35082
35265
|
function isHardBridge(n) {
|
|
35083
35266
|
return n.label === "Package" || n.label === "Language" || n.label === "Claim" && Number(n.attrs["abstractionLevel"] ?? 0) >= 2;
|
|
@@ -35098,6 +35281,8 @@ async function dualAugment(opts) {
|
|
|
35098
35281
|
const n = seedNode && nid === seedNode.id ? seedNode : store.getNode(nid);
|
|
35099
35282
|
return !!n && isHardBridge(n);
|
|
35100
35283
|
});
|
|
35284
|
+
const seedTwinIds = seedNode ? recordedCloudIds(seedNode) : [];
|
|
35285
|
+
const cloudSeeds = [.../* @__PURE__ */ new Set([...seedTwinIds, ...hardIds])];
|
|
35101
35286
|
const softText = queryText ?? (seedNode && BRIDGE_LABELS.has(seedNode.label) ? seedNode.description : void 0);
|
|
35102
35287
|
const softQ = softText ? await generalizeSoft?.(softText) ?? generalizeSymbols(softText, lexiconsFor(store).symbols, 1) : void 0;
|
|
35103
35288
|
if (seedNode?.label === "Package") {
|
|
@@ -35111,9 +35296,9 @@ async function dualAugment(opts) {
|
|
|
35111
35296
|
})
|
|
35112
35297
|
);
|
|
35113
35298
|
}
|
|
35114
|
-
if (
|
|
35299
|
+
if (cloudSeeds.length > 0 || softQ) {
|
|
35115
35300
|
calls.push(
|
|
35116
|
-
cloud.search({ stack: [], domains: [], kinds: [], seed:
|
|
35301
|
+
cloud.search({ stack: [], domains: [], kinds: [], seed: cloudSeeds, ...softQ ? { q: softQ } : {}, limit, community: true, via: true }).then((res) => {
|
|
35117
35302
|
cloudHits.push(...searchResultToCloudHits(res));
|
|
35118
35303
|
})
|
|
35119
35304
|
);
|
|
@@ -35134,9 +35319,18 @@ async function dualAugment(opts) {
|
|
|
35134
35319
|
return { status: "offline" };
|
|
35135
35320
|
}
|
|
35136
35321
|
if (cloudHits.length === 0) return { status: "empty" };
|
|
35322
|
+
const deduped = dedupCloudHits(cloudHits);
|
|
35137
35323
|
return {
|
|
35138
35324
|
status: "merged",
|
|
35139
|
-
merged: mergeDualBurst(localHits,
|
|
35325
|
+
merged: mergeDualBurst(localHits, deduped, {
|
|
35326
|
+
// A hit's `via` parent is resolved too, so an edge from a folded twin
|
|
35327
|
+
// can be re-pointed at the entity it folded into.
|
|
35328
|
+
twins: storeTwinIndex(store, deduped.flatMap((c) => {
|
|
35329
|
+
const parent = c.via?.parentId;
|
|
35330
|
+
return parent ? [c.id, parent] : [c.id];
|
|
35331
|
+
})),
|
|
35332
|
+
...seedNode ? { seedId: seedNode.id } : {}
|
|
35333
|
+
}),
|
|
35140
35334
|
seedProvenance,
|
|
35141
35335
|
seedUsageCount
|
|
35142
35336
|
};
|
|
@@ -35291,7 +35485,9 @@ function formatDualNodes(merged) {
|
|
|
35291
35485
|
trust: n.why.trust
|
|
35292
35486
|
}
|
|
35293
35487
|
} : {},
|
|
35294
|
-
...n.via ? { via: n.via } : {}
|
|
35488
|
+
...n.via ? { via: n.via } : {},
|
|
35489
|
+
...n.twins?.length ? { twins: n.twins } : {},
|
|
35490
|
+
...n.uploaded ? { uploaded: true } : {}
|
|
35295
35491
|
}));
|
|
35296
35492
|
}
|
|
35297
35493
|
var BRIDGE_LABELS, CANONICAL_KNOWLEDGE_ID, UUID_ID;
|
|
@@ -35301,6 +35497,7 @@ var init_dual_augment = __esm({
|
|
|
35301
35497
|
init_src2();
|
|
35302
35498
|
init_generalize_graph();
|
|
35303
35499
|
init_dual_burst();
|
|
35500
|
+
init_twin_index();
|
|
35304
35501
|
BRIDGE_LABELS = new Set(SEMANTIC_NODE_LABELS);
|
|
35305
35502
|
CANONICAL_KNOWLEDGE_ID = /^[a-z][a-z0-9]*_[0-9a-f]{8,}$/;
|
|
35306
35503
|
UUID_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -44593,6 +44790,10 @@ function collectiveSeedMiss(args2, outcome) {
|
|
|
44593
44790
|
function resolveSymbol2(store, args2) {
|
|
44594
44791
|
const id = args2["nodeId"];
|
|
44595
44792
|
if (typeof id === "string" && store.getNode(id)) return id;
|
|
44793
|
+
if (typeof id === "string" && hasCloudNodeShape(id)) {
|
|
44794
|
+
const twin = localTwinOf(store, id);
|
|
44795
|
+
if (twin) return twin.id;
|
|
44796
|
+
}
|
|
44596
44797
|
const qname = args2["qname"];
|
|
44597
44798
|
if (typeof qname === "string") {
|
|
44598
44799
|
const hits = store.searchNodes({ descriptionLike: qname, limit: 5 });
|
|
@@ -44602,6 +44803,14 @@ function resolveSymbol2(store, args2) {
|
|
|
44602
44803
|
}
|
|
44603
44804
|
return null;
|
|
44604
44805
|
}
|
|
44806
|
+
function seedTwinFields(args2, seed) {
|
|
44807
|
+
const twins = seed ? recordedCloudIds(seed) : [];
|
|
44808
|
+
const asked = args2["nodeId"];
|
|
44809
|
+
return {
|
|
44810
|
+
...twins.length ? { seedTwins: twins } : {},
|
|
44811
|
+
...typeof asked === "string" && seed && asked !== seed.id ? { requestedSeed: asked } : {}
|
|
44812
|
+
};
|
|
44813
|
+
}
|
|
44605
44814
|
function isSynthesizedScope(name2) {
|
|
44606
44815
|
return name2.includes(":") || name2.startsWith("anon@");
|
|
44607
44816
|
}
|
|
@@ -44783,6 +44992,8 @@ var init_mcp = __esm({
|
|
|
44783
44992
|
init_identity2();
|
|
44784
44993
|
init_registry();
|
|
44785
44994
|
init_dual_augment();
|
|
44995
|
+
init_dual_burst();
|
|
44996
|
+
init_twin_index();
|
|
44786
44997
|
init_src5();
|
|
44787
44998
|
init_src2();
|
|
44788
44999
|
init_src8();
|
|
@@ -45065,6 +45276,7 @@ var init_mcp = __esm({
|
|
|
45065
45276
|
if (dual.status === "merged") {
|
|
45066
45277
|
return {
|
|
45067
45278
|
seed: id,
|
|
45279
|
+
...seedTwinFields(args2, seedNode),
|
|
45068
45280
|
seedProvenance: dual.seedProvenance,
|
|
45069
45281
|
...dual.seedUsageCount != null ? { seedUsageCount: dual.seedUsageCount } : {},
|
|
45070
45282
|
collectiveReachable: true,
|
|
@@ -45079,25 +45291,17 @@ var init_mcp = __esm({
|
|
|
45079
45291
|
}
|
|
45080
45292
|
return {
|
|
45081
45293
|
seed: id,
|
|
45294
|
+
...seedTwinFields(args2, seedNode),
|
|
45082
45295
|
// reached-but-empty counts as reachable; offline/no-portal/local-only do not.
|
|
45083
45296
|
collectiveReachable: collectiveStatus === "empty",
|
|
45084
45297
|
collectiveStatus,
|
|
45085
45298
|
...federationHint(collectiveStatus) ? { collectiveHint: federationHint(collectiveStatus) } : {},
|
|
45086
|
-
|
|
45087
|
-
|
|
45088
|
-
|
|
45089
|
-
|
|
45090
|
-
|
|
45091
|
-
|
|
45092
|
-
hops: r.hops,
|
|
45093
|
-
provenance: "local",
|
|
45094
|
-
why: {
|
|
45095
|
-
semantic: Number(r.components.semantic.toFixed(3)),
|
|
45096
|
-
centrality: Number(r.components.centrality.toFixed(3)),
|
|
45097
|
-
trust: r.components.trust
|
|
45098
|
-
},
|
|
45099
|
-
...r.via ? { via: r.via } : {}
|
|
45100
|
-
}))
|
|
45299
|
+
// Same twin fold as the merged path: a hydrated in-store copy of a hit
|
|
45300
|
+
// (or of the seed) is not a second entity.
|
|
45301
|
+
...(() => {
|
|
45302
|
+
const localOnly = mergeDualBurst(localHits, [], { twins: storeTwinIndex(store, []), seedId: id });
|
|
45303
|
+
return { count: localOnly.nodes.length, results: formatDualNodes(localOnly) };
|
|
45304
|
+
})()
|
|
45101
45305
|
};
|
|
45102
45306
|
}
|
|
45103
45307
|
},
|
|
@@ -77678,11 +77882,26 @@ var CONFIRM_PREFIX = /^\s*confirm:\s*/i;
|
|
|
77678
77882
|
var REFUTE_PREFIX = /^\s*refute:\s*/i;
|
|
77679
77883
|
var REFUTE_REASON_MIN = 4;
|
|
77680
77884
|
var PATTERN_RE = /\(\s*pattern:\s*([^()\n]{3,}?)\s*\)/gi;
|
|
77681
|
-
var DOMAIN_RE = /\(\s*domain:\s*([^()\n]{
|
|
77885
|
+
var DOMAIN_RE = /\(\s*domain:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
77682
77886
|
var PACKAGE_RE = /\(\s*package:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
77683
77887
|
var COMPONENT_RE = /\(\s*component:\s*([^()\n]{2,}?)\s*\)/gi;
|
|
77684
77888
|
var CAUSE_TEXT_MIN = 8;
|
|
77685
|
-
var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*((?:\[[
|
|
77889
|
+
var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*((?:\[[^[\]\n]*\]|[^\]\n])*?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
|
|
77890
|
+
function flagScanView(text) {
|
|
77891
|
+
let out2 = "";
|
|
77892
|
+
let from = 0;
|
|
77893
|
+
for (; ; ) {
|
|
77894
|
+
const nl = text.indexOf("\n", from);
|
|
77895
|
+
const end = nl < 0 ? text.length : nl;
|
|
77896
|
+
const close = text.lastIndexOf("]", end - 1);
|
|
77897
|
+
const keep = close >= from ? close + 1 : from;
|
|
77898
|
+
out2 += text.slice(from, keep) + " ".repeat(end - keep);
|
|
77899
|
+
if (nl < 0) return out2;
|
|
77900
|
+
out2 += "\n";
|
|
77901
|
+
from = nl + 1;
|
|
77902
|
+
}
|
|
77903
|
+
}
|
|
77904
|
+
var MARKDOWN_LINK_RE = /\[([^[\]\n]+)\]\(([^()\s[\]]*[./][^()\s[\]]*)\)/g;
|
|
77686
77905
|
var CONSTRAINT_MIN = 8;
|
|
77687
77906
|
function clauseBefore(sentence, idx) {
|
|
77688
77907
|
const win = sentence.slice(Math.max(0, idx - 80), idx);
|
|
@@ -77702,13 +77921,15 @@ var SIBLING_MARKUP_SOURCES = [
|
|
|
77702
77921
|
CONSTRAINT_RE
|
|
77703
77922
|
].map((re) => ({ source: re.source, flags: re.flags.includes("g") ? re.flags : `${re.flags}g` }));
|
|
77704
77923
|
function maskSiblingMarkup(sentence, tagStart, tagEnd) {
|
|
77705
|
-
let masked = sentence;
|
|
77924
|
+
let masked = sentence.replace(MARKDOWN_LINK_RE, (m, label, _target, at) => at <= tagStart && at + m.length >= tagEnd ? m : ` ${label}${" ".repeat(m.length - label.length - 1)}`);
|
|
77706
77925
|
for (const { source, flags: flags2 } of SIBLING_MARKUP_SOURCES) {
|
|
77707
|
-
|
|
77708
|
-
|
|
77709
|
-
|
|
77710
|
-
|
|
77711
|
-
|
|
77926
|
+
const view = source === FLAG_RE.source ? flagScanView(masked) : masked;
|
|
77927
|
+
const spans = [];
|
|
77928
|
+
for (const m of view.matchAll(new RegExp(source, flags2))) {
|
|
77929
|
+
const at = m.index;
|
|
77930
|
+
if (!(at <= tagStart && at + m[0].length >= tagEnd)) spans.push([at, at + m[0].length]);
|
|
77931
|
+
}
|
|
77932
|
+
for (const [from, to] of spans) masked = masked.slice(0, from) + " ".repeat(to - from) + masked.slice(to);
|
|
77712
77933
|
}
|
|
77713
77934
|
return masked;
|
|
77714
77935
|
}
|
|
@@ -77724,7 +77945,7 @@ function fixRationaleBefore(sentence, idx) {
|
|
|
77724
77945
|
start2 = ws < 0 ? idx : start2 + ws;
|
|
77725
77946
|
}
|
|
77726
77947
|
const win = masked.slice(start2, idx).replace(/\s+$/, "").replace(/[.!?]$/, "");
|
|
77727
|
-
const scan2 = win.replace(/`[^`]*`/g, (s) => s.replace(/[.;!?—]/g, "_"));
|
|
77948
|
+
const scan2 = win.replace(/`[^`]*`/g, (s) => s.replace(/[.;!?—]/g, "_")).replace(/\.(?=[\w/])/g, "_");
|
|
77728
77949
|
const m = /[.;!?—][^.;!?—]*$/.exec(scan2);
|
|
77729
77950
|
const clause = (m ? win.slice(m.index + 1) : win).replace(/\*\*|__/g, "").replace(/^\s*(?:[-*+]|\d+[.)])\s+/, "").replace(/\s+([:;,])/g, "$1").replace(/\s+/g, " ").trim();
|
|
77730
77951
|
if (clause.endsWith(":")) return "";
|
|
@@ -77742,7 +77963,7 @@ function fixRationaleAfter(sentence, endIdx) {
|
|
|
77742
77963
|
const residual = RESIDUAL_OPENER_RE.exec(win);
|
|
77743
77964
|
if (residual) win = win.slice(0, residual.index);
|
|
77744
77965
|
const stripped = win.replace(/^[\s—:–,-]+/, "");
|
|
77745
|
-
const m = /^[
|
|
77966
|
+
const m = /^(?:[^.;!?]|\.(?=[\w/]))*/.exec(stripped);
|
|
77746
77967
|
const clause = (m ? m[0] : stripped).replace(/\s+/g, " ").trim();
|
|
77747
77968
|
if (/^(and|but|or|nor|so|yet|also|plus)\b/i.test(clause)) return "";
|
|
77748
77969
|
return clause;
|
|
@@ -77885,7 +78106,7 @@ function* captureSentences(text) {
|
|
|
77885
78106
|
yield line;
|
|
77886
78107
|
continue;
|
|
77887
78108
|
}
|
|
77888
|
-
const flags2 = [...line.matchAll(new RegExp(FLAG_RE.source, FLAG_RE.flags))].map((m) => ({ start: m.index, end: m.index + m[0].length }));
|
|
78109
|
+
const flags2 = [...flagScanView(line).matchAll(new RegExp(FLAG_RE.source, FLAG_RE.flags))].map((m) => ({ start: m.index, end: m.index + m[0].length }));
|
|
77889
78110
|
let flag = 0;
|
|
77890
78111
|
let start2 = 0;
|
|
77891
78112
|
for (const boundary of line.matchAll(/(?<=[.!?])\s+(?!\(fix:)/g)) {
|
|
@@ -77917,12 +78138,14 @@ function parseInlineTagsWithDispositions(text) {
|
|
|
77917
78138
|
});
|
|
77918
78139
|
const sfield = sentence.replace(/\s+/g, " ").trim().slice(0, 160);
|
|
77919
78140
|
const citeMatched = /* @__PURE__ */ new Set();
|
|
78141
|
+
const flagSpans = [...flagScanView(sentence).matchAll(new RegExp(FLAG_RE.source, FLAG_RE.flags))].map((m) => [m.index, m.index + m[0].length]);
|
|
77920
78142
|
CITE_GROUP_RE.lastIndex = 0;
|
|
77921
78143
|
let g;
|
|
77922
78144
|
while ((g = CITE_GROUP_RE.exec(sentence)) !== null) {
|
|
77923
78145
|
citeMatched.add(g.index);
|
|
77924
78146
|
let content = g[1];
|
|
77925
78147
|
if (/^\s*pattern:/i.test(content)) continue;
|
|
78148
|
+
if (/^\s*failed:/i.test(content)) continue;
|
|
77926
78149
|
const fixM = FIX_PREFIX.exec(content);
|
|
77927
78150
|
const causeM = fixM ? null : CAUSE_PREFIX.exec(content);
|
|
77928
78151
|
const aidsM = fixM || causeM ? null : AIDS_PREFIX.exec(content);
|
|
@@ -77985,6 +78208,17 @@ function parseInlineTagsWithDispositions(text) {
|
|
|
77985
78208
|
const verbThread = fixM?.[1] ?? causeM?.[1] ?? void 0;
|
|
77986
78209
|
if (isFix) content = content.replace(FIX_PREFIX, "");
|
|
77987
78210
|
else if (isCause) content = content.replace(CAUSE_PREFIX, "");
|
|
78211
|
+
if (isFix) {
|
|
78212
|
+
const joined = /[,;]\s*cause:\s*/i.exec(content);
|
|
78213
|
+
if (joined) {
|
|
78214
|
+
const causeBody = content.slice(joined.index + joined[0].length);
|
|
78215
|
+
content = content.slice(0, joined.index);
|
|
78216
|
+
const fixed = new RegExp(HANDLE_RE.source, "i").exec(content);
|
|
78217
|
+
const symptom = fixed && !/^\s*\[/.test(causeBody) ? `${fixed[0]} ` : "";
|
|
78218
|
+
const cause = parseCauseTag(`${symptom}${causeBody}`, sfield, verbThread, dispositions);
|
|
78219
|
+
if (cause) out2.push(cause);
|
|
78220
|
+
}
|
|
78221
|
+
}
|
|
77988
78222
|
if (isCause) {
|
|
77989
78223
|
const cause = parseCauseTag(content, sfield, verbThread, dispositions);
|
|
77990
78224
|
if (cause) out2.push(cause);
|
|
@@ -78023,6 +78257,8 @@ function parseInlineTagsWithDispositions(text) {
|
|
|
78023
78257
|
const note = content.replace(/\s+/g, " ").trim();
|
|
78024
78258
|
if (note.length >= FIX_RATIONALE_MIN)
|
|
78025
78259
|
out2.push({ kind: "fix", fixRationale: note, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
|
|
78260
|
+
else if (verbThread && fixRationale && !flagSpans.some(([a2, b]) => a2 < g.index && g.index < b))
|
|
78261
|
+
out2.push({ kind: "fix", fixRationale, sentence: sfield, threadId: verbThread });
|
|
78026
78262
|
else dispositions.unparseable++;
|
|
78027
78263
|
} else if (!isFix && !emittedHandle && BRACKETED_TOKEN_RE.test(content)) {
|
|
78028
78264
|
dispositions.unparseable++;
|
|
@@ -78106,8 +78342,9 @@ function parseInlineTagsWithDispositions(text) {
|
|
|
78106
78342
|
}
|
|
78107
78343
|
}
|
|
78108
78344
|
FLAG_RE.lastIndex = 0;
|
|
78345
|
+
const flagView = flagScanView(sentence);
|
|
78109
78346
|
let f;
|
|
78110
|
-
while ((f = FLAG_RE.exec(
|
|
78347
|
+
while ((f = FLAG_RE.exec(flagView)) !== null) {
|
|
78111
78348
|
const flagThread = f[2];
|
|
78112
78349
|
const raw3 = f[3].trim();
|
|
78113
78350
|
if (/^vuln\b/i.test(raw3)) {
|
|
@@ -78224,7 +78461,7 @@ function parseInlineTagsWithDispositions(text) {
|
|
|
78224
78461
|
let dm;
|
|
78225
78462
|
while ((dm = DOMAIN_RE.exec(sentence)) !== null) {
|
|
78226
78463
|
const raw3 = dm[1].replace(/\s+/g, " ").trim();
|
|
78227
|
-
if (raw3.length >=
|
|
78464
|
+
if (raw3.length >= 2) out2.push({ kind: "domain", domainText: raw3, sentence: sfield });
|
|
78228
78465
|
}
|
|
78229
78466
|
PACKAGE_RE.lastIndex = 0;
|
|
78230
78467
|
let pk;
|
|
@@ -83212,7 +83449,7 @@ function createWatchBreaker(deps) {
|
|
|
83212
83449
|
}
|
|
83213
83450
|
|
|
83214
83451
|
// src/engine.ts
|
|
83215
|
-
var DAEMON_VERSION = true ? "2.0.21-dev.
|
|
83452
|
+
var DAEMON_VERSION = true ? "2.0.21-dev.3930" : "2.0.0-alpha.0";
|
|
83216
83453
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
83217
83454
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
83218
83455
|
var GIT_OP_MUTE_MS = 4e3;
|
package/generalize-worker.mjs
CHANGED
|
@@ -15204,6 +15204,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
15204
15204
|
CREATE INDEX IF NOT EXISTS nodes_command_signature ON nodes(json_extract(attrs_json, '$.commandSignature')) WHERE valid_to IS NULL;
|
|
15205
15205
|
CREATE INDEX IF NOT EXISTS nodes_diag_command ON nodes(json_extract(attrs_json, '$.diagCommand')) WHERE valid_to IS NULL;
|
|
15206
15206
|
CREATE INDEX IF NOT EXISTS nodes_lsp_rel_path ON nodes(json_extract(attrs_json, '$.lspRelPath')) WHERE valid_to IS NULL;
|
|
15207
|
+
-- Local nodes by the cloud twin their upload receipt recorded. Every burst /
|
|
15208
|
+
-- search fusion folds the Network copy of the caller's own knowledge back onto
|
|
15209
|
+
-- the local node; unindexed, the reverse lookup was a ~300ms attrs scan per call.
|
|
15210
|
+
CREATE INDEX IF NOT EXISTS nodes_cloud_node_id ON nodes(json_extract(attrs_json, '$.cloudNodeId')) WHERE valid_to IS NULL;
|
|
15207
15211
|
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
15208
15212
|
-- tool response (the enrichment piggyback), so it must not parse every
|
|
15209
15213
|
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
@@ -16173,6 +16177,19 @@ var SqliteGraphStore = class {
|
|
|
16173
16177
|
).get(attr, `%${marker}%`, limit);
|
|
16174
16178
|
return { count: Number(r.count), total: Number(r.total) };
|
|
16175
16179
|
}
|
|
16180
|
+
liveNodeIdsByCloudNodeId(cloudIds) {
|
|
16181
|
+
const out = /* @__PURE__ */ new Map();
|
|
16182
|
+
const CHUNK = 900;
|
|
16183
|
+
for (let i = 0; i < cloudIds.length; i += CHUNK) {
|
|
16184
|
+
const slice = cloudIds.slice(i, i + CHUNK);
|
|
16185
|
+
if (slice.length === 0) continue;
|
|
16186
|
+
const rows = this.db.prepare(
|
|
16187
|
+
`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`
|
|
16188
|
+
).all(...slice);
|
|
16189
|
+
for (const r of rows) out.set(r.cloud, [...out.get(r.cloud) ?? [], r.id]);
|
|
16190
|
+
}
|
|
16191
|
+
return out;
|
|
16192
|
+
}
|
|
16176
16193
|
liveNodeIds(ids) {
|
|
16177
16194
|
const live = /* @__PURE__ */ new Set();
|
|
16178
16195
|
const CHUNK = 900;
|
|
@@ -16234,7 +16251,10 @@ var SqliteGraphStore = class {
|
|
|
16234
16251
|
if (relPaths.length === 0) return [];
|
|
16235
16252
|
const placeholders = relPaths.map(() => "?").join(",");
|
|
16236
16253
|
const rows = this.db.prepare(
|
|
16237
|
-
|
|
16254
|
+
// INDEXED BY: unforced, the planner took nodes_live_page_rank and
|
|
16255
|
+
// json-parsed every live row — 11–25s per reindexed file pair on the
|
|
16256
|
+
// live store vs 7ms here (2026-10-08).
|
|
16257
|
+
`SELECT * FROM nodes INDEXED BY nodes_relpath WHERE valid_to IS NULL AND json_extract(attrs_json, '$.relPath') IN (${placeholders})`
|
|
16238
16258
|
).all(...relPaths);
|
|
16239
16259
|
return rows.map(rowToNode);
|
|
16240
16260
|
}
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -26063,6 +26063,10 @@ CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_js
|
|
|
26063
26063
|
CREATE INDEX IF NOT EXISTS nodes_command_signature ON nodes(json_extract(attrs_json, '$.commandSignature')) WHERE valid_to IS NULL;
|
|
26064
26064
|
CREATE INDEX IF NOT EXISTS nodes_diag_command ON nodes(json_extract(attrs_json, '$.diagCommand')) WHERE valid_to IS NULL;
|
|
26065
26065
|
CREATE INDEX IF NOT EXISTS nodes_lsp_rel_path ON nodes(json_extract(attrs_json, '$.lspRelPath')) WHERE valid_to IS NULL;
|
|
26066
|
+
-- Local nodes by the cloud twin their upload receipt recorded. Every burst /
|
|
26067
|
+
-- search fusion folds the Network copy of the caller's own knowledge back onto
|
|
26068
|
+
-- the local node; unindexed, the reverse lookup was a ~300ms attrs scan per call.
|
|
26069
|
+
CREATE INDEX IF NOT EXISTS nodes_cloud_node_id ON nodes(json_extract(attrs_json, '$.cloudNodeId')) WHERE valid_to IS NULL;
|
|
26066
26070
|
-- Nodes still waiting on a root-cause ask. The MCP server checks this on EVERY
|
|
26067
26071
|
-- tool response (the enrichment piggyback), so it must not parse every
|
|
26068
26072
|
-- Solution's and Problem's attrs per call. Not partial: the Problem pull reads
|
|
@@ -27032,6 +27036,19 @@ var SqliteGraphStore = class {
|
|
|
27032
27036
|
).get(attr, `%${marker}%`, limit);
|
|
27033
27037
|
return { count: Number(r.count), total: Number(r.total) };
|
|
27034
27038
|
}
|
|
27039
|
+
liveNodeIdsByCloudNodeId(cloudIds) {
|
|
27040
|
+
const out2 = /* @__PURE__ */ new Map();
|
|
27041
|
+
const CHUNK = 900;
|
|
27042
|
+
for (let i2 = 0; i2 < cloudIds.length; i2 += CHUNK) {
|
|
27043
|
+
const slice = cloudIds.slice(i2, i2 + CHUNK);
|
|
27044
|
+
if (slice.length === 0) continue;
|
|
27045
|
+
const rows = this.db.prepare(
|
|
27046
|
+
`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`
|
|
27047
|
+
).all(...slice);
|
|
27048
|
+
for (const r of rows) out2.set(r.cloud, [...out2.get(r.cloud) ?? [], r.id]);
|
|
27049
|
+
}
|
|
27050
|
+
return out2;
|
|
27051
|
+
}
|
|
27035
27052
|
liveNodeIds(ids) {
|
|
27036
27053
|
const live = /* @__PURE__ */ new Set();
|
|
27037
27054
|
const CHUNK = 900;
|
|
@@ -27093,7 +27110,10 @@ var SqliteGraphStore = class {
|
|
|
27093
27110
|
if (relPaths.length === 0) return [];
|
|
27094
27111
|
const placeholders = relPaths.map(() => "?").join(",");
|
|
27095
27112
|
const rows = this.db.prepare(
|
|
27096
|
-
|
|
27113
|
+
// INDEXED BY: unforced, the planner took nodes_live_page_rank and
|
|
27114
|
+
// json-parsed every live row — 11–25s per reindexed file pair on the
|
|
27115
|
+
// live store vs 7ms here (2026-10-08).
|
|
27116
|
+
`SELECT * FROM nodes INDEXED BY nodes_relpath WHERE valid_to IS NULL AND json_extract(attrs_json, '$.relPath') IN (${placeholders})`
|
|
27097
27117
|
).all(...relPaths);
|
|
27098
27118
|
return rows.map(rowToNode);
|
|
27099
27119
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
7e11496cf4ef348e9e19cd5d191ad21dd9e54860dcb0c7b67fccd266dde126d1 .codex-plugin/plugin.json
|
|
2
2
|
a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
|
|
3
3
|
fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
|
|
4
4
|
73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js
|