@inerrata-corporation/errata 2.0.16-dev.3343 → 2.0.16-dev.3362

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 +800 -481
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -960,7 +960,7 @@ function lemma(token) {
960
960
  }
961
961
  return token;
962
962
  }
963
- function tokenize(text, resolve7) {
963
+ function tokenize(text, resolve8) {
964
964
  const matches = text.normalize("NFC").toLowerCase().match(TOKEN_RE) ?? [];
965
965
  const out2 = /* @__PURE__ */ new Set();
966
966
  for (const raw2 of matches) {
@@ -970,7 +970,7 @@ function tokenize(text, resolve7) {
970
970
  out2.add(token);
971
971
  continue;
972
972
  }
973
- const canonical = resolve7(token);
973
+ const canonical = resolve8(token);
974
974
  out2.add(canonical ?? lemma(token));
975
975
  }
976
976
  return [...out2].sort();
@@ -16455,8 +16455,8 @@ function parsePackageLockJson(jsonText) {
16455
16455
  }
16456
16456
  const dependencies = [];
16457
16457
  for (const [path2, meta3] of Object.entries(packages)) {
16458
- const self = byPath.get(path2);
16459
- if (!self) continue;
16458
+ const self2 = byPath.get(path2);
16459
+ if (!self2) continue;
16460
16460
  const deps = meta3.dependencies;
16461
16461
  if (!deps || typeof deps !== "object") continue;
16462
16462
  const dependsOn = [];
@@ -16465,7 +16465,7 @@ function parsePackageLockJson(jsonText) {
16465
16465
  if (target) dependsOn.push(npmPurl(depName, target.version));
16466
16466
  }
16467
16467
  if (dependsOn.length > 0)
16468
- dependencies.push({ ref: npmPurl(self.name, self.version), dependsOn });
16468
+ dependencies.push({ ref: npmPurl(self2.name, self2.version), dependsOn });
16469
16469
  }
16470
16470
  const directRaw = [];
16471
16471
  for (const [path2, meta3] of Object.entries(packages)) {
@@ -16936,9 +16936,9 @@ function pomSelf(text) {
16936
16936
  const group = (/<groupId>([^<]+)<\/groupId>/.exec(own)?.[1] ?? parentGroup)?.trim();
16937
16937
  const artifact = /<artifactId>([^<]+)<\/artifactId>/.exec(own)?.[1]?.trim();
16938
16938
  if (!group) return [];
16939
- const self = [{ ecosystem: "maven", kind: "namespace", value: group }];
16940
- if (artifact) self.push({ ecosystem: "maven", kind: "name", value: mavenName(group, artifact) });
16941
- return self;
16939
+ const self2 = [{ ecosystem: "maven", kind: "namespace", value: group }];
16940
+ if (artifact) self2.push({ ecosystem: "maven", kind: "name", value: mavenName(group, artifact) });
16941
+ return self2;
16942
16942
  }
16943
16943
  function parseManifestSelf(path2, text) {
16944
16944
  const file2 = basename(path2);
@@ -16951,10 +16951,10 @@ function parseManifestSelf(path2, text) {
16951
16951
  }
16952
16952
  const name2 = obj && typeof obj === "object" ? obj["name"] : null;
16953
16953
  if (typeof name2 !== "string" || !name2.trim()) return [];
16954
- const self = [{ ecosystem: "npm", kind: "name", value: name2.trim() }];
16954
+ const self2 = [{ ecosystem: "npm", kind: "name", value: name2.trim() }];
16955
16955
  const scope = /^(@[^/]+)\//.exec(name2.trim())?.[1];
16956
- if (scope) self.push({ ecosystem: "npm", kind: "namespace", value: scope });
16957
- return self;
16956
+ if (scope) self2.push({ ecosystem: "npm", kind: "namespace", value: scope });
16957
+ return self2;
16958
16958
  }
16959
16959
  if (file2 === "pom.xml") return pomSelf(text);
16960
16960
  if (file2 === "build.gradle" || file2 === "build.gradle.kts") {
@@ -17574,7 +17574,7 @@ var init_agents_md = __esm({
17574
17574
  });
17575
17575
 
17576
17576
  // ../../packages/context-writer/src/context-file.ts
17577
- import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
17577
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, renameSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
17578
17578
  import { dirname as dirname2, join } from "node:path";
17579
17579
  function contextFilePath(root) {
17580
17580
  return join(root, ".errata", "context.md");
@@ -17584,7 +17584,13 @@ function writeContextFile(root, body2) {
17584
17584
  mkdirSync(dirname2(path2), { recursive: true });
17585
17585
  const text = `${body2.trim()}
17586
17586
  `;
17587
- writeFileSync2(path2, text, "utf8");
17587
+ const temp = `${path2}.${process.pid}.tmp`;
17588
+ try {
17589
+ writeFileSync2(temp, text, { encoding: "utf8", mode: 384 });
17590
+ renameSync(temp, path2);
17591
+ } finally {
17592
+ if (existsSync2(temp)) unlinkSync(temp);
17593
+ }
17588
17594
  return contextHash(text);
17589
17595
  }
17590
17596
  function contextHash(body2) {
@@ -25065,7 +25071,7 @@ function buildSnapshot(opts) {
25065
25071
  const stillOpen = problems.filter((p) => p.attrs["resolvedAt"] == null);
25066
25072
  const allProblems = stillOpen.filter((p) => !isConstraintProblem(p));
25067
25073
  allProblems.sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt);
25068
- const recent2 = allProblems.slice(0, 8).map((p) => ({
25074
+ const recent3 = allProblems.slice(0, 8).map((p) => ({
25069
25075
  node: p,
25070
25076
  anchors: opts.store.outEdges(p.id, ["MANIFESTED_IN", "EVIDENCED_BY"])
25071
25077
  }));
@@ -25138,10 +25144,10 @@ function buildSnapshot(opts) {
25138
25144
  packages: opts.profile.stack.map((name2) => ({ name: name2, node: matchNode(pkgNodes, pkgBase(name2)) })),
25139
25145
  tools: toolNodes.map((node2) => ({ name: String(node2.attrs["name"] ?? node2.description), node: node2 }))
25140
25146
  };
25141
- const causalNudge = recent2.length >= 2 && recent2.every(
25147
+ const causalNudge = recent3.length >= 2 && recent3.every(
25142
25148
  (r) => opts.store.outEdges(r.node.id, ["CAUSED_BY"]).length === 0 && opts.store.inEdges(r.node.id, ["CAUSED_BY"]).length === 0
25143
25149
  );
25144
- const abstractUndomained = recent2.filter((r) => {
25150
+ const abstractUndomained = recent3.filter((r) => {
25145
25151
  const grounded = opts.store.outEdges(r.node.id, ["ANCHORED_AT", "OCCURS_IN", "DEPENDS_ON"]).length > 0;
25146
25152
  const hasDomain = opts.store.outEdges(r.node.id, ["PERTAIN_TO"]).length > 0;
25147
25153
  return !grounded && !hasDomain;
@@ -25150,7 +25156,7 @@ function buildSnapshot(opts) {
25150
25156
  return {
25151
25157
  profile: opts.profile,
25152
25158
  profileContext,
25153
- recentProblems: recent2,
25159
+ recentProblems: recent3,
25154
25160
  recentResolved,
25155
25161
  recentConstraints,
25156
25162
  regressions,
@@ -32169,7 +32175,11 @@ function contextCard(store, snapshot) {
32169
32175
  return deliveredCard(store, intent ? `${count} for \u201C${clipIntent(intent)}\u201D` : `${count} in context`, delivered);
32170
32176
  }
32171
32177
  function writeContextCard(root, hash2, card) {
32172
- writeFileSync6(join7(root, ".errata", CONTEXT_CARD_FILE), JSON.stringify({ hash: hash2, card }));
32178
+ writeFileSync6(join7(root, ".errata", CONTEXT_CARD_FILE), JSON.stringify({
32179
+ hash: hash2,
32180
+ card,
32181
+ line: card && recallCardEnabled() ? renderRecallLine(card) : null
32182
+ }));
32173
32183
  }
32174
32184
  function readContextCard(root, hash2) {
32175
32185
  const path2 = join7(root, ".errata", CONTEXT_CARD_FILE);
@@ -32578,17 +32588,172 @@ var init_checkout_root = __esm({
32578
32588
  }
32579
32589
  });
32580
32590
 
32591
+ // src/process-identity.ts
32592
+ import { execFileSync } from "node:child_process";
32593
+ import { readFileSync as readFileSync10 } from "node:fs";
32594
+ function readProcessIdentity(pid, fresh = false) {
32595
+ if (!Number.isSafeInteger(pid) || pid <= 0) return null;
32596
+ if (pid === process.pid && self) return self;
32597
+ const cached2 = recent.get(pid);
32598
+ if (!fresh && cached2 && Date.now() - cached2.at < 1e3) return cached2.value;
32599
+ try {
32600
+ const run3 = (bin, args2) => execFileSync(bin, args2, {
32601
+ encoding: "utf8",
32602
+ windowsHide: true,
32603
+ timeout: 3e3,
32604
+ stdio: ["ignore", "pipe", "ignore"],
32605
+ env: { ...process.env, LC_ALL: "C", TZ: "UTC" }
32606
+ }).trim();
32607
+ let value;
32608
+ if (process.platform === "win32") {
32609
+ const ticks = run3("powershell.exe", [
32610
+ "-NoProfile",
32611
+ "-NonInteractive",
32612
+ "-Command",
32613
+ `(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks`
32614
+ ]);
32615
+ if (!/^\d+$/.test(ticks)) return null;
32616
+ value = { key: `win32:${ticks}`, bornAt: Number((BigInt(ticks) - 621355968000000000n) / 10000n) };
32617
+ } else if (process.platform === "linux") {
32618
+ const stat4 = readFileSync10(`/proc/${pid}/stat`, "utf8");
32619
+ const ticks = stat4.slice(stat4.lastIndexOf(")") + 2).split(" ")[19];
32620
+ const bootId = readFileSync10("/proc/sys/kernel/random/boot_id", "utf8").trim();
32621
+ const boot = /^btime (\d+)$/m.exec(readFileSync10("/proc/stat", "utf8"))?.[1];
32622
+ const hz = Number(run3("getconf", ["CLK_TCK"]));
32623
+ if (!boot || !/^\d+$/.test(ticks) || !Number.isFinite(hz) || hz <= 0) return null;
32624
+ value = { key: `linux:${bootId}:${ticks}`, bornAt: Number(boot) * 1e3 + Number(ticks) * 1e3 / hz };
32625
+ } else if (process.platform === "darwin") {
32626
+ const start2 = run3("ps", ["-p", String(pid), "-o", "lstart="]);
32627
+ value = { key: `darwin:${start2}`, bornAt: Date.parse(`${start2} UTC`) };
32628
+ } else return null;
32629
+ if (!Number.isFinite(value.bornAt) || value.bornAt <= 0) return null;
32630
+ if (pid === process.pid) self = value;
32631
+ if (recent.size >= 64) recent.clear();
32632
+ recent.set(pid, { at: Date.now(), value });
32633
+ return value;
32634
+ } catch {
32635
+ return null;
32636
+ }
32637
+ }
32638
+ var recent, self;
32639
+ var init_process_identity = __esm({
32640
+ "src/process-identity.ts"() {
32641
+ "use strict";
32642
+ recent = /* @__PURE__ */ new Map();
32643
+ }
32644
+ });
32645
+
32646
+ // src/lock.ts
32647
+ import { existsSync as existsSync12, readFileSync as readFileSync11, unlinkSync as unlinkSync2 } from "node:fs";
32648
+ function daemonLockPayload(lock) {
32649
+ return JSON.stringify({
32650
+ pid: lock.pid,
32651
+ webUiUrl: lock.webUiUrl,
32652
+ startedAt: lock.processStartedAt,
32653
+ ...lock.pid === process.pid ? { processIdentity: readProcessIdentity(lock.pid)?.key } : {},
32654
+ ...lock.wokeAt !== void 0 ? { wokeAt: lock.wokeAt } : {},
32655
+ ...lock.entry ? { entry: lock.entry } : {},
32656
+ ...lock.version ? { version: lock.version } : {}
32657
+ });
32658
+ }
32659
+ function isInstalledEntry(entry) {
32660
+ return /\/node_modules\/@inerrata-corporation\/errata\//.test(normEntry(entry) + "/");
32661
+ }
32662
+ function foreignDaemonNote(lock, selfEntry) {
32663
+ if (!lock.entry || normEntry(lock.entry) === normEntry(selfEntry)) return null;
32664
+ const runningInstalled = isInstalledEntry(lock.entry);
32665
+ const head2 = [
32666
+ `launched from ${runningInstalled ? "the installed package" : "a LOCAL BUILD"}, not this one${lock.version ? ` (it is ${lock.version})` : ""}:`,
32667
+ ` running: ${lock.entry}`,
32668
+ ` this: ${selfEntry}`
32669
+ ];
32670
+ return runningInstalled ? [...head2, "this CLI is a different bundle from the daemon it is talking to \u2014 its view may not match what the daemon runs."] : [...head2, "`errata update` does not replace it. To move onto the installed package: errata stop, then errata dash."];
32671
+ }
32672
+ function isProcessAlive(pid) {
32673
+ if (!Number.isSafeInteger(pid) || pid <= 0) return false;
32674
+ try {
32675
+ process.kill(pid, 0);
32676
+ return true;
32677
+ } catch (err2) {
32678
+ return err2.code === "EPERM";
32679
+ }
32680
+ }
32681
+ function readDaemonLock(lockPath) {
32682
+ if (!existsSync12(lockPath)) return null;
32683
+ try {
32684
+ return parseDaemonLock(readFileSync11(lockPath, "utf8"));
32685
+ } catch {
32686
+ return null;
32687
+ }
32688
+ }
32689
+ function parseDaemonLock(raw2) {
32690
+ try {
32691
+ const lock = JSON.parse(raw2);
32692
+ return lock && Number.isSafeInteger(lock.pid) && lock.pid > 0 ? lock : null;
32693
+ } catch {
32694
+ return null;
32695
+ }
32696
+ }
32697
+ function daemonLockState(lock, fresh = false) {
32698
+ if (!lock || !isProcessAlive(lock.pid)) return "stale";
32699
+ const identity = readProcessIdentity(lock.pid, fresh);
32700
+ if (!identity) return "unknown";
32701
+ if (lock.processIdentity) return lock.processIdentity === identity.key ? "running" : "stale";
32702
+ if (!Number.isFinite(lock.startedAt) || lock.startedAt <= 0) return "unknown";
32703
+ return identity.bornAt <= lock.startedAt ? "running" : "stale";
32704
+ }
32705
+ function isDaemonAlive(lockPath) {
32706
+ return daemonLockState(readDaemonLock(lockPath)) === "running";
32707
+ }
32708
+ function daemonLockBlocksStartup(lockPath) {
32709
+ return daemonLockState(readDaemonLock(lockPath), true) !== "stale";
32710
+ }
32711
+ function stopLockedDaemon(lockPath) {
32712
+ let original;
32713
+ try {
32714
+ original = readFileSync11(lockPath, "utf8");
32715
+ } catch {
32716
+ return "missing";
32717
+ }
32718
+ const lock = parseDaemonLock(original);
32719
+ if (!lock) return "unknown";
32720
+ const state = daemonLockState(lock, true);
32721
+ try {
32722
+ if (readFileSync11(lockPath, "utf8") !== original) return "changed";
32723
+ } catch {
32724
+ return "changed";
32725
+ }
32726
+ if (state === "unknown") return "unknown";
32727
+ if (state === "stale") {
32728
+ unlinkSync2(lockPath);
32729
+ return "stale";
32730
+ }
32731
+ process.kill(lock.pid, "SIGTERM");
32732
+ return "signaled";
32733
+ }
32734
+ var normEntry;
32735
+ var init_lock = __esm({
32736
+ "src/lock.ts"() {
32737
+ "use strict";
32738
+ init_process_identity();
32739
+ normEntry = (p) => {
32740
+ const s = p.replace(/\\/g, "/").replace(/\/+$/, "");
32741
+ return /^[A-Za-z]:\//.test(s) ? s.toLowerCase() : s;
32742
+ };
32743
+ }
32744
+ });
32745
+
32581
32746
  // src/registry.ts
32582
- import { existsSync as existsSync12, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "node:fs";
32747
+ import { existsSync as existsSync13, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
32583
32748
  import { join as join11 } from "node:path";
32584
32749
  function registryPath() {
32585
32750
  return process.env["ERRATA_REGISTRY_PATH"] ?? join11(globalDir(), "workspaces.json");
32586
32751
  }
32587
32752
  function read() {
32588
32753
  const p = registryPath();
32589
- if (!existsSync12(p)) return { version: 1, workspaces: {} };
32754
+ if (!existsSync13(p)) return { version: 1, workspaces: {} };
32590
32755
  try {
32591
- const parsed = JSON.parse(readFileSync10(p, "utf8"));
32756
+ const parsed = JSON.parse(readFileSync12(p, "utf8"));
32592
32757
  return { version: 1, workspaces: parsed.workspaces ?? {} };
32593
32758
  } catch {
32594
32759
  return { version: 1, workspaces: {} };
@@ -32596,9 +32761,9 @@ function read() {
32596
32761
  }
32597
32762
  function registryCorrupt() {
32598
32763
  const p = registryPath();
32599
- if (!existsSync12(p)) return false;
32764
+ if (!existsSync13(p)) return false;
32600
32765
  try {
32601
- JSON.parse(readFileSync10(p, "utf8"));
32766
+ JSON.parse(readFileSync12(p, "utf8"));
32602
32767
  return false;
32603
32768
  } catch {
32604
32769
  return true;
@@ -32651,7 +32816,7 @@ function pruneMissingWorkspaces() {
32651
32816
  const reg = read();
32652
32817
  const removed = [];
32653
32818
  for (const [id, entry] of Object.entries(reg.workspaces)) {
32654
- if (!existsSync12(entry.path)) {
32819
+ if (!existsSync13(entry.path)) {
32655
32820
  removed.push(entry);
32656
32821
  delete reg.workspaces[id];
32657
32822
  }
@@ -32660,19 +32825,14 @@ function pruneMissingWorkspaces() {
32660
32825
  return removed;
32661
32826
  }
32662
32827
  function workspaceStatus(entry) {
32663
- const missing = !existsSync12(entry.path);
32828
+ const missing = !existsSync13(entry.path);
32664
32829
  const lockPath = workspacePaths(entry.path).daemonLock;
32665
32830
  let running = false;
32666
32831
  let webUiUrl = null;
32667
- if (existsSync12(lockPath)) {
32668
- try {
32669
- const lock = JSON.parse(readFileSync10(lockPath, "utf8"));
32670
- if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
32671
- running = true;
32672
- webUiUrl = lock.webUiUrl;
32673
- }
32674
- } catch {
32675
- }
32832
+ const lock = readDaemonLock(lockPath);
32833
+ if (lock?.webUiUrl && daemonLockState(lock) === "running") {
32834
+ running = true;
32835
+ webUiUrl = lock.webUiUrl;
32676
32836
  }
32677
32837
  return { ...entry, running, webUiUrl, missing };
32678
32838
  }
@@ -32682,19 +32842,12 @@ function listWorkspaces() {
32682
32842
  function listWorkspaceEntries() {
32683
32843
  return Object.values(read().workspaces).sort((a, b) => b.lastSeenAt - a.lastSeenAt);
32684
32844
  }
32685
- function pidAlive(pid) {
32686
- try {
32687
- process.kill(pid, 0);
32688
- return true;
32689
- } catch (err2) {
32690
- return err2.code === "EPERM";
32691
- }
32692
- }
32693
32845
  var init_registry = __esm({
32694
32846
  "src/registry.ts"() {
32695
32847
  "use strict";
32696
32848
  init_paths();
32697
32849
  init_checkout_root();
32850
+ init_lock();
32698
32851
  }
32699
32852
  });
32700
32853
 
@@ -33991,7 +34144,7 @@ var init_dual_augment = __esm({
33991
34144
 
33992
34145
  // ../../packages/indexer/src/parse-cache.ts
33993
34146
  import { createHash as createHash6 } from "node:crypto";
33994
- import { existsSync as existsSync13, mkdirSync as mkdirSync6, readFileSync as readFileSync11, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync10 } from "node:fs";
34147
+ import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync13, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync10 } from "node:fs";
33995
34148
  import { homedir as homedir3 } from "node:os";
33996
34149
  import { join as join12 } from "node:path";
33997
34150
  function parseCacheDir() {
@@ -34006,7 +34159,7 @@ function entryPath(dir, key) {
34006
34159
  function readParseCache(dir, key) {
34007
34160
  const file2 = entryPath(dir, key);
34008
34161
  try {
34009
- const raw2 = readFileSync11(file2, "utf8");
34162
+ const raw2 = readFileSync13(file2, "utf8");
34010
34163
  const parsed = JSON.parse(raw2);
34011
34164
  if (parsed.v !== PARSE_CACHE_VERSION || !Array.isArray(parsed.symbols)) return null;
34012
34165
  return { symbols: parsed.symbols, reExports: parsed.reExports ?? [] };
@@ -34035,7 +34188,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
34035
34188
  sweptThisProcess = true;
34036
34189
  let removed = 0;
34037
34190
  try {
34038
- if (!existsSync13(dir)) return 0;
34191
+ if (!existsSync14(dir)) return 0;
34039
34192
  for (const bucket of readdirSync2(dir)) {
34040
34193
  const bucketDir = join12(dir, bucket);
34041
34194
  let names;
@@ -34293,11 +34446,11 @@ var init_identity3 = __esm({
34293
34446
  });
34294
34447
 
34295
34448
  // ../../packages/indexer/src/pipeline.ts
34296
- import { appendFileSync, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
34449
+ import { appendFileSync, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
34297
34450
  import { readdir } from "node:fs/promises";
34298
34451
  import { extname, join as join13, relative as relative2, sep } from "node:path";
34299
34452
  import { createHash as createHash7 } from "node:crypto";
34300
- import { execFileSync } from "node:child_process";
34453
+ import { execFileSync as execFileSync2 } from "node:child_process";
34301
34454
  function nowTs() {
34302
34455
  return indexNow ?? Date.now();
34303
34456
  }
@@ -34433,7 +34586,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
34433
34586
  for (const rel of [...changedRelPaths]) {
34434
34587
  let h;
34435
34588
  try {
34436
- h = createHash7("sha256").update(readFileSync12(join13(rootPath, rel))).digest("hex");
34589
+ h = createHash7("sha256").update(readFileSync14(join13(rootPath, rel))).digest("hex");
34437
34590
  } catch {
34438
34591
  continue;
34439
34592
  }
@@ -34488,7 +34641,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
34488
34641
  if (!provider) continue;
34489
34642
  let symbols;
34490
34643
  try {
34491
- symbols = provider.extractSymbols(readFileSync12(abs, "utf8"), abs);
34644
+ symbols = provider.extractSymbols(readFileSync14(abs, "utf8"), abs);
34492
34645
  } catch {
34493
34646
  continue;
34494
34647
  }
@@ -34808,7 +34961,7 @@ async function runIndexer(store, opts) {
34808
34961
  report.filesSkipped++;
34809
34962
  continue;
34810
34963
  }
34811
- source = readFileSync12(f.absPath, "utf8");
34964
+ source = readFileSync14(f.absPath, "utf8");
34812
34965
  } catch {
34813
34966
  report.filesSkipped++;
34814
34967
  continue;
@@ -34880,7 +35033,7 @@ async function runIndexer(store, opts) {
34880
35033
  const depth = fileNode.relPath.split("/").length;
34881
35034
  if (depth !== 3) continue;
34882
35035
  try {
34883
- const pkg = JSON.parse(readFileSync12(fileNode.absPath, "utf8"));
35036
+ const pkg = JSON.parse(readFileSync14(fileNode.absPath, "utf8"));
34884
35037
  if (!pkg.name) continue;
34885
35038
  const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
34886
35039
  const candidates = [
@@ -35298,7 +35451,7 @@ async function scan(root, current, ignores, providers, out2) {
35298
35451
  function gitListRelPaths(root, ignores) {
35299
35452
  let stdout;
35300
35453
  try {
35301
- stdout = execFileSync(
35454
+ stdout = execFileSync2(
35302
35455
  "git",
35303
35456
  ["-C", root, "ls-files", "--cached", "--others", "--exclude-standard", "-z"],
35304
35457
  {
@@ -35356,7 +35509,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
35356
35509
  if (existing && fileUnchanged(existing.attrs, f, skip)) return;
35357
35510
  let contentHash;
35358
35511
  try {
35359
- contentHash = createHash7("sha256").update(readFileSync12(f.absPath)).digest("hex");
35512
+ contentHash = createHash7("sha256").update(readFileSync14(f.absPath)).digest("hex");
35360
35513
  } catch {
35361
35514
  }
35362
35515
  const carried = { ...existing?.attrs ?? {} };
@@ -35973,13 +36126,13 @@ async function Module2(moduleArg = {}) {
35973
36126
  }
35974
36127
  readAsync = /* @__PURE__ */ __name(async (url2) => {
35975
36128
  if (isFileURI(url2)) {
35976
- return new Promise((resolve7, reject) => {
36129
+ return new Promise((resolve8, reject) => {
35977
36130
  var xhr = new XMLHttpRequest();
35978
36131
  xhr.open("GET", url2, true);
35979
36132
  xhr.responseType = "arraybuffer";
35980
36133
  xhr.onload = () => {
35981
36134
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
35982
- resolve7(xhr.response);
36135
+ resolve8(xhr.response);
35983
36136
  return;
35984
36137
  }
35985
36138
  reject(xhr.status);
@@ -36175,9 +36328,9 @@ async function Module2(moduleArg = {}) {
36175
36328
  __name(receiveInstantiationResult, "receiveInstantiationResult");
36176
36329
  var info2 = getWasmImports();
36177
36330
  if (Module["instantiateWasm"]) {
36178
- return new Promise((resolve7, reject) => {
36331
+ return new Promise((resolve8, reject) => {
36179
36332
  Module["instantiateWasm"](info2, (mod, inst) => {
36180
- resolve7(receiveInstance(mod, inst));
36333
+ resolve8(receiveInstance(mod, inst));
36181
36334
  });
36182
36335
  });
36183
36336
  }
@@ -37508,8 +37661,8 @@ async function Module2(moduleArg = {}) {
37508
37661
  if (runtimeInitialized) {
37509
37662
  moduleRtn = Module;
37510
37663
  } else {
37511
- moduleRtn = new Promise((resolve7, reject) => {
37512
- readyPromiseResolve = resolve7;
37664
+ moduleRtn = new Promise((resolve8, reject) => {
37665
+ readyPromiseResolve = resolve8;
37513
37666
  readyPromiseReject = reject;
37514
37667
  });
37515
37668
  }
@@ -39740,7 +39893,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
39740
39893
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
39741
39894
  import { fileURLToPath } from "node:url";
39742
39895
  import { dirname as dirname7, join as join14 } from "node:path";
39743
- import { existsSync as existsSync14, readdirSync as readdirSync3 } from "node:fs";
39896
+ import { existsSync as existsSync15, readdirSync as readdirSync3 } from "node:fs";
39744
39897
  import { createRequire as createRequire2 } from "node:module";
39745
39898
  function entryDir() {
39746
39899
  try {
@@ -39755,7 +39908,7 @@ function entryDir() {
39755
39908
  function findWasmDir() {
39756
39909
  const here = entryDir();
39757
39910
  const seaWasm = join14(here, "resources", "wasm");
39758
- if (existsSync14(join14(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
39911
+ if (existsSync15(join14(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
39759
39912
  let dir = here;
39760
39913
  for (let i2 = 0; i2 < 6; i2++) {
39761
39914
  const flat = join14(
@@ -39765,13 +39918,13 @@ function findWasmDir() {
39765
39918
  "tree-sitter-wasm",
39766
39919
  "wasm"
39767
39920
  );
39768
- if (existsSync14(join14(flat, "tree-sitter-typescript.wasm"))) return flat;
39921
+ if (existsSync15(join14(flat, "tree-sitter-typescript.wasm"))) return flat;
39769
39922
  dir = dirname7(dir);
39770
39923
  }
39771
39924
  let root = here;
39772
39925
  for (let i2 = 0; i2 < 6; i2++) {
39773
39926
  const pnpmDir = join14(root, "node_modules", ".pnpm");
39774
- if (existsSync14(pnpmDir)) {
39927
+ if (existsSync15(pnpmDir)) {
39775
39928
  for (const entry of readdirSync3(pnpmDir)) {
39776
39929
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
39777
39930
  const candidate = join14(
@@ -39782,7 +39935,7 @@ function findWasmDir() {
39782
39935
  "tree-sitter-wasm",
39783
39936
  "wasm"
39784
39937
  );
39785
- if (existsSync14(join14(candidate, "tree-sitter-typescript.wasm"))) {
39938
+ if (existsSync15(join14(candidate, "tree-sitter-typescript.wasm"))) {
39786
39939
  return candidate;
39787
39940
  }
39788
39941
  }
@@ -39797,17 +39950,17 @@ function findWasmDir() {
39797
39950
  function findRuntimeDir() {
39798
39951
  const here = entryDir();
39799
39952
  const seaRuntime = join14(here, "resources", "wasm");
39800
- if (existsSync14(join14(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
39953
+ if (existsSync15(join14(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
39801
39954
  let dir = here;
39802
39955
  for (let i2 = 0; i2 < 6; i2++) {
39803
39956
  const flat = join14(dir, "node_modules", "web-tree-sitter");
39804
- if (existsSync14(join14(flat, "web-tree-sitter.wasm"))) return flat;
39957
+ if (existsSync15(join14(flat, "web-tree-sitter.wasm"))) return flat;
39805
39958
  dir = dirname7(dir);
39806
39959
  }
39807
39960
  let root = here;
39808
39961
  for (let i2 = 0; i2 < 6; i2++) {
39809
39962
  const pnpmDir = join14(root, "node_modules", ".pnpm");
39810
- if (existsSync14(pnpmDir)) {
39963
+ if (existsSync15(pnpmDir)) {
39811
39964
  for (const entry of readdirSync3(pnpmDir)) {
39812
39965
  if (entry.startsWith("web-tree-sitter@")) {
39813
39966
  const candidate = join14(
@@ -39816,7 +39969,7 @@ function findRuntimeDir() {
39816
39969
  "node_modules",
39817
39970
  "web-tree-sitter"
39818
39971
  );
39819
- if (existsSync14(join14(candidate, "web-tree-sitter.wasm"))) {
39972
+ if (existsSync15(join14(candidate, "web-tree-sitter.wasm"))) {
39820
39973
  return candidate;
39821
39974
  }
39822
39975
  }
@@ -42765,7 +42918,7 @@ var init_src11 = __esm({
42765
42918
  });
42766
42919
 
42767
42920
  // src/reconcile.ts
42768
- import { execFileSync as execFileSync2 } from "node:child_process";
42921
+ import { execFileSync as execFileSync3 } from "node:child_process";
42769
42922
  import { readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
42770
42923
  import { join as join15, relative as relative3, sep as sep2 } from "node:path";
42771
42924
  function indexerWouldScan(rel) {
@@ -42779,7 +42932,7 @@ function indexerWouldScan(rel) {
42779
42932
  function gitSourceFiles(root) {
42780
42933
  let stdout;
42781
42934
  try {
42782
- stdout = execFileSync2(
42935
+ stdout = execFileSync3(
42783
42936
  "git",
42784
42937
  ["-C", root, "ls-files", "--cached", "--others", "--exclude-standard", "-z"],
42785
42938
  { encoding: "utf8", maxBuffer: 128 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
@@ -42955,7 +43108,7 @@ __export(mcp_exports, {
42955
43108
  runTool: () => runTool,
42956
43109
  searchGraph: () => searchGraph
42957
43110
  });
42958
- import { existsSync as existsSync15, readFileSync as readFileSync13 } from "node:fs";
43111
+ import { existsSync as existsSync16, readFileSync as readFileSync15 } from "node:fs";
42959
43112
  import { resolve as resolve3 } from "node:path";
42960
43113
  function collectEnrichmentPulls(store, opts = {}) {
42961
43114
  const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
@@ -42992,7 +43145,7 @@ function takeEnrichmentNudge(store) {
42992
43145
  ` + items;
42993
43146
  }
42994
43147
  function takeDiscriminatorNudge(path2) {
42995
- if (!path2 || !existsSync15(path2)) return null;
43148
+ if (!path2 || !existsSync16(path2)) return null;
42996
43149
  let shared;
42997
43150
  try {
42998
43151
  shared = openGraphStore({ path: path2 });
@@ -43123,10 +43276,10 @@ function showNode(store, node2, maxLines) {
43123
43276
  if (!relPath) return { found: false, reason: "no file owner for node" };
43124
43277
  const workspaceRoot = process.cwd();
43125
43278
  const absPath = resolve3(workspaceRoot, relPath);
43126
- if (!existsSync15(absPath)) {
43279
+ if (!existsSync16(absPath)) {
43127
43280
  return { found: false, reason: `file not found on disk: ${absPath}` };
43128
43281
  }
43129
- const source = readFileSync13(absPath, "utf8");
43282
+ const source = readFileSync15(absPath, "utf8");
43130
43283
  const attrs = node2.attrs;
43131
43284
  let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
43132
43285
  let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
@@ -43845,7 +43998,7 @@ var init_mcp = __esm({
43845
43998
  const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
43846
43999
  try {
43847
44000
  const path2 = sharedStorePath();
43848
- if (!existsSync15(path2)) return { found: true, ...local };
44001
+ if (!existsSync16(path2)) return { found: true, ...local };
43849
44002
  const shared = openGraphStore({ path: path2 });
43850
44003
  try {
43851
44004
  if (!shared.getNode(id)) return { found: true, ...local };
@@ -44448,7 +44601,7 @@ var init_mcp = __esm({
44448
44601
  inputSchema: { type: "object", properties: {} },
44449
44602
  handler: () => {
44450
44603
  const path2 = sharedStorePath();
44451
- if (!existsSync15(path2)) return { count: 0, pending: [] };
44604
+ if (!existsSync16(path2)) return { count: 0, pending: [] };
44452
44605
  const shared = openGraphStore({ path: path2 });
44453
44606
  try {
44454
44607
  const pending = pendingAbstractions(shared);
@@ -44476,7 +44629,7 @@ var init_mcp = __esm({
44476
44629
  },
44477
44630
  handler: (args2) => {
44478
44631
  const path2 = sharedStorePath();
44479
- if (!existsSync15(path2)) return { count: 0, pending: [] };
44632
+ if (!existsSync16(path2)) return { count: 0, pending: [] };
44480
44633
  const shared = openGraphStore({ path: path2 });
44481
44634
  try {
44482
44635
  const pending = pendingDiscriminators(shared, {
@@ -44520,7 +44673,7 @@ var init_mcp = __esm({
44520
44673
  },
44521
44674
  handler: (args2) => {
44522
44675
  const path2 = sharedStorePath();
44523
- if (!existsSync15(path2)) return { count: 0, routes: [] };
44676
+ if (!existsSync16(path2)) return { count: 0, routes: [] };
44524
44677
  const shared = openGraphStore({ path: path2 });
44525
44678
  try {
44526
44679
  const result = triageOf(shared, {
@@ -52407,11 +52560,11 @@ var init_tool_index = __esm({
52407
52560
 
52408
52561
  // src/outbox.ts
52409
52562
  import {
52410
- existsSync as existsSync16,
52563
+ existsSync as existsSync17,
52411
52564
  readdirSync as readdirSync5,
52412
- readFileSync as readFileSync14,
52413
- renameSync,
52414
- unlinkSync,
52565
+ readFileSync as readFileSync16,
52566
+ renameSync as renameSync2,
52567
+ unlinkSync as unlinkSync3,
52415
52568
  writeFileSync as writeFileSync12
52416
52569
  } from "node:fs";
52417
52570
  import { join as join17 } from "node:path";
@@ -52425,12 +52578,12 @@ function enqueueOutbox(paths, payload) {
52425
52578
  }
52426
52579
  async function flushOutbox(paths, client, store) {
52427
52580
  ensureDir(paths.outbox);
52428
- const entries = existsSync16(paths.outbox) ? readdirSync5(paths.outbox) : [];
52581
+ const entries = existsSync17(paths.outbox) ? readdirSync5(paths.outbox) : [];
52429
52582
  let uploaded = 0;
52430
52583
  let failed = 0;
52431
52584
  const quarantine = (abs, reason) => {
52432
52585
  try {
52433
- renameSync(abs, `${abs}.bad`);
52586
+ renameSync2(abs, `${abs}.bad`);
52434
52587
  console.warn(`[errata] outbox: quarantined ${abs} (${reason})`);
52435
52588
  } catch {
52436
52589
  }
@@ -52439,7 +52592,7 @@ async function flushOutbox(paths, client, store) {
52439
52592
  const abs = join17(paths.outbox, f);
52440
52593
  let payload;
52441
52594
  try {
52442
- payload = JSON.parse(readFileSync14(abs, "utf8"));
52595
+ payload = JSON.parse(readFileSync16(abs, "utf8"));
52443
52596
  } catch {
52444
52597
  failed++;
52445
52598
  quarantine(abs, "unparseable JSON");
@@ -52474,7 +52627,7 @@ async function flushOutbox(paths, client, store) {
52474
52627
  }
52475
52628
  }
52476
52629
  }
52477
- unlinkSync(abs);
52630
+ unlinkSync3(abs);
52478
52631
  if (res.accepted === 0) uploaded++;
52479
52632
  } catch (err2) {
52480
52633
  failed++;
@@ -52484,7 +52637,7 @@ async function flushOutbox(paths, client, store) {
52484
52637
  }
52485
52638
  }
52486
52639
  }
52487
- const remainingFiles = existsSync16(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
52640
+ const remainingFiles = existsSync17(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
52488
52641
  return { uploaded, failed, remaining: remainingFiles.length };
52489
52642
  }
52490
52643
  var init_outbox = __esm({
@@ -53050,12 +53203,17 @@ function buildWebUi(deps) {
53050
53203
  block,
53051
53204
  lastInjectedHash
53052
53205
  });
53206
+ let systemMessage = null;
53053
53207
  if (sid && block && recallCardEnabled() && (decision || atPrompt)) {
53054
53208
  const card = readContextCard(deps.paths.root, block.hash);
53055
- if (card) rememberCard(sid, card);
53209
+ if (card) {
53210
+ rememberCard(sid, card);
53211
+ if (decision && sid.startsWith("codex:")) systemMessage = renderRecallLine(card);
53212
+ }
53056
53213
  }
53057
53214
  if (!decision) return c.json({});
53058
53215
  return c.json({
53216
+ ...systemMessage ? { systemMessage } : {},
53059
53217
  hookSpecificOutput: {
53060
53218
  hookEventName: decision.hookEventName,
53061
53219
  additionalContext: decision.additionalContext
@@ -55573,9 +55731,9 @@ var require_dispatcher_base = __commonJS({
55573
55731
  }
55574
55732
  close(callback) {
55575
55733
  if (callback === void 0) {
55576
- return new Promise((resolve7, reject) => {
55734
+ return new Promise((resolve8, reject) => {
55577
55735
  this.close((err2, data) => {
55578
- return err2 ? reject(err2) : resolve7(data);
55736
+ return err2 ? reject(err2) : resolve8(data);
55579
55737
  });
55580
55738
  });
55581
55739
  }
@@ -55613,12 +55771,12 @@ var require_dispatcher_base = __commonJS({
55613
55771
  err2 = null;
55614
55772
  }
55615
55773
  if (callback === void 0) {
55616
- return new Promise((resolve7, reject) => {
55774
+ return new Promise((resolve8, reject) => {
55617
55775
  this.destroy(err2, (err3, data) => {
55618
55776
  return err3 ? (
55619
55777
  /* istanbul ignore next: should never error */
55620
55778
  reject(err3)
55621
- ) : resolve7(data);
55779
+ ) : resolve8(data);
55622
55780
  });
55623
55781
  });
55624
55782
  }
@@ -57885,8 +58043,8 @@ var require_util2 = __commonJS({
57885
58043
  function createDeferredPromise() {
57886
58044
  let res;
57887
58045
  let rej;
57888
- const promise2 = new Promise((resolve7, reject) => {
57889
- res = resolve7;
58046
+ const promise2 = new Promise((resolve8, reject) => {
58047
+ res = resolve8;
57890
58048
  rej = reject;
57891
58049
  });
57892
58050
  return { promise: promise2, resolve: res, reject: rej };
@@ -60027,12 +60185,12 @@ upgrade: ${upgrade}\r
60027
60185
  cb();
60028
60186
  }
60029
60187
  }
60030
- const waitForDrain = () => new Promise((resolve7, reject) => {
60188
+ const waitForDrain = () => new Promise((resolve8, reject) => {
60031
60189
  assert2(callback === null);
60032
60190
  if (socket[kError]) {
60033
60191
  reject(socket[kError]);
60034
60192
  } else {
60035
- callback = resolve7;
60193
+ callback = resolve8;
60036
60194
  }
60037
60195
  });
60038
60196
  socket.on("close", onDrain).on("drain", onDrain);
@@ -60669,12 +60827,12 @@ var require_client_h2 = __commonJS({
60669
60827
  cb();
60670
60828
  }
60671
60829
  }
60672
- const waitForDrain = () => new Promise((resolve7, reject) => {
60830
+ const waitForDrain = () => new Promise((resolve8, reject) => {
60673
60831
  assert2(callback === null);
60674
60832
  if (socket[kError]) {
60675
60833
  reject(socket[kError]);
60676
60834
  } else {
60677
- callback = resolve7;
60835
+ callback = resolve8;
60678
60836
  }
60679
60837
  });
60680
60838
  h2stream.on("close", onDrain).on("drain", onDrain);
@@ -61151,16 +61309,16 @@ var require_client = __commonJS({
61151
61309
  return this[kNeedDrain] < 2;
61152
61310
  }
61153
61311
  async [kClose]() {
61154
- return new Promise((resolve7) => {
61312
+ return new Promise((resolve8) => {
61155
61313
  if (this[kSize]) {
61156
- this[kClosedResolve] = resolve7;
61314
+ this[kClosedResolve] = resolve8;
61157
61315
  } else {
61158
- resolve7(null);
61316
+ resolve8(null);
61159
61317
  }
61160
61318
  });
61161
61319
  }
61162
61320
  async [kDestroy](err2) {
61163
- return new Promise((resolve7) => {
61321
+ return new Promise((resolve8) => {
61164
61322
  const requests = this[kQueue].splice(this[kPendingIdx]);
61165
61323
  for (let i2 = 0; i2 < requests.length; i2++) {
61166
61324
  const request = requests[i2];
@@ -61171,7 +61329,7 @@ var require_client = __commonJS({
61171
61329
  this[kClosedResolve]();
61172
61330
  this[kClosedResolve] = null;
61173
61331
  }
61174
- resolve7(null);
61332
+ resolve8(null);
61175
61333
  };
61176
61334
  if (this[kHTTPContext]) {
61177
61335
  this[kHTTPContext].destroy(err2, callback);
@@ -61222,7 +61380,7 @@ var require_client = __commonJS({
61222
61380
  });
61223
61381
  }
61224
61382
  try {
61225
- const socket = await new Promise((resolve7, reject) => {
61383
+ const socket = await new Promise((resolve8, reject) => {
61226
61384
  client[kConnector]({
61227
61385
  host,
61228
61386
  hostname: hostname3,
@@ -61234,7 +61392,7 @@ var require_client = __commonJS({
61234
61392
  if (err2) {
61235
61393
  reject(err2);
61236
61394
  } else {
61237
- resolve7(socket2);
61395
+ resolve8(socket2);
61238
61396
  }
61239
61397
  });
61240
61398
  });
@@ -61570,8 +61728,8 @@ var require_pool_base = __commonJS({
61570
61728
  if (this[kQueue].isEmpty()) {
61571
61729
  await Promise.all(this[kClients].map((c) => c.close()));
61572
61730
  } else {
61573
- await new Promise((resolve7) => {
61574
- this[kClosedResolve] = resolve7;
61731
+ await new Promise((resolve8) => {
61732
+ this[kClosedResolve] = resolve8;
61575
61733
  });
61576
61734
  }
61577
61735
  }
@@ -62786,7 +62944,7 @@ var require_readable = __commonJS({
62786
62944
  if (this._readableState.closeEmitted) {
62787
62945
  return null;
62788
62946
  }
62789
- return await new Promise((resolve7, reject) => {
62947
+ return await new Promise((resolve8, reject) => {
62790
62948
  if (this[kContentLength] > limit) {
62791
62949
  this.destroy(new AbortError());
62792
62950
  }
@@ -62799,7 +62957,7 @@ var require_readable = __commonJS({
62799
62957
  if (signal?.aborted) {
62800
62958
  reject(signal.reason ?? new AbortError());
62801
62959
  } else {
62802
- resolve7(null);
62960
+ resolve8(null);
62803
62961
  }
62804
62962
  }).on("error", noop).on("data", function(chunk) {
62805
62963
  limit -= chunk.length;
@@ -62810,15 +62968,15 @@ var require_readable = __commonJS({
62810
62968
  });
62811
62969
  }
62812
62970
  };
62813
- function isLocked(self) {
62814
- return self[kBody] && self[kBody].locked === true || self[kConsume];
62971
+ function isLocked(self2) {
62972
+ return self2[kBody] && self2[kBody].locked === true || self2[kConsume];
62815
62973
  }
62816
- function isUnusable(self) {
62817
- return util.isDisturbed(self) || isLocked(self);
62974
+ function isUnusable(self2) {
62975
+ return util.isDisturbed(self2) || isLocked(self2);
62818
62976
  }
62819
62977
  async function consume(stream, type) {
62820
62978
  assert2(!stream[kConsume]);
62821
- return new Promise((resolve7, reject) => {
62979
+ return new Promise((resolve8, reject) => {
62822
62980
  if (isUnusable(stream)) {
62823
62981
  const rState = stream._readableState;
62824
62982
  if (rState.destroyed && rState.closeEmitted === false) {
@@ -62835,7 +62993,7 @@ var require_readable = __commonJS({
62835
62993
  stream[kConsume] = {
62836
62994
  type,
62837
62995
  stream,
62838
- resolve: resolve7,
62996
+ resolve: resolve8,
62839
62997
  reject,
62840
62998
  length: 0,
62841
62999
  body: []
@@ -62905,18 +63063,18 @@ var require_readable = __commonJS({
62905
63063
  return buffer;
62906
63064
  }
62907
63065
  function consumeEnd(consume2) {
62908
- const { type, body: body2, resolve: resolve7, stream, length } = consume2;
63066
+ const { type, body: body2, resolve: resolve8, stream, length } = consume2;
62909
63067
  try {
62910
63068
  if (type === "text") {
62911
- resolve7(chunksDecode(body2, length));
63069
+ resolve8(chunksDecode(body2, length));
62912
63070
  } else if (type === "json") {
62913
- resolve7(JSON.parse(chunksDecode(body2, length)));
63071
+ resolve8(JSON.parse(chunksDecode(body2, length)));
62914
63072
  } else if (type === "arrayBuffer") {
62915
- resolve7(chunksConcat(body2, length).buffer);
63073
+ resolve8(chunksConcat(body2, length).buffer);
62916
63074
  } else if (type === "blob") {
62917
- resolve7(new Blob(body2, { type: stream[kContentType] }));
63075
+ resolve8(new Blob(body2, { type: stream[kContentType] }));
62918
63076
  } else if (type === "bytes") {
62919
- resolve7(chunksConcat(body2, length));
63077
+ resolve8(chunksConcat(body2, length));
62920
63078
  }
62921
63079
  consumeFinish(consume2);
62922
63080
  } catch (err2) {
@@ -63173,9 +63331,9 @@ var require_api_request = __commonJS({
63173
63331
  };
63174
63332
  function request(opts, callback) {
63175
63333
  if (callback === void 0) {
63176
- return new Promise((resolve7, reject) => {
63334
+ return new Promise((resolve8, reject) => {
63177
63335
  request.call(this, opts, (err2, data) => {
63178
- return err2 ? reject(err2) : resolve7(data);
63336
+ return err2 ? reject(err2) : resolve8(data);
63179
63337
  });
63180
63338
  });
63181
63339
  }
@@ -63201,42 +63359,42 @@ var require_abort_signal = __commonJS({
63201
63359
  var { RequestAbortedError } = require_errors();
63202
63360
  var kListener = Symbol("kListener");
63203
63361
  var kSignal = Symbol("kSignal");
63204
- function abort2(self) {
63205
- if (self.abort) {
63206
- self.abort(self[kSignal]?.reason);
63362
+ function abort2(self2) {
63363
+ if (self2.abort) {
63364
+ self2.abort(self2[kSignal]?.reason);
63207
63365
  } else {
63208
- self.reason = self[kSignal]?.reason ?? new RequestAbortedError();
63366
+ self2.reason = self2[kSignal]?.reason ?? new RequestAbortedError();
63209
63367
  }
63210
- removeSignal(self);
63368
+ removeSignal(self2);
63211
63369
  }
63212
- function addSignal(self, signal) {
63213
- self.reason = null;
63214
- self[kSignal] = null;
63215
- self[kListener] = null;
63370
+ function addSignal(self2, signal) {
63371
+ self2.reason = null;
63372
+ self2[kSignal] = null;
63373
+ self2[kListener] = null;
63216
63374
  if (!signal) {
63217
63375
  return;
63218
63376
  }
63219
63377
  if (signal.aborted) {
63220
- abort2(self);
63378
+ abort2(self2);
63221
63379
  return;
63222
63380
  }
63223
- self[kSignal] = signal;
63224
- self[kListener] = () => {
63225
- abort2(self);
63381
+ self2[kSignal] = signal;
63382
+ self2[kListener] = () => {
63383
+ abort2(self2);
63226
63384
  };
63227
- addAbortListener(self[kSignal], self[kListener]);
63385
+ addAbortListener(self2[kSignal], self2[kListener]);
63228
63386
  }
63229
- function removeSignal(self) {
63230
- if (!self[kSignal]) {
63387
+ function removeSignal(self2) {
63388
+ if (!self2[kSignal]) {
63231
63389
  return;
63232
63390
  }
63233
- if ("removeEventListener" in self[kSignal]) {
63234
- self[kSignal].removeEventListener("abort", self[kListener]);
63391
+ if ("removeEventListener" in self2[kSignal]) {
63392
+ self2[kSignal].removeEventListener("abort", self2[kListener]);
63235
63393
  } else {
63236
- self[kSignal].removeListener("abort", self[kListener]);
63394
+ self2[kSignal].removeListener("abort", self2[kListener]);
63237
63395
  }
63238
- self[kSignal] = null;
63239
- self[kListener] = null;
63396
+ self2[kSignal] = null;
63397
+ self2[kListener] = null;
63240
63398
  }
63241
63399
  module2.exports = {
63242
63400
  addSignal,
@@ -63398,9 +63556,9 @@ var require_api_stream = __commonJS({
63398
63556
  };
63399
63557
  function stream(opts, factory, callback) {
63400
63558
  if (callback === void 0) {
63401
- return new Promise((resolve7, reject) => {
63559
+ return new Promise((resolve8, reject) => {
63402
63560
  stream.call(this, opts, factory, (err2, data) => {
63403
- return err2 ? reject(err2) : resolve7(data);
63561
+ return err2 ? reject(err2) : resolve8(data);
63404
63562
  });
63405
63563
  });
63406
63564
  }
@@ -63685,9 +63843,9 @@ var require_api_upgrade = __commonJS({
63685
63843
  };
63686
63844
  function upgrade(opts, callback) {
63687
63845
  if (callback === void 0) {
63688
- return new Promise((resolve7, reject) => {
63846
+ return new Promise((resolve8, reject) => {
63689
63847
  upgrade.call(this, opts, (err2, data) => {
63690
- return err2 ? reject(err2) : resolve7(data);
63848
+ return err2 ? reject(err2) : resolve8(data);
63691
63849
  });
63692
63850
  });
63693
63851
  }
@@ -63779,9 +63937,9 @@ var require_api_connect = __commonJS({
63779
63937
  };
63780
63938
  function connect(opts, callback) {
63781
63939
  if (callback === void 0) {
63782
- return new Promise((resolve7, reject) => {
63940
+ return new Promise((resolve8, reject) => {
63783
63941
  connect.call(this, opts, (err2, data) => {
63784
- return err2 ? reject(err2) : resolve7(data);
63942
+ return err2 ? reject(err2) : resolve8(data);
63785
63943
  });
63786
63944
  });
63787
63945
  }
@@ -67643,7 +67801,7 @@ var require_fetch = __commonJS({
67643
67801
  function dispatch({ body: body2 }) {
67644
67802
  const url2 = requestCurrentURL(request);
67645
67803
  const agent = fetchParams.controller.dispatcher;
67646
- return new Promise((resolve7, reject) => agent.dispatch(
67804
+ return new Promise((resolve8, reject) => agent.dispatch(
67647
67805
  {
67648
67806
  path: url2.pathname + url2.search,
67649
67807
  origin: url2.origin,
@@ -67719,7 +67877,7 @@ var require_fetch = __commonJS({
67719
67877
  }
67720
67878
  }
67721
67879
  const onError = this.onError.bind(this);
67722
- resolve7({
67880
+ resolve8({
67723
67881
  status,
67724
67882
  statusText,
67725
67883
  headersList,
@@ -67765,7 +67923,7 @@ var require_fetch = __commonJS({
67765
67923
  for (let i2 = 0; i2 < rawHeaders.length; i2 += 2) {
67766
67924
  headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i2]), rawHeaders[i2 + 1].toString("latin1"), true);
67767
67925
  }
67768
- resolve7({
67926
+ resolve8({
67769
67927
  status,
67770
67928
  statusText: STATUS_CODES[status],
67771
67929
  headersList,
@@ -71404,8 +71562,8 @@ var require_util8 = __commonJS({
71404
71562
  return true;
71405
71563
  }
71406
71564
  function delay(ms) {
71407
- return new Promise((resolve7) => {
71408
- setTimeout(resolve7, ms).unref();
71565
+ return new Promise((resolve8) => {
71566
+ setTimeout(resolve8, ms).unref();
71409
71567
  });
71410
71568
  }
71411
71569
  module2.exports = {
@@ -72093,7 +72251,7 @@ __export(witness_ledger_exports, {
72093
72251
  summarizeWitnessLedger: () => summarizeWitnessLedger,
72094
72252
  witnessLedgerPath: () => witnessLedgerPath
72095
72253
  });
72096
- import { appendFileSync as appendFileSync3, existsSync as existsSync25, readFileSync as readFileSync27, writeFileSync as writeFileSync20 } from "node:fs";
72254
+ import { appendFileSync as appendFileSync3, existsSync as existsSync26, readFileSync as readFileSync29, writeFileSync as writeFileSync20 } from "node:fs";
72097
72255
  import { join as join33 } from "node:path";
72098
72256
  function witnessLedgerPath(configDir) {
72099
72257
  return join33(configDir, "witness-ledger.jsonl");
@@ -72102,7 +72260,7 @@ function appendWitnessLedger(configDir, entry) {
72102
72260
  const path2 = witnessLedgerPath(configDir);
72103
72261
  try {
72104
72262
  appendFileSync3(path2, JSON.stringify(entry) + "\n");
72105
- const lines = readFileSync27(path2, "utf8").split("\n").filter(Boolean);
72263
+ const lines = readFileSync29(path2, "utf8").split("\n").filter(Boolean);
72106
72264
  if (lines.length > LEDGER_MAX_LINES) {
72107
72265
  writeFileSync20(path2, lines.slice(-Math.floor(LEDGER_MAX_LINES / 2)).join("\n") + "\n");
72108
72266
  }
@@ -72111,9 +72269,9 @@ function appendWitnessLedger(configDir, entry) {
72111
72269
  }
72112
72270
  function readWitnessLedger(configDir) {
72113
72271
  const path2 = witnessLedgerPath(configDir);
72114
- if (!existsSync25(path2)) return [];
72272
+ if (!existsSync26(path2)) return [];
72115
72273
  try {
72116
- return readFileSync27(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
72274
+ return readFileSync29(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter((e) => typeof e.ts === "number" && typeof e.channel === "string");
72117
72275
  } catch {
72118
72276
  return [];
72119
72277
  }
@@ -72552,12 +72710,12 @@ var init_report_render = __esm({
72552
72710
 
72553
72711
  // src/cli.ts
72554
72712
  init_src6();
72555
- import { closeSync as closeSync2, existsSync as existsSync36, openSync as openSync2, readFileSync as readFileSync37, renameSync as renameSync4, statSync as statSync10 } from "node:fs";
72556
- import { join as join44, resolve as pathResolve2 } from "node:path";
72713
+ import { closeSync as closeSync2, existsSync as existsSync37, openSync as openSync2, readFileSync as readFileSync40, renameSync as renameSync6, statSync as statSync11 } from "node:fs";
72714
+ import { join as join47, resolve as pathResolve2 } from "node:path";
72557
72715
  import { spawn as spawn5 } from "node:child_process";
72558
72716
 
72559
72717
  // src/daemon.ts
72560
- import { existsSync as existsSync27, writeFileSync as writeFileSync23 } from "node:fs";
72718
+ import { existsSync as existsSync28, writeFileSync as writeFileSync23 } from "node:fs";
72561
72719
 
72562
72720
  // ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
72563
72721
  import { createServer as createServerHTTP } from "http";
@@ -72987,7 +73145,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
72987
73145
  });
72988
73146
  if (!chunk) {
72989
73147
  if (i2 === 1) {
72990
- await new Promise((resolve7) => setTimeout(resolve7));
73148
+ await new Promise((resolve8) => setTimeout(resolve8));
72991
73149
  maxReadCount = 3;
72992
73150
  continue;
72993
73151
  }
@@ -73134,10 +73292,11 @@ var serve = (options, listeningListener) => {
73134
73292
  init_cloud_auth();
73135
73293
  init_webui();
73136
73294
  init_config();
73295
+ init_lock();
73137
73296
 
73138
73297
  // src/engine.ts
73139
- import { execFileSync as execFileSync4 } from "node:child_process";
73140
- import { existsSync as existsSync26, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync3, readFileSync as readFileSync29, writeFileSync as writeFileSync22 } from "node:fs";
73298
+ import { execFileSync as execFileSync5 } from "node:child_process";
73299
+ import { existsSync as existsSync27, statSync as statSync8, appendFileSync as appendFileSync4, readdirSync as readdirSync10, renameSync as renameSync4, readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
73141
73300
  import { basename as basename7, join as join35, relative as relative6, sep as sep4 } from "node:path";
73142
73301
 
73143
73302
  // src/source-watcher.ts
@@ -73874,9 +74033,9 @@ var NodeFsHandler = class {
73874
74033
  if (this.fsw.closed) {
73875
74034
  return;
73876
74035
  }
73877
- const dirname14 = sysPath.dirname(file2);
74036
+ const dirname15 = sysPath.dirname(file2);
73878
74037
  const basename9 = sysPath.basename(file2);
73879
- const parent = this.fsw._getWatchedDir(dirname14);
74038
+ const parent = this.fsw._getWatchedDir(dirname15);
73880
74039
  let prevStats = stats;
73881
74040
  if (parent.has(basename9))
73882
74041
  return;
@@ -73903,7 +74062,7 @@ var NodeFsHandler = class {
73903
74062
  prevStats = newStats2;
73904
74063
  }
73905
74064
  } catch (error48) {
73906
- this.fsw._remove(dirname14, basename9);
74065
+ this.fsw._remove(dirname15, basename9);
73907
74066
  }
73908
74067
  } else if (parent.has(basename9)) {
73909
74068
  const at = newStats.atimeMs;
@@ -73999,7 +74158,7 @@ var NodeFsHandler = class {
73999
74158
  this._addToNodeFs(path2, initialAdd, wh, depth + 1);
74000
74159
  }
74001
74160
  }).on(EV.ERROR, this._boundHandleError);
74002
- return new Promise((resolve7, reject) => {
74161
+ return new Promise((resolve8, reject) => {
74003
74162
  if (!stream)
74004
74163
  return reject();
74005
74164
  stream.once(STR_END, () => {
@@ -74008,7 +74167,7 @@ var NodeFsHandler = class {
74008
74167
  return;
74009
74168
  }
74010
74169
  const wasThrottled = throttler ? throttler.clear() : false;
74011
- resolve7(void 0);
74170
+ resolve8(void 0);
74012
74171
  previous.getChildren().filter((item2) => {
74013
74172
  return item2 !== directory && !current.has(item2);
74014
74173
  }).forEach((item2) => {
@@ -74845,16 +75004,16 @@ function createSourceWatcher(targets, opts) {
74845
75004
  }
74846
75005
  function chokidarSourceWatcher(targets, ignored) {
74847
75006
  const w = esm_default.watch([...targets], { ignored, ignoreInitial: true, persistent: true });
74848
- const self = {
75007
+ const self2 = {
74849
75008
  on(event, listener) {
74850
75009
  w.on(event, listener);
74851
- return self;
75010
+ return self2;
74852
75011
  },
74853
75012
  add: (p) => void w.add(p),
74854
75013
  unwatch: (p) => void w.unwatch(p),
74855
75014
  close: () => w.close()
74856
75015
  };
74857
- return self;
75016
+ return self2;
74858
75017
  }
74859
75018
  var NativeSourceWatcher = class extends EventEmitter2 {
74860
75019
  constructor(targets, ignored) {
@@ -75182,7 +75341,7 @@ init_review2();
75182
75341
 
75183
75342
  // src/turn.ts
75184
75343
  init_checkout_root();
75185
- import { closeSync, existsSync as existsSync17, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync6 } from "node:fs";
75344
+ import { closeSync, existsSync as existsSync18, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync6 } from "node:fs";
75186
75345
  import { basename as basename5, delimiter, dirname as dirname10, join as join21, normalize as normalize3 } from "node:path";
75187
75346
  import { homedir as homedir4 } from "node:os";
75188
75347
  import { createHash as createHash16 } from "node:crypto";
@@ -75575,7 +75734,7 @@ function claudeProjectDir(cwd, home = homedir4()) {
75575
75734
  }
75576
75735
  function recentTranscripts(cwd, opts = {}) {
75577
75736
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
75578
- if (!existsSync17(dir)) return [];
75737
+ if (!existsSync18(dir)) return [];
75579
75738
  let names;
75580
75739
  try {
75581
75740
  names = readdirSync6(dir);
@@ -75602,7 +75761,7 @@ function recentTranscripts(cwd, opts = {}) {
75602
75761
  function subagentTranscripts(mainTranscriptPath, sessionId) {
75603
75762
  if (!mainTranscriptPath || !sessionId) return [];
75604
75763
  const dir = join21(dirname10(mainTranscriptPath), sessionId, "subagents");
75605
- if (!existsSync17(dir)) return [];
75764
+ if (!existsSync18(dir)) return [];
75606
75765
  let names;
75607
75766
  try {
75608
75767
  names = readdirSync6(dir);
@@ -75686,7 +75845,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
75686
75845
  const owner = checkoutRootOf(cwd);
75687
75846
  const owners = /* @__PURE__ */ new Map();
75688
75847
  for (const root of codexSessionRoots(opts.env, opts.home)) {
75689
- if (!existsSync17(root)) {
75848
+ if (!existsSync18(root)) {
75690
75849
  codexRolloutActivity.delete(root);
75691
75850
  continue;
75692
75851
  }
@@ -75787,7 +75946,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
75787
75946
  const hashes = geminiHashesFor(cwd);
75788
75947
  const out2 = [];
75789
75948
  for (const root of geminiSessionRoots(opts.env, opts.home)) {
75790
- if (!existsSync17(root)) continue;
75949
+ if (!existsSync18(root)) continue;
75791
75950
  let slugs;
75792
75951
  try {
75793
75952
  slugs = readdirSync6(root);
@@ -75858,7 +76017,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
75858
76017
  }
75859
76018
  const out2 = [];
75860
76019
  for (const root of opencodeSessionRoots(opts.env, opts.home)) {
75861
- if (!existsSync17(root)) continue;
76020
+ if (!existsSync18(root)) continue;
75862
76021
  let names;
75863
76022
  try {
75864
76023
  names = readdirSync6(root);
@@ -75890,7 +76049,7 @@ init_src2();
75890
76049
  init_agent_signals();
75891
76050
  init_tool_index();
75892
76051
  init_src5();
75893
- import { readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "node:fs";
76052
+ import { readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "node:fs";
75894
76053
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
75895
76054
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
75896
76055
  var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|dvuln|prob|claim|err)_[0-9a-f]{6,})/gi;
@@ -76629,7 +76788,7 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
76629
76788
  }
76630
76789
  function readPrimingHandles(path2) {
76631
76790
  try {
76632
- return JSON.parse(readFileSync15(path2, "utf8"));
76791
+ return JSON.parse(readFileSync17(path2, "utf8"));
76633
76792
  } catch {
76634
76793
  return {};
76635
76794
  }
@@ -77109,7 +77268,7 @@ ${conversation}` }]
77109
77268
  // src/constraint-backfill.ts
77110
77269
  init_src5();
77111
77270
  init_src2();
77112
- import { existsSync as existsSync18, readFileSync as readFileSync16, readdirSync as readdirSync7, writeFileSync as writeFileSync14 } from "node:fs";
77271
+ import { existsSync as existsSync19, readFileSync as readFileSync18, readdirSync as readdirSync7, writeFileSync as writeFileSync14 } from "node:fs";
77113
77272
  import { join as join22 } from "node:path";
77114
77273
  import { homedir as homedir5 } from "node:os";
77115
77274
  var BACKFILL_VERSION = 1;
@@ -77128,9 +77287,9 @@ function markerPath(configDir) {
77128
77287
  }
77129
77288
  function alreadyDone(configDir) {
77130
77289
  const p = markerPath(configDir);
77131
- if (!existsSync18(p)) return false;
77290
+ if (!existsSync19(p)) return false;
77132
77291
  try {
77133
- const raw2 = JSON.parse(readFileSync16(p, "utf8"));
77292
+ const raw2 = JSON.parse(readFileSync18(p, "utf8"));
77134
77293
  return raw2?.version === BACKFILL_VERSION;
77135
77294
  } catch {
77136
77295
  return false;
@@ -77140,7 +77299,7 @@ function replay(root) {
77140
77299
  const statements = /* @__PURE__ */ new Set();
77141
77300
  const citedByFix = /* @__PURE__ */ new Set();
77142
77301
  const dir = claudeProjectDir(root, homedir5());
77143
- if (!existsSync18(dir)) return { statements, citedByFix };
77302
+ if (!existsSync19(dir)) return { statements, citedByFix };
77144
77303
  let names;
77145
77304
  try {
77146
77305
  names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
@@ -77150,7 +77309,7 @@ function replay(root) {
77150
77309
  for (const f of names) {
77151
77310
  let lines;
77152
77311
  try {
77153
- lines = readFileSync16(join22(dir, f), "utf8").split("\n");
77312
+ lines = readFileSync18(join22(dir, f), "utf8").split("\n");
77154
77313
  } catch {
77155
77314
  continue;
77156
77315
  }
@@ -77277,7 +77436,7 @@ function backfillConstraintKind(store, opts) {
77277
77436
  // src/edge-repair.ts
77278
77437
  init_src();
77279
77438
  init_src5();
77280
- import { existsSync as existsSync19, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
77439
+ import { existsSync as existsSync20, readFileSync as readFileSync19, writeFileSync as writeFileSync15 } from "node:fs";
77281
77440
  import { join as join23 } from "node:path";
77282
77441
  function citeEdgeId(from, type, to) {
77283
77442
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
@@ -77297,9 +77456,9 @@ function markerPath2(configDir) {
77297
77456
  }
77298
77457
  function alreadyDone2(configDir) {
77299
77458
  const p = markerPath2(configDir);
77300
- if (!existsSync19(p)) return false;
77459
+ if (!existsSync20(p)) return false;
77301
77460
  try {
77302
- return JSON.parse(readFileSync17(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
77461
+ return JSON.parse(readFileSync19(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
77303
77462
  } catch {
77304
77463
  return false;
77305
77464
  }
@@ -77362,7 +77521,7 @@ function repairInvalidEdges(store, opts) {
77362
77521
  init_reconcile();
77363
77522
 
77364
77523
  // src/pass-ledger.ts
77365
- import { appendFileSync as appendFileSync2, existsSync as existsSync20, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "node:fs";
77524
+ import { appendFileSync as appendFileSync2, existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
77366
77525
  import { join as join24 } from "node:path";
77367
77526
 
77368
77527
  // src/isolate-census.ts
@@ -77415,7 +77574,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
77415
77574
  return;
77416
77575
  }
77417
77576
  appendsSinceTrim.set(path2, 0);
77418
- const lines = readFileSync18(path2, "utf8").split("\n").filter(Boolean);
77577
+ const lines = readFileSync20(path2, "utf8").split("\n").filter(Boolean);
77419
77578
  const keptByKind = /* @__PURE__ */ new Map();
77420
77579
  const kept = [];
77421
77580
  for (let i2 = lines.length - 1; i2 >= 0; i2--) {
@@ -77438,9 +77597,9 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
77438
77597
  }
77439
77598
  function readPassLedger(configDir) {
77440
77599
  const path2 = passLedgerPath(configDir);
77441
- if (!existsSync20(path2)) return [];
77600
+ if (!existsSync21(path2)) return [];
77442
77601
  try {
77443
- return readFileSync18(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
77602
+ return readFileSync20(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
77444
77603
  (e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
77445
77604
  ).map((e) => ({ ...e, counts: e.counts ?? {} }));
77446
77605
  } catch {
@@ -77727,8 +77886,8 @@ var PassWorker = class {
77727
77886
  const id = this.nextId++;
77728
77887
  try {
77729
77888
  await this.ready;
77730
- return await new Promise((resolve7, reject) => {
77731
- this.pending.set(id, { resolve: resolve7, reject });
77889
+ return await new Promise((resolve8, reject) => {
77890
+ this.pending.set(id, { resolve: resolve8, reject });
77732
77891
  this.worker.postMessage({ id, kind, ...payload !== void 0 ? { payload } : {} });
77733
77892
  });
77734
77893
  } finally {
@@ -77762,12 +77921,12 @@ var PassWorker = class {
77762
77921
  });
77763
77922
  noteIsolateSpawned();
77764
77923
  this.worker = worker;
77765
- this.ready = new Promise((resolve7, reject) => {
77924
+ this.ready = new Promise((resolve8, reject) => {
77766
77925
  const onReady = (m) => {
77767
77926
  if (m?.ready) {
77768
77927
  worker.off("message", onReady);
77769
77928
  worker.off("error", onErr);
77770
- resolve7();
77929
+ resolve8();
77771
77930
  }
77772
77931
  };
77773
77932
  const onErr = (err2) => reject(err2);
@@ -77812,11 +77971,11 @@ init_outbox();
77812
77971
  init_src10();
77813
77972
  init_src();
77814
77973
  init_src2();
77815
- import { readFileSync as readFileSync19 } from "node:fs";
77974
+ import { readFileSync as readFileSync21 } from "node:fs";
77816
77975
  import { join as join25 } from "node:path";
77817
77976
  function loadClaimIgnorePatterns(workspaceRoot) {
77818
77977
  try {
77819
- return readFileSync19(join25(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
77978
+ return readFileSync21(join25(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
77820
77979
  } catch {
77821
77980
  return [];
77822
77981
  }
@@ -78193,8 +78352,8 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
78193
78352
 
78194
78353
  // src/retrieval-stack.ts
78195
78354
  init_src();
78196
- import { execFileSync as execFileSync3 } from "node:child_process";
78197
- import { existsSync as existsSync21, readFileSync as readFileSync20, statSync as statSync7 } from "node:fs";
78355
+ import { execFileSync as execFileSync4 } from "node:child_process";
78356
+ import { existsSync as existsSync22, readFileSync as readFileSync22, statSync as statSync7 } from "node:fs";
78198
78357
  import { homedir as homedir6 } from "node:os";
78199
78358
  import { join as join26 } from "node:path";
78200
78359
  var RETRIEVAL_STACK_CAP = 24;
@@ -78486,7 +78645,7 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
78486
78645
  function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
78487
78646
  const read2 = (p) => {
78488
78647
  try {
78489
- return readFileSync20(p, "utf8");
78648
+ return readFileSync22(p, "utf8");
78490
78649
  } catch {
78491
78650
  return null;
78492
78651
  }
@@ -78712,7 +78871,7 @@ function readDirectDependencies(root) {
78712
78871
  for (const c of LOCKFILES) {
78713
78872
  if (familiesSeen.has(c.family)) continue;
78714
78873
  const p = join26(root, c.file);
78715
- if (!existsSync21(p)) continue;
78874
+ if (!existsSync22(p)) continue;
78716
78875
  try {
78717
78876
  const s = statSync7(p);
78718
78877
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
@@ -78732,7 +78891,7 @@ function readDirectDependencies(root) {
78732
78891
  const direct = [];
78733
78892
  for (const { c, path: path2 } of found) {
78734
78893
  try {
78735
- direct.push(...c.parse(readFileSync20(path2, "utf8")).direct ?? []);
78894
+ direct.push(...c.parse(readFileSync22(path2, "utf8")).direct ?? []);
78736
78895
  } catch {
78737
78896
  }
78738
78897
  }
@@ -78741,7 +78900,7 @@ function readDirectDependencies(root) {
78741
78900
  }
78742
78901
  function manifestPaths(root) {
78743
78902
  try {
78744
- const out2 = execFileSync3("git", ["-C", root, "ls-files", "-z"], {
78903
+ const out2 = execFileSync4("git", ["-C", root, "ls-files", "-z"], {
78745
78904
  encoding: "utf8",
78746
78905
  maxBuffer: 128 * 1024 * 1024,
78747
78906
  windowsHide: true,
@@ -78775,14 +78934,14 @@ function manifestPaths(root) {
78775
78934
  "project.godot"
78776
78935
  ];
78777
78936
  return {
78778
- paths: ROOT_MANIFESTS.filter((f) => existsSync21(join26(root, f))),
78937
+ paths: ROOT_MANIFESTS.filter((f) => existsSync22(join26(root, f))),
78779
78938
  tracked: false,
78780
78939
  truncated: false
78781
78940
  };
78782
78941
  }
78783
78942
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
78784
78943
  function rootDeclaresWorkspace(root, texts) {
78785
- if (WORKSPACE_MARKERS.some((f) => existsSync21(join26(root, f)))) return true;
78944
+ if (WORKSPACE_MARKERS.some((f) => existsSync22(join26(root, f)))) return true;
78786
78945
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
78787
78946
  }
78788
78947
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -78800,7 +78959,7 @@ function scanManifests(root) {
78800
78959
  try {
78801
78960
  const s = statSync7(abs);
78802
78961
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
78803
- texts.set(rel, readFileSync20(abs, "utf8"));
78962
+ texts.set(rel, readFileSync22(abs, "utf8"));
78804
78963
  } catch {
78805
78964
  }
78806
78965
  }
@@ -78829,11 +78988,11 @@ function readManifestDependencies(root) {
78829
78988
  }
78830
78989
 
78831
78990
  // src/git-sensor.ts
78832
- import { existsSync as existsSync22, readFileSync as readFileSync21, watch as fsWatch } from "node:fs";
78991
+ import { existsSync as existsSync23, readFileSync as readFileSync23, watch as fsWatch } from "node:fs";
78833
78992
  import { join as join27 } from "node:path";
78834
78993
  function readFirstLine(path2) {
78835
78994
  try {
78836
- return readFileSync21(path2, "utf8").split(/\r?\n/, 1)[0].trim();
78995
+ return readFileSync23(path2, "utf8").split(/\r?\n/, 1)[0].trim();
78837
78996
  } catch {
78838
78997
  return null;
78839
78998
  }
@@ -78852,13 +79011,13 @@ function readGitRefState(gitDir) {
78852
79011
  return {
78853
79012
  branch,
78854
79013
  sha: sha2,
78855
- mergeHeadExists: existsSync22(join27(gitDir, "MERGE_HEAD")),
78856
- origHeadExists: existsSync22(join27(gitDir, "ORIG_HEAD"))
79014
+ mergeHeadExists: existsSync23(join27(gitDir, "MERGE_HEAD")),
79015
+ origHeadExists: existsSync23(join27(gitDir, "ORIG_HEAD"))
78857
79016
  };
78858
79017
  }
78859
79018
  function shaFromPackedRefs(gitDir, ref) {
78860
79019
  try {
78861
- for (const line of readFileSync21(join27(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
79020
+ for (const line of readFileSync23(join27(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
78862
79021
  const [sha2, name2] = line.split(/\s+/);
78863
79022
  if (name2 === ref && sha2) return sha2;
78864
79023
  }
@@ -78892,7 +79051,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
78892
79051
  const settle = () => {
78893
79052
  if (timer) clearTimeout(timer);
78894
79053
  timer = setTimeout(() => {
78895
- if (existsSync22(join27(gitDir, "index.lock"))) {
79054
+ if (existsSync23(join27(gitDir, "index.lock"))) {
78896
79055
  settle();
78897
79056
  return;
78898
79057
  }
@@ -78923,7 +79082,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
78923
79082
  // src/git-delta.ts
78924
79083
  import { execFile } from "node:child_process";
78925
79084
  function git(repoDir, args2) {
78926
- return new Promise((resolve7, reject) => {
79085
+ return new Promise((resolve8, reject) => {
78927
79086
  execFile(
78928
79087
  "git",
78929
79088
  ["-C", repoDir, ...args2],
@@ -78934,7 +79093,7 @@ function git(repoDir, args2) {
78934
79093
  // git-sensor runs on every commit/checkout.
78935
79094
  windowsHide: true
78936
79095
  },
78937
- (err2, stdout) => err2 ? reject(err2) : resolve7(stdout)
79096
+ (err2, stdout) => err2 ? reject(err2) : resolve8(stdout)
78938
79097
  );
78939
79098
  });
78940
79099
  }
@@ -79127,7 +79286,7 @@ var TelemetryRecorder = class {
79127
79286
  };
79128
79287
 
79129
79288
  // src/file-activity.ts
79130
- import { readFileSync as readFileSync23 } from "node:fs";
79289
+ import { readFileSync as readFileSync25 } from "node:fs";
79131
79290
  import { join as join29 } from "node:path";
79132
79291
  import { createHash as createHash17 } from "node:crypto";
79133
79292
 
@@ -79880,7 +80039,7 @@ init_git_remote();
79880
80039
  // src/history-bundle.ts
79881
80040
  init_src();
79882
80041
  import { execFile as execFile2 } from "node:child_process";
79883
- import { readFileSync as readFileSync22 } from "node:fs";
80042
+ import { readFileSync as readFileSync24 } from "node:fs";
79884
80043
  import { join as join28 } from "node:path";
79885
80044
  var DEFAULT_MAX_TOKENS = 6e3;
79886
80045
  var FILE_LIST_CAP = 60;
@@ -79916,7 +80075,7 @@ function pathAllowedByFloor(path2) {
79916
80075
  function loadRepoIgnore(root, extraPatterns = []) {
79917
80076
  let source = "";
79918
80077
  try {
79919
- source = readFileSync22(join28(root, ".errataignore"), "utf8");
80078
+ source = readFileSync24(join28(root, ".errataignore"), "utf8");
79920
80079
  } catch {
79921
80080
  source = "";
79922
80081
  }
@@ -80092,12 +80251,12 @@ function headerPaths(diff) {
80092
80251
  return out2.filter((p) => p !== "/dev/null");
80093
80252
  }
80094
80253
  function git2(repoDir, args2) {
80095
- return new Promise((resolve7, reject) => {
80254
+ return new Promise((resolve8, reject) => {
80096
80255
  execFile2(
80097
80256
  "git",
80098
80257
  ["-C", repoDir, ...args2],
80099
80258
  { encoding: "utf8", maxBuffer: 64 * 1024 * 1024, windowsHide: true },
80100
- (err2, stdout) => err2 ? reject(err2) : resolve7(stdout)
80259
+ (err2, stdout) => err2 ? reject(err2) : resolve8(stdout)
80101
80260
  );
80102
80261
  });
80103
80262
  }
@@ -80209,7 +80368,7 @@ function readActivityBranch(root) {
80209
80368
  try {
80210
80369
  const gitDir = resolveGitDir(root);
80211
80370
  if (!gitDir) return null;
80212
- const head2 = readFileSync23(join29(gitDir, "HEAD"), "utf8").trim();
80371
+ const head2 = readFileSync25(join29(gitDir, "HEAD"), "utf8").trim();
80213
80372
  const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
80214
80373
  return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
80215
80374
  } catch {
@@ -80366,11 +80525,11 @@ var FileActivityReporter = class {
80366
80525
 
80367
80526
  // src/skills.ts
80368
80527
  import {
80369
- existsSync as existsSync23,
80528
+ existsSync as existsSync24,
80370
80529
  mkdirSync as mkdirSync7,
80371
- readFileSync as readFileSync24,
80530
+ readFileSync as readFileSync26,
80372
80531
  readdirSync as readdirSync8,
80373
- unlinkSync as unlinkSync2,
80532
+ unlinkSync as unlinkSync4,
80374
80533
  writeFileSync as writeFileSync17
80375
80534
  } from "node:fs";
80376
80535
  import { basename as basename6, join as join30 } from "node:path";
@@ -80378,9 +80537,9 @@ function skillFileName(id) {
80378
80537
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
80379
80538
  }
80380
80539
  function readSkillManifest(manifestPath) {
80381
- if (!existsSync23(manifestPath)) return [];
80540
+ if (!existsSync24(manifestPath)) return [];
80382
80541
  try {
80383
- const parsed = JSON.parse(readFileSync24(manifestPath, "utf8"));
80542
+ const parsed = JSON.parse(readFileSync26(manifestPath, "utf8"));
80384
80543
  return (parsed.skills ?? []).map((s) => ({
80385
80544
  title: s.title ?? "",
80386
80545
  layer: s.layer ?? "technique",
@@ -80431,7 +80590,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
80431
80590
  if (!f.endsWith(".md")) continue;
80432
80591
  if (keep.has(basename6(f))) continue;
80433
80592
  try {
80434
- unlinkSync2(join30(paths.skillsDir, f));
80593
+ unlinkSync4(join30(paths.skillsDir, f));
80435
80594
  pruned++;
80436
80595
  } catch {
80437
80596
  }
@@ -80449,10 +80608,10 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
80449
80608
  init_src2();
80450
80609
  import {
80451
80610
  cpSync,
80452
- existsSync as existsSync24,
80611
+ existsSync as existsSync25,
80453
80612
  lstatSync,
80454
80613
  mkdirSync as mkdirSync8,
80455
- readFileSync as readFileSync25,
80614
+ readFileSync as readFileSync27,
80456
80615
  readdirSync as readdirSync9,
80457
80616
  rmSync as rmSync3,
80458
80617
  symlinkSync,
@@ -80509,7 +80668,7 @@ function skillCiteHandle(s) {
80509
80668
  return priorHandle({ id: s.id, description: s.title });
80510
80669
  }
80511
80670
  function reconcileNamespaced(dir, keep) {
80512
- if (!existsSync24(dir)) return 0;
80671
+ if (!existsSync25(dir)) return 0;
80513
80672
  let pruned = 0;
80514
80673
  for (const name2 of readdirSync9(dir)) {
80515
80674
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
@@ -80523,7 +80682,7 @@ function reconcileNamespaced(dir, keep) {
80523
80682
  }
80524
80683
  function linkOrCopy(linkPath, target) {
80525
80684
  try {
80526
- if (existsSync24(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
80685
+ if (existsSync25(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
80527
80686
  } catch {
80528
80687
  }
80529
80688
  try {
@@ -80552,7 +80711,7 @@ function emitAndProjectSkills(root, skills) {
80552
80711
  for (const s of skills) {
80553
80712
  let body2;
80554
80713
  try {
80555
- body2 = readFileSync25(s.bodyPath, "utf8");
80714
+ body2 = readFileSync27(s.bodyPath, "utf8");
80556
80715
  } catch {
80557
80716
  continue;
80558
80717
  }
@@ -80572,7 +80731,7 @@ function emitAndProjectSkills(root, skills) {
80572
80731
  reconcileNamespaced(agentsSkillsDir, keep);
80573
80732
  let projected = 0;
80574
80733
  for (const h of HARNESS_SKILL_DIRS) {
80575
- if (!existsSync24(join31(root, h.configDir))) continue;
80734
+ if (!existsSync25(join31(root, h.configDir))) continue;
80576
80735
  const dir = join31(root, h.skillsDir);
80577
80736
  mkdirSync8(dir, { recursive: true });
80578
80737
  for (const slug2 of slugs) {
@@ -80585,9 +80744,9 @@ function emitAndProjectSkills(root, skills) {
80585
80744
  return { slugs, emitted, projected };
80586
80745
  }
80587
80746
  function emitInputsFromManifest(erretaDir, manifestPath) {
80588
- if (!existsSync24(manifestPath)) return [];
80747
+ if (!existsSync25(manifestPath)) return [];
80589
80748
  try {
80590
- const parsed = JSON.parse(readFileSync25(manifestPath, "utf8"));
80749
+ const parsed = JSON.parse(readFileSync27(manifestPath, "utf8"));
80591
80750
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
80592
80751
  id: s.id,
80593
80752
  title: s.title ?? s.id,
@@ -80610,7 +80769,7 @@ function ensureSkillGitignore(root) {
80610
80769
  const path2 = join31(root, ".gitignore");
80611
80770
  let current = "";
80612
80771
  try {
80613
- current = existsSync24(path2) ? readFileSync25(path2, "utf8") : "";
80772
+ current = existsSync25(path2) ? readFileSync27(path2, "utf8") : "";
80614
80773
  } catch {
80615
80774
  return;
80616
80775
  }
@@ -80628,7 +80787,7 @@ ${GITIGNORE_LINES.join("\n")}
80628
80787
  var INTENT_TTL_MS = 15 * 60 * 1e3;
80629
80788
  function createIntentState(ttlMs = INTENT_TTL_MS) {
80630
80789
  const bySession = /* @__PURE__ */ new Map();
80631
- let recent2 = null;
80790
+ let recent3 = null;
80632
80791
  const live3 = (s, nowMs) => s !== void 0 && nowMs - s.atMs < ttlMs;
80633
80792
  return {
80634
80793
  set(sessionId, text, nowMs) {
@@ -80636,8 +80795,8 @@ function createIntentState(ttlMs = INTENT_TTL_MS) {
80636
80795
  if (!trimmed) return false;
80637
80796
  const prev = bySession.get(sessionId);
80638
80797
  bySession.set(sessionId, { text: trimmed, atMs: nowMs });
80639
- const changed = !(recent2 && recent2.text === trimmed);
80640
- recent2 = { sessionId, text: trimmed, atMs: nowMs };
80798
+ const changed = !(recent3 && recent3.text === trimmed);
80799
+ recent3 = { sessionId, text: trimmed, atMs: nowMs };
80641
80800
  if (!changed && prev && prev.text === trimmed) return false;
80642
80801
  return changed;
80643
80802
  },
@@ -80646,12 +80805,12 @@ function createIntentState(ttlMs = INTENT_TTL_MS) {
80646
80805
  return live3(s, nowMs) ? s.text : void 0;
80647
80806
  },
80648
80807
  mostRecent(nowMs) {
80649
- if (!recent2) return void 0;
80650
- return nowMs - recent2.atMs < ttlMs ? recent2.text : void 0;
80808
+ if (!recent3) return void 0;
80809
+ return nowMs - recent3.atMs < ttlMs ? recent3.text : void 0;
80651
80810
  },
80652
80811
  clear(sessionId) {
80653
80812
  bySession.delete(sessionId);
80654
- if (recent2?.sessionId === sessionId) recent2 = null;
80813
+ if (recent3?.sessionId === sessionId) recent3 = null;
80655
80814
  }
80656
80815
  };
80657
80816
  }
@@ -80659,19 +80818,19 @@ function createIntentState(ttlMs = INTENT_TTL_MS) {
80659
80818
  // src/working-file-state.ts
80660
80819
  function createWorkingFileState() {
80661
80820
  const bySession = /* @__PURE__ */ new Map();
80662
- let recent2 = null;
80821
+ let recent3 = null;
80663
80822
  return {
80664
80823
  set(sessionId, rel) {
80665
80824
  bySession.set(sessionId, rel);
80666
- if (rel === recent2) return false;
80667
- recent2 = rel;
80825
+ if (rel === recent3) return false;
80826
+ recent3 = rel;
80668
80827
  return true;
80669
80828
  },
80670
80829
  get(sessionId) {
80671
80830
  return bySession.get(sessionId);
80672
80831
  },
80673
80832
  mostRecent() {
80674
- return recent2;
80833
+ return recent3;
80675
80834
  }
80676
80835
  };
80677
80836
  }
@@ -80713,7 +80872,7 @@ init_paths();
80713
80872
  init_profile2();
80714
80873
 
80715
80874
  // src/witness-queue.ts
80716
- import { readFileSync as readFileSync26, renameSync as renameSync2, writeFileSync as writeFileSync19 } from "node:fs";
80875
+ import { readFileSync as readFileSync28, renameSync as renameSync3, writeFileSync as writeFileSync19 } from "node:fs";
80717
80876
  import { dirname as dirname11, join as join32 } from "node:path";
80718
80877
  var WITNESS_QUEUE_CAP = 500;
80719
80878
  var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
@@ -80724,7 +80883,7 @@ function witnessQueuePath(workspaceConfigDir) {
80724
80883
  function loadWitnessQueueWithLosses(path2) {
80725
80884
  let raw2;
80726
80885
  try {
80727
- raw2 = JSON.parse(readFileSync26(path2, "utf8"));
80886
+ raw2 = JSON.parse(readFileSync28(path2, "utf8"));
80728
80887
  } catch (err2) {
80729
80888
  const absent = err2?.code === "ENOENT";
80730
80889
  return { queue: [], fileUnreadable: !absent, malformedEntries: 0 };
@@ -80739,7 +80898,7 @@ function saveWitnessQueue(path2, queue) {
80739
80898
  try {
80740
80899
  const tmp = join32(dirname11(path2), `.${Date.now()}.witness-queue.tmp`);
80741
80900
  writeFileSync19(tmp, JSON.stringify(queue), "utf8");
80742
- renameSync2(tmp, path2);
80901
+ renameSync3(tmp, path2);
80743
80902
  } catch {
80744
80903
  }
80745
80904
  }
@@ -81045,7 +81204,7 @@ function maybeFlushDigests() {
81045
81204
 
81046
81205
  // src/liveness-watch.ts
81047
81206
  init_src5();
81048
- import { readFileSync as readFileSync28, writeFileSync as writeFileSync21 } from "node:fs";
81207
+ import { readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
81049
81208
  import { join as join34 } from "node:path";
81050
81209
 
81051
81210
  // src/loop-lag.ts
@@ -81054,7 +81213,7 @@ var RECENT_PASS_LIMIT = 12;
81054
81213
  var active = /* @__PURE__ */ new Map();
81055
81214
  var nextPassId = 1;
81056
81215
  var started = false;
81057
- var recent = [];
81216
+ var recent2 = [];
81058
81217
  function markPass(name2) {
81059
81218
  const id = nextPassId++;
81060
81219
  const startedAt = Date.now();
@@ -81064,8 +81223,8 @@ function markPass(name2) {
81064
81223
  if (ended) return;
81065
81224
  ended = true;
81066
81225
  active.delete(id);
81067
- recent.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now() });
81068
- if (recent.length > RECENT_PASS_LIMIT) recent.pop();
81226
+ recent2.unshift({ name: name2, ms: Date.now() - startedAt, endedAt: Date.now() });
81227
+ if (recent2.length > RECENT_PASS_LIMIT) recent2.pop();
81069
81228
  };
81070
81229
  }
81071
81230
  function oldestActive() {
@@ -81079,7 +81238,7 @@ function passState() {
81079
81238
  current: oldest?.name ?? "idle",
81080
81239
  runningMs: oldest === null ? null : now - oldest.startedAt,
81081
81240
  active: [...active.values()].map((p) => ({ name: p.name, runningMs: now - p.startedAt })),
81082
- recent: [...recent]
81241
+ recent: [...recent2]
81083
81242
  };
81084
81243
  }
81085
81244
  function describeHolders(running, finished, windowStart, now) {
@@ -81098,7 +81257,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
81098
81257
  const now = Date.now();
81099
81258
  const lag = now - last - HEARTBEAT_MS;
81100
81259
  if (lag > thresholdMs) {
81101
- const who = describeHolders(active.values(), recent, last, now);
81260
+ const who = describeHolders(active.values(), recent2, last, now);
81102
81261
  console.warn(
81103
81262
  `[loop-lag] ${(/* @__PURE__ */ new Date()).toISOString()} event loop held ~${(lag / 1e3).toFixed(1)}s during "${who}"`
81104
81263
  );
@@ -81181,7 +81340,7 @@ function alarmStatePath(configDir) {
81181
81340
  }
81182
81341
  function loadAlarmState(configDir) {
81183
81342
  try {
81184
- const raw2 = JSON.parse(readFileSync28(alarmStatePath(configDir), "utf8"));
81343
+ const raw2 = JSON.parse(readFileSync30(alarmStatePath(configDir), "utf8"));
81185
81344
  return new Map(Object.entries(raw2).filter((e) => typeof e[1] === "number"));
81186
81345
  } catch {
81187
81346
  return /* @__PURE__ */ new Map();
@@ -81342,8 +81501,8 @@ function createWatchBreaker(deps) {
81342
81501
  windows2.set(watchedPath, w);
81343
81502
  }
81344
81503
  w.dispatched++;
81345
- const self = evPath == null || evPath === "" || typeof evPath === "string" && normalizeWatchPath(evPath) === normalizeWatchPath(watchedPath);
81346
- if (!self) return;
81504
+ const self2 = evPath == null || evPath === "" || typeof evPath === "string" && normalizeWatchPath(evPath) === normalizeWatchPath(watchedPath);
81505
+ if (!self2) return;
81347
81506
  w.self++;
81348
81507
  if (!w.tripped && !quarantined.has(watchedPath) && w.self >= BREAKER_TRIP_SELF_EVENTS) {
81349
81508
  w.tripped = true;
@@ -81358,7 +81517,7 @@ function createWatchBreaker(deps) {
81358
81517
  }
81359
81518
 
81360
81519
  // src/engine.ts
81361
- var DAEMON_VERSION = true ? "2.0.16-dev.3343" : "2.0.0-alpha.0";
81520
+ var DAEMON_VERSION = true ? "2.0.16-dev.3362" : "2.0.0-alpha.0";
81362
81521
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
81363
81522
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
81364
81523
  var GIT_OP_MUTE_MS = 4e3;
@@ -81370,8 +81529,8 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
81370
81529
  function appendIdentityAudit(path2, record2, line) {
81371
81530
  if (!record2.accepted && record2.score <= 0) return;
81372
81531
  try {
81373
- if (existsSync26(path2) && statSync8(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
81374
- renameSync3(path2, `${path2}.1`);
81532
+ if (existsSync27(path2) && statSync8(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
81533
+ renameSync4(path2, `${path2}.1`);
81375
81534
  }
81376
81535
  appendFileSync4(path2, line);
81377
81536
  } catch {
@@ -81380,7 +81539,7 @@ function appendIdentityAudit(path2, record2, line) {
81380
81539
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
81381
81540
  function loadTurnCursors(path2) {
81382
81541
  try {
81383
- const raw2 = JSON.parse(readFileSync29(path2, "utf8"));
81542
+ const raw2 = JSON.parse(readFileSync31(path2, "utf8"));
81384
81543
  return new Map(
81385
81544
  Object.entries(raw2).map(([k, v]) => [k, typeof v === "string" ? v : String(v?.uuid ?? "")])
81386
81545
  );
@@ -81390,7 +81549,7 @@ function loadTurnCursors(path2) {
81390
81549
  }
81391
81550
  function loadTurnOffsets(path2) {
81392
81551
  try {
81393
- const raw2 = JSON.parse(readFileSync29(path2, "utf8"));
81552
+ const raw2 = JSON.parse(readFileSync31(path2, "utf8"));
81394
81553
  const out2 = /* @__PURE__ */ new Map();
81395
81554
  for (const [k, v] of Object.entries(raw2)) {
81396
81555
  const off = typeof v === "object" && v !== null ? v.offset : void 0;
@@ -81413,7 +81572,7 @@ function saveTurnCursors(path2, cursors, offsets) {
81413
81572
  function gitSourceWatchTargets(root) {
81414
81573
  const SOURCE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
81415
81574
  try {
81416
- const lsOut = execFileSync4("git", ["-C", root, "ls-files", "-z"], {
81575
+ const lsOut = execFileSync5("git", ["-C", root, "ls-files", "-z"], {
81417
81576
  encoding: "utf8",
81418
81577
  maxBuffer: 128 * 1024 * 1024,
81419
81578
  windowsHide: true,
@@ -81423,7 +81582,7 @@ function gitSourceWatchTargets(root) {
81423
81582
  if (sourceFiles.length === 0) throw new Error("no tracked source");
81424
81583
  let ignoredDirs = [];
81425
81584
  try {
81426
- const igOut = execFileSync4(
81585
+ const igOut = execFileSync5(
81427
81586
  "git",
81428
81587
  ["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
81429
81588
  { encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
@@ -81695,7 +81854,7 @@ function createWorkspaceEngine(opts) {
81695
81854
  );
81696
81855
  };
81697
81856
  const gitDir = join35(opts.workspaceRoot, ".git");
81698
- if (existsSync26(gitDir)) {
81857
+ if (existsSync27(gitDir)) {
81699
81858
  stopGit = startGitSensor(gitDir, (ev) => {
81700
81859
  void handleGitEvent(ev).catch((err2) => {
81701
81860
  console.warn("[errata] git event handler failed:", err2);
@@ -82496,7 +82655,7 @@ function createWorkspaceEngine(opts) {
82496
82655
  let anchorReadFailed = false;
82497
82656
  if (p.location) {
82498
82657
  try {
82499
- fileText = readFileSync29(join35(opts.workspaceRoot, p.location.path), "utf8");
82658
+ fileText = readFileSync31(join35(opts.workspaceRoot, p.location.path), "utf8");
82500
82659
  } catch {
82501
82660
  anchorReadFailed = true;
82502
82661
  }
@@ -82656,7 +82815,7 @@ function createWorkspaceEngine(opts) {
82656
82815
  const headSha = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
82657
82816
  enclosing = {
82658
82817
  line: p.location.line,
82659
- fileText: readFileSync29(join35(opts.workspaceRoot, anchorPath), "utf8"),
82818
+ fileText: readFileSync31(join35(opts.workspaceRoot, anchorPath), "utf8"),
82660
82819
  ...headSha ? { headSha } : {}
82661
82820
  };
82662
82821
  } catch {
@@ -83238,7 +83397,7 @@ function createWorkspaceEngine(opts) {
83238
83397
  }
83239
83398
  turns = next.turns;
83240
83399
  nextOffset = next.nextOffset;
83241
- await new Promise((resolve7) => setImmediate(resolve7));
83400
+ await new Promise((resolve8) => setImmediate(resolve8));
83242
83401
  }
83243
83402
  };
83244
83403
  const seenMessageIds = /* @__PURE__ */ new Set();
@@ -83785,7 +83944,7 @@ B: ${b}`,
83785
83944
  console.log(
83786
83945
  "[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
83787
83946
  );
83788
- const pending = existsSync26(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
83947
+ const pending = existsSync27(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
83789
83948
  return { uploaded: 0, failed: 0, remaining: pending };
83790
83949
  }
83791
83950
  const onDisk = loadProfile(opts.workspaceRoot);
@@ -83793,7 +83952,7 @@ B: ${b}`,
83793
83952
  console.log(
83794
83953
  "[errata] sync held \u2014 this repo is already on errata in another workspace; run `errata link` to join it or create your own project"
83795
83954
  );
83796
- const pending = existsSync26(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
83955
+ const pending = existsSync27(paths.outbox) ? readdirSync10(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
83797
83956
  return { uploaded: 0, failed: 0, remaining: pending };
83798
83957
  }
83799
83958
  try {
@@ -83865,6 +84024,7 @@ B: ${b}`,
83865
84024
 
83866
84025
  // src/daemon.ts
83867
84026
  async function startDaemon(opts) {
84027
+ const processStartedAt = Date.now();
83868
84028
  const cfg = loadConfig();
83869
84029
  const merged = { ...cfg, cloudUrl: opts.cloudUrl ?? cfg.cloudUrl };
83870
84030
  if (opts.apiKey) {
@@ -83888,7 +84048,7 @@ async function startDaemon(opts) {
83888
84048
  const writeLockFile = (url2) => {
83889
84049
  writeFileSync23(
83890
84050
  engine.paths.daemonLock,
83891
- JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
84051
+ daemonLockPayload({ pid: process.pid, webUiUrl: url2, processStartedAt, version: DAEMON_VERSION }),
83892
84052
  "utf8"
83893
84053
  );
83894
84054
  };
@@ -83929,7 +84089,7 @@ async function startDaemon(opts) {
83929
84089
  );
83930
84090
  await engine.stop();
83931
84091
  try {
83932
- if (existsSync27(engine.paths.daemonLock)) {
84092
+ if (existsSync28(engine.paths.daemonLock)) {
83933
84093
  }
83934
84094
  } catch {
83935
84095
  }
@@ -83937,9 +84097,9 @@ async function startDaemon(opts) {
83937
84097
  };
83938
84098
  }
83939
84099
  async function listenServer(fetchFn, port) {
83940
- return new Promise((resolve7) => {
84100
+ return new Promise((resolve8) => {
83941
84101
  const server = serve({ fetch: fetchFn, hostname: "127.0.0.1", port }, (info2) => {
83942
- resolve7({ server, port: info2.port });
84102
+ resolve8({ server, port: info2.port });
83943
84103
  });
83944
84104
  });
83945
84105
  }
@@ -84130,7 +84290,7 @@ function instanceReceiptSequence(n) {
84130
84290
  // src/multi.ts
84131
84291
  init_dist();
84132
84292
  init_src5();
84133
- import { existsSync as existsSync33, readFileSync as readFileSync34, unlinkSync as unlinkSync3, writeFileSync as writeFileSync25 } from "node:fs";
84293
+ import { existsSync as existsSync33, readFileSync as readFileSync35, unlinkSync as unlinkSync5, writeFileSync as writeFileSync25 } from "node:fs";
84134
84294
  import { resolve as pathResolve } from "node:path";
84135
84295
 
84136
84296
  // src/principle-sync.ts
@@ -84159,7 +84319,7 @@ init_reconcile();
84159
84319
 
84160
84320
  // src/lockfile-auto.ts
84161
84321
  init_src();
84162
- import { existsSync as existsSync28, readFileSync as readFileSync30 } from "node:fs";
84322
+ import { existsSync as existsSync29, readFileSync as readFileSync32 } from "node:fs";
84163
84323
  import { join as join36 } from "node:path";
84164
84324
 
84165
84325
  // src/package-index.ts
@@ -84310,10 +84470,10 @@ function runLockfilePass(opts) {
84310
84470
  ];
84311
84471
  for (const c of candidates) {
84312
84472
  const p = join36(opts.root, c.file);
84313
- if (!existsSync28(p)) continue;
84473
+ if (!existsSync29(p)) continue;
84314
84474
  let sbom;
84315
84475
  try {
84316
- sbom = c.parse(readFileSync30(p, "utf8"));
84476
+ sbom = c.parse(readFileSync32(p, "utf8"));
84317
84477
  } catch {
84318
84478
  continue;
84319
84479
  }
@@ -84373,7 +84533,7 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
84373
84533
  init_profile2();
84374
84534
 
84375
84535
  // src/public-symbols.ts
84376
- import { readFileSync as readFileSync31, readdirSync as readdirSync11, existsSync as existsSync29 } from "node:fs";
84536
+ import { readFileSync as readFileSync33, readdirSync as readdirSync11, existsSync as existsSync30 } from "node:fs";
84377
84537
  import { join as join37 } from "node:path";
84378
84538
  var HEAD_BYTES = 8 * 1024;
84379
84539
  var INDEX_TTL_MS = 10 * 60 * 1e3;
@@ -84408,9 +84568,9 @@ function internalPackageNames(workspaceRoot) {
84408
84568
  const names = /* @__PURE__ */ new Set();
84409
84569
  const tryRead = (dir) => {
84410
84570
  const pj = join37(dir, "package.json");
84411
- if (!existsSync29(pj)) return;
84571
+ if (!existsSync30(pj)) return;
84412
84572
  try {
84413
- const name2 = JSON.parse(readFileSync31(pj, "utf8")).name;
84573
+ const name2 = JSON.parse(readFileSync33(pj, "utf8")).name;
84414
84574
  if (typeof name2 === "string" && name2.length > 0) names.add(name2);
84415
84575
  } catch {
84416
84576
  }
@@ -84418,7 +84578,7 @@ function internalPackageNames(workspaceRoot) {
84418
84578
  tryRead(workspaceRoot);
84419
84579
  for (const group of ["packages", "apps"]) {
84420
84580
  const groupDir = join37(workspaceRoot, group);
84421
- if (!existsSync29(groupDir)) continue;
84581
+ if (!existsSync30(groupDir)) continue;
84422
84582
  try {
84423
84583
  for (const entry of readdirSync11(groupDir)) tryRead(join37(groupDir, entry));
84424
84584
  } catch {
@@ -84439,7 +84599,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
84439
84599
  }
84440
84600
  const readHead = deps.readHead ?? ((absPath) => {
84441
84601
  try {
84442
- return readFileSync31(absPath, "utf8").slice(0, HEAD_BYTES);
84602
+ return readFileSync33(absPath, "utf8").slice(0, HEAD_BYTES);
84443
84603
  } catch {
84444
84604
  return "";
84445
84605
  }
@@ -85152,8 +85312,8 @@ var ConsolidateWorker = class {
85152
85312
  const id = this.nextId++;
85153
85313
  try {
85154
85314
  await this.ready;
85155
- return await new Promise((resolve7, reject) => {
85156
- this.pending.set(id, { resolve: resolve7, reject });
85315
+ return await new Promise((resolve8, reject) => {
85316
+ this.pending.set(id, { resolve: resolve8, reject });
85157
85317
  this.worker.postMessage({ ...req, id });
85158
85318
  });
85159
85319
  } finally {
@@ -85182,12 +85342,12 @@ var ConsolidateWorker = class {
85182
85342
  });
85183
85343
  noteIsolateSpawned();
85184
85344
  this.worker = worker;
85185
- this.ready = new Promise((resolve7, reject) => {
85345
+ this.ready = new Promise((resolve8, reject) => {
85186
85346
  const onReady = (m) => {
85187
85347
  if (m?.ready) {
85188
85348
  worker.off("message", onReady);
85189
85349
  worker.off("error", onErr);
85190
- resolve7();
85350
+ resolve8();
85191
85351
  }
85192
85352
  };
85193
85353
  const onErr = (err2) => {
@@ -85266,63 +85426,13 @@ function cloudTargetDrift(daemon, shell2) {
85266
85426
  return out2;
85267
85427
  }
85268
85428
 
85269
- // src/lock.ts
85270
- import { existsSync as existsSync30, readFileSync as readFileSync32 } from "node:fs";
85271
- function daemonLockPayload(lock) {
85272
- return JSON.stringify({
85273
- pid: lock.pid,
85274
- webUiUrl: lock.webUiUrl,
85275
- startedAt: lock.processStartedAt,
85276
- ...lock.wokeAt !== void 0 ? { wokeAt: lock.wokeAt } : {},
85277
- ...lock.entry ? { entry: lock.entry } : {},
85278
- ...lock.version ? { version: lock.version } : {}
85279
- });
85280
- }
85281
- var normEntry = (p) => {
85282
- const s = p.replace(/\\/g, "/").replace(/\/+$/, "");
85283
- return /^[A-Za-z]:\//.test(s) ? s.toLowerCase() : s;
85284
- };
85285
- function isInstalledEntry(entry) {
85286
- return /\/node_modules\/@inerrata-corporation\/errata\//.test(normEntry(entry) + "/");
85287
- }
85288
- function foreignDaemonNote(lock, selfEntry) {
85289
- if (!lock.entry || normEntry(lock.entry) === normEntry(selfEntry)) return null;
85290
- const runningInstalled = isInstalledEntry(lock.entry);
85291
- const head2 = [
85292
- `launched from ${runningInstalled ? "the installed package" : "a LOCAL BUILD"}, not this one${lock.version ? ` (it is ${lock.version})` : ""}:`,
85293
- ` running: ${lock.entry}`,
85294
- ` this: ${selfEntry}`
85295
- ];
85296
- return runningInstalled ? [...head2, "this CLI is a different bundle from the daemon it is talking to \u2014 its view may not match what the daemon runs."] : [...head2, "`errata update` does not replace it. To move onto the installed package: errata stop, then errata dash."];
85297
- }
85298
- function isProcessAlive(pid) {
85299
- if (!pid || pid <= 0) return false;
85300
- try {
85301
- process.kill(pid, 0);
85302
- return true;
85303
- } catch (err2) {
85304
- return err2.code === "EPERM";
85305
- }
85306
- }
85307
- function readDaemonLock(lockPath) {
85308
- if (!existsSync30(lockPath)) return null;
85309
- try {
85310
- const lock = JSON.parse(readFileSync32(lockPath, "utf8"));
85311
- return typeof lock.pid === "number" ? lock : null;
85312
- } catch {
85313
- return null;
85314
- }
85315
- }
85316
- function isDaemonAlive(lockPath) {
85317
- const lock = readDaemonLock(lockPath);
85318
- return lock !== null && isProcessAlive(lock.pid);
85319
- }
85320
-
85321
85429
  // src/multi.ts
85430
+ init_lock();
85322
85431
  init_config();
85323
85432
 
85324
85433
  // src/update.ts
85325
85434
  import { spawn as spawn2 } from "node:child_process";
85435
+ import { isAbsolute as isAbsolute5, join as join38 } from "node:path";
85326
85436
  var PACKAGE_NAME = "@inerrata-corporation/errata";
85327
85437
  function parse3(v) {
85328
85438
  const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
@@ -85442,13 +85552,40 @@ function startUpdatePoller(opts) {
85442
85552
  };
85443
85553
  }
85444
85554
  function runNpmInstall(channel) {
85445
- return new Promise((resolve7) => {
85555
+ return new Promise((resolve8) => {
85446
85556
  const child = spawn2("npm", ["install", "-g", `${PACKAGE_NAME}@${channel}`], {
85447
85557
  stdio: "inherit",
85448
85558
  shell: true
85449
85559
  });
85450
- child.on("close", (code) => resolve7(code ?? 1));
85451
- child.on("error", () => resolve7(1));
85560
+ child.on("close", (code) => resolve8(code ?? 1));
85561
+ child.on("error", () => resolve8(1));
85562
+ });
85563
+ }
85564
+ async function runInstalledHookRefresh() {
85565
+ const root = await new Promise((resolve8) => {
85566
+ const child = spawn2("npm", ["root", "-g"], {
85567
+ shell: true,
85568
+ windowsHide: true,
85569
+ stdio: ["ignore", "pipe", "ignore"],
85570
+ timeout: 15e3
85571
+ });
85572
+ let output = "";
85573
+ child.stdout.on("data", (chunk) => {
85574
+ output += chunk;
85575
+ if (output.length > 32768) child.kill();
85576
+ });
85577
+ child.on("error", () => resolve8(""));
85578
+ child.on("close", (code) => resolve8(code === 0 ? output.trim() : ""));
85579
+ });
85580
+ if (!isAbsolute5(root)) return 1;
85581
+ return new Promise((resolve8) => {
85582
+ const child = spawn2(process.execPath, [join38(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
85583
+ windowsHide: true,
85584
+ stdio: "inherit",
85585
+ timeout: 3e4
85586
+ });
85587
+ child.on("error", () => resolve8(1));
85588
+ child.on("close", (code) => resolve8(code ?? 1));
85452
85589
  });
85453
85590
  }
85454
85591
 
@@ -85463,7 +85600,7 @@ function liveCloudClient(src) {
85463
85600
  let current = null;
85464
85601
  let currentKey = "";
85465
85602
  let checkedAt = -Infinity;
85466
- const resolve7 = () => {
85603
+ const resolve8 = () => {
85467
85604
  const t = now();
85468
85605
  if (current && t - checkedAt < recheckMs) return current;
85469
85606
  checkedAt = t;
@@ -85483,7 +85620,7 @@ function liveCloudClient(src) {
85483
85620
  };
85484
85621
  return new Proxy({}, {
85485
85622
  get(_target, prop) {
85486
- const client = resolve7();
85623
+ const client = resolve8();
85487
85624
  const value = Reflect.get(client, prop, client);
85488
85625
  return typeof value === "function" ? value.bind(client) : value;
85489
85626
  }
@@ -85918,7 +86055,7 @@ async function syncHistoryRevision(opts) {
85918
86055
  changed += result.changed;
85919
86056
  remaining = result.remaining;
85920
86057
  if (!remaining || Date.now() - started2 >= (opts.budgetMs ?? 45e3)) break;
85921
- await new Promise((resolve7) => setImmediate(resolve7));
86058
+ await new Promise((resolve8) => setImmediate(resolve8));
85922
86059
  }
85923
86060
  return { changed, remaining };
85924
86061
  })();
@@ -86021,8 +86158,8 @@ async function syncHistoryRevisionPage(opts) {
86021
86158
  init_src7();
86022
86159
  init_src();
86023
86160
  import { execFile as execFile5 } from "node:child_process";
86024
- import { readFileSync as readFileSync33 } from "node:fs";
86025
- import { join as join38 } from "node:path";
86161
+ import { readFileSync as readFileSync34 } from "node:fs";
86162
+ import { join as join39 } from "node:path";
86026
86163
  import { promisify as promisify3 } from "node:util";
86027
86164
 
86028
86165
  // src/history-walk.ts
@@ -86422,8 +86559,8 @@ var GitBlobReader = class {
86422
86559
  if (this.failed) return Promise.reject(this.failed);
86423
86560
  if (/[\r\n]/.test(spec)) return Promise.resolve(null);
86424
86561
  const proc = this.start();
86425
- return new Promise((resolve7, reject) => {
86426
- this.queue.push({ resolve: resolve7, reject });
86562
+ return new Promise((resolve8, reject) => {
86563
+ this.queue.push({ resolve: resolve8, reject });
86427
86564
  proc.stdin.write(`${spec}
86428
86565
  `);
86429
86566
  });
@@ -86437,14 +86574,14 @@ var GitBlobReader = class {
86437
86574
  const proc = this.proc;
86438
86575
  this.proc = null;
86439
86576
  if (!proc || proc.exitCode !== null) return Promise.resolve();
86440
- return new Promise((resolve7) => {
86577
+ return new Promise((resolve8) => {
86441
86578
  const timer = setTimeout(() => {
86442
86579
  proc.kill();
86443
- resolve7();
86580
+ resolve8();
86444
86581
  }, timeoutMs);
86445
86582
  proc.once("exit", () => {
86446
86583
  clearTimeout(timer);
86447
- resolve7();
86584
+ resolve8();
86448
86585
  });
86449
86586
  proc.stdin.end();
86450
86587
  });
@@ -86569,7 +86706,7 @@ async function defaultGit(root, args2) {
86569
86706
  function readIgnoreLines(root, profile) {
86570
86707
  let lines = [];
86571
86708
  try {
86572
- lines = readFileSync33(join38(root, ".errataignore"), "utf8").split("\n");
86709
+ lines = readFileSync34(join39(root, ".errataignore"), "utf8").split("\n");
86573
86710
  } catch {
86574
86711
  }
86575
86712
  return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
@@ -86998,9 +87135,9 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
86998
87135
  // src/link-flow.ts
86999
87136
  init_cloud_auth();
87000
87137
  import { createHash as createHash19 } from "node:crypto";
87001
- import { execFileSync as execFileSync5 } from "node:child_process";
87138
+ import { execFileSync as execFileSync6 } from "node:child_process";
87002
87139
  import { existsSync as existsSync31, writeFileSync as writeFileSync24 } from "node:fs";
87003
- import { join as join39 } from "node:path";
87140
+ import { join as join40 } from "node:path";
87004
87141
 
87005
87142
  // src/device-poll.ts
87006
87143
  var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
@@ -87089,7 +87226,7 @@ async function loginOAuthDevice(opts) {
87089
87226
  let deviceSession = null;
87090
87227
  let approvedInstallation = null;
87091
87228
  while (Date.now() < deadline) {
87092
- await (opts.sleep ?? ((ms) => new Promise((resolve7) => setTimeout(resolve7, ms))))(waitMs);
87229
+ await (opts.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms))))(waitMs);
87093
87230
  waitMs = intervalMs;
87094
87231
  const poll = await fetchDevicePoll(fetchFn, device.token, {
87095
87232
  method: "POST",
@@ -87214,7 +87351,7 @@ async function loginOAuthLoopback(opts) {
87214
87351
  const state = randomState();
87215
87352
  const scope = opts.scope ?? DEFAULT_OAUTH_SCOPE;
87216
87353
  const { code, redirectUri, clientId } = await new Promise(
87217
- (resolve7, reject) => {
87354
+ (resolve8, reject) => {
87218
87355
  const server = createServer((req, res) => {
87219
87356
  const u = new URL(req.url ?? "/", "http://127.0.0.1");
87220
87357
  if (u.pathname !== "/callback") {
@@ -87237,7 +87374,7 @@ async function loginOAuthLoopback(opts) {
87237
87374
  res.writeHead(200, { "content-type": "text/html" });
87238
87375
  res.end("<html><body>inErrata: you're logged in. You can close this tab.</body></html>");
87239
87376
  server.close();
87240
- resolve7({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback`, clientId: activeClientId });
87377
+ resolve8({ code: code2, redirectUri: `http://127.0.0.1:${port}/callback`, clientId: activeClientId });
87241
87378
  });
87242
87379
  let activeClientId = oauthClientId();
87243
87380
  server.on("error", reject);
@@ -87336,7 +87473,7 @@ async function linkThroughConsole(opts) {
87336
87473
  const deadline = Date.now() + Math.min(code.expires_in * 1e3, opts.timeoutMs ?? Number.POSITIVE_INFINITY);
87337
87474
  let intervalMs = Math.max(2, code.interval ?? 5) * 1e3;
87338
87475
  let waitMs = intervalMs;
87339
- const sleep = opts.sleep ?? ((ms) => new Promise((resolve7) => setTimeout(resolve7, ms)));
87476
+ const sleep = opts.sleep ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms)));
87340
87477
  while (Date.now() < deadline) {
87341
87478
  await sleep(waitMs);
87342
87479
  waitMs = intervalMs;
@@ -87386,7 +87523,7 @@ async function linkThroughConsole(opts) {
87386
87523
  function collectRepoFacts(root) {
87387
87524
  const git3 = (args2) => {
87388
87525
  try {
87389
- return execFileSync5("git", args2, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
87526
+ return execFileSync6("git", args2, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
87390
87527
  } catch {
87391
87528
  return null;
87392
87529
  }
@@ -87458,7 +87595,7 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
87458
87595
  delete nextProfile.projectLinkHold;
87459
87596
  let wroteIgnore = false;
87460
87597
  if (decision.writeIgnoreStarter !== false) {
87461
- const target = join39(root, ".errataignore");
87598
+ const target = join40(root, ".errataignore");
87462
87599
  if (!existsSync31(target)) {
87463
87600
  writeFileSync24(target, IGNORE_STARTER, "utf8");
87464
87601
  wroteIgnore = true;
@@ -87474,11 +87611,11 @@ init_registry();
87474
87611
  // src/adopt.ts
87475
87612
  init_git_remote();
87476
87613
  import { existsSync as existsSync32 } from "node:fs";
87477
- import { dirname as dirname12, join as join40 } from "node:path";
87614
+ import { dirname as dirname12, join as join41 } from "node:path";
87478
87615
  function findGitRoot(absPath) {
87479
87616
  let dir = absPath;
87480
87617
  for (let depth = 0; depth < 64; depth++) {
87481
- if (existsSync32(join40(dir, ".git"))) return dir;
87618
+ if (existsSync32(join41(dir, ".git"))) return dir;
87482
87619
  const parent = dirname12(dir);
87483
87620
  if (parent === dir) return null;
87484
87621
  dir = parent;
@@ -87820,9 +87957,9 @@ function ownerOf(records, absPath) {
87820
87957
  }
87821
87958
  async function startMultiDaemon(opts = {}) {
87822
87959
  const lockPath = globalDaemonLock();
87823
- if (opts.enforceSingleton !== false && isDaemonAlive(lockPath)) {
87960
+ if (opts.enforceSingleton !== false && daemonLockBlocksStartup(lockPath)) {
87824
87961
  throw new Error(
87825
- `an errata daemon is already running (lock: ${lockPath}). Run \`errata stop\` first, or attach to the running one.`
87962
+ `a daemon lock is live or its process ownership cannot be verified (lock: ${lockPath}). Run \`errata doctor\` to inspect it, or \`errata stop\` to stop a verified owner.`
87826
87963
  );
87827
87964
  }
87828
87965
  const cfg = loadConfig();
@@ -88771,7 +88908,7 @@ async function startMultiDaemon(opts = {}) {
88771
88908
  const packageAutoAll = async () => {
88772
88909
  const out2 = /* @__PURE__ */ new Map();
88773
88910
  for (const r of records) {
88774
- await new Promise((resolve7) => setImmediate(resolve7));
88911
+ await new Promise((resolve8) => setImmediate(resolve8));
88775
88912
  const done = markPass(`package-index:${r.entry.name}`);
88776
88913
  try {
88777
88914
  out2.set(
@@ -89509,8 +89646,8 @@ async function startMultiDaemon(opts = {}) {
89509
89646
  clearInterval(anchorPull);
89510
89647
  clearTimeout(codexWakeBoot);
89511
89648
  try {
89512
- const cur = readFileSync34(lockPath, "utf8");
89513
- if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
89649
+ const cur = readFileSync35(lockPath, "utf8");
89650
+ if (JSON.parse(cur).pid === process.pid) unlinkSync5(lockPath);
89514
89651
  } catch {
89515
89652
  }
89516
89653
  await new Promise(
@@ -89870,6 +90007,7 @@ function openInBrowser(url2) {
89870
90007
  // src/cli.ts
89871
90008
  init_paths();
89872
90009
  init_checkout_root();
90010
+ init_lock();
89873
90011
 
89874
90012
  // src/cli-args.ts
89875
90013
  var BURST_VALUE_FLAGS = /* @__PURE__ */ new Set(["--limit", "--hops", "--max-hops"]);
@@ -89932,7 +90070,7 @@ import { spawnSync } from "node:child_process";
89932
90070
 
89933
90071
  // src/codex-runtime.ts
89934
90072
  import { readdirSync as readdirSync12, statSync as statSync9 } from "node:fs";
89935
- import { join as join41 } from "node:path";
90073
+ import { join as join42 } from "node:path";
89936
90074
  function resolveCodexExecutable(options = {}) {
89937
90075
  const platform = options.platform ?? process.platform;
89938
90076
  const env2 = options.env ?? process.env;
@@ -89947,13 +90085,13 @@ function resolveCodexExecutable(options = {}) {
89947
90085
  };
89948
90086
  for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
89949
90087
  if (!dir.trim()) continue;
89950
- const path2 = join41(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
90088
+ const path2 = join42(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
89951
90089
  if (fileTime(path2) !== null) return path2;
89952
90090
  }
89953
90091
  if (!env2["LOCALAPPDATA"]) return "codex";
89954
- const root = join41(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
90092
+ const root = join42(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
89955
90093
  try {
89956
- const candidates = readdirSync12(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join41(root, entry.name, "codex.exe")).map((path2) => ({ path: path2, mtime: fileTime(path2) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
90094
+ const candidates = readdirSync12(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join42(root, entry.name, "codex.exe")).map((path2) => ({ path: path2, mtime: fileTime(path2) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
89957
90095
  return candidates[0]?.path ?? "codex";
89958
90096
  } catch {
89959
90097
  return "codex";
@@ -90069,12 +90207,14 @@ async function diagnoseInstallation(cfg, dependencies) {
90069
90207
 
90070
90208
  // src/codex-doctor.ts
90071
90209
  import { spawn as spawn4 } from "node:child_process";
90210
+ import { readFileSync as readFileSync37, statSync as statSync10 } from "node:fs";
90211
+ import { join as join44 } from "node:path";
90072
90212
  import { createInterface } from "node:readline";
90073
90213
 
90074
90214
  // src/codex-hooks.ts
90075
- import { existsSync as existsSync34, mkdirSync as mkdirSync9, readFileSync as readFileSync35, writeFileSync as writeFileSync26 } from "node:fs";
90215
+ import { existsSync as existsSync34, mkdirSync as mkdirSync9, readFileSync as readFileSync36, renameSync as renameSync5, unlinkSync as unlinkSync6, writeFileSync as writeFileSync26 } from "node:fs";
90076
90216
  import { homedir as homedir7 } from "node:os";
90077
- import { join as join42 } from "node:path";
90217
+ import { join as join43 } from "node:path";
90078
90218
 
90079
90219
  // src/hook-commands.ts
90080
90220
  function hookCurlCommand(port, path2 = "/api/hook") {
@@ -90098,15 +90238,27 @@ function buildCodexHooksToml(port, options) {
90098
90238
  };
90099
90239
  if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid hook port");
90100
90240
  const command = (platform === "win32" ? "& " : "") + quote(options.nodePath) + " " + quote(options.relayPath) + " " + port;
90101
- const handlers = ["SessionStart", "UserPromptSubmit", "PreToolUse", "PostToolUse", "Stop"].map(
90102
- (event) => "[[hooks." + event + "]]\n" + (["UserPromptSubmit", "Stop"].includes(event) ? "" : 'matcher = ".*"\n') + "\n[[hooks." + event + '.hooks]]\ntype = "command"\ncommand = ' + JSON.stringify(command) + "\ntimeout = 10\n" + (event === "Stop" ? "" : "additionalContextLimit = 5000\n")
90241
+ const status = {
90242
+ SessionStart: "errata: loading workspace priors",
90243
+ UserPromptSubmit: "errata: checking workspace priors",
90244
+ PreToolUse: "errata: checking relevant priors",
90245
+ PostToolUse: "errata: capturing feedback and checking priors",
90246
+ Stop: "errata: capturing session feedback"
90247
+ };
90248
+ const handlers = Object.keys(status).map(
90249
+ (event) => "[[hooks." + event + "]]\n" + (["UserPromptSubmit", "Stop"].includes(event) ? "" : 'matcher = ".*"\n') + "\n[[hooks." + event + '.hooks]]\ntype = "command"\ncommand = ' + JSON.stringify(command) + "\nstatusMessage = " + JSON.stringify(status[event]) + "\ntimeout = 10\n" + (event === "Stop" ? "" : "additionalContextLimit = 5000\n")
90103
90250
  );
90104
90251
  return CODEX_HOOKS_BEGIN + "\n" + handlers.join("\n") + CODEX_HOOKS_END + "\n";
90105
90252
  }
90106
90253
 
90107
90254
  // src/codex-hook-relay.ts
90108
90255
  var CODEX_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata install-hooks codex
90109
- import { readFileSync } from 'node:fs';
90256
+ import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'node:fs';
90257
+ import { createHash } from 'node:crypto';
90258
+ import { join } from 'node:path';
90259
+ const workspaceRoot = null;
90260
+ // Stdout closing early is not delivery. Never stamp a receipt on EPIPE.
90261
+ process.stdout.on('error', () => process.exit(0));
90110
90262
 
90111
90263
  try {
90112
90264
  const payload = JSON.parse(readFileSync(0, 'utf8') || '{}');
@@ -90118,43 +90270,124 @@ try {
90118
90270
  if (!Number.isInteger(port) || port < 1 || port > 65535) process.exit(0);
90119
90271
  const contexts = [];
90120
90272
  const messages = [];
90273
+ const hash = (text) => createHash('sha256').update(text).digest('hex');
90274
+ const boundedRead = (path, max) => statSync(path).size <= max ? readFileSync(path, 'utf8') : '';
90275
+ const stateDir = workspaceRoot && join(workspaceRoot, '.errata', 'codex-hook-state');
90276
+ const statePath = stateDir && typeof payload.session_id === 'string' && payload.session_id
90277
+ ? join(stateDir, hash(payload.session_id) + '.json') : null;
90278
+ let previous = {};
90279
+ try {
90280
+ if (statePath) {
90281
+ const saved = JSON.parse(boundedRead(statePath, 4096));
90282
+ if (saved && typeof saved === 'object') previous = saved;
90283
+ }
90284
+ } catch {}
90285
+ let receipt = null;
90121
90286
  const post = async (endpoint, relay = false) => {
90122
90287
  try {
90123
90288
  const response = await fetch('http://127.0.0.1:' + port + '/api/' + endpoint, {
90124
90289
  method: 'POST', headers: { 'Content-Type': 'application/json' },
90125
90290
  body: JSON.stringify(payload), signal: AbortSignal.timeout(2000),
90126
90291
  });
90127
- if (!response.ok || !relay) return;
90292
+ if (!response.ok) return false;
90293
+ if (!relay) return true;
90128
90294
  const result = await response.json();
90129
90295
  const context = result.hookSpecificOutput?.additionalContext;
90130
90296
  if (typeof context === 'string' && context.trim()) contexts.push(context);
90131
- // The user-visible recall card; Codex renders it inline as '↳ Hook · …'.
90297
+ // Codex exposes systemMessage to the UI/event stream; styling is host-owned.
90132
90298
  if (typeof result.systemMessage === 'string' && result.systemMessage.trim()) messages.push(result.systemMessage);
90133
- } catch { /* An unavailable daemon must never block the agent. */ }
90299
+ return true;
90300
+ } catch { return false; /* An unavailable daemon must never block the agent. */ }
90134
90301
  };
90135
90302
  if (event === 'PreToolUse' || event === 'PostToolUse') await post('hook', true);
90136
90303
  // Stop sees the final assistant message, including turns with no tools.
90137
90304
  if (event === 'PostToolUse' || event === 'Stop') await post('turn');
90138
- if (['SessionStart', 'UserPromptSubmit', 'PostToolUse'].includes(event)) {
90139
- // Run after capture, so changes already rendered by the daemon arrive now.
90140
- // Background extraction finishing later arrives at the next tool boundary.
90305
+ if (['SessionStart', 'UserPromptSubmit'].includes(event)) {
90306
+ // Wake/route the engine, bounded independently of context delivery. Older
90307
+ // daemons may stamp their HTTP dedup gate before a timed-out response arrives;
90308
+ // that gate is deliberately NOT authoritative for this file-based relay.
90309
+ await post('context-inject', !workspaceRoot);
90310
+ }
90311
+ if (workspaceRoot && ['SessionStart', 'UserPromptSubmit', 'PostToolUse'].includes(event)) {
90312
+ let body = '';
90313
+ try { body = boundedRead(join(workspaceRoot, '.errata', 'context.md'), 128 * 1024).trim(); } catch {}
90314
+ if (body) {
90315
+ const digest = hash(body.replace(/\r\n?/g, '\n')).slice(0, 16);
90316
+ // Receipt is local to this graph + session, survives daemon restarts, and
90317
+ // records stdout emission, not a server's intention to send a response.
90318
+ if (event === 'SessionStart' || previous.hash !== digest) {
90319
+ contexts.push('Errata loaded the maintained local workspace context. This block REPLACES any earlier errata context block in this conversation. It is the latest saved snapshot; the daemon maintains it as work proceeds.\n\n' + body);
90320
+ if (!/^(0|off|false|no)$/i.test((process.env.ERRATA_RECALL_CARD || '').trim())) {
90321
+ try {
90322
+ const card = JSON.parse(boundedRead(join(workspaceRoot, '.errata', 'context-card.json'), 128 * 1024));
90323
+ if (card.hash === digest && typeof card.line === 'string' && card.line) messages.push(card.line);
90324
+ } catch { /* Never show a card for a different snapshot. */ }
90325
+ }
90326
+ receipt = { hash: digest, at: Date.now() };
90327
+ }
90328
+ } else if (event === 'SessionStart' || !previous.unavailable) {
90329
+ messages.push('errata: workspace priors are unavailable; run errata doctor in this checkout.');
90330
+ receipt = { unavailable: true, at: Date.now() };
90331
+ }
90332
+ } else if (!workspaceRoot && event === 'PostToolUse') {
90141
90333
  await post('context-inject', true);
90142
90334
  }
90143
90335
  if (contexts.length || messages.length) {
90144
- process.stdout.write(JSON.stringify({
90336
+ await new Promise((resolve) => process.stdout.write(JSON.stringify({
90145
90337
  ...(messages.length ? { systemMessage: messages.join('\n\n') } : {}),
90146
90338
  ...(contexts.length ? { hookSpecificOutput: {
90147
90339
  hookEventName: event, additionalContext: contexts.join('\n\n'),
90148
90340
  } } : {}),
90341
+ }), (error) => {
90342
+ if (!error && receipt && statePath) {
90343
+ try {
90344
+ mkdirSync(stateDir, { recursive: true });
90345
+ const temp = statePath + '.' + process.pid + '.tmp';
90346
+ writeFileSync(temp, JSON.stringify(receipt), { mode: 0o600 });
90347
+ renameSync(temp, statePath);
90348
+ } catch { /* Read-only workspace: retry next time rather than drop context. */ }
90349
+ }
90350
+ resolve();
90149
90351
  }));
90150
90352
  }
90151
90353
  } catch { /* Invalid input is also fail-open. */ }
90152
90354
  `;
90355
+ function buildCodexRelaySource(workspaceRoot) {
90356
+ return CODEX_RELAY_SOURCE.replace("const workspaceRoot = null;", () => `const workspaceRoot = ${JSON.stringify(workspaceRoot)};`);
90357
+ }
90153
90358
 
90154
90359
  // src/codex-hooks.ts
90360
+ init_checkout_root();
90155
90361
  var CODEX_HOOK_REVIEW_HELP = "Codex desktop: Settings > Hooks, select this project, expand each event and Trust the Errata hook. CLI users can use /hooks.";
90156
- function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join42(homedir7(), ".codex")) {
90157
- return existsSync34(join42(root, ".codex")) || existsSync34(codexHome);
90362
+ function writeRelay(file2, source) {
90363
+ if (existsSync34(file2) && readFileSync36(file2, "utf8") === source) return;
90364
+ const temp = `${file2}.${process.pid}.tmp`;
90365
+ try {
90366
+ writeFileSync26(temp, source, { encoding: "utf8", mode: 384 });
90367
+ renameSync5(temp, file2);
90368
+ } finally {
90369
+ if (existsSync34(temp)) unlinkSync6(temp);
90370
+ }
90371
+ }
90372
+ function refreshCodexRelay(root) {
90373
+ const config2 = join43(root, ".codex", "config.toml");
90374
+ if (!existsSync34(config2)) return "absent";
90375
+ const existing = readFileSync36(config2, "utf8");
90376
+ if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
90377
+ replaceCodexHooks(existing, "");
90378
+ const relay = join43(root, ".codex", "hooks", "errata-relay.mjs");
90379
+ const prior = existsSync34(relay) ? readFileSync36(relay, "utf8") : "";
90380
+ if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
90381
+ throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
90382
+ }
90383
+ const source = buildCodexRelaySource(checkoutRootOf(root));
90384
+ if (prior === source) return "current";
90385
+ mkdirSync9(join43(root, ".codex", "hooks"), { recursive: true });
90386
+ writeRelay(relay, source);
90387
+ return "updated";
90388
+ }
90389
+ function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join43(homedir7(), ".codex")) {
90390
+ return existsSync34(join43(root, ".codex")) || existsSync34(codexHome);
90158
90391
  }
90159
90392
  function replaceCodexHooks(existing, block) {
90160
90393
  const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
@@ -90170,20 +90403,43 @@ function replaceCodexHooks(existing, block) {
90170
90403
  return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
90171
90404
  }
90172
90405
  function writeCodexHooks(root, port, nodePath = process.execPath) {
90173
- const dir = join42(root, ".codex");
90174
- const file2 = join42(dir, "config.toml");
90175
- const relay = join42(dir, "hooks", "errata-relay.mjs");
90406
+ const dir = join43(root, ".codex");
90407
+ const file2 = join43(dir, "config.toml");
90408
+ const relay = join43(dir, "hooks", "errata-relay.mjs");
90176
90409
  const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
90177
- const final = replaceCodexHooks(existsSync34(file2) ? readFileSync35(file2, "utf8") : "", block);
90178
- mkdirSync9(join42(dir, "hooks"), { recursive: true });
90179
- writeFileSync26(relay, CODEX_RELAY_SOURCE, "utf8");
90180
- writeFileSync26(file2, final, "utf8");
90410
+ const final = replaceCodexHooks(existsSync34(file2) ? readFileSync36(file2, "utf8") : "", block);
90411
+ mkdirSync9(join43(dir, "hooks"), { recursive: true });
90412
+ writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
90413
+ if (!existsSync34(file2) || readFileSync36(file2, "utf8") !== final) writeFileSync26(file2, final, "utf8");
90181
90414
  return file2;
90182
90415
  }
90183
90416
 
90184
90417
  // src/codex-doctor.ts
90418
+ init_checkout_root();
90419
+ function inspectCodexRelay(cwd) {
90420
+ const root = nearestGitRoot(cwd) ?? cwd;
90421
+ try {
90422
+ const source = readFileSync37(join44(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
90423
+ if (source === buildCodexRelaySource(checkoutRootOf(root))) {
90424
+ return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
90425
+ }
90426
+ } catch {
90427
+ }
90428
+ return { id: "codex_relay", status: "fail", detail: "Codex relay is missing or outdated; run errata install-hooks codex --refresh-existing, or errata install-hooks codex for a new setup" };
90429
+ }
90430
+ function inspectCodexContext(cwd) {
90431
+ const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
90432
+ try {
90433
+ const file2 = join44(root, ".errata", "context.md");
90434
+ if (statSync10(file2).size <= 128 * 1024 && readFileSync37(file2, "utf8").trim()) {
90435
+ return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
90436
+ }
90437
+ } catch {
90438
+ }
90439
+ return { id: "codex_context", status: "fail", detail: "No usable saved workspace context; run errata start here and check the daemon log if context.md remains unavailable" };
90440
+ }
90185
90441
  function readCodexHookState(cwd, options = {}) {
90186
- return new Promise((resolve7, reject) => {
90442
+ return new Promise((resolve8, reject) => {
90187
90443
  const child = spawn4(options.bin ?? resolveCodexExecutable(), options.args ?? ["app-server", "--stdio"], {
90188
90444
  cwd,
90189
90445
  windowsHide: true,
@@ -90199,9 +90455,14 @@ function readCodexHookState(cwd, options = {}) {
90199
90455
  settled = true;
90200
90456
  clearTimeout(timer);
90201
90457
  lines.close();
90458
+ const reap = setTimeout(() => child.kill("SIGKILL"), 1e3);
90459
+ reap.unref();
90460
+ child.once("close", () => {
90461
+ clearTimeout(reap);
90462
+ if (error48) reject(error48);
90463
+ else resolve8({ ...hooks, features });
90464
+ });
90202
90465
  child.kill();
90203
- if (error48) reject(error48);
90204
- else resolve7({ ...hooks, features });
90205
90466
  };
90206
90467
  const timer = setTimeout(() => finish(new Error("Codex hook inspection timed out")), options.timeoutMs ?? 1e4);
90207
90468
  const send = (id, method, params) => {
@@ -90266,10 +90527,11 @@ function assessCodexHooks(state, platform = process.platform) {
90266
90527
  return checks.length ? checks : check2("pass", "Codex discovers enabled, trusted Errata hooks; verify live context and capture in a session");
90267
90528
  }
90268
90529
  async function diagnoseCodexHooks(cwd) {
90530
+ const local = [inspectCodexRelay(cwd), inspectCodexContext(cwd)];
90269
90531
  try {
90270
- return assessCodexHooks(await readCodexHookState(cwd));
90532
+ return [...local, ...assessCodexHooks(await readCodexHookState(cwd))];
90271
90533
  } catch (error48) {
90272
- return [{ id: "codex_hooks", status: "fail", detail: error48 instanceof Error ? error48.message : "Cannot verify Codex hooks" }];
90534
+ return [...local, { id: "codex_hooks", status: "fail", detail: error48 instanceof Error ? error48.message : "Cannot verify Codex hooks" }];
90273
90535
  }
90274
90536
  }
90275
90537
 
@@ -90343,10 +90605,51 @@ function consolidationGapMs(lastPassMs, policy) {
90343
90605
  return Math.max(policy.baseFloorMs, lastPassMs * policy.dutyFactor);
90344
90606
  }
90345
90607
 
90608
+ // src/codex-hook-refresh.ts
90609
+ init_checkout_root();
90610
+ import { existsSync as existsSync35, readdirSync as readdirSync13, readFileSync as readFileSync38 } from "node:fs";
90611
+ import { dirname as dirname13, join as join45, resolve as resolve7 } from "node:path";
90612
+ init_registry();
90613
+ function codexHookRoots(roots) {
90614
+ const found = new Set(roots.map((root) => resolve7(root)));
90615
+ for (const root of [...found]) {
90616
+ const main2 = mainCheckoutOfWorktree(root) ?? root;
90617
+ found.add(main2);
90618
+ const dir = join45(main2, ".git", "worktrees");
90619
+ if (!existsSync35(dir)) continue;
90620
+ let names;
90621
+ try {
90622
+ names = readdirSync13(dir);
90623
+ } catch {
90624
+ continue;
90625
+ }
90626
+ for (const name2 of names) {
90627
+ try {
90628
+ const checkout = dirname13(readFileSync38(join45(dir, name2, "gitdir"), "utf8").trim());
90629
+ if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
90630
+ } catch {
90631
+ }
90632
+ }
90633
+ }
90634
+ return [...found];
90635
+ }
90636
+ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry) => entry.path)) {
90637
+ const results = [];
90638
+ for (const root of codexHookRoots(roots)) {
90639
+ try {
90640
+ const status = refreshCodexRelay(root);
90641
+ if (status !== "absent") results.push({ root, status });
90642
+ } catch (error48) {
90643
+ results.push({ root, status: "error", detail: error48 instanceof Error ? error48.message : String(error48) });
90644
+ }
90645
+ }
90646
+ return results;
90647
+ }
90648
+
90346
90649
  // src/claude-statusline.ts
90347
- import { existsSync as existsSync35, mkdirSync as mkdirSync10, readFileSync as readFileSync36, writeFileSync as writeFileSync27 } from "node:fs";
90650
+ import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync39, writeFileSync as writeFileSync27 } from "node:fs";
90348
90651
  import { homedir as homedir8 } from "node:os";
90349
- import { dirname as dirname13, join as join43 } from "node:path";
90652
+ import { dirname as dirname14, join as join46 } from "node:path";
90350
90653
  var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
90351
90654
  import { readFileSync } from 'node:fs';
90352
90655
 
@@ -90379,8 +90682,8 @@ function removeProjectStatusLine(settings) {
90379
90682
  return true;
90380
90683
  }
90381
90684
  function userClaudeSettingsPath() {
90382
- const base = process.env["CLAUDE_CONFIG_DIR"] ?? join43(homedir8(), ".claude");
90383
- return join43(base, "settings.json");
90685
+ const base = process.env["CLAUDE_CONFIG_DIR"] ?? join46(homedir8(), ".claude");
90686
+ return join46(base, "settings.json");
90384
90687
  }
90385
90688
  function ensureUserStatusLine(opts) {
90386
90689
  const env2 = opts.env ?? process.env;
@@ -90388,9 +90691,9 @@ function ensureUserStatusLine(opts) {
90388
90691
  if (off === "0" || off === "off" || off === "false" || off === "no") return "disabled";
90389
90692
  const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
90390
90693
  let settings = {};
90391
- if (existsSync35(settingsPath)) {
90694
+ if (existsSync36(settingsPath)) {
90392
90695
  try {
90393
- const parsed = JSON.parse(readFileSync36(settingsPath, "utf8"));
90696
+ const parsed = JSON.parse(readFileSync39(settingsPath, "utf8"));
90394
90697
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
90395
90698
  settings = parsed;
90396
90699
  } catch {
@@ -90398,15 +90701,15 @@ function ensureUserStatusLine(opts) {
90398
90701
  }
90399
90702
  }
90400
90703
  if (settings["statusLine"] !== void 0 && !isErrataStatusLine(settings["statusLine"])) return "kept-own";
90401
- const relay = join43(opts.relayDir, STATUSLINE_RELAY_FILE);
90704
+ const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
90402
90705
  mkdirSync10(opts.relayDir, { recursive: true });
90403
- if (!existsSync35(relay) || readFileSync36(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
90706
+ if (!existsSync36(relay) || readFileSync39(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
90404
90707
  writeFileSync27(relay, STATUSLINE_RELAY_SOURCE, "utf8");
90405
90708
  }
90406
90709
  const next = buildStatusLine(opts.port, opts.nodePath ?? process.execPath, relay);
90407
90710
  if (JSON.stringify(settings["statusLine"]) === JSON.stringify(next)) return "unchanged";
90408
90711
  settings["statusLine"] = next;
90409
- mkdirSync10(dirname13(settingsPath), { recursive: true });
90712
+ mkdirSync10(dirname14(settingsPath), { recursive: true });
90410
90713
  writeFileSync27(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
90411
90714
  return "installed";
90412
90715
  }
@@ -90830,14 +91133,14 @@ async function cmdInit() {
90830
91133
  if (!skipHooks) {
90831
91134
  console.log("");
90832
91135
  console.log("installing harness hooks...");
90833
- const { existsSync: existsSync37 } = await import("node:fs");
90834
- const { join: join45 } = await import("node:path");
91136
+ const { existsSync: existsSync38 } = await import("node:fs");
91137
+ const { join: join48 } = await import("node:path");
90835
91138
  try {
90836
91139
  await installClaudeHooks(port);
90837
91140
  } catch (err2) {
90838
91141
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
90839
91142
  }
90840
- if (existsSync37(join45(ROOT, ".cursor"))) {
91143
+ if (existsSync38(join48(ROOT, ".cursor"))) {
90841
91144
  try {
90842
91145
  await installCursorMcpConfig();
90843
91146
  } catch (err2) {
@@ -90921,6 +91224,7 @@ async function cmdNotifyTest() {
90921
91224
  }
90922
91225
  }
90923
91226
  async function cmdStart() {
91227
+ refreshExistingCodexHooks();
90924
91228
  if (!loadProfile(ROOT)) {
90925
91229
  const cfg = loadConfig();
90926
91230
  const locator = detectRepoLocator(ROOT);
@@ -90943,6 +91247,9 @@ async function cmdStart() {
90943
91247
  const lockPath = globalDaemonLock();
90944
91248
  const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
90945
91249
  const where = profile ? `${profile.name} (${profile.id})` : ROOT;
91250
+ if (!running && daemonLockState(readDaemonLock(lockPath), true) === "unknown") {
91251
+ throw new Error(`Cannot verify the daemon process owning ${lockPath}; leaving it untouched. Run errata doctor to inspect it.`);
91252
+ }
90946
91253
  if (running) {
90947
91254
  console.log(`errata: workspace registered; attached to the running daemon`);
90948
91255
  console.log(` workspace: ${where}`);
@@ -91027,9 +91334,9 @@ async function cmdStatus() {
91027
91334
  console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
91028
91335
  console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
91029
91336
  }
91030
- console.log(` graph db: ${existsSync36(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
91031
- console.log(` event log: ${existsSync36(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
91032
- if (existsSync36(paths.castalia)) {
91337
+ console.log(` graph db: ${existsSync37(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
91338
+ console.log(` event log: ${existsSync37(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
91339
+ if (existsSync37(paths.castalia)) {
91033
91340
  try {
91034
91341
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
91035
91342
  const store = openGraphStore2({ path: paths.castalia });
@@ -91365,6 +91672,9 @@ async function cmdUpdate(args2) {
91365
91672
  `);
91366
91673
  const code = await runNpmInstall(channel);
91367
91674
  if (code === 0) {
91675
+ if (await runInstalledHookRefresh() !== 0) {
91676
+ console.warn("[!] Package updated, but some Codex relays could not be refreshed. Run `errata install-hooks codex --refresh-existing`; daemon startup also retries.");
91677
+ }
91368
91678
  console.log(`
91369
91679
  [OK] updated to ${status.latest}. Restart the daemon to run it:`);
91370
91680
  console.log(` errata stop (autostart relaunches it at next logon, or run 'errata dash')`);
@@ -91997,11 +92307,11 @@ async function cmdInstallationProfile(args2) {
91997
92307
  }
91998
92308
  async function cmdReview() {
91999
92309
  const paths = workspacePaths(ROOT);
92000
- if (!existsSync36(paths.reviewQueue)) {
92310
+ if (!existsSync37(paths.reviewQueue)) {
92001
92311
  console.log("(review queue empty)");
92002
92312
  return;
92003
92313
  }
92004
- const queue = JSON.parse(readFileSync37(paths.reviewQueue, "utf8"));
92314
+ const queue = JSON.parse(readFileSync40(paths.reviewQueue, "utf8"));
92005
92315
  if (queue.length === 0) {
92006
92316
  console.log("(review queue empty)");
92007
92317
  return;
@@ -92672,7 +92982,7 @@ async function gatherRepo(store, ws) {
92672
92982
  };
92673
92983
  }
92674
92984
  async function gatherReportData(generatedAt) {
92675
- const { existsSync: existsSync37 } = await import("node:fs");
92985
+ const { existsSync: existsSync38 } = await import("node:fs");
92676
92986
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src5(), src_exports2));
92677
92987
  const cfg = loadConfig();
92678
92988
  const outbound = cfg.consent.sync ? "auto" : "off";
@@ -92680,7 +92990,7 @@ async function gatherReportData(generatedAt) {
92680
92990
  for (const ws of listWorkspaces()) {
92681
92991
  if (ws.missing) continue;
92682
92992
  const dbPath = workspacePaths(ws.path).castalia;
92683
- if (!existsSync37(dbPath)) continue;
92993
+ if (!existsSync38(dbPath)) continue;
92684
92994
  let store = null;
92685
92995
  try {
92686
92996
  store = openGraphStore2({ path: dbPath });
@@ -92724,8 +93034,8 @@ async function cmdReport(args2) {
92724
93034
  const outDir = workspacePaths(ROOT).configDir;
92725
93035
  mkdirSync11(outDir, { recursive: true });
92726
93036
  const files = renderReport2(data, { includeFutureVerbs });
92727
- for (const f of files) writeFileSync28(join44(outDir, f.name), f.html, "utf8");
92728
- const indexPath = join44(outDir, "report.html");
93037
+ for (const f of files) writeFileSync28(join47(outDir, f.name), f.html, "utf8");
93038
+ const indexPath = join47(outDir, "report.html");
92729
93039
  console.log(`report \u2192 ${indexPath}`);
92730
93040
  console.log(
92731
93041
  ` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
@@ -92733,31 +93043,20 @@ async function cmdReport(args2) {
92733
93043
  console.log(` open: file://${indexPath.replace(/\\/g, "/")}`);
92734
93044
  }
92735
93045
  async function cmdStop() {
92736
- const { unlinkSync: unlinkSync4 } = await import("node:fs");
92737
93046
  const lockPath = [globalDaemonLock(), workspacePaths(ROOT).daemonLock].find((p) => readDaemonLock(p) !== null);
92738
93047
  if (!lockPath) {
92739
93048
  console.log(`no daemon lock found \u2014 nothing to stop`);
92740
93049
  return;
92741
93050
  }
92742
- const lock = readDaemonLock(lockPath);
92743
- if (!isProcessAlive(lock.pid)) {
92744
- try {
92745
- unlinkSync4(lockPath);
92746
- console.log(`removed stale lock (pid ${lock.pid} not running)`);
92747
- } catch {
92748
- }
92749
- return;
92750
- }
92751
93051
  try {
92752
- process.kill(lock.pid, "SIGTERM");
92753
- console.log(`sent SIGTERM to daemon (pid ${lock.pid})`);
93052
+ const result = stopLockedDaemon(lockPath);
93053
+ if (result === "signaled") console.log(`sent SIGTERM to the verified daemon process`);
93054
+ else if (result === "stale") console.log(`removed stale daemon lock; no process was signaled`);
93055
+ else if (result === "missing") console.log(`no daemon lock found \u2014 nothing to stop`);
93056
+ else throw new Error(`daemon lock ownership is ${result}; no process was signaled and the lock was preserved`);
92754
93057
  } catch (err2) {
92755
- console.warn(`could not signal pid ${lock.pid}: ${err2 instanceof Error ? err2.message : err2}`);
92756
- try {
92757
- unlinkSync4(lockPath);
92758
- console.log(`removed stale lock file`);
92759
- } catch {
92760
- }
93058
+ console.warn(`could not stop daemon: ${err2 instanceof Error ? err2.message : err2}`);
93059
+ process.exitCode = 1;
92761
93060
  }
92762
93061
  }
92763
93062
  async function cmdMcp(args2) {
@@ -92768,9 +93067,9 @@ async function cmdMcp(args2) {
92768
93067
  await runMcpServer2(ROOT, { toolNameStyle: grokCompatibility ? "bare" : "prefixed" });
92769
93068
  }
92770
93069
  function selfArgv(sub) {
92771
- const self = process.execPath;
92772
- if (/errata(\.exe)?$/i.test(self)) return { cmd: self, args: [sub] };
92773
- return { cmd: self, args: [...process.execArgv, process.argv[1] ?? "", sub] };
93070
+ const self2 = process.execPath;
93071
+ if (/errata(\.exe)?$/i.test(self2)) return { cmd: self2, args: [sub] };
93072
+ return { cmd: self2, args: [...process.execArgv, process.argv[1] ?? "", sub] };
92774
93073
  }
92775
93074
  function spawnDaemonDetached(options = {}) {
92776
93075
  const { cmd: cmd2, args: args2 } = selfArgv("dash");
@@ -92780,7 +93079,7 @@ function spawnDaemonDetached(options = {}) {
92780
93079
  try {
92781
93080
  const logPath = daemonLogPath();
92782
93081
  try {
92783
- if (statSync10(logPath).size > 5 * 1024 * 1024) renameSync4(logPath, `${logPath}.1`);
93082
+ if (statSync11(logPath).size > 5 * 1024 * 1024) renameSync6(logPath, `${logPath}.1`);
92784
93083
  } catch {
92785
93084
  }
92786
93085
  out2 = openSync2(logPath, "a");
@@ -92805,11 +93104,11 @@ function spawnDaemonDetached(options = {}) {
92805
93104
  }
92806
93105
  function ensureSingletonRunning(options = {}) {
92807
93106
  try {
92808
- if (isDaemonAlive(globalDaemonLock())) return true;
93107
+ if (daemonLockBlocksStartup(globalDaemonLock())) return true;
92809
93108
  spawnDaemonDetached(options);
92810
93109
  void (async () => {
92811
93110
  if (await waitForDaemon(globalDaemonLock(), 8e3)) return;
92812
- if (isDaemonAlive(globalDaemonLock())) return;
93111
+ if (daemonLockBlocksStartup(globalDaemonLock())) return;
92813
93112
  spawnDaemonDetached(options);
92814
93113
  await waitForDaemon(globalDaemonLock(), 8e3);
92815
93114
  })();
@@ -92830,6 +93129,10 @@ async function cmdInstallHooks(args2) {
92830
93129
  await installCursorMcpConfig();
92831
93130
  return;
92832
93131
  case "codex":
93132
+ if (args2.includes("--refresh-existing")) {
93133
+ if (!refreshExistingCodexHooks()) process.exitCode = 1;
93134
+ return;
93135
+ }
92833
93136
  await installCodexHooks(port);
92834
93137
  return;
92835
93138
  case "opencode":
@@ -92845,24 +93148,24 @@ async function cmdInstallHooks(args2) {
92845
93148
  }
92846
93149
  }
92847
93150
  async function installOpencodePlugin(port) {
92848
- const { mkdirSync: mkdirSync11, existsSync: existsSync37, readFileSync: readFileSync38, writeFileSync: writeFileSync28 } = await import("node:fs");
92849
- const { join: join45 } = await import("node:path");
92850
- const dir = join45(ROOT, ".opencode", "plugin");
92851
- if (!existsSync37(dir)) mkdirSync11(dir, { recursive: true });
92852
- const file2 = join45(dir, "inerrata.js");
92853
- if (existsSync37(file2)) {
92854
- const head2 = readFileSync38(file2, "utf8").split("\n")[0] ?? "";
93151
+ const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
93152
+ const { join: join48 } = await import("node:path");
93153
+ const dir = join48(ROOT, ".opencode", "plugin");
93154
+ if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
93155
+ const file2 = join48(dir, "inerrata.js");
93156
+ if (existsSync38(file2)) {
93157
+ const head2 = readFileSync41(file2, "utf8").split("\n")[0] ?? "";
92855
93158
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
92856
93159
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
92857
93160
  process.exit(2);
92858
93161
  }
92859
93162
  }
92860
93163
  writeFileSync28(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
92861
- const cfgFile = join45(ROOT, "opencode.json");
93164
+ const cfgFile = join48(ROOT, "opencode.json");
92862
93165
  let cfg = { $schema: "https://opencode.ai/config.json" };
92863
- if (existsSync37(cfgFile)) {
93166
+ if (existsSync38(cfgFile)) {
92864
93167
  try {
92865
- cfg = JSON.parse(readFileSync38(cfgFile, "utf8"));
93168
+ cfg = JSON.parse(readFileSync41(cfgFile, "utf8"));
92866
93169
  } catch {
92867
93170
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
92868
93171
  process.exit(2);
@@ -92900,15 +93203,15 @@ function ensureStatusLine(port) {
92900
93203
  }
92901
93204
  }
92902
93205
  async function installClaudeHooks(port) {
92903
- const { mkdirSync: mkdirSync11, existsSync: existsSync37, readFileSync: readFileSync38, writeFileSync: writeFileSync28 } = await import("node:fs");
92904
- const { join: join45 } = await import("node:path");
92905
- const dir = join45(ROOT, ".claude");
92906
- if (!existsSync37(dir)) mkdirSync11(dir, { recursive: true });
92907
- const file2 = join45(dir, "settings.json");
93206
+ const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
93207
+ const { join: join48 } = await import("node:path");
93208
+ const dir = join48(ROOT, ".claude");
93209
+ if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
93210
+ const file2 = join48(dir, "settings.json");
92908
93211
  let settings = {};
92909
- if (existsSync37(file2)) {
93212
+ if (existsSync38(file2)) {
92910
93213
  try {
92911
- settings = JSON.parse(readFileSync38(file2, "utf8"));
93214
+ settings = JSON.parse(readFileSync41(file2, "utf8"));
92912
93215
  } catch {
92913
93216
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
92914
93217
  process.exit(2);
@@ -92960,7 +93263,7 @@ async function installClaudeHooks(port) {
92960
93263
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
92961
93264
  console.log(` ${ensureStatusLine(port)}`);
92962
93265
  await installClaudeMcpConfig();
92963
- const claudeMd = join45(ROOT, "CLAUDE.md");
93266
+ const claudeMd = join48(ROOT, "CLAUDE.md");
92964
93267
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
92965
93268
  if (recall.kind === "collision") {
92966
93269
  console.warn(
@@ -92972,15 +93275,15 @@ async function installClaudeHooks(port) {
92972
93275
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
92973
93276
  }
92974
93277
  async function installClaudeMcpConfig() {
92975
- const { mkdirSync: mkdirSync11, existsSync: existsSync37, readFileSync: readFileSync38, writeFileSync: writeFileSync28 } = await import("node:fs");
92976
- const { join: join45, dirname: dirname14 } = await import("node:path");
92977
- const file2 = join45(ROOT, ".mcp.json");
92978
- const dir = dirname14(file2);
92979
- if (!existsSync37(dir)) mkdirSync11(dir, { recursive: true });
93278
+ const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
93279
+ const { join: join48, dirname: dirname15 } = await import("node:path");
93280
+ const file2 = join48(ROOT, ".mcp.json");
93281
+ const dir = dirname15(file2);
93282
+ if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
92980
93283
  let cfg = {};
92981
- if (existsSync37(file2)) {
93284
+ if (existsSync38(file2)) {
92982
93285
  try {
92983
- cfg = JSON.parse(readFileSync38(file2, "utf8"));
93286
+ cfg = JSON.parse(readFileSync41(file2, "utf8"));
92984
93287
  } catch {
92985
93288
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
92986
93289
  process.exit(2);
@@ -92994,15 +93297,15 @@ async function installClaudeMcpConfig() {
92994
93297
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
92995
93298
  }
92996
93299
  async function installCursorMcpConfig() {
92997
- const { mkdirSync: mkdirSync11, existsSync: existsSync37, readFileSync: readFileSync38, writeFileSync: writeFileSync28 } = await import("node:fs");
92998
- const { join: join45 } = await import("node:path");
92999
- const dir = join45(ROOT, ".cursor");
93000
- if (!existsSync37(dir)) mkdirSync11(dir, { recursive: true });
93001
- const file2 = join45(dir, "mcp.json");
93300
+ const { mkdirSync: mkdirSync11, existsSync: existsSync38, readFileSync: readFileSync41, writeFileSync: writeFileSync28 } = await import("node:fs");
93301
+ const { join: join48 } = await import("node:path");
93302
+ const dir = join48(ROOT, ".cursor");
93303
+ if (!existsSync38(dir)) mkdirSync11(dir, { recursive: true });
93304
+ const file2 = join48(dir, "mcp.json");
93002
93305
  let cfg = {};
93003
- if (existsSync37(file2)) {
93306
+ if (existsSync38(file2)) {
93004
93307
  try {
93005
- cfg = JSON.parse(readFileSync38(file2, "utf8"));
93308
+ cfg = JSON.parse(readFileSync41(file2, "utf8"));
93006
93309
  } catch {
93007
93310
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
93008
93311
  process.exit(2);
@@ -93021,7 +93324,7 @@ async function installCodexHooks(port) {
93021
93324
  const gitRoot = nearestGitRoot(process.cwd());
93022
93325
  const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
93023
93326
  const file2 = writeCodexHooks(hookRoot, port);
93024
- const instructions = writeManagedBlock(join44(hookRoot, "AGENTS.md"), {
93327
+ const instructions = writeManagedBlock(join47(hookRoot, "AGENTS.md"), {
93025
93328
  body: AGENTS_POINTER_BODY,
93026
93329
  stable: true
93027
93330
  });
@@ -93039,6 +93342,21 @@ async function installCodexHooks(port) {
93039
93342
  console.log(" Run `errata doctor` here to check hook discovery and trust; installation alone is not activation.");
93040
93343
  console.log(" Respect an explicit [features] hooks = false setting (older builds use codex_hooks).");
93041
93344
  console.log(" Older Codex versions may not support every event; update if hooks do not fire.");
93345
+ for (const check2 of await diagnoseCodexHooks(hookRoot)) {
93346
+ console.log(` ${check2.status === "pass" ? "\u2713" : "!"} ${check2.detail}`);
93347
+ }
93348
+ }
93349
+ function refreshExistingCodexHooks() {
93350
+ let ok = true;
93351
+ const roots = [...listWorkspaceEntries().map((entry) => entry.path), process.cwd()];
93352
+ for (const result of refreshInstalledCodexRelays(roots)) {
93353
+ if (result.status === "updated") console.log(`updated existing Codex relay \u2192 ${result.root} (hook definitions preserved)`);
93354
+ if (result.status === "error") {
93355
+ ok = false;
93356
+ console.warn(`Codex relay refresh needs attention in ${result.root}: ${result.detail}`);
93357
+ }
93358
+ }
93359
+ return ok;
93042
93360
  }
93043
93361
  async function refreshLinkedCodexHooks(args2) {
93044
93362
  if (args2.includes("--skip-hooks") || !hasCodexConfig(ROOT)) return;
@@ -93193,6 +93511,7 @@ function installLogTimestamps() {
93193
93511
  async function cmdDash(args2) {
93194
93512
  process.title = "errata-daemon";
93195
93513
  installLogTimestamps();
93514
+ refreshExistingCodexHooks();
93196
93515
  const portIdx = args2.indexOf("--port");
93197
93516
  const port = portIdx >= 0 && args2[portIdx + 1] ? Number(args2[portIdx + 1]) : 7891;
93198
93517
  const reindexOnStart = !args2.includes("--no-reindex");
@@ -93347,7 +93666,7 @@ async function cmdDash(args2) {
93347
93666
  const hotspotScanMark = /* @__PURE__ */ new Map();
93348
93667
  const HOTSPOT_FANIN = 20;
93349
93668
  const runNightlyPass = async (dueIds) => {
93350
- const yieldToLoop2 = () => new Promise((resolve7) => setImmediate(resolve7));
93669
+ const yieldToLoop2 = () => new Promise((resolve8) => setImmediate(resolve8));
93351
93670
  const fullReclusterPass = nightlyCount++ % FULL_RECLUSTER_EVERY === 0;
93352
93671
  const m = dueIds ? await handle2.nightlyFor(dueIds) : await handle2.nightlyAll();
93353
93672
  let skillsLearned = 0;
@@ -93425,9 +93744,9 @@ async function cmdDash(args2) {
93425
93744
  await yieldToLoop2();
93426
93745
  try {
93427
93746
  const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
93428
- atCommit: readGitRefState(join44(r.root, ".git")).sha ?? void 0
93747
+ atCommit: readGitRefState(join47(r.root, ".git")).sha ?? void 0
93429
93748
  });
93430
- const res = bleedRules(join44(r.root, ".claude", "rules"), items);
93749
+ const res = bleedRules(join47(r.root, ".claude", "rules"), items);
93431
93750
  if (res.written || res.pruned) {
93432
93751
  console.log(
93433
93752
  `[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")