@inerrata-corporation/errata 2.0.8-dev.2881 → 2.0.8-dev.2890
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 +10 -0
- package/errata.mjs +52 -9
- package/package.json +1 -1
- package/pass-worker.mjs +10 -0
package/consolidate-worker.mjs
CHANGED
|
@@ -16146,6 +16146,9 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
|
|
|
16146
16146
|
-- Live rows by name, for looking up the few symbols a statement mentions
|
|
16147
16147
|
-- instead of hydrating every code symbol per minted problem.
|
|
16148
16148
|
CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) WHERE valid_to IS NULL;
|
|
16149
|
+
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
16150
|
+
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
16151
|
+
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
16149
16152
|
`;
|
|
16150
16153
|
function encodeEmbedding(emb) {
|
|
16151
16154
|
if (!emb || emb.length === 0) return null;
|
|
@@ -17004,6 +17007,13 @@ var SqliteGraphStore = class {
|
|
|
17004
17007
|
).all(...relPaths);
|
|
17005
17008
|
return rows.map(rowToNode);
|
|
17006
17009
|
}
|
|
17010
|
+
findLiveNodesByAttr(label, attrPath, value) {
|
|
17011
|
+
if (!/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attrPath)) throw new Error(`invalid attr path: ${attrPath}`);
|
|
17012
|
+
const rows = this.db.prepare(
|
|
17013
|
+
`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attrPath}') = ? AND valid_to IS NULL AND label = ?`
|
|
17014
|
+
).all(value, label);
|
|
17015
|
+
return rows.map(rowToNode);
|
|
17016
|
+
}
|
|
17007
17017
|
// ── Bi-temporal versioning ───────────────────────────────────────────
|
|
17008
17018
|
// NOTE: the adapter's transaction() is non-reentrant (raw BEGIN/COMMIT), and
|
|
17009
17019
|
// the indexer calls freezeNode inside its own store.transaction(). So this
|
package/errata.mjs
CHANGED
|
@@ -17568,6 +17568,9 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
|
|
|
17568
17568
|
-- Live rows by name, for looking up the few symbols a statement mentions
|
|
17569
17569
|
-- instead of hydrating every code symbol per minted problem.
|
|
17570
17570
|
CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) WHERE valid_to IS NULL;
|
|
17571
|
+
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
17572
|
+
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
17573
|
+
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
17571
17574
|
`;
|
|
17572
17575
|
SqliteGraphStore = class {
|
|
17573
17576
|
db;
|
|
@@ -18369,6 +18372,13 @@ CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) W
|
|
|
18369
18372
|
).all(...relPaths);
|
|
18370
18373
|
return rows.map(rowToNode);
|
|
18371
18374
|
}
|
|
18375
|
+
findLiveNodesByAttr(label, attrPath, value) {
|
|
18376
|
+
if (!/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attrPath)) throw new Error(`invalid attr path: ${attrPath}`);
|
|
18377
|
+
const rows = this.db.prepare(
|
|
18378
|
+
`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attrPath}') = ? AND valid_to IS NULL AND label = ?`
|
|
18379
|
+
).all(value, label);
|
|
18380
|
+
return rows.map(rowToNode);
|
|
18381
|
+
}
|
|
18372
18382
|
// ── Bi-temporal versioning ───────────────────────────────────────────
|
|
18373
18383
|
// NOTE: the adapter's transaction() is non-reentrant (raw BEGIN/COMMIT), and
|
|
18374
18384
|
// the indexer calls freezeNode inside its own store.transaction(). So this
|
|
@@ -20645,7 +20655,7 @@ function consumeAnchorHint(store, p, ts) {
|
|
|
20645
20655
|
}
|
|
20646
20656
|
function upgradeAnchorHintsForFile(store, relPath, workspaceId2, ts) {
|
|
20647
20657
|
let upgraded = 0;
|
|
20648
|
-
for (const p of store.
|
|
20658
|
+
for (const p of store.findLiveNodesByAttr("Problem", "anchorHint.path", relPath)) {
|
|
20649
20659
|
if (p.validTo != null || p.attrs["resolvedAt"]) continue;
|
|
20650
20660
|
const hint = openAnchorHint(p);
|
|
20651
20661
|
if (!hint || hint.path !== relPath) continue;
|
|
@@ -80114,7 +80124,7 @@ function createWatchBreaker(deps) {
|
|
|
80114
80124
|
}
|
|
80115
80125
|
|
|
80116
80126
|
// src/engine.ts
|
|
80117
|
-
var DAEMON_VERSION = true ? "2.0.8-dev.
|
|
80127
|
+
var DAEMON_VERSION = true ? "2.0.8-dev.2890" : "2.0.0-alpha.0";
|
|
80118
80128
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
80119
80129
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
80120
80130
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -85807,6 +85817,27 @@ function codexWakeCandidates(input) {
|
|
|
85807
85817
|
return out2;
|
|
85808
85818
|
}
|
|
85809
85819
|
|
|
85820
|
+
// src/wake-policy.ts
|
|
85821
|
+
function wakeIndexPlan(nodeCount, reindexOnStart) {
|
|
85822
|
+
if (nodeCount > 0) return "catch-up";
|
|
85823
|
+
return reindexOnStart ? "full-index" : "skip";
|
|
85824
|
+
}
|
|
85825
|
+
var WAKE_STAGGER_MS = 2e4;
|
|
85826
|
+
function wakeDelay(index, staggerMs = WAKE_STAGGER_MS) {
|
|
85827
|
+
return Math.max(0, index) * staggerMs;
|
|
85828
|
+
}
|
|
85829
|
+
function serialQueue() {
|
|
85830
|
+
let chain2 = Promise.resolve();
|
|
85831
|
+
return (job) => {
|
|
85832
|
+
const run3 = chain2.then(job).then(
|
|
85833
|
+
() => void 0,
|
|
85834
|
+
() => void 0
|
|
85835
|
+
);
|
|
85836
|
+
chain2 = run3;
|
|
85837
|
+
return run3;
|
|
85838
|
+
};
|
|
85839
|
+
}
|
|
85840
|
+
|
|
85810
85841
|
// src/multi.ts
|
|
85811
85842
|
init_profile2();
|
|
85812
85843
|
|
|
@@ -86277,6 +86308,7 @@ async function startMultiDaemon(opts = {}) {
|
|
|
86277
86308
|
);
|
|
86278
86309
|
}
|
|
86279
86310
|
const app = new Hono2();
|
|
86311
|
+
const enqueueWakeIndex = serialQueue();
|
|
86280
86312
|
const attachWorkspace = (root) => {
|
|
86281
86313
|
const norm = normPath(root);
|
|
86282
86314
|
if (records.some((r) => normPath(r.root) === norm)) return { attached: false, id: null, reason: "already-watched" };
|
|
@@ -86306,8 +86338,16 @@ async function startMultiDaemon(opts = {}) {
|
|
|
86306
86338
|
registerWorkspace(rec.engine.profile, rec.root);
|
|
86307
86339
|
} catch {
|
|
86308
86340
|
}
|
|
86309
|
-
|
|
86310
|
-
|
|
86341
|
+
if (wakeIndexPlan(rec.engine.store.nodeCount(), opts.reindexOnStart !== false) === "full-index") {
|
|
86342
|
+
void enqueueWakeIndex(async () => {
|
|
86343
|
+
const done = markPass(`wake-index:${rec.entry.name}`);
|
|
86344
|
+
try {
|
|
86345
|
+
await rec.engine.reindex({ skipEmbed: true });
|
|
86346
|
+
} finally {
|
|
86347
|
+
done();
|
|
86348
|
+
}
|
|
86349
|
+
});
|
|
86350
|
+
}
|
|
86311
86351
|
console.log(`[errata] hot-registered ${rec.entry.name} (${rec.id}) \u2014 now watching live`);
|
|
86312
86352
|
return { attached: true, id: rec.id };
|
|
86313
86353
|
};
|
|
@@ -86583,11 +86623,14 @@ async function startMultiDaemon(opts = {}) {
|
|
|
86583
86623
|
sinceMs: Date.now() - lookback,
|
|
86584
86624
|
disabled: process.env["ERRATA_CODEX_WAKE_DISABLE"] === "1"
|
|
86585
86625
|
});
|
|
86586
|
-
|
|
86587
|
-
|
|
86588
|
-
|
|
86589
|
-
|
|
86590
|
-
|
|
86626
|
+
candidates.forEach((c, i2) => {
|
|
86627
|
+
const wake = setTimeout(() => {
|
|
86628
|
+
if (attachWorkspace(c.path).attached) {
|
|
86629
|
+
console.log(`[errata] woke workspace ${c.name} \u2014 recent Codex/Gemini/OpenCode transcript (headless capture)`);
|
|
86630
|
+
}
|
|
86631
|
+
}, wakeDelay(i2));
|
|
86632
|
+
wake.unref?.();
|
|
86633
|
+
});
|
|
86591
86634
|
};
|
|
86592
86635
|
const codexWake = setInterval(sweepCodexWake, WORKSPACE_SWEEP_INTERVAL_MS);
|
|
86593
86636
|
codexWake.unref?.();
|
package/package.json
CHANGED
package/pass-worker.mjs
CHANGED
|
@@ -24528,6 +24528,9 @@ CREATE INDEX IF NOT EXISTS nodes_relpath ON nodes(json_extract(attrs_json, '$.re
|
|
|
24528
24528
|
-- Live rows by name, for looking up the few symbols a statement mentions
|
|
24529
24529
|
-- instead of hydrating every code symbol per minted problem.
|
|
24530
24530
|
CREATE INDEX IF NOT EXISTS nodes_live_description ON nodes(description, label) WHERE valid_to IS NULL;
|
|
24531
|
+
-- Problems by the file their anchor hint names: the harvest upgrades hints for
|
|
24532
|
+
-- every edited file of every turn, and a scan parses every Problem's attrs.
|
|
24533
|
+
CREATE INDEX IF NOT EXISTS nodes_anchor_hint_path ON nodes(json_extract(attrs_json, '$.anchorHint.path')) WHERE valid_to IS NULL;
|
|
24531
24534
|
`;
|
|
24532
24535
|
function encodeEmbedding(emb) {
|
|
24533
24536
|
if (!emb || emb.length === 0) return null;
|
|
@@ -25386,6 +25389,13 @@ var SqliteGraphStore = class {
|
|
|
25386
25389
|
).all(...relPaths);
|
|
25387
25390
|
return rows.map(rowToNode);
|
|
25388
25391
|
}
|
|
25392
|
+
findLiveNodesByAttr(label, attrPath, value) {
|
|
25393
|
+
if (!/^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/.test(attrPath)) throw new Error(`invalid attr path: ${attrPath}`);
|
|
25394
|
+
const rows = this.db.prepare(
|
|
25395
|
+
`SELECT * FROM nodes WHERE json_extract(attrs_json, '$.${attrPath}') = ? AND valid_to IS NULL AND label = ?`
|
|
25396
|
+
).all(value, label);
|
|
25397
|
+
return rows.map(rowToNode);
|
|
25398
|
+
}
|
|
25389
25399
|
// ── Bi-temporal versioning ───────────────────────────────────────────
|
|
25390
25400
|
// NOTE: the adapter's transaction() is non-reentrant (raw BEGIN/COMMIT), and
|
|
25391
25401
|
// the indexer calls freezeNode inside its own store.transaction(). So this
|