@inerrata-corporation/errata 2.0.17-dev.3492 → 2.0.17-dev.3501

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 +120 -56
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -82246,7 +82246,7 @@ function createWatchBreaker(deps) {
82246
82246
  }
82247
82247
 
82248
82248
  // src/engine.ts
82249
- var DAEMON_VERSION = true ? "2.0.17-dev.3492" : "2.0.0-alpha.0";
82249
+ var DAEMON_VERSION = true ? "2.0.17-dev.3501" : "2.0.0-alpha.0";
82250
82250
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
82251
82251
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
82252
82252
  var GIT_OP_MUTE_MS = 4e3;
@@ -87726,6 +87726,10 @@ var execFileAsync2 = promisify4(execFile5);
87726
87726
  var HISTORY_EXTRACTOR_VERSION = "history-2";
87727
87727
  var LEASE_POLL_MS = 2e4;
87728
87728
  var RECOVERY_DEADLINE_MS = 15 * 6e4;
87729
+ var UNIT_ATTEMPTS = 3;
87730
+ function isDoorDeferral(outcome) {
87731
+ return outcome.status === "error" && !!outcome.parked && !!outcome.runId && ["deferred-context", "deferred-budget"].includes(outcome.errorCode ?? "");
87732
+ }
87729
87733
  var DEFAULT_LOOKAHEAD = 2;
87730
87734
  var CONTENT_TRANSPORT_VERSION = 1;
87731
87735
  async function defaultGit(root, args2) {
@@ -88036,58 +88040,69 @@ async function walk10(root, input, client, opts, readBlob) {
88036
88040
  let attempt = 0;
88037
88041
  let edgeBlocks = 0;
88038
88042
  let parkedAtEdge = false;
88039
- while (outcome === null) {
88040
- attempt += 1;
88041
- if (!first && body2.backfill && body2.backfill.anchorSeq === void 0 && anchor.seq !== void 0) {
88042
- body2.backfill = { ...body2.backfill, anchorSeq: anchor.seq };
88043
- }
88044
- if (!first && body2.after) {
88045
- const prev = predecessor(k);
88046
- if (!prev) delete body2.after;
88047
- else if (prev.sha !== body2.after.sha || prev.subIndex !== body2.after.subIndex) body2.after = { sha: prev.sha, subIndex: prev.subIndex };
88048
- }
88049
- const settled = await (first ?? settle(Promise.resolve().then(() => post(projectId, body2))));
88050
- first = null;
88051
- if ("err" in settled) {
88052
- const err2 = settled.err;
88053
- const status = err2 instanceof CloudError ? err2.status : 0;
88054
- const elapsed = Math.round((Date.now() - started2) / 1e3);
88055
- if (isEdgeContentBlock(err2) && ++edgeBlocks >= 2) {
88056
- parkedAtEdge = true;
88057
- break;
88043
+ let unitTries = 0;
88044
+ unitAttempt: for (; ; ) {
88045
+ unitTries += 1;
88046
+ outcome = null;
88047
+ while (outcome === null) {
88048
+ attempt += 1;
88049
+ if (!first && body2.backfill && body2.backfill.anchorSeq === void 0 && anchor.seq !== void 0) {
88050
+ body2.backfill = { ...body2.backfill, anchorSeq: anchor.seq };
88051
+ }
88052
+ if (!first && body2.after) {
88053
+ const prev = predecessor(k);
88054
+ if (!prev) delete body2.after;
88055
+ else if (prev.sha !== body2.after.sha || prev.subIndex !== body2.after.subIndex) body2.after = { sha: prev.sha, subIndex: prev.subIndex };
88056
+ }
88057
+ const settled = await (first ?? settle(Promise.resolve().then(() => post(projectId, body2))));
88058
+ first = null;
88059
+ if ("err" in settled) {
88060
+ const err2 = settled.err;
88061
+ const status = err2 instanceof CloudError ? err2.status : 0;
88062
+ const elapsed = Math.round((Date.now() - started2) / 1e3);
88063
+ if (isEdgeContentBlock(err2) && ++edgeBlocks >= 2) {
88064
+ parkedAtEdge = true;
88065
+ break;
88066
+ }
88067
+ if (Date.now() - started2 > RECOVERY_DEADLINE_MS) {
88068
+ profile = stage(profile, { state: "paused", lastError: `unit ${label}: ${status || "connection"} after ${elapsed}s, giving up until the next run` }, now);
88069
+ persist(profile);
88070
+ await reportHistoryStage(client, profile, log);
88071
+ return { profile, processed, state: "paused" };
88072
+ }
88073
+ const detail = err2 instanceof Error ? ` (${err2.message.replace(/\s+/g, " ").slice(0, 160)})` : "";
88074
+ log(`[errata] history ${label}: HTTP ${status || "connection error"} on attempt ${attempt} after ${elapsed}s${detail} \u2014 re-POSTing the same unit`);
88075
+ await sleep(attempt === 1 ? 1e4 : Math.min(3e4 * attempt, 12e4));
88076
+ continue;
88058
88077
  }
88059
- if (Date.now() - started2 > RECOVERY_DEADLINE_MS) {
88060
- profile = stage(profile, { state: "paused", lastError: `unit ${label}: ${status || "connection"} after ${elapsed}s, giving up until the next run` }, now);
88078
+ const res = settled.res;
88079
+ if (res.ordered) doorOrders = true;
88080
+ if (res.backfill && anchor.seq === void 0) {
88081
+ anchor.seq = res.backfill.anchorSeq;
88082
+ profile = stage(profile, { backfillAnchor: { ...anchor } }, now);
88061
88083
  persist(profile);
88062
- await reportHistoryStage(client, profile, log);
88063
- return { profile, processed, state: "paused" };
88064
88084
  }
88065
- const detail = err2 instanceof Error ? ` (${err2.message.replace(/\s+/g, " ").slice(0, 160)})` : "";
88066
- log(`[errata] history ${label}: HTTP ${status || "connection error"} on attempt ${attempt} after ${elapsed}s${detail} \u2014 re-POSTing the same unit`);
88067
- await sleep(attempt === 1 ? 1e4 : Math.min(3e4 * attempt, 12e4));
88068
- continue;
88069
- }
88070
- const res = settled.res;
88071
- if (res.ordered) doorOrders = true;
88072
- if (res.backfill && anchor.seq === void 0) {
88073
- anchor.seq = res.backfill.anchorSeq;
88074
- profile = stage(profile, { backfillAnchor: { ...anchor } }, now);
88075
- persist(profile);
88076
- }
88077
- if (res.status === "in_progress") {
88078
- const retryAt = new Date(Date.now() + res.retryAfterMs).toISOString();
88079
- if (Date.now() - started2 > RECOVERY_DEADLINE_MS) {
88080
- profile = stage(profile, { state: "paused", lastError: `waiting on held lease for ${label}, retry at ${retryAt}` }, now);
88081
- persist(profile);
88082
- await reportHistoryStage(client, profile, log);
88083
- return { profile, processed, state: "paused" };
88085
+ if (res.status === "in_progress") {
88086
+ const retryAt = new Date(Date.now() + res.retryAfterMs).toISOString();
88087
+ if (Date.now() - started2 > RECOVERY_DEADLINE_MS) {
88088
+ profile = stage(profile, { state: "paused", lastError: `waiting on held lease for ${label}, retry at ${retryAt}` }, now);
88089
+ persist(profile);
88090
+ await reportHistoryStage(client, profile, log);
88091
+ return { profile, processed, state: "paused" };
88092
+ }
88093
+ const why = res.waitingOn === "predecessor" ? `sent ahead, its predecessor ${res.predecessor === "failed" ? "failed" : "had not landed"} \u2014 re-POSTing in turn` : "run held by the door (lease)";
88094
+ log(`[errata] history ${label}: ${why}, polling in ${Math.min(LEASE_POLL_MS, res.retryAfterMs) / 1e3}s`);
88095
+ await sleep(Math.min(LEASE_POLL_MS, Math.max(1e3, res.retryAfterMs)));
88096
+ continue;
88084
88097
  }
88085
- const why = res.waitingOn === "predecessor" ? `sent ahead, its predecessor ${res.predecessor === "failed" ? "failed" : "had not landed"} \u2014 re-POSTing in turn` : "run held by the door (lease)";
88086
- log(`[errata] history ${label}: ${why}, polling in ${Math.min(LEASE_POLL_MS, res.retryAfterMs) / 1e3}s`);
88087
- await sleep(Math.min(LEASE_POLL_MS, Math.max(1e3, res.retryAfterMs)));
88088
- continue;
88098
+ outcome = res;
88099
+ }
88100
+ if (!parkedAtEdge && outcome !== null && outcome.status === "error" && !isDoorDeferral(outcome) && unitTries < UNIT_ATTEMPTS) {
88101
+ log(`[errata] history ${label}: ${outcome.errorCode ?? "error"} on try ${unitTries}/${UNIT_ATTEMPTS} (${outcome.error.slice(0, 80)}) \u2014 re-sending`);
88102
+ await sleep(5e3);
88103
+ continue unitAttempt;
88089
88104
  }
88090
- outcome = res;
88105
+ break;
88091
88106
  }
88092
88107
  if (parkedAtEdge || outcome === null) {
88093
88108
  edgeParked.add(k);
@@ -88135,7 +88150,7 @@ async function walk10(root, input, client, opts, readBlob) {
88135
88150
  return { profile, processed, state: "refused" };
88136
88151
  case "rejected":
88137
88152
  case "error":
88138
- if (outcome.status === "error" && outcome.parked && outcome.runId && ["deferred-context", "deferred-budget"].includes(outcome.errorCode ?? "")) {
88153
+ if (isDoorDeferral(outcome)) {
88139
88154
  const gaps = [...profile.historyStage?.coverageGaps ?? []];
88140
88155
  const recoveredGap = recovering ? gaps.findIndex((g) => g.reason === "edge-blocked" && unitKey(g) === unitKey(u)) : -1;
88141
88156
  if (recoveredGap >= 0) gaps.splice(recoveredGap, 1);
@@ -88146,10 +88161,28 @@ async function walk10(root, input, client, opts, readBlob) {
88146
88161
  log(`[errata] history ${label}: deferred (${outcome.errorCode}); coverage gap retained as ${outcome.runId}`);
88147
88162
  break;
88148
88163
  }
88149
- profile = stage(profile, { state: "paused", lastError: `unit ${label} ${outcome.status}: ${outcome.error.slice(0, 200)}` }, now);
88150
- persist(profile);
88151
- await reportHistoryStage(client, profile, log);
88152
- return { profile, processed, state: "paused" };
88164
+ {
88165
+ edgeParked.add(k);
88166
+ const code = outcome.errorCode ?? (outcome.status === "rejected" ? "invalid" : "error");
88167
+ const reason = `${outcome.status === "rejected" ? "rejected" : "failed"}:${code}`;
88168
+ const runId = `unit-${reason}:${u.sha}/${u.subIndex}`;
88169
+ const gaps = [...profile.historyStage?.coverageGaps ?? []];
88170
+ const known = gaps.some((g) => unitKey(g) === unitKey(u) && g.reason === reason);
88171
+ counts = addCounts(counts, { commitsWalked: walkIncrement, deferredUnits: known ? 0 : 1 });
88172
+ if (!known) gaps.push({ sha: u.sha, subIndex: u.subIndex, runId, reason });
88173
+ profile = stage(profile, { coverageGaps: gaps.slice(-1e3) }, now);
88174
+ log(`[errata] history ${label}: ${outcome.status} (${code}) after ${unitTries} ${unitTries === 1 ? "try" : "tries"}: ${outcome.error.slice(0, 120)} \u2014 coverage gap retained as ${runId}, walking on`);
88175
+ break;
88176
+ }
88177
+ }
88178
+ if (["completed", "replayed", "empty"].includes(outcome.status)) {
88179
+ const before = profile.historyStage?.coverageGaps ?? [];
88180
+ const gaps = before.filter((g) => !(unitKey(g) === unitKey(u) && g.reason.startsWith("failed:")));
88181
+ if (gaps.length !== before.length) {
88182
+ counts.deferredUnits = Math.max(0, (counts.deferredUnits ?? 0) - (before.length - gaps.length));
88183
+ profile = stage(profile, { coverageGaps: gaps }, now);
88184
+ log(`[errata] history ${label}: recovered an earlier failed extraction`);
88185
+ }
88153
88186
  }
88154
88187
  if (recovering && ["completed", "replayed", "empty"].includes(outcome.status)) {
88155
88188
  const gaps = (profile.historyStage?.coverageGaps ?? []).filter((g) => !(g.reason === "edge-blocked" && unitKey(g) === unitKey(u)));
@@ -91449,6 +91482,27 @@ function buildCodexHooksToml(port, options) {
91449
91482
  );
91450
91483
  return CODEX_HOOKS_BEGIN + "\n" + handlers.join("\n") + CODEX_HOOKS_END + "\n";
91451
91484
  }
91485
+ function installedHookPort(settingsText) {
91486
+ let settings;
91487
+ try {
91488
+ settings = JSON.parse(settingsText);
91489
+ } catch {
91490
+ return null;
91491
+ }
91492
+ const hooks = settings?.hooks;
91493
+ if (!hooks || typeof hooks !== "object") return null;
91494
+ for (const groups of Object.values(hooks)) {
91495
+ for (const group of Array.isArray(groups) ? groups : []) {
91496
+ for (const h of group?.hooks ?? []) {
91497
+ if (typeof h?.command !== "string" || !h.command.includes("errata-managed")) continue;
91498
+ const m = /http:\/\/127\.0\.0\.1:(\d+)\//.exec(h.command);
91499
+ const port = m ? Number(m[1]) : NaN;
91500
+ if (Number.isInteger(port) && port > 0 && port < 65536) return port;
91501
+ }
91502
+ }
91503
+ }
91504
+ return null;
91505
+ }
91452
91506
 
91453
91507
  // src/codex-hook-relay.ts
91454
91508
  var CODEX_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata install-hooks codex
@@ -91891,6 +91945,10 @@ function removeProjectStatusLine(settings) {
91891
91945
  }
91892
91946
  return removed;
91893
91947
  }
91948
+ function isSameInstall(value, relay) {
91949
+ const command = value["command"].replace(/\\/g, "/").toLowerCase();
91950
+ return command.includes(relay.replace(/\\/g, "/").toLowerCase());
91951
+ }
91894
91952
  function userClaudeSettingsPath() {
91895
91953
  const base = process.env["CLAUDE_CONFIG_DIR"] ?? join46(homedir8(), ".claude");
91896
91954
  return join46(base, "settings.json");
@@ -91910,10 +91968,11 @@ function ensureUserStatusLine(opts) {
91910
91968
  return "unreadable";
91911
91969
  }
91912
91970
  }
91913
- const ownMain = settings["statusLine"] !== void 0 && !isErrataStatusLine(settings["statusLine"]);
91914
- const ownRows = settings["subagentStatusLine"] !== void 0 && !isErrataStatusLine(settings["subagentStatusLine"]);
91915
- if (ownMain && ownRows) return "kept-own";
91916
91971
  const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
91972
+ const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
91973
+ const ownMain = keep(settings["statusLine"]);
91974
+ const ownRows = keep(settings["subagentStatusLine"]);
91975
+ if (ownMain && ownRows) return "kept-own";
91917
91976
  mkdirSync10(opts.relayDir, { recursive: true });
91918
91977
  if (!existsSync37(relay) || readFileSync40(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
91919
91978
  writeFileSync28(relay, STATUSLINE_RELAY_SOURCE, "utf8");
@@ -92329,6 +92388,11 @@ function resolveHookPort(explicit) {
92329
92388
  }
92330
92389
  }
92331
92390
  }
92391
+ const settingsPath = join47(ROOT, ".claude", "settings.json");
92392
+ try {
92393
+ if (existsSync38(settingsPath)) return installedHookPort(readFileSync41(settingsPath, "utf8")) ?? 7891;
92394
+ } catch {
92395
+ }
92332
92396
  return 7891;
92333
92397
  }
92334
92398
  async function cmdInit() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.17-dev.3492",
3
+ "version": "2.0.17-dev.3501",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {