@inerrata-corporation/errata 2.0.0-dev.30 → 2.0.0-dev.31

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.
Files changed (3) hide show
  1. package/errata.mjs +57 -14
  2. package/package.json +1 -1
  3. package/pass-worker.mjs +62 -43
package/errata.mjs CHANGED
@@ -26207,8 +26207,8 @@ async function runIndexer(store, opts) {
26207
26207
  if (reExports.length > 0) reExportsByFile.set(f.relPath, reExports);
26208
26208
  report.filesParsed++;
26209
26209
  report.byLanguage[f.provider.id] = (report.byLanguage[f.provider.id] ?? 0) + 1;
26210
- if (report.filesParsed % 250 === 0) {
26211
- perf(`parse @ ${report.filesParsed}/${files.length}`);
26210
+ if (report.filesParsed % 250 === 0) perf(`parse @ ${report.filesParsed}/${files.length}`);
26211
+ if (report.filesParsed % 25 === 0) {
26212
26212
  await new Promise((r) => setImmediate(r));
26213
26213
  }
26214
26214
  }
@@ -26370,7 +26370,12 @@ async function runIndexer(store, opts) {
26370
26370
  const pendingEdges = [];
26371
26371
  perf("index-build (exports/imports/workspace-pkgs/re-export-fixpoint)");
26372
26372
  const providerByRel = new Map(files.map((x) => [x.relPath, x.provider]));
26373
+ let emittedFiles = 0;
26373
26374
  for (const [relPath, symbols] of symbolsByFile) {
26375
+ if (emittedFiles > 0 && emittedFiles % 50 === 0) {
26376
+ await new Promise((r) => setImmediate(r));
26377
+ }
26378
+ emittedFiles++;
26374
26379
  store.transaction(() => {
26375
26380
  const fileId = fileNodeId(opts.workspaceId, relPath);
26376
26381
  const langProvider = providerByRel.get(relPath);
@@ -26565,6 +26570,7 @@ async function runIndexer(store, opts) {
26565
26570
  if (pendingEdges.length > 0) {
26566
26571
  const EDGE_BATCH = 5e3;
26567
26572
  for (let ei = 0; ei < pendingEdges.length; ei += EDGE_BATCH) {
26573
+ if (ei > 0) await new Promise((r) => setImmediate(r));
26568
26574
  const slice = pendingEdges.slice(ei, ei + EDGE_BATCH);
26569
26575
  store.transaction(() => {
26570
26576
  for (const e of slice) {
@@ -40284,6 +40290,12 @@ var PassWorker = class {
40284
40290
  snapshot(opts) {
40285
40291
  return this.call("snapshot", opts);
40286
40292
  }
40293
+ /** Run an fs/git incremental reindex on the worker — `incrementalReindex`
40294
+ * embeds a full-workspace `runIndexer` (cross-file re-resolution), which held
40295
+ * the main loop ~30s+ per saved file when run inline (HZ-reindex-offload). */
40296
+ reindex(opts) {
40297
+ return this.call("reindex", opts);
40298
+ }
40287
40299
  call(kind, payload) {
40288
40300
  if (this.stopped) return Promise.reject(new Error("pass worker stopped"));
40289
40301
  this.ensureWorker();
@@ -41363,7 +41375,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
41363
41375
  }
41364
41376
 
41365
41377
  // src/engine.ts
41366
- var DAEMON_VERSION = true ? "2.0.0-dev.30" : "2.0.0-alpha.0";
41378
+ var DAEMON_VERSION = true ? "2.0.0-dev.31" : "2.0.0-alpha.0";
41367
41379
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
41368
41380
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
41369
41381
  var GIT_OP_MUTE_MS = 4e3;
@@ -41485,6 +41497,36 @@ function createWorkspaceEngine(opts) {
41485
41497
  watcher.on("add", onFs("fs.add"));
41486
41498
  watcher.on("change", onFs("fs.change"));
41487
41499
  watcher.on("unlink", onFs("fs.unlink"));
41500
+ const auditIdentity = (t, e) => {
41501
+ appendIdentityAudit(identityAuditPath, e, JSON.stringify({ t, ...e }) + "\n");
41502
+ };
41503
+ const runReindexPass = async (passName, changed, t, declaredRenames) => {
41504
+ if (passWorker) {
41505
+ try {
41506
+ const { identityEvaluations, ...r } = await passWorker.reindex({
41507
+ changedAbsPaths: changed,
41508
+ t,
41509
+ ...declaredRenames !== void 0 ? { declaredRenames } : {}
41510
+ });
41511
+ for (const e of identityEvaluations) auditIdentity(t, e);
41512
+ return r;
41513
+ } catch (err2) {
41514
+ console.warn(
41515
+ "[errata] reindex worker unavailable, running inline:",
41516
+ err2 instanceof Error ? err2.message : err2
41517
+ );
41518
+ }
41519
+ }
41520
+ const done = markPass(passName);
41521
+ try {
41522
+ return await incrementalReindex(store, opts.workspaceRoot, profile.id, changed, t, {
41523
+ onIdentityEvaluate: (e) => auditIdentity(t, e),
41524
+ ...declaredRenames !== void 0 ? { declaredRenames } : {}
41525
+ });
41526
+ } finally {
41527
+ done();
41528
+ }
41529
+ };
41488
41530
  const dirty = /* @__PURE__ */ new Set();
41489
41531
  let gitOpMuteUntil = 0;
41490
41532
  const scheduleFlush = () => {
@@ -41496,13 +41538,12 @@ function createWorkspaceEngine(opts) {
41496
41538
  const t = Date.now();
41497
41539
  const relChanged = changed.map((p) => relative6(opts.workspaceRoot, p).split(sep4).join("/"));
41498
41540
  const causal = causalBuffer.correlate(relChanged, t) ?? void 0;
41499
- const doneReindex = markPass(`fs-reindex:${profile.name} (${changed.length} files)`);
41500
- void incrementalReindex(store, opts.workspaceRoot, profile.id, changed, t, {
41501
- onIdentityEvaluate: (e) => {
41502
- appendIdentityAudit(identityAuditPath, e, JSON.stringify({ t, ...e }) + "\n");
41503
- },
41504
- declaredRenames: causal?.declaredRenames
41505
- }).finally(doneReindex).then((r) => {
41541
+ void runReindexPass(
41542
+ `fs-reindex:${profile.name} (${changed.length} files)`,
41543
+ changed,
41544
+ t,
41545
+ causal?.declaredRenames
41546
+ ).then((r) => {
41506
41547
  if (r.filesReindexed > 0) {
41507
41548
  console.log(
41508
41549
  `[errata] incremental reindex: ${r.filesReindexed} file(s), +${r.nodesEmitted} nodes / +${r.edgesEmitted} edges`
@@ -41560,9 +41601,13 @@ function createWorkspaceEngine(opts) {
41560
41601
  let episodeId2;
41561
41602
  if (srcPaths.length > 0) {
41562
41603
  const abs = srcPaths.map((p) => join19(opts.workspaceRoot, p));
41563
- const doneReindex = markPass(`git-reindex:${profile.name} (${abs.length} files)`);
41564
41604
  try {
41565
- const r = await incrementalReindex(store, opts.workspaceRoot, profile.id, abs, t, { declaredRenames });
41605
+ const r = await runReindexPass(
41606
+ `git-reindex:${profile.name} (${abs.length} files)`,
41607
+ abs,
41608
+ t,
41609
+ declaredRenames
41610
+ );
41566
41611
  if (r.filesReindexed > 0) {
41567
41612
  const epId = recordEpisode(store, profile.id, t, r.delta, void 0);
41568
41613
  if (epId) {
@@ -41573,8 +41618,6 @@ function createWorkspaceEngine(opts) {
41573
41618
  }
41574
41619
  } catch (err2) {
41575
41620
  console.warn("[errata] git reindex failed:", err2);
41576
- } finally {
41577
- doneReindex();
41578
41621
  }
41579
41622
  }
41580
41623
  recordGitCommit(store, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.0-dev.30",
3
+ "version": "2.0.0-dev.31",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/pass-worker.mjs CHANGED
@@ -15395,7 +15395,7 @@ var init_identity2 = __esm({
15395
15395
  // ../../packages/indexer/src/pipeline.ts
15396
15396
  import { appendFileSync, readFileSync, statSync } from "node:fs";
15397
15397
  import { readdir } from "node:fs/promises";
15398
- import { extname, join as join2, relative, sep } from "node:path";
15398
+ import { extname, join, relative, sep } from "node:path";
15399
15399
  import { createHash as createHash2 } from "node:crypto";
15400
15400
  import { execFileSync } from "node:child_process";
15401
15401
  function nowTs() {
@@ -15511,7 +15511,7 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
15511
15511
  for (const rel of [...changedRelPaths]) {
15512
15512
  let h;
15513
15513
  try {
15514
- h = createHash2("sha256").update(readFileSync(join2(rootPath, rel))).digest("hex");
15514
+ h = createHash2("sha256").update(readFileSync(join(rootPath, rel))).digest("hex");
15515
15515
  } catch {
15516
15516
  continue;
15517
15517
  }
@@ -15558,7 +15558,7 @@ async function incrementalReindex(store2, rootPath, workspaceId, changedAbsPaths
15558
15558
  let parsedFiles = 0;
15559
15559
  for (const rel of changedRelPaths) {
15560
15560
  if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
15561
- const abs = join2(rootPath, ...rel.split("/"));
15561
+ const abs = join(rootPath, ...rel.split("/"));
15562
15562
  const ext = extname(abs).toLowerCase();
15563
15563
  const provider = providers.find((p) => p.fileExtensions.includes(ext));
15564
15564
  if (!provider) continue;
@@ -15881,8 +15881,8 @@ async function runIndexer(store2, opts) {
15881
15881
  if (reExports.length > 0) reExportsByFile.set(f.relPath, reExports);
15882
15882
  report.filesParsed++;
15883
15883
  report.byLanguage[f.provider.id] = (report.byLanguage[f.provider.id] ?? 0) + 1;
15884
- if (report.filesParsed % 250 === 0) {
15885
- perf(`parse @ ${report.filesParsed}/${files.length}`);
15884
+ if (report.filesParsed % 250 === 0) perf(`parse @ ${report.filesParsed}/${files.length}`);
15885
+ if (report.filesParsed % 25 === 0) {
15886
15886
  await new Promise((r) => setImmediate(r));
15887
15887
  }
15888
15888
  }
@@ -16044,7 +16044,12 @@ async function runIndexer(store2, opts) {
16044
16044
  const pendingEdges = [];
16045
16045
  perf("index-build (exports/imports/workspace-pkgs/re-export-fixpoint)");
16046
16046
  const providerByRel = new Map(files.map((x) => [x.relPath, x.provider]));
16047
+ let emittedFiles = 0;
16047
16048
  for (const [relPath, symbols] of symbolsByFile) {
16049
+ if (emittedFiles > 0 && emittedFiles % 50 === 0) {
16050
+ await new Promise((r) => setImmediate(r));
16051
+ }
16052
+ emittedFiles++;
16048
16053
  store2.transaction(() => {
16049
16054
  const fileId = fileNodeId(opts.workspaceId, relPath);
16050
16055
  const langProvider = providerByRel.get(relPath);
@@ -16239,6 +16244,7 @@ async function runIndexer(store2, opts) {
16239
16244
  if (pendingEdges.length > 0) {
16240
16245
  const EDGE_BATCH = 5e3;
16241
16246
  for (let ei = 0; ei < pendingEdges.length; ei += EDGE_BATCH) {
16247
+ if (ei > 0) await new Promise((r) => setImmediate(r));
16242
16248
  const slice = pendingEdges.slice(ei, ei + EDGE_BATCH);
16243
16249
  store2.transaction(() => {
16244
16250
  for (const e of slice) {
@@ -16292,7 +16298,7 @@ async function scan(root, current, ignores, providers, out2) {
16292
16298
  for (const ent of entries) {
16293
16299
  if (ignores.has(ent.name)) continue;
16294
16300
  if (ent.name.startsWith(".") && ent.name !== ".") continue;
16295
- const abs = join2(current, ent.name);
16301
+ const abs = join(current, ent.name);
16296
16302
  if (ent.isDirectory()) {
16297
16303
  await scan(root, abs, ignores, providers, out2);
16298
16304
  } else if (ent.isFile()) {
@@ -16338,7 +16344,7 @@ function gitListFiles(root, ignores, providers) {
16338
16344
  if (segs.some((s) => ignores.has(s) || s.startsWith(".") && s.length > 1)) {
16339
16345
  continue;
16340
16346
  }
16341
- const abs = join2(root, rel);
16347
+ const abs = join(root, rel);
16342
16348
  let size;
16343
16349
  try {
16344
16350
  size = statSync(abs).size;
@@ -20723,42 +20729,42 @@ ${JSON.stringify(symbolNames, null, 2)}`);
20723
20729
 
20724
20730
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
20725
20731
  import { fileURLToPath } from "node:url";
20726
- import { dirname as dirname2, join as join3 } from "node:path";
20732
+ import { dirname, join as join2 } from "node:path";
20727
20733
  import { existsSync, readdirSync } from "node:fs";
20728
20734
  import { createRequire } from "node:module";
20729
20735
  function entryDir() {
20730
20736
  try {
20731
20737
  const url2 = import.meta?.url;
20732
20738
  if (typeof url2 === "string" && url2.length > 0) {
20733
- return dirname2(fileURLToPath(url2));
20739
+ return dirname(fileURLToPath(url2));
20734
20740
  }
20735
20741
  } catch {
20736
20742
  }
20737
- return dirname2(process.execPath);
20743
+ return dirname(process.execPath);
20738
20744
  }
20739
20745
  function findWasmDir() {
20740
20746
  const here = entryDir();
20741
- const seaWasm = join3(here, "resources", "wasm");
20742
- if (existsSync(join3(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
20747
+ const seaWasm = join2(here, "resources", "wasm");
20748
+ if (existsSync(join2(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
20743
20749
  let dir = here;
20744
20750
  for (let i2 = 0; i2 < 6; i2++) {
20745
- const flat = join3(
20751
+ const flat = join2(
20746
20752
  dir,
20747
20753
  "node_modules",
20748
20754
  "@vscode",
20749
20755
  "tree-sitter-wasm",
20750
20756
  "wasm"
20751
20757
  );
20752
- if (existsSync(join3(flat, "tree-sitter-typescript.wasm"))) return flat;
20753
- dir = dirname2(dir);
20758
+ if (existsSync(join2(flat, "tree-sitter-typescript.wasm"))) return flat;
20759
+ dir = dirname(dir);
20754
20760
  }
20755
20761
  let root = here;
20756
20762
  for (let i2 = 0; i2 < 6; i2++) {
20757
- const pnpmDir = join3(root, "node_modules", ".pnpm");
20763
+ const pnpmDir = join2(root, "node_modules", ".pnpm");
20758
20764
  if (existsSync(pnpmDir)) {
20759
20765
  for (const entry of readdirSync(pnpmDir)) {
20760
20766
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
20761
- const candidate = join3(
20767
+ const candidate = join2(
20762
20768
  pnpmDir,
20763
20769
  entry,
20764
20770
  "node_modules",
@@ -20766,13 +20772,13 @@ function findWasmDir() {
20766
20772
  "tree-sitter-wasm",
20767
20773
  "wasm"
20768
20774
  );
20769
- if (existsSync(join3(candidate, "tree-sitter-typescript.wasm"))) {
20775
+ if (existsSync(join2(candidate, "tree-sitter-typescript.wasm"))) {
20770
20776
  return candidate;
20771
20777
  }
20772
20778
  }
20773
20779
  }
20774
20780
  }
20775
- root = dirname2(root);
20781
+ root = dirname(root);
20776
20782
  }
20777
20783
  throw new Error(
20778
20784
  "@vscode/tree-sitter-wasm grammar files not found \u2014 is the package installed?"
@@ -20780,33 +20786,33 @@ function findWasmDir() {
20780
20786
  }
20781
20787
  function findRuntimeDir() {
20782
20788
  const here = entryDir();
20783
- const seaRuntime = join3(here, "resources", "wasm");
20784
- if (existsSync(join3(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
20789
+ const seaRuntime = join2(here, "resources", "wasm");
20790
+ if (existsSync(join2(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
20785
20791
  let dir = here;
20786
20792
  for (let i2 = 0; i2 < 6; i2++) {
20787
- const flat = join3(dir, "node_modules", "web-tree-sitter");
20788
- if (existsSync(join3(flat, "web-tree-sitter.wasm"))) return flat;
20789
- dir = dirname2(dir);
20793
+ const flat = join2(dir, "node_modules", "web-tree-sitter");
20794
+ if (existsSync(join2(flat, "web-tree-sitter.wasm"))) return flat;
20795
+ dir = dirname(dir);
20790
20796
  }
20791
20797
  let root = here;
20792
20798
  for (let i2 = 0; i2 < 6; i2++) {
20793
- const pnpmDir = join3(root, "node_modules", ".pnpm");
20799
+ const pnpmDir = join2(root, "node_modules", ".pnpm");
20794
20800
  if (existsSync(pnpmDir)) {
20795
20801
  for (const entry of readdirSync(pnpmDir)) {
20796
20802
  if (entry.startsWith("web-tree-sitter@")) {
20797
- const candidate = join3(
20803
+ const candidate = join2(
20798
20804
  pnpmDir,
20799
20805
  entry,
20800
20806
  "node_modules",
20801
20807
  "web-tree-sitter"
20802
20808
  );
20803
- if (existsSync(join3(candidate, "web-tree-sitter.wasm"))) {
20809
+ if (existsSync(join2(candidate, "web-tree-sitter.wasm"))) {
20804
20810
  return candidate;
20805
20811
  }
20806
20812
  }
20807
20813
  }
20808
20814
  }
20809
- root = dirname2(root);
20815
+ root = dirname(root);
20810
20816
  }
20811
20817
  throw new Error("web-tree-sitter runtime WASM not found");
20812
20818
  }
@@ -20817,7 +20823,7 @@ async function loadWebTreeSitter() {
20817
20823
  void err2;
20818
20824
  }
20819
20825
  const here = entryDir();
20820
- const seaResourceBase = join3(here, "resources", "_resolve.js");
20826
+ const seaResourceBase = join2(here, "resources", "_resolve.js");
20821
20827
  const resourceRequire = createRequire(seaResourceBase);
20822
20828
  return resourceRequire("web-tree-sitter");
20823
20829
  }
@@ -20832,9 +20838,9 @@ async function ensureTreeSitterReady() {
20832
20838
  await Parser2.init({
20833
20839
  locateFile: (name2) => {
20834
20840
  if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
20835
- return join3(runtime, name2);
20841
+ return join2(runtime, name2);
20836
20842
  }
20837
- return join3(grammars, name2);
20843
+ return join2(grammars, name2);
20838
20844
  }
20839
20845
  });
20840
20846
  })();
@@ -20846,7 +20852,7 @@ async function loadGrammar(name2) {
20846
20852
  if (cached2) return cached2;
20847
20853
  if (!languageClass) throw new Error("tree-sitter not initialized");
20848
20854
  const grammars = findWasmDir();
20849
- const lang = await languageClass.load(join3(grammars, `${name2}.wasm`));
20855
+ const lang = await languageClass.load(join2(grammars, `${name2}.wasm`));
20850
20856
  grammarCache.set(name2, lang);
20851
20857
  return lang;
20852
20858
  }
@@ -25709,6 +25715,9 @@ function fileOf(store2, nodeId) {
25709
25715
  // ../../packages/context-writer/src/select-durable-memory.ts
25710
25716
  init_src2();
25711
25717
 
25718
+ // src/pass-worker.ts
25719
+ init_src3();
25720
+
25712
25721
  // ../../node_modules/.pnpm/env-paths@3.0.0/node_modules/env-paths/index.js
25713
25722
  import os from "node:os";
25714
25723
  import process3 from "node:process";
@@ -25717,24 +25726,24 @@ var tmpdir = os.tmpdir();
25717
25726
  var { env } = process3;
25718
25727
 
25719
25728
  // src/paths.ts
25720
- import { dirname, join } from "node:path";
25729
+ import { dirname as dirname2, join as join3 } from "node:path";
25721
25730
  function workspaceDir(workspaceRoot) {
25722
- return join(workspaceRoot, ".errata");
25731
+ return join3(workspaceRoot, ".errata");
25723
25732
  }
25724
25733
  function workspacePaths(root) {
25725
25734
  const dir = workspaceDir(root);
25726
25735
  return {
25727
25736
  root,
25728
25737
  configDir: dir,
25729
- workspaceJson: join(dir, "workspace.json"),
25730
- eventLog: join(dir, "eventlog.sqlite"),
25731
- castalia: join(dir, "castalia.db"),
25732
- reviewQueue: join(dir, "review-queue.json"),
25733
- outbox: join(dir, "outbox"),
25734
- daemonLock: join(dir, "daemon.lock"),
25735
- identityAudit: join(dir, "identity-audit.log"),
25736
- skillsDir: join(dir, "skills"),
25737
- skillsManifest: join(dir, "skills.json")
25738
+ workspaceJson: join3(dir, "workspace.json"),
25739
+ eventLog: join3(dir, "eventlog.sqlite"),
25740
+ castalia: join3(dir, "castalia.db"),
25741
+ reviewQueue: join3(dir, "review-queue.json"),
25742
+ outbox: join3(dir, "outbox"),
25743
+ daemonLock: join3(dir, "daemon.lock"),
25744
+ identityAudit: join3(dir, "identity-audit.log"),
25745
+ skillsDir: join3(dir, "skills"),
25746
+ skillsManifest: join3(dir, "skills.json")
25738
25747
  };
25739
25748
  }
25740
25749
 
@@ -25853,10 +25862,20 @@ function runPass(msg) {
25853
25862
  ...p.skills !== void 0 ? { skills: p.skills } : {}
25854
25863
  });
25855
25864
  }
25865
+ case "reindex":
25866
+ return runReindex(msg.payload);
25856
25867
  default:
25857
25868
  throw new Error(`pass-worker: unknown pass "${msg.kind}"`);
25858
25869
  }
25859
25870
  }
25871
+ async function runReindex(p) {
25872
+ const identityEvaluations = [];
25873
+ const r = await incrementalReindex(store, init2.workspaceRoot, init2.workspaceId, p.changedAbsPaths, p.t, {
25874
+ onIdentityEvaluate: (e) => identityEvaluations.push(e),
25875
+ ...p.declaredRenames !== void 0 ? { declaredRenames: p.declaredRenames } : {}
25876
+ });
25877
+ return { ...r, identityEvaluations };
25878
+ }
25860
25879
  function runNightly() {
25861
25880
  const report = runNightlyPipeline(store);
25862
25881
  let merged = 0;