@inerrata-corporation/errata 2.0.2-dev.145 → 2.0.2-dev.156

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 (2) hide show
  1. package/errata.mjs +112 -11
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -18572,7 +18572,8 @@ function resolveDesignProblemById(store, id, fixNote, t) {
18572
18572
  }
18573
18573
  function closeDesignProblem(store, problemId, fixNote, t) {
18574
18574
  const p = store.getNode(problemId);
18575
- if (!p || p.label !== "Problem" || p.attrs["resolvedAt"]) return false;
18575
+ if (!p || p.label !== "Problem") return false;
18576
+ if (p.attrs["resolvedAs"]) return false;
18576
18577
  if (fixNote?.trim() && store.outEdges(problemId, ["SOLVED_BY"]).length === 0) {
18577
18578
  const solId = `dfix_${digest({ problemId, fix: fixNote })}`.slice(0, 56);
18578
18579
  store.mergeNode(
@@ -18580,6 +18581,7 @@ function closeDesignProblem(store, problemId, fixNote, t) {
18580
18581
  );
18581
18582
  mergeEdge(store, problemId, solId, "SOLVED_BY", t);
18582
18583
  }
18584
+ if (p.attrs["resolvedAt"]) return false;
18583
18585
  store.updateNode(problemId, {
18584
18586
  attrs: { ...p.attrs, provisional: false, resolvedAt: t },
18585
18587
  lastUpdatedAt: t
@@ -49707,10 +49709,13 @@ init_src4();
49707
49709
  import { readFileSync as readFileSync10, writeFileSync as writeFileSync10 } from "node:fs";
49708
49710
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
49709
49711
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
49710
- var HANDLE_RE = /\[([a-z0-9][\w-]{0,40})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
49712
+ var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
49711
49713
  var FIX_PREFIX = /^\s*fix:(?:#([a-z][\w-]{0,63}))?\s*/i;
49712
49714
  var CONSTRAINT_RE = /\(\s*constraint:\s*([^()\n]{8,}?)\s*\)/gi;
49713
49715
  var CAUSE_PREFIX = /^\s*cause:(?:#([a-z][\w-]{0,63}))?\s*/i;
49716
+ var NEST2_UNIT = String.raw`(?:[^()\n]|\((?:[^()\n]|\([^()\n]*\))*\))`;
49717
+ var FIX_LONG_RE = new RegExp(String.raw`\(\s*fix:(?:#([a-z][\w-]{0,63}))?\s*(${NEST2_UNIT}{12,}?)\s*\)`, "gi");
49718
+ var CAUSE_LONG_RE = new RegExp(String.raw`\(\s*cause:(?:#([a-z][\w-]{0,63}))?\s*(${NEST2_UNIT}{8,}?)\s*\)`, "gi");
49714
49719
  var CAUSE_ARROW = /\s+(?:<-|←)\s+/;
49715
49720
  var ATTEMPT_RE = /\(\s*(tried|failed):(?:#([a-z][\w-]{0,63}))?\s*((?:[^()\n]|\([^()\n]*\)){8,}?)\s*\)/gi;
49716
49721
  var AIDS_PREFIX = /^\s*aids:(?:#([a-z][\w-]{0,63}))?\s*/i;
@@ -49723,7 +49728,7 @@ var DOMAIN_RE = /\(\s*domain:\s*([^()\n]{3,}?)\s*\)/gi;
49723
49728
  var PACKAGE_RE = /\(\s*package:\s*([^()\n]{2,}?)\s*\)/gi;
49724
49729
  var COMPONENT_RE = /\(\s*component:\s*([^()\n]{2,}?)\s*\)/gi;
49725
49730
  var CAUSE_TEXT_MIN = 8;
49726
- var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*([^\]\n]{8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
49731
+ var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*((?:\[[^\]\n]*\]|[^\]\n]){8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
49727
49732
  var CONSTRAINT_MIN = 8;
49728
49733
  function clauseBefore(sentence, idx) {
49729
49734
  const win = sentence.slice(Math.max(0, idx - 80), idx);
@@ -49738,6 +49743,17 @@ function fixRationaleBefore(sentence, idx) {
49738
49743
  const clause = m ? win.slice(m.index + 1) : win;
49739
49744
  return clause.replace(/\s+/g, " ").trim();
49740
49745
  }
49746
+ function fixRationaleAfter(sentence, endIdx) {
49747
+ const win = sentence.slice(endIdx, endIdx + FIX_RATIONALE_WINDOW).replace(new RegExp(CITE_GROUP_RE.source, "g"), " ").replace(new RegExp(FLAG_RE.source, "g"), " ");
49748
+ const stripped = win.replace(/^[\s—:–,-]+/, "");
49749
+ const m = /^[^.;!?—]*/.exec(stripped);
49750
+ return (m ? m[0] : stripped).replace(/\s+/g, " ").trim();
49751
+ }
49752
+ function deriveFixRationale(sentence, startIdx, endIdx) {
49753
+ const before = fixRationaleBefore(sentence, startIdx);
49754
+ if (before.length >= FIX_RATIONALE_MIN) return before;
49755
+ return fixRationaleAfter(sentence, endIdx);
49756
+ }
49741
49757
  function parseInlineTags(text) {
49742
49758
  const out2 = [];
49743
49759
  const deFenced = text.replace(/```[\s\S]*?```/g, " ");
@@ -49751,9 +49767,11 @@ function parseInlineTags(text) {
49751
49767
  (m) => /\[[!?]|\((?:fix|cause|constraint|tried|failed):|\(\[/.test(m) ? " " : m
49752
49768
  );
49753
49769
  const sfield = sentence.replace(/\s+/g, " ").trim().slice(0, 160);
49770
+ const citeMatched = /* @__PURE__ */ new Set();
49754
49771
  CITE_GROUP_RE.lastIndex = 0;
49755
49772
  let g;
49756
49773
  while ((g = CITE_GROUP_RE.exec(sentence)) !== null) {
49774
+ citeMatched.add(g.index);
49757
49775
  let content = g[1];
49758
49776
  if (/^\s*pattern:/i.test(content)) continue;
49759
49777
  const fixM = FIX_PREFIX.exec(content);
@@ -49807,7 +49825,7 @@ function parseInlineTags(text) {
49807
49825
  if (!isFix && NEG.test(clauseBefore(sentence, g.index))) continue;
49808
49826
  let fixRationale;
49809
49827
  if (isFix) {
49810
- const r = fixRationaleBefore(sentence, g.index);
49828
+ const r = deriveFixRationale(sentence, g.index, g.index + g[0].length);
49811
49829
  if (r.length >= FIX_RATIONALE_MIN) fixRationale = r;
49812
49830
  }
49813
49831
  HANDLE_RE.lastIndex = 0;
@@ -49832,6 +49850,55 @@ function parseInlineTags(text) {
49832
49850
  out2.push({ kind: "fix", fixRationale: note, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
49833
49851
  }
49834
49852
  }
49853
+ for (const pass of [
49854
+ { re: FIX_LONG_RE, isFix: true },
49855
+ { re: CAUSE_LONG_RE, isFix: false }
49856
+ ]) {
49857
+ pass.re.lastIndex = 0;
49858
+ let lm;
49859
+ while ((lm = pass.re.exec(sentence)) !== null) {
49860
+ if (citeMatched.has(lm.index)) continue;
49861
+ const verbThread = lm[1] ?? void 0;
49862
+ const content = lm[2];
49863
+ HANDLE_RE.lastIndex = 0;
49864
+ const h = HANDLE_RE.exec(content);
49865
+ const handle2 = h ? h[1] ?? h[2] : void 0;
49866
+ if (!pass.isFix) {
49867
+ if (handle2) {
49868
+ out2.push({ kind: "triage", handle: handle2, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
49869
+ } else {
49870
+ const causeText = content.replace(/\s+/g, " ").trim();
49871
+ if (causeText.length >= CAUSE_TEXT_MIN)
49872
+ out2.push({ kind: "triage", causeText, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
49873
+ }
49874
+ continue;
49875
+ }
49876
+ if (handle2) {
49877
+ const inGroup = content.replace(new RegExp(HANDLE_RE.source, "gi"), " ").replace(/\s+/g, " ").trim();
49878
+ const r = inGroup.length >= FIX_RATIONALE_MIN ? inGroup : deriveFixRationale(sentence, lm.index, lm.index + lm[0].length);
49879
+ let emitted = false;
49880
+ HANDLE_RE.lastIndex = 0;
49881
+ let hh;
49882
+ while ((hh = HANDLE_RE.exec(content)) !== null) {
49883
+ const hcap = hh[1] ?? hh[2];
49884
+ if (hcap) {
49885
+ emitted = true;
49886
+ out2.push({
49887
+ kind: "fix",
49888
+ handle: hcap,
49889
+ sentence: sfield,
49890
+ ...r.length >= FIX_RATIONALE_MIN ? { fixRationale: r } : {},
49891
+ ...verbThread ? { threadId: verbThread } : {}
49892
+ });
49893
+ }
49894
+ }
49895
+ if (emitted) continue;
49896
+ }
49897
+ const note = content.replace(/\s+/g, " ").trim();
49898
+ if (note.length >= FIX_RATIONALE_MIN)
49899
+ out2.push({ kind: "fix", fixRationale: note, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
49900
+ }
49901
+ }
49835
49902
  FLAG_RE.lastIndex = 0;
49836
49903
  let f;
49837
49904
  while ((f = FLAG_RE.exec(sentence)) !== null) {
@@ -51869,7 +51936,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
51869
51936
  }
51870
51937
 
51871
51938
  // src/engine.ts
51872
- var DAEMON_VERSION = true ? "2.0.2-dev.145" : "2.0.0-alpha.0";
51939
+ var DAEMON_VERSION = true ? "2.0.2-dev.156" : "2.0.0-alpha.0";
51873
51940
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
51874
51941
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
51875
51942
  var GIT_OP_MUTE_MS = 4e3;
@@ -54319,6 +54386,20 @@ async function startMultiDaemon(opts = {}) {
54319
54386
  let serverPending = null;
54320
54387
  const boundaryListeners = [];
54321
54388
  let boundaryFlushing = false;
54389
+ let boundaryFlushStartedAt = 0;
54390
+ let boundaryFlushStage = "";
54391
+ const beginFlush = (stage) => {
54392
+ boundaryFlushing = true;
54393
+ boundaryFlushStartedAt = Date.now();
54394
+ boundaryFlushStage = stage;
54395
+ };
54396
+ const flushStage = (stage) => {
54397
+ boundaryFlushStage = stage;
54398
+ };
54399
+ const endFlush = () => {
54400
+ boundaryFlushing = false;
54401
+ boundaryFlushStage = "";
54402
+ };
54322
54403
  const fireBoundary = () => {
54323
54404
  for (const l of boundaryListeners) {
54324
54405
  try {
@@ -55023,12 +55104,14 @@ async function startMultiDaemon(opts = {}) {
55023
55104
  },
55024
55105
  async sessionBoundaryFlush() {
55025
55106
  if (boundaryFlushing) return { uploaded: 0, written: 0, pruned: 0, skipped: "in-flight" };
55026
- boundaryFlushing = true;
55107
+ beginFlush("embed");
55027
55108
  try {
55028
55109
  for (const r of records) {
55029
55110
  await r.engine.embedSettled();
55030
55111
  }
55112
+ flushStage("instances");
55031
55113
  const inst = await daemon.syncInstancesPublic();
55114
+ flushStage("skills");
55032
55115
  const skills = await daemon.syncSkillsAll();
55033
55116
  return {
55034
55117
  uploaded: inst.uploaded,
@@ -55037,7 +55120,7 @@ async function startMultiDaemon(opts = {}) {
55037
55120
  ...inst.errors ? { errors: inst.errors } : {}
55038
55121
  };
55039
55122
  } finally {
55040
- boundaryFlushing = false;
55123
+ endFlush();
55041
55124
  }
55042
55125
  },
55043
55126
  onSessionBoundary(cb) {
@@ -55062,18 +55145,25 @@ async function startMultiDaemon(opts = {}) {
55062
55145
  }
55063
55146
  };
55064
55147
  app.post("/api/sync", async (c) => {
55065
- if (boundaryFlushing) return c.json({ skipped: "in-flight" }, 409);
55066
- boundaryFlushing = true;
55148
+ if (boundaryFlushing)
55149
+ return c.json(
55150
+ { skipped: "in-flight", stage: boundaryFlushStage, ageMs: Date.now() - boundaryFlushStartedAt },
55151
+ 409
55152
+ );
55153
+ beginFlush("principles");
55067
55154
  try {
55068
55155
  const principles = await daemon.syncPrinciplesPublic();
55156
+ flushStage("triage");
55069
55157
  const triage = await daemon.syncTriagePublic();
55158
+ flushStage("instances");
55070
55159
  const instances = await daemon.syncInstancesPublic();
55160
+ flushStage("edge-backfill");
55071
55161
  const edgeBackfill = await daemon.backfillCausalEdges();
55072
55162
  return c.json({ principles, triage, instances, edgeBackfill });
55073
55163
  } catch (err2) {
55074
55164
  return c.json({ error: err2 instanceof Error ? err2.message : String(err2) }, 500);
55075
55165
  } finally {
55076
- boundaryFlushing = false;
55166
+ endFlush();
55077
55167
  }
55078
55168
  });
55079
55169
  app.post("/api/tick", async (c) => {
@@ -57900,7 +57990,18 @@ async function cmdSync(arg) {
57900
57990
  signal: AbortSignal.timeout(15 * 6e4)
57901
57991
  });
57902
57992
  if (res.status === 409) {
57903
- console.log("sync already running: the daemon is mid-drain \u2014 it will finish on its own. Nothing new was started.");
57993
+ const body2 = await res.json().catch(() => null);
57994
+ const ageMs = typeof body2?.ageMs === "number" ? body2.ageMs : 0;
57995
+ const dur = ageMs >= 6e4 ? `${Math.floor(ageMs / 6e4)}m` : `${Math.max(1, Math.round(ageMs / 1e3))}s`;
57996
+ const stage = body2?.stage ? ` \u2014 stage: ${body2.stage}` : "";
57997
+ console.log(
57998
+ ageMs > 0 ? `sync already running: the daemon has been draining for ${dur}${stage}. It will finish on its own; nothing new was started.` : "sync already running: the daemon is mid-drain \u2014 it will finish on its own. Nothing new was started."
57999
+ );
58000
+ if (ageMs > 30 * 6e4) {
58001
+ console.log(
58002
+ " \u26A0 this pass has run past 30 min \u2014 if daemon.log shows no upload progress it may be stranded (a sleep/resume can do this). Restart with: errata stop && errata start"
58003
+ );
58004
+ }
57904
58005
  return;
57905
58006
  }
57906
58007
  if (!res.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.145",
3
+ "version": "2.0.2-dev.156",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {