@inerrata-corporation/errata 2.0.6-dev.2627 → 2.0.6-dev.2632
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 +18 -0
- package/errata.mjs +50 -13
- package/package.json +1 -1
- package/pass-worker.mjs +18 -0
package/consolidate-worker.mjs
CHANGED
|
@@ -16143,6 +16143,9 @@ CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
|
16143
16143
|
-- incremental reindex can fetch just the changed files' symbols instead of
|
|
16144
16144
|
-- scanning every versioned node. Partial: only live rows are ever queried.
|
|
16145
16145
|
CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.relPath')) WHERE valid_to IS NULL;
|
|
16146
|
+
-- Live rows by name, for looking up the few symbols a statement mentions
|
|
16147
|
+
-- instead of hydrating every code symbol per minted problem.
|
|
16148
|
+
CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) WHERE valid_to IS NULL;
|
|
16146
16149
|
`;
|
|
16147
16150
|
function encodeEmbedding(emb) {
|
|
16148
16151
|
if (!emb || emb.length === 0) return null;
|
|
@@ -16957,6 +16960,21 @@ var SqliteGraphStore = class {
|
|
|
16957
16960
|
/** Live nodes whose attrs.relPath is one of `relPaths`. Uses the nodes_relpath
|
|
16958
16961
|
* expression index so the incremental reindex fetches only the changed files'
|
|
16959
16962
|
* symbols instead of scanning every versioned node. */
|
|
16963
|
+
/** Live nodes of `labels` whose description is exactly one of `names`, via
|
|
16964
|
+
* the nodes_live_description index. Chunked under the bound-parameter cap. */
|
|
16965
|
+
liveNodesByDescription(names, labels) {
|
|
16966
|
+
if (names.length === 0 || labels.length === 0) return [];
|
|
16967
|
+
const out = [];
|
|
16968
|
+
const labelPh = labels.map(() => "?").join(",");
|
|
16969
|
+
for (let i = 0; i < names.length; i += 400) {
|
|
16970
|
+
const chunk = names.slice(i, i + 400);
|
|
16971
|
+
const rows = this.db.prepare(
|
|
16972
|
+
`SELECT * FROM nodes WHERE valid_to IS NULL AND description IN (${chunk.map(() => "?").join(",")}) AND label IN (${labelPh})`
|
|
16973
|
+
).all(...chunk, ...labels);
|
|
16974
|
+
for (const r of rows) out.push(rowToNode(r));
|
|
16975
|
+
}
|
|
16976
|
+
return out;
|
|
16977
|
+
}
|
|
16960
16978
|
nodesByRelPath(relPaths) {
|
|
16961
16979
|
if (relPaths.length === 0) return [];
|
|
16962
16980
|
const placeholders = relPaths.map(() => "?").join(",");
|
package/errata.mjs
CHANGED
|
@@ -17560,6 +17560,9 @@ CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
|
17560
17560
|
-- incremental reindex can fetch just the changed files' symbols instead of
|
|
17561
17561
|
-- scanning every versioned node. Partial: only live rows are ever queried.
|
|
17562
17562
|
CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.relPath')) WHERE valid_to IS NULL;
|
|
17563
|
+
-- Live rows by name, for looking up the few symbols a statement mentions
|
|
17564
|
+
-- instead of hydrating every code symbol per minted problem.
|
|
17565
|
+
CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) WHERE valid_to IS NULL;
|
|
17563
17566
|
`;
|
|
17564
17567
|
SqliteGraphStore = class {
|
|
17565
17568
|
db;
|
|
@@ -18317,6 +18320,21 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
|
|
|
18317
18320
|
/** Live nodes whose attrs.relPath is one of `relPaths`. Uses the nodes_relpath
|
|
18318
18321
|
* expression index so the incremental reindex fetches only the changed files'
|
|
18319
18322
|
* symbols instead of scanning every versioned node. */
|
|
18323
|
+
/** Live nodes of `labels` whose description is exactly one of `names`, via
|
|
18324
|
+
* the nodes_live_description index. Chunked under the bound-parameter cap. */
|
|
18325
|
+
liveNodesByDescription(names, labels) {
|
|
18326
|
+
if (names.length === 0 || labels.length === 0) return [];
|
|
18327
|
+
const out2 = [];
|
|
18328
|
+
const labelPh = labels.map(() => "?").join(",");
|
|
18329
|
+
for (let i2 = 0; i2 < names.length; i2 += 400) {
|
|
18330
|
+
const chunk = names.slice(i2, i2 + 400);
|
|
18331
|
+
const rows = this.db.prepare(
|
|
18332
|
+
`SELECT * FROM nodes WHERE valid_to IS NULL AND description IN (${chunk.map(() => "?").join(",")}) AND label IN (${labelPh})`
|
|
18333
|
+
).all(...chunk, ...labels);
|
|
18334
|
+
for (const r of rows) out2.push(rowToNode(r));
|
|
18335
|
+
}
|
|
18336
|
+
return out2;
|
|
18337
|
+
}
|
|
18320
18338
|
nodesByRelPath(relPaths) {
|
|
18321
18339
|
if (relPaths.length === 0) return [];
|
|
18322
18340
|
const placeholders = relPaths.map(() => "?").join(",");
|
|
@@ -19303,6 +19321,33 @@ function buildSymbolIndex(store) {
|
|
|
19303
19321
|
}
|
|
19304
19322
|
return idx;
|
|
19305
19323
|
}
|
|
19324
|
+
function symbolCandidatesInText(text) {
|
|
19325
|
+
const out2 = /* @__PURE__ */ new Set();
|
|
19326
|
+
for (const run3 of text.match(/[\w$.]+/g) ?? []) {
|
|
19327
|
+
const segs = run3.split(".");
|
|
19328
|
+
for (let i2 = 0; i2 < segs.length; i2++) {
|
|
19329
|
+
if (!segs[i2]) continue;
|
|
19330
|
+
let name2 = "";
|
|
19331
|
+
for (let j = i2; j < segs.length && segs[j]; j++) {
|
|
19332
|
+
name2 = j === i2 ? segs[j] : `${name2}.${segs[j]}`;
|
|
19333
|
+
if (isShapedSymbol(name2)) out2.add(name2);
|
|
19334
|
+
}
|
|
19335
|
+
}
|
|
19336
|
+
}
|
|
19337
|
+
return [...out2];
|
|
19338
|
+
}
|
|
19339
|
+
function symbolIndexForText(store, text) {
|
|
19340
|
+
const counts = /* @__PURE__ */ new Map();
|
|
19341
|
+
for (const n of store.liveNodesByDescription(symbolCandidatesInText(text), SYMBOL_LABELS)) {
|
|
19342
|
+
const name2 = n.description.trim();
|
|
19343
|
+
const list = counts.get(name2);
|
|
19344
|
+
if (list) list.push(n);
|
|
19345
|
+
else counts.set(name2, [n]);
|
|
19346
|
+
}
|
|
19347
|
+
const idx = /* @__PURE__ */ new Map();
|
|
19348
|
+
for (const [name2, nodes] of counts) if (nodes.length === 1) idx.set(name2, nodes[0]);
|
|
19349
|
+
return idx;
|
|
19350
|
+
}
|
|
19306
19351
|
function matchSymbolsInText(text, index) {
|
|
19307
19352
|
const out2 = [];
|
|
19308
19353
|
for (const [name2, node2] of index) {
|
|
@@ -19315,19 +19360,9 @@ function matchSymbolsInText(text, index) {
|
|
|
19315
19360
|
function linkProblemToSymbols(store, problemId, text, ts, index) {
|
|
19316
19361
|
const p = store.getNode(problemId);
|
|
19317
19362
|
if (!p || p.label !== "Problem") return [];
|
|
19318
|
-
const idx = index ??
|
|
19363
|
+
const idx = index ?? symbolIndexForText(store, text);
|
|
19319
19364
|
if (idx.size === 0) return [];
|
|
19320
|
-
|
|
19321
|
-
const fileFor2 = (relPath) => {
|
|
19322
|
-
if (!fileByPath) {
|
|
19323
|
-
fileByPath = /* @__PURE__ */ new Map();
|
|
19324
|
-
for (const f of store.findNodesByLabel("File")) {
|
|
19325
|
-
const rp = String(f.attrs["relPath"] ?? f.description ?? "");
|
|
19326
|
-
if (rp) fileByPath.set(rp, f);
|
|
19327
|
-
}
|
|
19328
|
-
}
|
|
19329
|
-
return fileByPath.get(relPath) ?? null;
|
|
19330
|
-
};
|
|
19365
|
+
const fileFor2 = (relPath) => store.nodesByRelPath([relPath]).find((f) => f.label === "File") ?? null;
|
|
19331
19366
|
const already = new Set(store.outEdges(problemId, ["ANCHORED_AT"]).map((e) => e.to));
|
|
19332
19367
|
const linked = [];
|
|
19333
19368
|
for (const sym of matchSymbolsInText(text, idx)) {
|
|
@@ -24052,6 +24087,8 @@ __export(src_exports2, {
|
|
|
24052
24087
|
stampObservedOs: () => stampObservedOs,
|
|
24053
24088
|
statementIdentityKey: () => statementIdentityKey,
|
|
24054
24089
|
staticConductance: () => staticConductance,
|
|
24090
|
+
symbolCandidatesInText: () => symbolCandidatesInText,
|
|
24091
|
+
symbolIndexForText: () => symbolIndexForText,
|
|
24055
24092
|
toolNodeId: () => toolNodeId,
|
|
24056
24093
|
toolPriorsFor: () => toolPriorsFor,
|
|
24057
24094
|
triageOf: () => triageOf,
|
|
@@ -78478,7 +78515,7 @@ function createWatchBreaker(deps) {
|
|
|
78478
78515
|
}
|
|
78479
78516
|
|
|
78480
78517
|
// src/engine.ts
|
|
78481
|
-
var DAEMON_VERSION = true ? "2.0.6-dev.
|
|
78518
|
+
var DAEMON_VERSION = true ? "2.0.6-dev.2632" : "2.0.0-alpha.0";
|
|
78482
78519
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
78483
78520
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
78484
78521
|
var GIT_OP_MUTE_MS = 4e3;
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -24525,6 +24525,9 @@ CREATE INDEX IF NOT EXISTS edges_live ON edges(valid_to);
|
|
|
24525
24525
|
-- incremental reindex can fetch just the changed files' symbols instead of
|
|
24526
24526
|
-- scanning every versioned node. Partial: only live rows are ever queried.
|
|
24527
24527
|
CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.relPath')) WHERE valid_to IS NULL;
|
|
24528
|
+
-- Live rows by name, for looking up the few symbols a statement mentions
|
|
24529
|
+
-- instead of hydrating every code symbol per minted problem.
|
|
24530
|
+
CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) WHERE valid_to IS NULL;
|
|
24528
24531
|
`;
|
|
24529
24532
|
function encodeEmbedding(emb) {
|
|
24530
24533
|
if (!emb || emb.length === 0) return null;
|
|
@@ -25339,6 +25342,21 @@ var SqliteGraphStore = class {
|
|
|
25339
25342
|
/** Live nodes whose attrs.relPath is one of `relPaths`. Uses the nodes_relpath
|
|
25340
25343
|
* expression index so the incremental reindex fetches only the changed files'
|
|
25341
25344
|
* symbols instead of scanning every versioned node. */
|
|
25345
|
+
/** Live nodes of `labels` whose description is exactly one of `names`, via
|
|
25346
|
+
* the nodes_live_description index. Chunked under the bound-parameter cap. */
|
|
25347
|
+
liveNodesByDescription(names, labels) {
|
|
25348
|
+
if (names.length === 0 || labels.length === 0) return [];
|
|
25349
|
+
const out2 = [];
|
|
25350
|
+
const labelPh = labels.map(() => "?").join(",");
|
|
25351
|
+
for (let i2 = 0; i2 < names.length; i2 += 400) {
|
|
25352
|
+
const chunk = names.slice(i2, i2 + 400);
|
|
25353
|
+
const rows = this.db.prepare(
|
|
25354
|
+
`SELECT * FROM nodes WHERE valid_to IS NULL AND description IN (${chunk.map(() => "?").join(",")}) AND label IN (${labelPh})`
|
|
25355
|
+
).all(...chunk, ...labels);
|
|
25356
|
+
for (const r of rows) out2.push(rowToNode(r));
|
|
25357
|
+
}
|
|
25358
|
+
return out2;
|
|
25359
|
+
}
|
|
25342
25360
|
nodesByRelPath(relPaths) {
|
|
25343
25361
|
if (relPaths.length === 0) return [];
|
|
25344
25362
|
const placeholders = relPaths.map(() => "?").join(",");
|