@inerrata-corporation/errata 2.0.22-dev.4638 → 2.0.22-dev.4641

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.
@@ -18253,6 +18253,22 @@ var SqliteGraphStore = class {
18253
18253
  AND (t.id IS NULL OR t.valid_to IS NOT NULL)
18254
18254
  `).all();
18255
18255
  }
18256
+ strandedSymbolsForFiles(fileIds) {
18257
+ const out = [];
18258
+ for (let i = 0; i < fileIds.length; i += 500) {
18259
+ const slice = fileIds.slice(i, i + 500);
18260
+ if (slice.length === 0) continue;
18261
+ out.push(...this.db.prepare(`
18262
+ SELECT f.id AS fileId, e.to_id AS symbolId
18263
+ FROM nodes f CROSS JOIN edges e ON e.from_id = f.id
18264
+ LEFT JOIN nodes t ON t.id = e.to_id
18265
+ WHERE f.id IN (${slice.map(() => "?").join(",")}) AND f.label = 'File' AND f.valid_to IS NULL AND e.valid_to IS NULL
18266
+ AND e.type IN ('DEFINES', 'CONTAINS')
18267
+ AND (t.id IS NULL OR t.valid_to IS NOT NULL)
18268
+ `).all(...slice));
18269
+ }
18270
+ return out;
18271
+ }
18256
18272
  strandedEdges() {
18257
18273
  return countStrandedEdges(this.db);
18258
18274
  }
@@ -21754,7 +21770,7 @@ function runPass(msg) {
21754
21770
  return revisitContradictedPrinciples(shared, msg.ts ?? Date.now());
21755
21771
  case "strandedCount": {
21756
21772
  if (!msg.castaliaPath) throw new Error("strandedCount: castaliaPath required");
21757
- return findStrandedSymbols(storeAt(msg.castaliaPath)).length;
21773
+ return findStrandedSymbols(storeAt(msg.castaliaPath));
21758
21774
  }
21759
21775
  case "drainContext": {
21760
21776
  if (!msg.castaliaPath) throw new Error("drainContext: castaliaPath required");
package/errata.mjs CHANGED
@@ -21105,6 +21105,22 @@ CREATE INDEX IF NOT EXISTS nodes_revisit_true ON nodes(valid_from) WHERE json_ty
21105
21105
  AND (t.id IS NULL OR t.valid_to IS NOT NULL)
21106
21106
  `).all();
21107
21107
  }
21108
+ strandedSymbolsForFiles(fileIds) {
21109
+ const out2 = [];
21110
+ for (let i2 = 0; i2 < fileIds.length; i2 += 500) {
21111
+ const slice = fileIds.slice(i2, i2 + 500);
21112
+ if (slice.length === 0) continue;
21113
+ out2.push(...this.db.prepare(`
21114
+ SELECT f.id AS fileId, e.to_id AS symbolId
21115
+ FROM nodes f CROSS JOIN edges e ON e.from_id = f.id
21116
+ LEFT JOIN nodes t ON t.id = e.to_id
21117
+ WHERE f.id IN (${slice.map(() => "?").join(",")}) AND f.label = 'File' AND f.valid_to IS NULL AND e.valid_to IS NULL
21118
+ AND e.type IN ('DEFINES', 'CONTAINS')
21119
+ AND (t.id IS NULL OR t.valid_to IS NOT NULL)
21120
+ `).all(...slice));
21121
+ }
21122
+ return out2;
21123
+ }
21108
21124
  strandedEdges() {
21109
21125
  return countStrandedEdges(this.db);
21110
21126
  }
@@ -47122,14 +47138,31 @@ function standingStrandedCount(store) {
47122
47138
  try {
47123
47139
  const last = JSON.parse(store.getMeta?.(STRANDED_KEY) ?? "null");
47124
47140
  if (!last) return null;
47125
- if ((store.changeSeq?.() ?? Infinity) - last.seq > STRANDED_WINDOW_MAX) return null;
47126
- return store.lineageChangedFiles?.(last.seq)?.length === 0 ? last.count : null;
47141
+ const seq = store.changeSeq?.();
47142
+ if ((seq ?? Infinity) - last.seq > STRANDED_WINDOW_MAX) return null;
47143
+ const changed = store.lineageChangedFiles?.(last.seq);
47144
+ if (!changed) return null;
47145
+ if (changed.length === 0) return last.count;
47146
+ if (!last.byFile || !store.strandedSymbolsForFiles || seq === void 0) return null;
47147
+ const byFile = { ...last.byFile };
47148
+ for (const f of changed) delete byFile[f];
47149
+ for (const s of store.strandedSymbolsForFiles(changed)) byFile[s.fileId] = (byFile[s.fileId] ?? 0) + 1;
47150
+ const count = Object.values(byFile).reduce((a, b) => a + b, 0);
47151
+ store.setMeta?.(STRANDED_KEY, JSON.stringify({ seq, count, byFile }));
47152
+ return count;
47127
47153
  } catch {
47128
47154
  return null;
47129
47155
  }
47130
47156
  }
47131
- function recordStrandedCount(store, seq, count) {
47132
- if (seq !== void 0) store.setMeta?.(STRANDED_KEY, JSON.stringify({ seq, count }));
47157
+ function recordStrandedCount(store, seq, stranded) {
47158
+ if (seq === void 0) return;
47159
+ if (typeof stranded === "number") {
47160
+ store.setMeta?.(STRANDED_KEY, JSON.stringify({ seq, count: stranded }));
47161
+ return;
47162
+ }
47163
+ const byFile = {};
47164
+ for (const s of stranded) byFile[s.fileId] = (byFile[s.fileId] ?? 0) + 1;
47165
+ store.setMeta?.(STRANDED_KEY, JSON.stringify({ seq, count: stranded.length, byFile }));
47133
47166
  }
47134
47167
  function reapOrphanedFiles(store, rootPath, workspaceId2, ignoreDirs = []) {
47135
47168
  const ignores = /* @__PURE__ */ new Set([...DEFAULT_IGNORES, ...ignoreDirs]);
@@ -80199,7 +80232,7 @@ import { readFileSync as readFileSync18, renameSync as renameSync3, statSync as
80199
80232
  import { fileURLToPath as fileURLToPath2 } from "node:url";
80200
80233
  import { dirname as dirname11, join as join22 } from "node:path";
80201
80234
  function snapshotReusable(held, want) {
80202
- return held !== null && held.key === want.key && held.atCommit === want.atCommit && held.workingFile === want.workingFile;
80235
+ return held !== null && held.key === want.key && held.atCommit === want.atCommit;
80203
80236
  }
80204
80237
  var codeIdentityMemo;
80205
80238
  function snapshotCodeIdentity(version3) {
@@ -86861,7 +86894,7 @@ function createWatchBreaker(deps) {
86861
86894
  }
86862
86895
 
86863
86896
  // src/engine.ts
86864
- var DAEMON_VERSION = true ? "2.0.22-dev.4638" : "2.0.0-alpha.0";
86897
+ var DAEMON_VERSION = true ? "2.0.22-dev.4641" : "2.0.0-alpha.0";
86865
86898
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
86866
86899
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
86867
86900
  var GIT_OP_MUTE_MS = 4e3;
@@ -87374,10 +87407,18 @@ function createWorkspaceEngine(opts) {
87374
87407
  };
87375
87408
  const changes = store.changeSeq ? store.changeSeq() - store.changeSeq([EXPOSURE_SCOPE]) : store.changeStamp();
87376
87409
  const { id, name: name2, stack, languages, domains, goals } = snapOpts.profile;
87377
- const snapshotKey = `${snapshotCodeIdentity(DAEMON_VERSION)}|${changes}|${JSON.stringify({ ...snapOpts, profile: { id, name: name2, stack, languages, domains, goals } })}`;
87410
+ const { workingFile: _workingFile, ...keyedOpts } = snapOpts;
87411
+ const snapshotKey = `${snapshotCodeIdentity(DAEMON_VERSION)}|${changes}|${JSON.stringify({ ...keyedOpts, profile: { id, name: name2, stack, languages, domains, goals } })}`;
87378
87412
  lastWorkerSnapshot ??= loadHeldSnapshot(heldSnapshotPath(paths.configDir));
87379
87413
  const held = lastWorkerSnapshot;
87380
- const prebuilt = snapshotReusable(held, { key: snapshotKey, atCommit: snapOpts.atCommit, workingFile: snapOpts.workingFile }) ? structuredClone(held.snapshot) : passWorker ? await passWorker.snapshot(snapOpts).then((snapshot2) => {
87414
+ const withWorkingFile = (snap, builtFor, want, atCommit) => {
87415
+ if (builtFor === want) return snap;
87416
+ const slice = want ? sliceForFile(store, want, atCommit) : void 0;
87417
+ if (slice) snap.workingFile = slice;
87418
+ else delete snap.workingFile;
87419
+ return snap;
87420
+ };
87421
+ const prebuilt = snapshotReusable(held, { key: snapshotKey, atCommit: snapOpts.atCommit }) ? withWorkingFile(structuredClone(held.snapshot), held.workingFile, snapOpts.workingFile, snapOpts.atCommit) : passWorker ? await passWorker.snapshot(snapOpts).then((snapshot2) => {
87381
87422
  lastWorkerSnapshot = { key: snapshotKey, at: Date.now(), atCommit: snapOpts.atCommit, workingFile: snapOpts.workingFile, snapshot: structuredClone(snapshot2) };
87382
87423
  saveHeldSnapshot(heldSnapshotPath(paths.configDir), lastWorkerSnapshot);
87383
87424
  return snapshot2;
@@ -95314,17 +95355,17 @@ async function startMultiDaemon(opts = {}) {
95314
95355
  if (!strandedRefreshing.has(r.id)) {
95315
95356
  strandedRefreshing.add(r.id);
95316
95357
  const seq = store.changeSeq?.();
95317
- const finish = (count) => {
95318
- strandedCache.set(r.id, { at: Date.now(), count });
95358
+ const finish = (stranded) => {
95359
+ strandedCache.set(r.id, { at: Date.now(), count: stranded.length });
95319
95360
  strandedRefreshing.delete(r.id);
95320
- recordStrandedCount(store, seq, count);
95361
+ recordStrandedCount(store, seq, stranded);
95321
95362
  };
95322
95363
  if (consolidateWorker && r.engine.paths.castalia !== ":memory:") {
95323
- consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((n) => finish(Number(n))).catch(() => {
95364
+ consolidateWorker.run({ kind: "strandedCount", sharedDbPath, castaliaPath: r.engine.paths.castalia }).then((stranded) => finish(Array.isArray(stranded) ? stranded : [])).catch(() => {
95324
95365
  setImmediate(() => {
95325
95366
  const done = markPass(`stranded-scan:${r.entry.name}`);
95326
95367
  try {
95327
- finish(findStrandedSymbols(r.engine.store).length);
95368
+ finish(findStrandedSymbols(r.engine.store));
95328
95369
  } catch {
95329
95370
  strandedRefreshing.delete(r.id);
95330
95371
  } finally {
@@ -95336,7 +95377,7 @@ async function startMultiDaemon(opts = {}) {
95336
95377
  setImmediate(() => {
95337
95378
  const done = markPass(`stranded-scan:${r.entry.name}`);
95338
95379
  try {
95339
- finish(findStrandedSymbols(r.engine.store).length);
95380
+ finish(findStrandedSymbols(r.engine.store));
95340
95381
  } catch {
95341
95382
  strandedRefreshing.delete(r.id);
95342
95383
  } finally {
@@ -16650,6 +16650,22 @@ var SqliteGraphStore = class {
16650
16650
  AND (t.id IS NULL OR t.valid_to IS NOT NULL)
16651
16651
  `).all();
16652
16652
  }
16653
+ strandedSymbolsForFiles(fileIds) {
16654
+ const out = [];
16655
+ for (let i = 0; i < fileIds.length; i += 500) {
16656
+ const slice = fileIds.slice(i, i + 500);
16657
+ if (slice.length === 0) continue;
16658
+ out.push(...this.db.prepare(`
16659
+ SELECT f.id AS fileId, e.to_id AS symbolId
16660
+ FROM nodes f CROSS JOIN edges e ON e.from_id = f.id
16661
+ LEFT JOIN nodes t ON t.id = e.to_id
16662
+ WHERE f.id IN (${slice.map(() => "?").join(",")}) AND f.label = 'File' AND f.valid_to IS NULL AND e.valid_to IS NULL
16663
+ AND e.type IN ('DEFINES', 'CONTAINS')
16664
+ AND (t.id IS NULL OR t.valid_to IS NOT NULL)
16665
+ `).all(...slice));
16666
+ }
16667
+ return out;
16668
+ }
16653
16669
  strandedEdges() {
16654
16670
  return countStrandedEdges(this.db);
16655
16671
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.22-dev.4638",
3
+ "version": "2.0.22-dev.4641",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -27528,6 +27528,22 @@ var SqliteGraphStore = class {
27528
27528
  AND (t.id IS NULL OR t.valid_to IS NOT NULL)
27529
27529
  `).all();
27530
27530
  }
27531
+ strandedSymbolsForFiles(fileIds) {
27532
+ const out2 = [];
27533
+ for (let i2 = 0; i2 < fileIds.length; i2 += 500) {
27534
+ const slice = fileIds.slice(i2, i2 + 500);
27535
+ if (slice.length === 0) continue;
27536
+ out2.push(...this.db.prepare(`
27537
+ SELECT f.id AS fileId, e.to_id AS symbolId
27538
+ FROM nodes f CROSS JOIN edges e ON e.from_id = f.id
27539
+ LEFT JOIN nodes t ON t.id = e.to_id
27540
+ WHERE f.id IN (${slice.map(() => "?").join(",")}) AND f.label = 'File' AND f.valid_to IS NULL AND e.valid_to IS NULL
27541
+ AND e.type IN ('DEFINES', 'CONTAINS')
27542
+ AND (t.id IS NULL OR t.valid_to IS NOT NULL)
27543
+ `).all(...slice));
27544
+ }
27545
+ return out2;
27546
+ }
27531
27547
  strandedEdges() {
27532
27548
  return countStrandedEdges(this.db);
27533
27549
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "errata-context",
3
- "version": "2.0.22-dev.4638",
3
+ "version": "2.0.22-dev.4641",
4
4
  "description": "A minimal 3D view of loaded Errata priors and recent graph bursts.",
5
5
  "author": {
6
6
  "name": "inErrata"
@@ -1,4 +1,4 @@
1
- 16485de5505d71b8dbb138984d557208bdfde9d8bf52baff33f96a477df65145 .codex-plugin/plugin.json
1
+ ad67194b8165c74c1b5c411cac4f968637fe21c28e678627b77597b0b54c2339 .codex-plugin/plugin.json
2
2
  a7bebae9fb01c838d6c75fc784129e28be571233fa66ff5ee8039b574f35ccf7 assets/icon.png
3
3
  fc38b64e4df1e0b72c35764bef6c4c05430d97c9009ad0ecc8a9e75b4deab232 configure-local.mjs
4
4
  73dc6028b3b070257c7c31f252d11e55a9e096f4aed0f187f10cb21716e1e6d7 dist/client.js