@inerrata-corporation/errata 2.0.22-dev.4186 → 2.0.22-dev.4293

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.
package/errata.mjs CHANGED
@@ -19108,17 +19108,23 @@ function installTextIndex(db) {
19108
19108
  db.transaction(() => {
19109
19109
  db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS nodes_text
19110
19110
  USING fts5(description, content='nodes', content_rowid='rowid', tokenize='trigram')`);
19111
+ db.exec(`DROP TRIGGER IF EXISTS nodes_text_update_out; DROP TRIGGER IF EXISTS nodes_text_update_in;
19112
+ DROP TRIGGER IF EXISTS nodes_text_update`);
19111
19113
  db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_insert AFTER INSERT ON nodes WHEN NEW.valid_to IS NULL
19112
19114
  BEGIN INSERT INTO nodes_text(rowid, description) VALUES (NEW.rowid, NEW.description); END;`);
19113
- db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_update_out AFTER UPDATE OF description, valid_to ON nodes
19114
- WHEN OLD.valid_to IS NULL
19115
- BEGIN INSERT INTO nodes_text(nodes_text, rowid, description) VALUES ('delete', OLD.rowid, OLD.description); END;`);
19116
- db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_update_in AFTER UPDATE OF description, valid_to ON nodes
19117
- WHEN NEW.valid_to IS NULL
19118
- BEGIN INSERT INTO nodes_text(rowid, description) VALUES (NEW.rowid, NEW.description); END;`);
19115
+ db.exec(`CREATE TRIGGER nodes_text_update AFTER UPDATE OF description, valid_to ON nodes
19116
+ WHEN OLD.description IS NOT NEW.description OR OLD.valid_to IS NOT NEW.valid_to
19117
+ BEGIN
19118
+ INSERT INTO nodes_text(nodes_text, rowid, description)
19119
+ SELECT 'delete', OLD.rowid, OLD.description WHERE OLD.valid_to IS NULL;
19120
+ INSERT INTO nodes_text(rowid, description)
19121
+ SELECT NEW.rowid, NEW.description WHERE NEW.valid_to IS NULL;
19122
+ END;`);
19119
19123
  db.exec(`CREATE TRIGGER IF NOT EXISTS nodes_text_delete AFTER DELETE ON nodes WHEN OLD.valid_to IS NULL
19120
19124
  BEGIN INSERT INTO nodes_text(nodes_text, rowid, description) VALUES ('delete', OLD.rowid, OLD.description); END;`);
19125
+ db.exec(`INSERT INTO nodes_text(nodes_text) VALUES ('delete-all')`);
19121
19126
  db.exec(`INSERT INTO nodes_text(rowid, description) SELECT rowid, description FROM nodes WHERE valid_to IS NULL`);
19127
+ db.prepare("INSERT OR REPLACE INTO store_meta(key,value) VALUES (?,?)").run("text-index-trigram-1", "installed");
19122
19128
  db.prepare("INSERT INTO store_meta(key,value) VALUES (?,?)").run(TEXT_INDEX_KEY, "installed");
19123
19129
  });
19124
19130
  }
@@ -19129,7 +19135,7 @@ var TEXT_INDEX_KEY, TEXT_INDEX_MIN_TERM;
19129
19135
  var init_text_index = __esm({
19130
19136
  "../../packages/local-graph/src/text-index.ts"() {
19131
19137
  "use strict";
19132
- TEXT_INDEX_KEY = "text-index-trigram-1";
19138
+ TEXT_INDEX_KEY = "text-index-trigram-2";
19133
19139
  TEXT_INDEX_MIN_TERM = 3;
19134
19140
  }
19135
19141
  });
@@ -29559,6 +29565,78 @@ var init_src7 = __esm({
29559
29565
  }
29560
29566
  });
29561
29567
 
29568
+ // src/owner-only-file.ts
29569
+ import { chmodSync, statSync } from "node:fs";
29570
+ import { execFileSync } from "node:child_process";
29571
+ import { join as join5 } from "node:path";
29572
+ function system32(exe) {
29573
+ return join5(process.env["SystemRoot"] ?? "C:\\Windows", "System32", exe);
29574
+ }
29575
+ function parseWhoamiSid(output) {
29576
+ const match2 = /"(S-1-\d+(?:-\d+)+)"/.exec(output);
29577
+ return match2 ? match2[1] : null;
29578
+ }
29579
+ function windowsAccount() {
29580
+ if (cachedSid !== void 0) return cachedSid;
29581
+ try {
29582
+ const out2 = execFileSync(system32("whoami.exe"), ["/user", "/fo", "csv", "/nh"], {
29583
+ encoding: "utf8",
29584
+ stdio: ["ignore", "pipe", "ignore"],
29585
+ windowsHide: true,
29586
+ timeout: 5e3
29587
+ });
29588
+ const sid = parseWhoamiSid(out2);
29589
+ cachedSid = sid ? `*${sid}` : null;
29590
+ } catch {
29591
+ cachedSid = null;
29592
+ }
29593
+ return cachedSid;
29594
+ }
29595
+ function runIcacls(args2) {
29596
+ execFileSync(system32("icacls.exe"), args2, { stdio: "ignore", windowsHide: true, timeout: 5e3 });
29597
+ }
29598
+ function statIdentity(path3) {
29599
+ try {
29600
+ const stat4 = statSync(path3, { bigint: true });
29601
+ return `${stat4.dev}:${stat4.ino}:${stat4.birthtimeNs}`;
29602
+ } catch {
29603
+ return null;
29604
+ }
29605
+ }
29606
+ function restrictToOwner(path3, deps = defaultDeps) {
29607
+ try {
29608
+ if (deps.platform !== "win32") {
29609
+ deps.chmod(path3, 384);
29610
+ return "chmod";
29611
+ }
29612
+ const identity = deps.fileIdentity(path3);
29613
+ if (identity !== null && restrictedThisProcess.get(path3) === identity) return "acl-cached";
29614
+ const account = deps.account();
29615
+ if (!account) return "skipped";
29616
+ deps.icacls([path3, "/grant:r", `${account}:F`, `${LOCAL_SYSTEM_SID}:F`]);
29617
+ deps.icacls([path3, "/inheritance:r"]);
29618
+ if (identity !== null) restrictedThisProcess.set(path3, identity);
29619
+ return "acl";
29620
+ } catch {
29621
+ return "failed";
29622
+ }
29623
+ }
29624
+ var LOCAL_SYSTEM_SID, cachedSid, defaultDeps, restrictedThisProcess;
29625
+ var init_owner_only_file = __esm({
29626
+ "src/owner-only-file.ts"() {
29627
+ "use strict";
29628
+ LOCAL_SYSTEM_SID = "*S-1-5-18";
29629
+ defaultDeps = {
29630
+ platform: process.platform,
29631
+ chmod: chmodSync,
29632
+ icacls: runIcacls,
29633
+ account: windowsAccount,
29634
+ fileIdentity: statIdentity
29635
+ };
29636
+ restrictedThisProcess = /* @__PURE__ */ new Map();
29637
+ }
29638
+ });
29639
+
29562
29640
  // ../../node_modules/.pnpm/env-paths@3.0.0/node_modules/env-paths/index.js
29563
29641
  import path2 from "node:path";
29564
29642
  import os from "node:os";
@@ -29634,26 +29712,26 @@ __export(paths_exports, {
29634
29712
  workspacePaths: () => workspacePaths
29635
29713
  });
29636
29714
  import { mkdirSync as mkdirSync5 } from "node:fs";
29637
- import { dirname as dirname5, join as join5 } from "node:path";
29715
+ import { dirname as dirname5, join as join6 } from "node:path";
29638
29716
  function globalDir() {
29639
29717
  const p = envPaths("errata", { suffix: "" });
29640
29718
  return p.config;
29641
29719
  }
29642
29720
  function globalConfigPath() {
29643
- return process.env["ERRATA_CONFIG_PATH"] ?? join5(globalDir(), "config.json");
29721
+ return process.env["ERRATA_CONFIG_PATH"] ?? join6(globalDir(), "config.json");
29644
29722
  }
29645
29723
  function daemonLogPath() {
29646
29724
  mkdirSync5(globalDir(), { recursive: true });
29647
- return join5(globalDir(), "daemon.log");
29725
+ return join6(globalDir(), "daemon.log");
29648
29726
  }
29649
29727
  function globalDaemonLock() {
29650
- return process.env["ERRATA_DAEMON_LOCK"] ?? join5(globalDir(), "daemon.lock");
29728
+ return process.env["ERRATA_DAEMON_LOCK"] ?? join6(globalDir(), "daemon.lock");
29651
29729
  }
29652
29730
  function sharedStorePath() {
29653
- return process.env["ERRATA_SHARED_DB"] ?? join5(globalDir(), "shared", "graph.db");
29731
+ return process.env["ERRATA_SHARED_DB"] ?? join6(globalDir(), "shared", "graph.db");
29654
29732
  }
29655
29733
  function workspaceDir(workspaceRoot) {
29656
- return join5(workspaceRoot, ".errata");
29734
+ return join6(workspaceRoot, ".errata");
29657
29735
  }
29658
29736
  function ensureDir(p) {
29659
29737
  mkdirSync5(p, { recursive: true });
@@ -29668,15 +29746,15 @@ function workspacePaths(root) {
29668
29746
  return {
29669
29747
  root,
29670
29748
  configDir: dir,
29671
- workspaceJson: join5(dir, "workspace.json"),
29672
- eventLog: join5(dir, "eventlog.sqlite"),
29673
- castalia: join5(dir, "castalia.db"),
29674
- reviewQueue: join5(dir, "review-queue.json"),
29675
- outbox: join5(dir, "outbox"),
29676
- daemonLock: join5(dir, "daemon.lock"),
29677
- identityAudit: join5(dir, "identity-audit.log"),
29678
- skillsDir: join5(dir, "skills"),
29679
- skillsManifest: join5(dir, "skills.json")
29749
+ workspaceJson: join6(dir, "workspace.json"),
29750
+ eventLog: join6(dir, "eventlog.sqlite"),
29751
+ castalia: join6(dir, "castalia.db"),
29752
+ reviewQueue: join6(dir, "review-queue.json"),
29753
+ outbox: join6(dir, "outbox"),
29754
+ daemonLock: join6(dir, "daemon.lock"),
29755
+ identityAudit: join6(dir, "identity-audit.log"),
29756
+ skillsDir: join6(dir, "skills"),
29757
+ skillsManifest: join6(dir, "skills.json")
29680
29758
  };
29681
29759
  }
29682
29760
  var init_paths = __esm({
@@ -29748,7 +29826,9 @@ function loadConfig() {
29748
29826
  function saveConfig(cfg) {
29749
29827
  ensureDir(globalDir());
29750
29828
  const normalized = snapshotActiveInstallationProfile(cfg);
29751
- writeFileSync5(globalConfigPath(), JSON.stringify(normalized, null, 2), { encoding: "utf8", mode: 384 });
29829
+ const path3 = globalConfigPath();
29830
+ writeFileSync5(path3, JSON.stringify(normalized, null, 2), { encoding: "utf8", mode: 384 });
29831
+ restrictToOwner(path3);
29752
29832
  }
29753
29833
  function profileFromCurrent(cfg, installationId) {
29754
29834
  return {
@@ -29849,6 +29929,7 @@ var LEGACY_CLOUD_URL, DEFAULT_CLOUD_URL, DEFAULT_UPDATE_CHANNEL;
29849
29929
  var init_config = __esm({
29850
29930
  "src/config.ts"() {
29851
29931
  "use strict";
29932
+ init_owner_only_file();
29852
29933
  init_paths();
29853
29934
  LEGACY_CLOUD_URL = "https://inerrata-gateway.onrender.com";
29854
29935
  DEFAULT_CLOUD_URL = true ? "https://dev.inerrata.dev" : DEV_CLOUD_URL;
@@ -32459,7 +32540,7 @@ var init_dist = __esm({
32459
32540
  });
32460
32541
 
32461
32542
  // src/context-baselines.ts
32462
- import { closeSync, openSync, readSync, statSync } from "node:fs";
32543
+ import { closeSync, openSync, readSync, statSync as statSync2 } from "node:fs";
32463
32544
  function deliveryMarker(hash2) {
32464
32545
  return `<!-- errata-context ${hash2.slice(0, 16)} -->`;
32465
32546
  }
@@ -32471,7 +32552,7 @@ function appendedSince(path3, offset, needle) {
32471
32552
  return { found: false, turnRan: false };
32472
32553
  }
32473
32554
  try {
32474
- const size = statSync(path3).size;
32555
+ const size = statSync2(path3).size;
32475
32556
  const keep = Math.max(needle.length, MODEL_TURN.length);
32476
32557
  const buf = Buffer.alloc(CHUNK);
32477
32558
  let carry = "";
@@ -32490,7 +32571,7 @@ function appendedSince(path3, offset, needle) {
32490
32571
  }
32491
32572
  function sizeOf(path3) {
32492
32573
  try {
32493
- return statSync(path3).size;
32574
+ return statSync2(path3).size;
32494
32575
  } catch {
32495
32576
  return 0;
32496
32577
  }
@@ -32714,7 +32795,7 @@ var init_diagnostic_matcher = __esm({
32714
32795
  });
32715
32796
 
32716
32797
  // ../../packages/generalizer/src/generalizer.ts
32717
- import { isAbsolute, join as join6, relative } from "node:path";
32798
+ import { isAbsolute, join as join7, relative } from "node:path";
32718
32799
  async function runGeneralizer(opts) {
32719
32800
  const report = {
32720
32801
  eventsProcessed: 0,
@@ -32822,7 +32903,7 @@ function extractDiagnostics(ev) {
32822
32903
  function diagRelPath(file2, cwd, workspaceRoot) {
32823
32904
  const norm = (p) => p.replace(/\\/g, "/");
32824
32905
  if (!workspaceRoot) return norm(file2);
32825
- const abs = isAbsolute(file2) ? file2 : join6(cwd ?? workspaceRoot, file2);
32906
+ const abs = isAbsolute(file2) ? file2 : join7(cwd ?? workspaceRoot, file2);
32826
32907
  return norm(relative(workspaceRoot, abs));
32827
32908
  }
32828
32909
  function extractErrorSignature(ev) {
@@ -35111,7 +35192,7 @@ var init_recall_card = __esm({
35111
35192
 
35112
35193
  // src/recall-signal.ts
35113
35194
  import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
35114
- import { join as join7 } from "node:path";
35195
+ import { join as join8 } from "node:path";
35115
35196
  function live(n) {
35116
35197
  return n != null && n.validTo == null && historyReadPolicy(n, { mode: "passive" }).allow;
35117
35198
  }
@@ -35180,14 +35261,14 @@ function contextCard(store, snapshot) {
35180
35261
  return deliveredCard(store, intent ? `${count} for \u201C${clipIntent(intent)}\u201D` : `${count} in context`, delivered);
35181
35262
  }
35182
35263
  function writeContextCard(root, hash2, card) {
35183
- writeFileSync6(join7(root, ".errata", CONTEXT_CARD_FILE), JSON.stringify({
35264
+ writeFileSync6(join8(root, ".errata", CONTEXT_CARD_FILE), JSON.stringify({
35184
35265
  hash: hash2,
35185
35266
  card,
35186
35267
  line: card && recallCardEnabled() ? renderRecallLine(card) : null
35187
35268
  }));
35188
35269
  }
35189
35270
  function readContextCard(root, hash2) {
35190
- const path3 = join7(root, ".errata", CONTEXT_CARD_FILE);
35271
+ const path3 = join8(root, ".errata", CONTEXT_CARD_FILE);
35191
35272
  if (!existsSync7(path3)) return null;
35192
35273
  try {
35193
35274
  const saved = JSON.parse(readFileSync5(path3, "utf8"));
@@ -35468,12 +35549,12 @@ var init_consent = __esm({
35468
35549
 
35469
35550
  // src/git-remote.ts
35470
35551
  import { spawnSync } from "node:child_process";
35471
- import { existsSync as existsSync10, readFileSync as readFileSync8, statSync as statSync2 } from "node:fs";
35472
- import { isAbsolute as isAbsolute2, join as join8, resolve as resolve2 } from "node:path";
35552
+ import { existsSync as existsSync10, readFileSync as readFileSync8, statSync as statSync3 } from "node:fs";
35553
+ import { isAbsolute as isAbsolute2, join as join9, resolve as resolve2 } from "node:path";
35473
35554
  function resolveGitDir(root) {
35474
- const dotGit = join8(root, ".git");
35555
+ const dotGit = join9(root, ".git");
35475
35556
  try {
35476
- const st = statSync2(dotGit);
35557
+ const st = statSync3(dotGit);
35477
35558
  if (st.isDirectory()) return dotGit;
35478
35559
  const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync8(dotGit, "utf8"));
35479
35560
  if (!m) return null;
@@ -35484,13 +35565,13 @@ function resolveGitDir(root) {
35484
35565
  }
35485
35566
  }
35486
35567
  function gitConfigPath(gitDir) {
35487
- const commondirFile = join8(gitDir, "commondir");
35568
+ const commondirFile = join9(gitDir, "commondir");
35488
35569
  if (existsSync10(commondirFile)) {
35489
35570
  const common = readFileSync8(commondirFile, "utf8").trim();
35490
35571
  const commonDir = isAbsolute2(common) ? common : resolve2(gitDir, common);
35491
- return join8(commonDir, "config");
35572
+ return join9(commonDir, "config");
35492
35573
  }
35493
- return join8(gitDir, "config");
35574
+ return join9(gitDir, "config");
35494
35575
  }
35495
35576
  function readRemotes(root) {
35496
35577
  const gitDir = resolveGitDir(root);
@@ -35556,7 +35637,7 @@ var init_git_remote = __esm({
35556
35637
  // src/profile.ts
35557
35638
  import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
35558
35639
  import { createHash as createHash5 } from "node:crypto";
35559
- import { join as join9 } from "node:path";
35640
+ import { join as join10 } from "node:path";
35560
35641
  function workspaceId(root) {
35561
35642
  return "wp_" + createHash5("sha256").update(root).digest("hex").slice(0, 12);
35562
35643
  }
@@ -35593,13 +35674,13 @@ function autodetectProfile(root) {
35593
35674
  const p = emptyProfile(id, name2);
35594
35675
  const locator = detectRepoLocator(root);
35595
35676
  if (locator) p.repoLocator = locator;
35596
- const pkgPath = join9(root, "package.json");
35677
+ const pkgPath = join10(root, "package.json");
35597
35678
  if (existsSync11(pkgPath)) {
35598
35679
  try {
35599
35680
  const pkg = JSON.parse(readFileSync9(pkgPath, "utf8"));
35600
35681
  const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
35601
35682
  p.languages.push("javascript");
35602
- if (existsSync11(join9(root, "tsconfig.json")) || deps["typescript"]) {
35683
+ if (existsSync11(join10(root, "tsconfig.json")) || deps["typescript"]) {
35603
35684
  p.languages.push("typescript");
35604
35685
  }
35605
35686
  const nodeVer = pkg.engines?.node?.trim();
@@ -35620,7 +35701,7 @@ function autodetectProfile(root) {
35620
35701
  } catch {
35621
35702
  }
35622
35703
  }
35623
- const pyproject = join9(root, "pyproject.toml");
35704
+ const pyproject = join10(root, "pyproject.toml");
35624
35705
  if (existsSync11(pyproject)) {
35625
35706
  try {
35626
35707
  const txt = readFileSync9(pyproject, "utf8");
@@ -35634,16 +35715,16 @@ function autodetectProfile(root) {
35634
35715
  } catch {
35635
35716
  }
35636
35717
  }
35637
- const reqs = join9(root, "requirements.txt");
35718
+ const reqs = join10(root, "requirements.txt");
35638
35719
  if (existsSync11(reqs)) {
35639
35720
  if (!p.languages.includes("python")) p.languages.push("python");
35640
35721
  if (!p.stack.includes("python@3")) p.stack.push("python@3");
35641
35722
  }
35642
- if (existsSync11(join9(root, "go.mod"))) {
35723
+ if (existsSync11(join10(root, "go.mod"))) {
35643
35724
  p.languages.push("go");
35644
35725
  p.stack.push("go");
35645
35726
  }
35646
- if (existsSync11(join9(root, "Cargo.toml"))) {
35727
+ if (existsSync11(join10(root, "Cargo.toml"))) {
35647
35728
  p.languages.push("rust");
35648
35729
  p.stack.push("rust");
35649
35730
  }
@@ -35749,11 +35830,11 @@ var init_identity2 = __esm({
35749
35830
 
35750
35831
  // src/checkout-root.ts
35751
35832
  import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
35752
- import { basename as basename3, dirname as dirname7, isAbsolute as isAbsolute3, join as join10, resolve as resolve3 } from "node:path";
35833
+ import { basename as basename3, dirname as dirname7, isAbsolute as isAbsolute3, join as join11, resolve as resolve3 } from "node:path";
35753
35834
  function nearestGitRoot(dir) {
35754
35835
  let cur = resolve3(dir);
35755
35836
  for (; ; ) {
35756
- if (existsSync12(join10(cur, ".git"))) return cur;
35837
+ if (existsSync12(join11(cur, ".git"))) return cur;
35757
35838
  const parent = dirname7(cur);
35758
35839
  if (parent === cur) return null;
35759
35840
  cur = parent;
@@ -35761,8 +35842,8 @@ function nearestGitRoot(dir) {
35761
35842
  }
35762
35843
  function mainCheckoutOfWorktree(root) {
35763
35844
  const gitDir = resolveGitDir(root);
35764
- if (!gitDir || gitDir === join10(root, ".git")) return null;
35765
- const commondirFile = join10(gitDir, "commondir");
35845
+ if (!gitDir || gitDir === join11(root, ".git")) return null;
35846
+ const commondirFile = join11(gitDir, "commondir");
35766
35847
  if (!existsSync12(commondirFile)) return null;
35767
35848
  let common;
35768
35849
  try {
@@ -35773,7 +35854,7 @@ function mainCheckoutOfWorktree(root) {
35773
35854
  const commonDir = resolve3(isAbsolute3(common) ? common : resolve3(gitDir, common));
35774
35855
  if (basename3(commonDir) !== ".git") return null;
35775
35856
  const main2 = dirname7(commonDir);
35776
- return existsSync12(join10(main2, ".git")) ? main2 : null;
35857
+ return existsSync12(join11(main2, ".git")) ? main2 : null;
35777
35858
  }
35778
35859
  function checkoutRootOf(cwd) {
35779
35860
  const root = nearestGitRoot(cwd);
@@ -35791,7 +35872,7 @@ var init_checkout_root = __esm({
35791
35872
  });
35792
35873
 
35793
35874
  // src/process-identity.ts
35794
- import { execFileSync } from "node:child_process";
35875
+ import { execFileSync as execFileSync2 } from "node:child_process";
35795
35876
  import { readFileSync as readFileSync11 } from "node:fs";
35796
35877
  function readProcessIdentity(pid, fresh = false) {
35797
35878
  if (!Number.isSafeInteger(pid) || pid <= 0) return null;
@@ -35799,7 +35880,7 @@ function readProcessIdentity(pid, fresh = false) {
35799
35880
  const cached2 = recent.get(pid);
35800
35881
  if (!fresh && cached2 && Date.now() - cached2.at < 1e3) return cached2.value;
35801
35882
  try {
35802
- const run3 = (bin, args2) => execFileSync(bin, args2, {
35883
+ const run3 = (bin, args2) => execFileSync2(bin, args2, {
35803
35884
  encoding: "utf8",
35804
35885
  windowsHide: true,
35805
35886
  timeout: 3e3,
@@ -35968,9 +36049,9 @@ var init_lock = __esm({
35968
36049
 
35969
36050
  // src/registry.ts
35970
36051
  import { existsSync as existsSync14, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
35971
- import { join as join11 } from "node:path";
36052
+ import { join as join12 } from "node:path";
35972
36053
  function registryPath() {
35973
- return process.env["ERRATA_REGISTRY_PATH"] ?? join11(globalDir(), "workspaces.json");
36054
+ return process.env["ERRATA_REGISTRY_PATH"] ?? join12(globalDir(), "workspaces.json");
35974
36055
  }
35975
36056
  function read() {
35976
36057
  const p = registryPath();
@@ -37458,6 +37539,7 @@ function isQuotaError(err2) {
37458
37539
  async function dualAugment(opts) {
37459
37540
  const { store, cloud, localHits, seedNode, queryText, limit, generalizeSoft } = opts;
37460
37541
  const cloudHits = [];
37542
+ let completeResponse = true;
37461
37543
  let seedUsageCount;
37462
37544
  let seedProvenance = "local";
37463
37545
  const calls = [];
@@ -37484,6 +37566,7 @@ async function dualAugment(opts) {
37484
37566
  if (cloudSeeds.length > 0 || softQ) {
37485
37567
  calls.push(
37486
37568
  cloud.search({ stack: [], domains: [], kinds: [], seed: cloudSeeds, ...softQ ? { q: softQ } : {}, limit, community: true, via: true }).then((res) => {
37569
+ if (res.seeds?.some((seed) => seed.status === "error")) completeResponse = false;
37487
37570
  cloudHits.push(...searchResultToCloudHits(res));
37488
37571
  })
37489
37572
  );
@@ -37505,18 +37588,29 @@ async function dualAugment(opts) {
37505
37588
  }
37506
37589
  if (cloudHits.length === 0) return { status: "empty" };
37507
37590
  const deduped = dedupCloudHits(cloudHits);
37591
+ const merged = mergeDualBurst(localHits, deduped, {
37592
+ // A hit's `via` parent is resolved too, so an edge from a folded twin
37593
+ // can be re-pointed at the entity it folded into.
37594
+ twins: storeTwinIndex(store, deduped.flatMap((c) => {
37595
+ const parent = c.via?.parentId;
37596
+ return parent ? [c.id, parent] : [c.id];
37597
+ })),
37598
+ ...seedNode ? { seedId: seedNode.id } : {},
37599
+ ...opts.fuse ? { fuse: opts.fuse } : {}
37600
+ });
37601
+ if (completeResponse) {
37602
+ const candidates = new Set(deduped.filter((hit) => !isCodeLabel(hit.label)).map((hit) => hit.id));
37603
+ const localIds = /* @__PURE__ */ new Set([...localHits.map((hit) => hit.id), ...seedNode ? [seedNode.id] : []]);
37604
+ const emitted = [];
37605
+ for (const node2 of merged.nodes) {
37606
+ const ids = [...node2.provenance === "collective" ? [node2.id] : [], ...node2.twins ?? []];
37607
+ for (const id of ids) if (candidates.has(id) && !localIds.has(id)) emitted.push(id);
37608
+ }
37609
+ rememberCollectiveIds(cloud, emitted);
37610
+ }
37508
37611
  return {
37509
37612
  status: "merged",
37510
- merged: mergeDualBurst(localHits, deduped, {
37511
- // A hit's `via` parent is resolved too, so an edge from a folded twin
37512
- // can be re-pointed at the entity it folded into.
37513
- twins: storeTwinIndex(store, deduped.flatMap((c) => {
37514
- const parent = c.via?.parentId;
37515
- return parent ? [c.id, parent] : [c.id];
37516
- })),
37517
- ...seedNode ? { seedId: seedNode.id } : {},
37518
- ...opts.fuse ? { fuse: opts.fuse } : {}
37519
- }),
37613
+ merged,
37520
37614
  seedProvenance,
37521
37615
  seedUsageCount
37522
37616
  };
@@ -37534,6 +37628,38 @@ function federationHint(status) {
37534
37628
  function hasCloudNodeShape(id) {
37535
37629
  return CANONICAL_KNOWLEDGE_ID.test(id) || UUID_ID.test(id) || id.startsWith("pkg:");
37536
37630
  }
37631
+ function safeCollectiveId(id) {
37632
+ if (typeof id !== "string") return false;
37633
+ const separator = id.indexOf("_");
37634
+ return id.length > 0 && id.trim() === id && !/[\u0000-\u001f\u007f,]/.test(id) && !(separator > 0 && isCodeLabel(id.slice(0, separator)));
37635
+ }
37636
+ function rememberCollectiveIds(cloud, ids) {
37637
+ const now = Date.now();
37638
+ let remembered = returnedCollectiveIds.get(cloud);
37639
+ if (!remembered) {
37640
+ remembered = /* @__PURE__ */ new Map();
37641
+ returnedCollectiveIds.set(cloud, remembered);
37642
+ }
37643
+ for (const [id, expiresAt] of remembered) if (expiresAt <= now) remembered.delete(id);
37644
+ for (const id of ids) {
37645
+ if (!safeCollectiveId(id) || id.length > 160) continue;
37646
+ remembered.delete(id);
37647
+ remembered.set(id, now + COLLECTIVE_ID_TTL_MS);
37648
+ if (remembered.size > COLLECTIVE_ID_LIMIT) remembered.delete(remembered.keys().next().value);
37649
+ }
37650
+ }
37651
+ function canFollowCollectiveId(cloud, id) {
37652
+ if (!safeCollectiveId(id)) return false;
37653
+ if (hasCloudNodeShape(id)) return true;
37654
+ const remembered = returnedCollectiveIds.get(cloud);
37655
+ const expiresAt = remembered?.get(id);
37656
+ if (expiresAt === void 0) return false;
37657
+ if (expiresAt <= Date.now()) {
37658
+ remembered.delete(id);
37659
+ return false;
37660
+ }
37661
+ return true;
37662
+ }
37537
37663
  function attrsCommunity(attrs) {
37538
37664
  const id = attrs?.["community"];
37539
37665
  if (typeof id !== "number") return void 0;
@@ -37573,7 +37699,7 @@ async function collectiveDrilldown(cloud, seedId, limit, opts = {}) {
37573
37699
  if (resolution === "unresolved") return { status: "no-twin" };
37574
37700
  if (resolution === "error") return { status: "seed-error" };
37575
37701
  if (res.nodes.length === 0 && resolution !== "resolved") return { status: "no-twin" };
37576
- return {
37702
+ const resolved = {
37577
37703
  status: "resolved",
37578
37704
  neighborhood: {
37579
37705
  seed: seedId,
@@ -37600,6 +37726,10 @@ async function collectiveDrilldown(cloud, seedId, limit, opts = {}) {
37600
37726
  ...seedEntry?.bridges ? { bridges: seedEntry.bridges } : {}
37601
37727
  }
37602
37728
  };
37729
+ if (!res.seeds?.some((seed) => seed.status === "error")) {
37730
+ rememberCollectiveIds(cloud, resolved.neighborhood.nodes.filter((node2) => node2.id !== seedId && !isCodeLabel(node2.label)).map((node2) => node2.id));
37731
+ }
37732
+ return resolved;
37603
37733
  }
37604
37734
  async function collectiveNodeDetail(cloud, id) {
37605
37735
  const read2 = async (nodeId) => {
@@ -37676,7 +37806,7 @@ function formatDualNodes(merged) {
37676
37806
  ...n.uploaded ? { uploaded: true } : {}
37677
37807
  }));
37678
37808
  }
37679
- var BRIDGE_LABELS, CANONICAL_KNOWLEDGE_ID, UUID_ID;
37809
+ var BRIDGE_LABELS, CANONICAL_KNOWLEDGE_ID, UUID_ID, COLLECTIVE_ID_LIMIT, COLLECTIVE_ID_TTL_MS, returnedCollectiveIds;
37680
37810
  var init_dual_augment = __esm({
37681
37811
  "src/dual-augment.ts"() {
37682
37812
  "use strict";
@@ -37687,6 +37817,9 @@ var init_dual_augment = __esm({
37687
37817
  BRIDGE_LABELS = new Set(SEMANTIC_NODE_LABELS);
37688
37818
  CANONICAL_KNOWLEDGE_ID = /^[a-z][a-z0-9]*_[0-9a-f]{8,}$/;
37689
37819
  UUID_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
37820
+ COLLECTIVE_ID_LIMIT = 512;
37821
+ COLLECTIVE_ID_TTL_MS = 15 * 6e4;
37822
+ returnedCollectiveIds = /* @__PURE__ */ new WeakMap();
37690
37823
  }
37691
37824
  });
37692
37825
 
@@ -37736,17 +37869,17 @@ var init_daemon_generalize_client = __esm({
37736
37869
 
37737
37870
  // ../../packages/indexer/src/parse-cache.ts
37738
37871
  import { createHash as createHash6 } from "node:crypto";
37739
- import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
37872
+ import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync4, writeFileSync as writeFileSync11 } from "node:fs";
37740
37873
  import { homedir as homedir3 } from "node:os";
37741
- import { join as join12 } from "node:path";
37874
+ import { join as join13 } from "node:path";
37742
37875
  function parseCacheDir() {
37743
- return process.env["ERRATA_PARSE_CACHE"] ?? join12(homedir3(), ".errata", "parse-cache");
37876
+ return process.env["ERRATA_PARSE_CACHE"] ?? join13(homedir3(), ".errata", "parse-cache");
37744
37877
  }
37745
37878
  function parseCacheKey(source, providerId) {
37746
37879
  return createHash6("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
37747
37880
  }
37748
37881
  function entryPath(dir, key) {
37749
- return join12(dir, key.slice(0, 2), `${key.slice(2)}.json`);
37882
+ return join13(dir, key.slice(0, 2), `${key.slice(2)}.json`);
37750
37883
  }
37751
37884
  function readParseCache(dir, key) {
37752
37885
  const file2 = entryPath(dir, key);
@@ -37770,7 +37903,7 @@ function writeParseCache(dir, key, providerId, value) {
37770
37903
  const body2 = JSON.stringify(envelope);
37771
37904
  if (body2.length > MAX_ENTRY_BYTES) return;
37772
37905
  const file2 = entryPath(dir, key);
37773
- mkdirSync6(join12(dir, key.slice(0, 2)), { recursive: true });
37906
+ mkdirSync6(join13(dir, key.slice(0, 2)), { recursive: true });
37774
37907
  writeFileSync11(file2, body2);
37775
37908
  } catch {
37776
37909
  }
@@ -37782,7 +37915,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
37782
37915
  try {
37783
37916
  if (!existsSync15(dir)) return 0;
37784
37917
  for (const bucket of readdirSync2(dir)) {
37785
- const bucketDir = join12(dir, bucket);
37918
+ const bucketDir = join13(dir, bucket);
37786
37919
  let names;
37787
37920
  try {
37788
37921
  names = readdirSync2(bucketDir);
@@ -37790,9 +37923,9 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
37790
37923
  continue;
37791
37924
  }
37792
37925
  for (const name2 of names) {
37793
- const file2 = join12(bucketDir, name2);
37926
+ const file2 = join13(bucketDir, name2);
37794
37927
  try {
37795
- if (now - statSync3(file2).mtimeMs > ENTRY_TTL_MS) {
37928
+ if (now - statSync4(file2).mtimeMs > ENTRY_TTL_MS) {
37796
37929
  rmSync2(file2, { force: true });
37797
37930
  removed++;
37798
37931
  }
@@ -38038,11 +38171,11 @@ var init_identity3 = __esm({
38038
38171
  });
38039
38172
 
38040
38173
  // ../../packages/indexer/src/pipeline.ts
38041
- import { appendFileSync, readFileSync as readFileSync15, statSync as statSync4 } from "node:fs";
38174
+ import { appendFileSync, readFileSync as readFileSync15, statSync as statSync5 } from "node:fs";
38042
38175
  import { readdir } from "node:fs/promises";
38043
- import { extname, join as join13, relative as relative2, sep } from "node:path";
38176
+ import { extname, join as join14, relative as relative2, sep } from "node:path";
38044
38177
  import { createHash as createHash7 } from "node:crypto";
38045
- import { execFileSync as execFileSync2 } from "node:child_process";
38178
+ import { execFileSync as execFileSync3 } from "node:child_process";
38046
38179
  function nowTs() {
38047
38180
  return indexNow ?? Date.now();
38048
38181
  }
@@ -38179,7 +38312,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
38179
38312
  for (const rel of [...changedRelPaths]) {
38180
38313
  let h;
38181
38314
  try {
38182
- h = createHash7("sha256").update(readFileSync15(join13(rootPath, rel))).digest("hex");
38315
+ h = createHash7("sha256").update(readFileSync15(join14(rootPath, rel))).digest("hex");
38183
38316
  } catch {
38184
38317
  continue;
38185
38318
  }
@@ -38228,7 +38361,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
38228
38361
  let parsedFiles = 0;
38229
38362
  for (const rel of changedRelPaths) {
38230
38363
  if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
38231
- const abs = join13(rootPath, ...rel.split("/"));
38364
+ const abs = join14(rootPath, ...rel.split("/"));
38232
38365
  const ext = extname(abs).toLowerCase();
38233
38366
  const provider = providers.find((p) => p.fileExtensions.includes(ext));
38234
38367
  if (!provider) continue;
@@ -38551,7 +38684,7 @@ async function runIndexer(store, opts) {
38551
38684
  }
38552
38685
  let source;
38553
38686
  try {
38554
- const st = statSync4(f.absPath);
38687
+ const st = statSync5(f.absPath);
38555
38688
  if (st.size > maxBytes) {
38556
38689
  report.filesSkipped++;
38557
38690
  continue;
@@ -39016,7 +39149,7 @@ async function scan(root, current, ignores, providers, out2) {
39016
39149
  for (const ent of entries) {
39017
39150
  if (ignores.has(ent.name)) continue;
39018
39151
  if (ent.name.startsWith(".") && ent.name !== ".") continue;
39019
- const abs = join13(current, ent.name);
39152
+ const abs = join14(current, ent.name);
39020
39153
  if (ent.isDirectory()) {
39021
39154
  await scan(root, abs, ignores, providers, out2);
39022
39155
  } else if (ent.isFile()) {
@@ -39026,7 +39159,7 @@ async function scan(root, current, ignores, providers, out2) {
39026
39159
  let size = 0;
39027
39160
  let mtimeMs;
39028
39161
  try {
39029
- const st = statSync4(abs);
39162
+ const st = statSync5(abs);
39030
39163
  size = st.size;
39031
39164
  mtimeMs = st.mtimeMs;
39032
39165
  } catch {
@@ -39046,7 +39179,7 @@ async function scan(root, current, ignores, providers, out2) {
39046
39179
  function gitListRelPaths(root, ignores) {
39047
39180
  let stdout;
39048
39181
  try {
39049
- stdout = execFileSync2(
39182
+ stdout = execFileSync3(
39050
39183
  "git",
39051
39184
  ["-C", root, "ls-files", "--cached", "--others", "--exclude-standard", "-z"],
39052
39185
  {
@@ -39075,11 +39208,11 @@ function gitListFiles(root, ignores, providers) {
39075
39208
  if (rels === null) return null;
39076
39209
  const out2 = [];
39077
39210
  for (const rel of rels) {
39078
- const abs = join13(root, rel);
39211
+ const abs = join14(root, rel);
39079
39212
  let size;
39080
39213
  let mtimeMs;
39081
39214
  try {
39082
- const st = statSync4(abs);
39215
+ const st = statSync5(abs);
39083
39216
  size = st.size;
39084
39217
  mtimeMs = st.mtimeMs;
39085
39218
  } catch {
@@ -43487,7 +43620,7 @@ ${JSON.stringify(symbolNames, null, 2)}`);
43487
43620
 
43488
43621
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
43489
43622
  import { fileURLToPath } from "node:url";
43490
- import { dirname as dirname8, join as join14 } from "node:path";
43623
+ import { dirname as dirname8, join as join15 } from "node:path";
43491
43624
  import { existsSync as existsSync16, readdirSync as readdirSync3 } from "node:fs";
43492
43625
  import { createRequire as createRequire2 } from "node:module";
43493
43626
  function entryDir() {
@@ -43502,27 +43635,27 @@ function entryDir() {
43502
43635
  }
43503
43636
  function findWasmDir() {
43504
43637
  const here = entryDir();
43505
- const seaWasm = join14(here, "resources", "wasm");
43506
- if (existsSync16(join14(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
43638
+ const seaWasm = join15(here, "resources", "wasm");
43639
+ if (existsSync16(join15(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
43507
43640
  let dir = here;
43508
43641
  for (let i2 = 0; i2 < 6; i2++) {
43509
- const flat = join14(
43642
+ const flat = join15(
43510
43643
  dir,
43511
43644
  "node_modules",
43512
43645
  "@vscode",
43513
43646
  "tree-sitter-wasm",
43514
43647
  "wasm"
43515
43648
  );
43516
- if (existsSync16(join14(flat, "tree-sitter-typescript.wasm"))) return flat;
43649
+ if (existsSync16(join15(flat, "tree-sitter-typescript.wasm"))) return flat;
43517
43650
  dir = dirname8(dir);
43518
43651
  }
43519
43652
  let root = here;
43520
43653
  for (let i2 = 0; i2 < 6; i2++) {
43521
- const pnpmDir = join14(root, "node_modules", ".pnpm");
43654
+ const pnpmDir = join15(root, "node_modules", ".pnpm");
43522
43655
  if (existsSync16(pnpmDir)) {
43523
43656
  for (const entry of readdirSync3(pnpmDir)) {
43524
43657
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
43525
- const candidate = join14(
43658
+ const candidate = join15(
43526
43659
  pnpmDir,
43527
43660
  entry,
43528
43661
  "node_modules",
@@ -43530,7 +43663,7 @@ function findWasmDir() {
43530
43663
  "tree-sitter-wasm",
43531
43664
  "wasm"
43532
43665
  );
43533
- if (existsSync16(join14(candidate, "tree-sitter-typescript.wasm"))) {
43666
+ if (existsSync16(join15(candidate, "tree-sitter-typescript.wasm"))) {
43534
43667
  return candidate;
43535
43668
  }
43536
43669
  }
@@ -43544,27 +43677,27 @@ function findWasmDir() {
43544
43677
  }
43545
43678
  function findRuntimeDir() {
43546
43679
  const here = entryDir();
43547
- const seaRuntime = join14(here, "resources", "wasm");
43548
- if (existsSync16(join14(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
43680
+ const seaRuntime = join15(here, "resources", "wasm");
43681
+ if (existsSync16(join15(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
43549
43682
  let dir = here;
43550
43683
  for (let i2 = 0; i2 < 6; i2++) {
43551
- const flat = join14(dir, "node_modules", "web-tree-sitter");
43552
- if (existsSync16(join14(flat, "web-tree-sitter.wasm"))) return flat;
43684
+ const flat = join15(dir, "node_modules", "web-tree-sitter");
43685
+ if (existsSync16(join15(flat, "web-tree-sitter.wasm"))) return flat;
43553
43686
  dir = dirname8(dir);
43554
43687
  }
43555
43688
  let root = here;
43556
43689
  for (let i2 = 0; i2 < 6; i2++) {
43557
- const pnpmDir = join14(root, "node_modules", ".pnpm");
43690
+ const pnpmDir = join15(root, "node_modules", ".pnpm");
43558
43691
  if (existsSync16(pnpmDir)) {
43559
43692
  for (const entry of readdirSync3(pnpmDir)) {
43560
43693
  if (entry.startsWith("web-tree-sitter@")) {
43561
- const candidate = join14(
43694
+ const candidate = join15(
43562
43695
  pnpmDir,
43563
43696
  entry,
43564
43697
  "node_modules",
43565
43698
  "web-tree-sitter"
43566
43699
  );
43567
- if (existsSync16(join14(candidate, "web-tree-sitter.wasm"))) {
43700
+ if (existsSync16(join15(candidate, "web-tree-sitter.wasm"))) {
43568
43701
  return candidate;
43569
43702
  }
43570
43703
  }
@@ -43581,7 +43714,7 @@ async function loadWebTreeSitter() {
43581
43714
  void err2;
43582
43715
  }
43583
43716
  const here = entryDir();
43584
- const seaResourceBase = join14(here, "resources", "_resolve.js");
43717
+ const seaResourceBase = join15(here, "resources", "_resolve.js");
43585
43718
  const resourceRequire = createRequire2(seaResourceBase);
43586
43719
  return resourceRequire("web-tree-sitter");
43587
43720
  }
@@ -43596,9 +43729,9 @@ async function ensureTreeSitterReady() {
43596
43729
  await Parser2.init({
43597
43730
  locateFile: (name2) => {
43598
43731
  if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
43599
- return join14(runtime, name2);
43732
+ return join15(runtime, name2);
43600
43733
  }
43601
- return join14(grammars, name2);
43734
+ return join15(grammars, name2);
43602
43735
  }
43603
43736
  });
43604
43737
  })();
@@ -43610,7 +43743,7 @@ async function loadGrammar(name2) {
43610
43743
  if (cached2) return cached2;
43611
43744
  if (!languageClass) throw new Error("tree-sitter not initialized");
43612
43745
  const grammars = findWasmDir();
43613
- const lang = await languageClass.load(join14(grammars, `${name2}.wasm`));
43746
+ const lang = await languageClass.load(join15(grammars, `${name2}.wasm`));
43614
43747
  grammarCache.set(name2, lang);
43615
43748
  return lang;
43616
43749
  }
@@ -46513,9 +46646,9 @@ var init_src11 = __esm({
46513
46646
  });
46514
46647
 
46515
46648
  // src/reconcile.ts
46516
- import { execFileSync as execFileSync3 } from "node:child_process";
46517
- import { readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
46518
- import { join as join15, relative as relative3, sep as sep2 } from "node:path";
46649
+ import { execFileSync as execFileSync4 } from "node:child_process";
46650
+ import { readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
46651
+ import { join as join16, relative as relative3, sep as sep2 } from "node:path";
46519
46652
  function indexerWouldScan(rel) {
46520
46653
  for (const seg of rel.split(/[\\/]/)) {
46521
46654
  if (seg.length === 0) continue;
@@ -46527,7 +46660,7 @@ function indexerWouldScan(rel) {
46527
46660
  function gitSourceFiles(root) {
46528
46661
  let stdout;
46529
46662
  try {
46530
- stdout = execFileSync3(
46663
+ stdout = execFileSync4(
46531
46664
  "git",
46532
46665
  ["-C", root, "ls-files", "--cached", "--others", "--exclude-standard", "-z"],
46533
46666
  { encoding: "utf8", maxBuffer: 128 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
@@ -46538,7 +46671,7 @@ function gitSourceFiles(root) {
46538
46671
  const out2 = [];
46539
46672
  for (const rel of stdout.split("\0")) {
46540
46673
  if (!rel || !SOURCE_RE.test(rel) || !indexerWouldScan(rel)) continue;
46541
- const abs = join15(root, rel);
46674
+ const abs = join16(root, rel);
46542
46675
  if (IGNORED.test(abs)) continue;
46543
46676
  out2.push(abs);
46544
46677
  }
@@ -46553,7 +46686,7 @@ function* walkSource(dir) {
46553
46686
  }
46554
46687
  for (const e of entries) {
46555
46688
  const name2 = String(e.name);
46556
- const full = join15(dir, name2);
46689
+ const full = join16(dir, name2);
46557
46690
  if (IGNORED.test(full)) continue;
46558
46691
  if (!indexerWouldScan(name2)) continue;
46559
46692
  if (e.isDirectory()) yield* walkSource(full);
@@ -46578,7 +46711,7 @@ async function findStaleFiles(store, rootPath, workspaceId2) {
46578
46711
  for (const abs of listSourceFiles(rootPath)) {
46579
46712
  try {
46580
46713
  const rel = relative3(rootPath, abs).split(sep2).join("/");
46581
- pending.push({ abs, id: fileNodeId(workspaceId2, rel), mtimeMs: statSync5(abs).mtimeMs });
46714
+ pending.push({ abs, id: fileNodeId(workspaceId2, rel), mtimeMs: statSync6(abs).mtimeMs });
46582
46715
  } catch {
46583
46716
  }
46584
46717
  if (++scanned % SCAN_YIELD_EVERY === 0) {
@@ -47083,7 +47216,7 @@ function cosine3(a, b) {
47083
47216
  }
47084
47217
  async function collectiveSeedFallback(args2, ctx, defaultLimit, opts = {}) {
47085
47218
  const seedId = typeof args2["nodeId"] === "string" ? args2["nodeId"] : null;
47086
- if (!seedId || !ctx.cloud || !hasCloudNodeShape(seedId)) return null;
47219
+ if (!seedId || !ctx.cloud || !canFollowCollectiveId(ctx.cloud, seedId)) return null;
47087
47220
  const limit = Math.max(1, Math.min(100, Number(args2["limit"] ?? defaultLimit)));
47088
47221
  const scope = args2["scope"];
47089
47222
  return collectiveDrilldown(ctx.cloud, seedId, limit, {
@@ -48177,7 +48310,7 @@ var init_mcp = __esm({
48177
48310
  const id = resolveSymbol2(store, args2);
48178
48311
  if (!id) {
48179
48312
  const seedId = typeof args2["nodeId"] === "string" ? args2["nodeId"] : null;
48180
- if (!seedId || !ctx.cloud || !hasCloudNodeShape(seedId)) return unresolved(args2);
48313
+ if (!seedId || !ctx.cloud || !canFollowCollectiveId(ctx.cloud, seedId)) return unresolved(args2);
48181
48314
  const shown = await collectiveNodeDetail(ctx.cloud, seedId);
48182
48315
  if (shown.status !== "found") return collectiveSeedMiss(args2, shown);
48183
48316
  return {
@@ -48887,7 +49020,7 @@ __export(vfile_exports, {
48887
49020
  segmentsOf: () => segmentsOf
48888
49021
  });
48889
49022
  import { writeFileSync as writeFileSync12 } from "node:fs";
48890
- import { join as join16, resolve as resolve5, sep as sep3 } from "node:path";
49023
+ import { join as join17, resolve as resolve5, sep as sep3 } from "node:path";
48891
49024
  function segmentsOf(rawPath) {
48892
49025
  let p = rawPath.replace(/\\/g, "/");
48893
49026
  p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
@@ -48961,7 +49094,7 @@ async function renderVFile(rawPath, store, ctx = {}) {
48961
49094
  }
48962
49095
  async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
48963
49096
  const segs = segmentsOf(rawPath);
48964
- const gRoot = join16(workspaceRoot, ".errata", "g");
49097
+ const gRoot = join17(workspaceRoot, ".errata", "g");
48965
49098
  const abs = resolve5(gRoot, ...segs.length ? segs : ["index"]);
48966
49099
  if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
48967
49100
  throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
@@ -56395,12 +56528,12 @@ import {
56395
56528
  unlinkSync as unlinkSync3,
56396
56529
  writeFileSync as writeFileSync13
56397
56530
  } from "node:fs";
56398
- import { join as join17 } from "node:path";
56531
+ import { join as join18 } from "node:path";
56399
56532
  import { createHash as createHash15 } from "node:crypto";
56400
56533
  function enqueueOutbox(paths, payload) {
56401
56534
  ensureDir(paths.outbox);
56402
56535
  const id = createHash15("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
56403
- const file2 = join17(paths.outbox, `${Date.now()}-${id}.json`);
56536
+ const file2 = join18(paths.outbox, `${Date.now()}-${id}.json`);
56404
56537
  writeFileSync13(file2, JSON.stringify(payload, null, 2), "utf8");
56405
56538
  return file2;
56406
56539
  }
@@ -56417,7 +56550,7 @@ async function flushOutbox(paths, client, store) {
56417
56550
  }
56418
56551
  };
56419
56552
  for (const f of entries.filter((e) => e.endsWith(".json")).sort()) {
56420
- const abs = join17(paths.outbox, f);
56553
+ const abs = join18(paths.outbox, f);
56421
56554
  let payload;
56422
56555
  try {
56423
56556
  payload = JSON.parse(readFileSync17(abs, "utf8"));
@@ -76302,9 +76435,9 @@ __export(witness_ledger_exports, {
76302
76435
  witnessLedgerPath: () => witnessLedgerPath
76303
76436
  });
76304
76437
  import { appendFileSync as appendFileSync3, existsSync as existsSync27, readFileSync as readFileSync30, writeFileSync as writeFileSync21 } from "node:fs";
76305
- import { join as join33 } from "node:path";
76438
+ import { join as join34 } from "node:path";
76306
76439
  function witnessLedgerPath(configDir) {
76307
- return join33(configDir, "witness-ledger.jsonl");
76440
+ return join34(configDir, "witness-ledger.jsonl");
76308
76441
  }
76309
76442
  function appendWitnessLedger(configDir, entry) {
76310
76443
  const path3 = witnessLedgerPath(configDir);
@@ -76760,8 +76893,8 @@ var init_report_render = __esm({
76760
76893
 
76761
76894
  // src/cli.ts
76762
76895
  init_src6();
76763
- import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync44, renameSync as renameSync9, statSync as statSync13 } from "node:fs";
76764
- import { join as join51, resolve as pathResolve2 } from "node:path";
76896
+ import { closeSync as closeSync3, existsSync as existsSync40, openSync as openSync3, readFileSync as readFileSync45, renameSync as renameSync9, statSync as statSync15 } from "node:fs";
76897
+ import { join as join53, resolve as pathResolve2 } from "node:path";
76765
76898
  import { spawn as spawn5 } from "node:child_process";
76766
76899
 
76767
76900
  // src/daemon.ts
@@ -77448,9 +77581,9 @@ function knowledgeTag(label, attrs) {
77448
77581
  }
77449
77582
 
77450
77583
  // src/engine.ts
77451
- import { execFileSync as execFileSync5 } from "node:child_process";
77452
- import { existsSync as existsSync28, statSync as statSync9, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
77453
- import { basename as basename8, join as join35, relative as relative7, sep as sep4 } from "node:path";
77584
+ import { execFileSync as execFileSync6 } from "node:child_process";
77585
+ import { existsSync as existsSync28, statSync as statSync10, appendFileSync as appendFileSync4, readdirSync as readdirSync11, renameSync as renameSync4, readFileSync as readFileSync32, writeFileSync as writeFileSync23 } from "node:fs";
77586
+ import { basename as basename8, join as join36, relative as relative7, sep as sep4 } from "node:path";
77454
77587
 
77455
77588
  // src/coalesced-file-pass.ts
77456
77589
  function createCoalescedFilePass(delayMs, run3, onError) {
@@ -77494,8 +77627,8 @@ function createCoalescedFilePass(delayMs, run3, onError) {
77494
77627
 
77495
77628
  // src/source-watcher.ts
77496
77629
  import { EventEmitter as EventEmitter2 } from "node:events";
77497
- import { readdirSync as readdirSync6, statSync as statSync6, watch as watch2 } from "node:fs";
77498
- import { isAbsolute as isAbsolute5, join as join20, relative as relative6 } from "node:path";
77630
+ import { readdirSync as readdirSync6, statSync as statSync7, watch as watch2 } from "node:fs";
77631
+ import { isAbsolute as isAbsolute5, join as join21, relative as relative6 } from "node:path";
77499
77632
 
77500
77633
  // ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
77501
77634
  import { stat as statcb } from "fs";
@@ -79223,13 +79356,13 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79223
79356
  if (this.closed || this.handles.has(target)) return;
79224
79357
  let isDir;
79225
79358
  try {
79226
- isDir = statSync6(target).isDirectory();
79359
+ isDir = statSync7(target).isDirectory();
79227
79360
  } catch {
79228
79361
  return;
79229
79362
  }
79230
79363
  try {
79231
79364
  const h = watch2(target, { recursive: isDir, persistent: true }, (event, name2) => {
79232
- const path3 = isDir ? name2 ? join20(target, name2.toString()) : null : target;
79365
+ const path3 = isDir ? name2 ? join21(target, name2.toString()) : null : target;
79233
79366
  if (!path3) {
79234
79367
  this.emit("raw", event, target, { watchedPath: target, filenameMissing: true });
79235
79368
  this.scheduleReconcile(target, isDir);
@@ -79282,7 +79415,7 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79282
79415
  try {
79283
79416
  for (const entry of readdirSync6(target, { recursive: true, withFileTypes: true })) {
79284
79417
  if (!entry.isFile()) continue;
79285
- const path3 = join20(entry.parentPath, entry.name);
79418
+ const path3 = join21(entry.parentPath, entry.name);
79286
79419
  if (!this.ignored(path3)) files.add(path3);
79287
79420
  }
79288
79421
  } catch {
@@ -79319,7 +79452,7 @@ var NativeSourceWatcher = class extends EventEmitter2 {
79319
79452
  if (this.closed) return;
79320
79453
  let isFile;
79321
79454
  try {
79322
- const s = statSync6(path3);
79455
+ const s = statSync7(path3);
79323
79456
  if (s.isDirectory()) return;
79324
79457
  isFile = s.isFile();
79325
79458
  } catch {
@@ -79774,8 +79907,8 @@ init_review2();
79774
79907
 
79775
79908
  // src/turn.ts
79776
79909
  init_checkout_root();
79777
- import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync7 } from "node:fs";
79778
- import { basename as basename6, delimiter, dirname as dirname11, join as join21, normalize as normalize3 } from "node:path";
79910
+ import { closeSync as closeSync2, existsSync as existsSync19, fstatSync, openSync as openSync2, readdirSync as readdirSync7, readSync as readSync2, realpathSync as realpathSync2, statSync as statSync8 } from "node:fs";
79911
+ import { basename as basename6, delimiter, dirname as dirname11, join as join22, normalize as normalize3 } from "node:path";
79779
79912
  import { homedir as homedir4 } from "node:os";
79780
79913
  import { createHash as createHash16 } from "node:crypto";
79781
79914
  function completeJsonlPrefix(buf) {
@@ -80163,7 +80296,7 @@ function turnsSince(turns, mark) {
80163
80296
  return at >= 0 ? turns.slice(at + 1) : turns;
80164
80297
  }
80165
80298
  function claudeProjectDir(cwd, home = homedir4()) {
80166
- return join21(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
80299
+ return join22(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
80167
80300
  }
80168
80301
  function recentTranscripts(cwd, opts = {}) {
80169
80302
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
@@ -80178,10 +80311,10 @@ function recentTranscripts(cwd, opts = {}) {
80178
80311
  const refs = [];
80179
80312
  for (const name2 of names) {
80180
80313
  if (!name2.endsWith(".jsonl")) continue;
80181
- const path3 = join21(dir, name2);
80314
+ const path3 = join22(dir, name2);
80182
80315
  let mtimeMs;
80183
80316
  try {
80184
- mtimeMs = statSync7(path3).mtimeMs;
80317
+ mtimeMs = statSync8(path3).mtimeMs;
80185
80318
  } catch {
80186
80319
  continue;
80187
80320
  }
@@ -80193,7 +80326,7 @@ function recentTranscripts(cwd, opts = {}) {
80193
80326
  }
80194
80327
  function subagentTranscripts(mainTranscriptPath, sessionId) {
80195
80328
  if (!mainTranscriptPath || !sessionId) return [];
80196
- const dir = join21(dirname11(mainTranscriptPath), sessionId, "subagents");
80329
+ const dir = join22(dirname11(mainTranscriptPath), sessionId, "subagents");
80197
80330
  if (!existsSync19(dir)) return [];
80198
80331
  let names;
80199
80332
  try {
@@ -80204,10 +80337,10 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
80204
80337
  const refs = [];
80205
80338
  for (const name2 of names) {
80206
80339
  if (!name2.endsWith(".jsonl")) continue;
80207
- const path3 = join21(dir, name2);
80340
+ const path3 = join22(dir, name2);
80208
80341
  let mtimeMs;
80209
80342
  try {
80210
- mtimeMs = statSync7(path3).mtimeMs;
80343
+ mtimeMs = statSync8(path3).mtimeMs;
80211
80344
  } catch {
80212
80345
  continue;
80213
80346
  }
@@ -80223,8 +80356,8 @@ function splitPathList(value, sep6 = delimiter) {
80223
80356
  function codexSessionRoots(env2 = process.env, home = homedir4()) {
80224
80357
  const roots = /* @__PURE__ */ new Set();
80225
80358
  for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
80226
- if (env2["CODEX_HOME"]) roots.add(join21(env2["CODEX_HOME"], "sessions"));
80227
- roots.add(join21(home, ".codex", "sessions"));
80359
+ if (env2["CODEX_HOME"]) roots.add(join22(env2["CODEX_HOME"], "sessions"));
80360
+ roots.add(join22(home, ".codex", "sessions"));
80228
80361
  return [...roots];
80229
80362
  }
80230
80363
  function readCodexRolloutIdentity(path3) {
@@ -80296,10 +80429,10 @@ function codexRolloutsForCwd(cwd, opts = {}) {
80296
80429
  continue;
80297
80430
  }
80298
80431
  for (const name2 of names) {
80299
- const full = join21(dir, name2);
80432
+ const full = join22(dir, name2);
80300
80433
  let st;
80301
80434
  try {
80302
- st = statSync7(full);
80435
+ st = statSync8(full);
80303
80436
  } catch {
80304
80437
  continue;
80305
80438
  }
@@ -80338,8 +80471,8 @@ function codexRolloutsForCwd(cwd, opts = {}) {
80338
80471
  function geminiSessionRoots(env2 = process.env, home = homedir4()) {
80339
80472
  const roots = /* @__PURE__ */ new Set();
80340
80473
  for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
80341
- if (env2["GEMINI_CLI_HOME"]) roots.add(join21(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
80342
- roots.add(join21(home, ".gemini", "tmp"));
80474
+ if (env2["GEMINI_CLI_HOME"]) roots.add(join22(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
80475
+ roots.add(join22(home, ".gemini", "tmp"));
80343
80476
  return [...roots];
80344
80477
  }
80345
80478
  function geminiProjectHash(cwd) {
@@ -80387,7 +80520,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80387
80520
  continue;
80388
80521
  }
80389
80522
  for (const slug2 of slugs) {
80390
- const chats = join21(root, slug2, "chats");
80523
+ const chats = join22(root, slug2, "chats");
80391
80524
  let names;
80392
80525
  try {
80393
80526
  names = readdirSync7(chats);
@@ -80396,10 +80529,10 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80396
80529
  }
80397
80530
  for (const name2 of names) {
80398
80531
  if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
80399
- const full = join21(chats, name2);
80532
+ const full = join22(chats, name2);
80400
80533
  let st;
80401
80534
  try {
80402
- st = statSync7(full);
80535
+ st = statSync8(full);
80403
80536
  } catch {
80404
80537
  continue;
80405
80538
  }
@@ -80416,8 +80549,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
80416
80549
  function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
80417
80550
  const roots = /* @__PURE__ */ new Set();
80418
80551
  for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
80419
- if (env2["XDG_DATA_HOME"]) roots.add(join21(env2["XDG_DATA_HOME"], "opencode", "errata"));
80420
- roots.add(join21(home, ".local", "share", "opencode", "errata"));
80552
+ if (env2["XDG_DATA_HOME"]) roots.add(join22(env2["XDG_DATA_HOME"], "opencode", "errata"));
80553
+ roots.add(join22(home, ".local", "share", "opencode", "errata"));
80421
80554
  return [...roots];
80422
80555
  }
80423
80556
  function readOpencodeTranscriptDirectory(path3) {
@@ -80459,10 +80592,10 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
80459
80592
  }
80460
80593
  for (const name2 of names) {
80461
80594
  if (!name2.endsWith(".jsonl")) continue;
80462
- const full = join21(root, name2);
80595
+ const full = join22(root, name2);
80463
80596
  let st;
80464
80597
  try {
80465
- st = statSync7(full);
80598
+ st = statSync8(full);
80466
80599
  } catch {
80467
80600
  continue;
80468
80601
  }
@@ -81778,7 +81911,7 @@ ${conversation}` }]
81778
81911
  init_src5();
81779
81912
  init_src2();
81780
81913
  import { existsSync as existsSync20, readFileSync as readFileSync19, readdirSync as readdirSync8, writeFileSync as writeFileSync15 } from "node:fs";
81781
- import { join as join22 } from "node:path";
81914
+ import { join as join23 } from "node:path";
81782
81915
  import { homedir as homedir5 } from "node:os";
81783
81916
  var BACKFILL_VERSION = 1;
81784
81917
  var EMPTY = {
@@ -81792,7 +81925,7 @@ var EMPTY = {
81792
81925
  recoverable: 0
81793
81926
  };
81794
81927
  function markerPath(configDir) {
81795
- return join22(configDir, "constraint-backfill.json");
81928
+ return join23(configDir, "constraint-backfill.json");
81796
81929
  }
81797
81930
  function alreadyDone(configDir) {
81798
81931
  const p = markerPath(configDir);
@@ -81818,7 +81951,7 @@ function replay(root) {
81818
81951
  for (const f of names) {
81819
81952
  let lines;
81820
81953
  try {
81821
- lines = readFileSync19(join22(dir, f), "utf8").split("\n");
81954
+ lines = readFileSync19(join23(dir, f), "utf8").split("\n");
81822
81955
  } catch {
81823
81956
  continue;
81824
81957
  }
@@ -81946,7 +82079,7 @@ function backfillConstraintKind(store, opts) {
81946
82079
  init_src();
81947
82080
  init_src5();
81948
82081
  import { existsSync as existsSync21, readFileSync as readFileSync20, writeFileSync as writeFileSync16 } from "node:fs";
81949
- import { join as join23 } from "node:path";
82082
+ import { join as join24 } from "node:path";
81950
82083
  function citeEdgeId(from, type, to) {
81951
82084
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
81952
82085
  }
@@ -81961,7 +82094,7 @@ var EMPTY2 = {
81961
82094
  byType: {}
81962
82095
  };
81963
82096
  function markerPath2(configDir) {
81964
- return join23(configDir, "edge-repair.json");
82097
+ return join24(configDir, "edge-repair.json");
81965
82098
  }
81966
82099
  function alreadyDone2(configDir) {
81967
82100
  const p = markerPath2(configDir);
@@ -82031,7 +82164,7 @@ init_reconcile();
82031
82164
 
82032
82165
  // src/pass-ledger.ts
82033
82166
  import { appendFileSync as appendFileSync2, existsSync as existsSync22, readFileSync as readFileSync21, writeFileSync as writeFileSync17 } from "node:fs";
82034
- import { join as join24 } from "node:path";
82167
+ import { join as join25 } from "node:path";
82035
82168
 
82036
82169
  // src/isolate-census.ts
82037
82170
  var live2 = 0;
@@ -82057,7 +82190,7 @@ var HOUR_MS = 36e5;
82057
82190
  var TRIM_EVERY = 50;
82058
82191
  var appendsSinceTrim = /* @__PURE__ */ new Map();
82059
82192
  function passLedgerPath(configDir) {
82060
- return join24(configDir, "pass-ledger.jsonl");
82193
+ return join25(configDir, "pass-ledger.jsonl");
82061
82194
  }
82062
82195
  function appendPassLedger(configDir, kind, durationMs, counts) {
82063
82196
  const path3 = passLedgerPath(configDir);
@@ -82535,10 +82668,10 @@ init_src10();
82535
82668
  init_src();
82536
82669
  init_src2();
82537
82670
  import { readFileSync as readFileSync22 } from "node:fs";
82538
- import { join as join25 } from "node:path";
82671
+ import { join as join26 } from "node:path";
82539
82672
  function loadClaimIgnorePatterns(workspaceRoot) {
82540
82673
  try {
82541
- return readFileSync22(join25(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
82674
+ return readFileSync22(join26(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
82542
82675
  } catch {
82543
82676
  return [];
82544
82677
  }
@@ -82920,10 +83053,10 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
82920
83053
 
82921
83054
  // src/retrieval-stack.ts
82922
83055
  init_src();
82923
- import { execFileSync as execFileSync4 } from "node:child_process";
82924
- import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync8 } from "node:fs";
83056
+ import { execFileSync as execFileSync5 } from "node:child_process";
83057
+ import { existsSync as existsSync23, readFileSync as readFileSync23, statSync as statSync9 } from "node:fs";
82925
83058
  import { homedir as homedir6 } from "node:os";
82926
- import { join as join26 } from "node:path";
83059
+ import { join as join27 } from "node:path";
82927
83060
  var RETRIEVAL_STACK_CAP = 24;
82928
83061
  var MANIFEST_SCAN_CAP = 400;
82929
83062
  var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
@@ -83220,44 +83353,44 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
83220
83353
  };
83221
83354
  const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
83222
83355
  const home = homedir6();
83223
- const npm = parseNpmrcPolicy(texts(join26(root, ".npmrc"), join26(home, ".npmrc")));
83356
+ const npm = parseNpmrcPolicy(texts(join27(root, ".npmrc"), join27(home, ".npmrc")));
83224
83357
  const blocked = /* @__PURE__ */ new Set();
83225
83358
  if (!npm.defaultPublic) blocked.add("npm");
83226
83359
  if (pypiIndexIsPrivate(
83227
83360
  texts(
83228
- join26(root, "pip.conf"),
83229
- join26(root, "pip.ini"),
83230
- join26(root, "pyproject.toml"),
83231
- join26(root, "requirements.txt"),
83232
- join26(home, ".pip", "pip.conf"),
83233
- join26(home, ".config", "pip", "pip.conf"),
83234
- join26(env2["APPDATA"] ?? home, "pip", "pip.ini")
83361
+ join27(root, "pip.conf"),
83362
+ join27(root, "pip.ini"),
83363
+ join27(root, "pyproject.toml"),
83364
+ join27(root, "requirements.txt"),
83365
+ join27(home, ".pip", "pip.conf"),
83366
+ join27(home, ".config", "pip", "pip.conf"),
83367
+ join27(env2["APPDATA"] ?? home, "pip", "pip.ini")
83235
83368
  )
83236
83369
  )) {
83237
83370
  blocked.add("pypi");
83238
83371
  }
83239
83372
  if (cargoRegistryIsPrivate(
83240
83373
  texts(
83241
- join26(root, ".cargo", "config.toml"),
83242
- join26(root, ".cargo", "config"),
83243
- join26(home, ".cargo", "config.toml"),
83244
- join26(home, ".cargo", "config")
83374
+ join27(root, ".cargo", "config.toml"),
83375
+ join27(root, ".cargo", "config"),
83376
+ join27(home, ".cargo", "config.toml"),
83377
+ join27(home, ".cargo", "config")
83245
83378
  )
83246
83379
  )) {
83247
83380
  blocked.add("cargo");
83248
83381
  }
83249
83382
  if (nugetSourcesArePrivate(
83250
83383
  texts(
83251
- join26(root, "NuGet.config"),
83252
- join26(root, "nuget.config"),
83253
- join26(root, "NuGet.Config"),
83254
- join26(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
83255
- join26(home, ".nuget", "NuGet", "NuGet.Config")
83384
+ join27(root, "NuGet.config"),
83385
+ join27(root, "nuget.config"),
83386
+ join27(root, "NuGet.Config"),
83387
+ join27(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
83388
+ join27(home, ".nuget", "NuGet", "NuGet.Config")
83256
83389
  )
83257
83390
  )) {
83258
83391
  blocked.add("nuget");
83259
83392
  }
83260
- const goEnvFile = env2["GOENV"] ?? join26(env2["APPDATA"] ?? join26(home, ".config"), "go", "env");
83393
+ const goEnvFile = env2["GOENV"] ?? join27(env2["APPDATA"] ?? join27(home, ".config"), "go", "env");
83261
83394
  const goEnvText = read2(goEnvFile) ?? "";
83262
83395
  const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
83263
83396
  (k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
@@ -83268,10 +83401,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
83268
83401
  env2["GONOSUMCHECK"],
83269
83402
  ...fromFile
83270
83403
  ]);
83271
- const gemfiles = texts(join26(root, "Gemfile"));
83404
+ const gemfiles = texts(join27(root, "Gemfile"));
83272
83405
  if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
83273
83406
  if (mavenReposArePrivate(
83274
- texts(join26(root, "pom.xml"), join26(home, ".m2", "settings.xml"))
83407
+ texts(join27(root, "pom.xml"), join27(home, ".m2", "settings.xml"))
83275
83408
  )) {
83276
83409
  blocked.add("maven");
83277
83410
  }
@@ -83438,10 +83571,10 @@ function readDirectDependencies(root) {
83438
83571
  const familiesSeen = /* @__PURE__ */ new Set();
83439
83572
  for (const c of LOCKFILES) {
83440
83573
  if (familiesSeen.has(c.family)) continue;
83441
- const p = join26(root, c.file);
83574
+ const p = join27(root, c.file);
83442
83575
  if (!existsSync23(p)) continue;
83443
83576
  try {
83444
- const s = statSync8(p);
83577
+ const s = statSync9(p);
83445
83578
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
83446
83579
  } catch {
83447
83580
  continue;
@@ -83468,7 +83601,7 @@ function readDirectDependencies(root) {
83468
83601
  }
83469
83602
  function manifestPaths(root) {
83470
83603
  try {
83471
- const out2 = execFileSync4("git", ["-C", root, "ls-files", "-z"], {
83604
+ const out2 = execFileSync5("git", ["-C", root, "ls-files", "-z"], {
83472
83605
  encoding: "utf8",
83473
83606
  maxBuffer: 128 * 1024 * 1024,
83474
83607
  windowsHide: true,
@@ -83502,14 +83635,14 @@ function manifestPaths(root) {
83502
83635
  "project.godot"
83503
83636
  ];
83504
83637
  return {
83505
- paths: ROOT_MANIFESTS.filter((f) => existsSync23(join26(root, f))),
83638
+ paths: ROOT_MANIFESTS.filter((f) => existsSync23(join27(root, f))),
83506
83639
  tracked: false,
83507
83640
  truncated: false
83508
83641
  };
83509
83642
  }
83510
83643
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
83511
83644
  function rootDeclaresWorkspace(root, texts) {
83512
- if (WORKSPACE_MARKERS.some((f) => existsSync23(join26(root, f)))) return true;
83645
+ if (WORKSPACE_MARKERS.some((f) => existsSync23(join27(root, f)))) return true;
83513
83646
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
83514
83647
  }
83515
83648
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -83523,9 +83656,9 @@ function scanManifests(root) {
83523
83656
  const texts = /* @__PURE__ */ new Map();
83524
83657
  const stamps = [];
83525
83658
  for (const rel of paths) {
83526
- const abs = join26(root, rel);
83659
+ const abs = join27(root, rel);
83527
83660
  try {
83528
- const s = statSync8(abs);
83661
+ const s = statSync9(abs);
83529
83662
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
83530
83663
  texts.set(rel, readFileSync23(abs, "utf8"));
83531
83664
  } catch {
@@ -83564,7 +83697,7 @@ function readRetrievalInputs(root, repoLocator) {
83564
83697
 
83565
83698
  // src/git-sensor.ts
83566
83699
  import { existsSync as existsSync24, readFileSync as readFileSync24, watch as fsWatch } from "node:fs";
83567
- import { join as join27 } from "node:path";
83700
+ import { join as join28 } from "node:path";
83568
83701
  function readFirstLine(path3) {
83569
83702
  try {
83570
83703
  return readFileSync24(path3, "utf8").split(/\r?\n/, 1)[0].trim();
@@ -83573,12 +83706,12 @@ function readFirstLine(path3) {
83573
83706
  }
83574
83707
  }
83575
83708
  function readGitRefState(gitDir) {
83576
- const head2 = readFirstLine(join27(gitDir, "HEAD"));
83709
+ const head2 = readFirstLine(join28(gitDir, "HEAD"));
83577
83710
  const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
83578
83711
  const branch = m ? m[1] : null;
83579
83712
  let sha2 = null;
83580
83713
  if (branch) {
83581
- sha2 = readFirstLine(join27(gitDir, "refs", "heads", branch));
83714
+ sha2 = readFirstLine(join28(gitDir, "refs", "heads", branch));
83582
83715
  if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
83583
83716
  } else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
83584
83717
  sha2 = head2;
@@ -83586,13 +83719,13 @@ function readGitRefState(gitDir) {
83586
83719
  return {
83587
83720
  branch,
83588
83721
  sha: sha2,
83589
- mergeHeadExists: existsSync24(join27(gitDir, "MERGE_HEAD")),
83590
- origHeadExists: existsSync24(join27(gitDir, "ORIG_HEAD"))
83722
+ mergeHeadExists: existsSync24(join28(gitDir, "MERGE_HEAD")),
83723
+ origHeadExists: existsSync24(join28(gitDir, "ORIG_HEAD"))
83591
83724
  };
83592
83725
  }
83593
83726
  function shaFromPackedRefs(gitDir, ref) {
83594
83727
  try {
83595
- for (const line of readFileSync24(join27(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
83728
+ for (const line of readFileSync24(join28(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
83596
83729
  const [sha2, name2] = line.split(/\s+/);
83597
83730
  if (name2 === ref && sha2) return sha2;
83598
83731
  }
@@ -83626,7 +83759,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
83626
83759
  const settle = () => {
83627
83760
  if (timer) clearTimeout(timer);
83628
83761
  timer = setTimeout(() => {
83629
- if (existsSync24(join27(gitDir, "index.lock"))) {
83762
+ if (existsSync24(join28(gitDir, "index.lock"))) {
83630
83763
  settle();
83631
83764
  return;
83632
83765
  }
@@ -83637,7 +83770,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
83637
83770
  }, debounceMs);
83638
83771
  };
83639
83772
  for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
83640
- const p = join27(gitDir, sub);
83773
+ const p = join28(gitDir, sub);
83641
83774
  try {
83642
83775
  watchers.push(fsWatch(p, settle));
83643
83776
  } catch {
@@ -83868,7 +84001,7 @@ var TelemetryRecorder = class {
83868
84001
 
83869
84002
  // src/file-activity.ts
83870
84003
  import { readFileSync as readFileSync26 } from "node:fs";
83871
- import { join as join29 } from "node:path";
84004
+ import { join as join30 } from "node:path";
83872
84005
  import { createHash as createHash17 } from "node:crypto";
83873
84006
 
83874
84007
  // ../../packages/privacy/src/patterns/credentials.ts
@@ -84621,7 +84754,7 @@ init_git_remote();
84621
84754
  init_src();
84622
84755
  import { execFile as execFile2 } from "node:child_process";
84623
84756
  import { readFileSync as readFileSync25 } from "node:fs";
84624
- import { join as join28 } from "node:path";
84757
+ import { join as join29 } from "node:path";
84625
84758
  var DEFAULT_MAX_TOKENS = 6e3;
84626
84759
  var FILE_LIST_CAP = 60;
84627
84760
  var DIFF_FILE_CAP = 40;
@@ -84660,7 +84793,7 @@ function pathAllowedByFloor(path3) {
84660
84793
  function loadRepoIgnore(root, extraPatterns = []) {
84661
84794
  let source = "";
84662
84795
  try {
84663
- source = readFileSync25(join28(root, ".errataignore"), "utf8");
84796
+ source = readFileSync25(join29(root, ".errataignore"), "utf8");
84664
84797
  } catch {
84665
84798
  source = "";
84666
84799
  }
@@ -84959,7 +85092,7 @@ function readActivityBranch(root) {
84959
85092
  try {
84960
85093
  const gitDir = resolveGitDir(root);
84961
85094
  if (!gitDir) return null;
84962
- const head2 = readFileSync26(join29(gitDir, "HEAD"), "utf8").trim();
85095
+ const head2 = readFileSync26(join30(gitDir, "HEAD"), "utf8").trim();
84963
85096
  const branch = head2.startsWith("ref: refs/heads/") ? head2.slice(16) : /^[a-f0-9]{40,64}$/i.test(head2) ? "HEAD" : null;
84964
85097
  return branch && branch.length <= 256 && !/[\x00-\x1f\x7f]/.test(branch) ? branch : null;
84965
85098
  } catch {
@@ -85123,7 +85256,7 @@ import {
85123
85256
  unlinkSync as unlinkSync4,
85124
85257
  writeFileSync as writeFileSync18
85125
85258
  } from "node:fs";
85126
- import { basename as basename7, join as join30 } from "node:path";
85259
+ import { basename as basename7, join as join31 } from "node:path";
85127
85260
  function skillFileName(id) {
85128
85261
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
85129
85262
  }
@@ -85154,7 +85287,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85154
85287
  for (const s of res.skills) {
85155
85288
  const fileName = skillFileName(s.id);
85156
85289
  keep.add(fileName);
85157
- writeFileSync18(join30(paths.skillsDir, fileName), s.markdown, "utf8");
85290
+ writeFileSync18(join31(paths.skillsDir, fileName), s.markdown, "utf8");
85158
85291
  rows.push({
85159
85292
  id: s.id,
85160
85293
  title: s.title,
@@ -85167,7 +85300,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85167
85300
  const fileName = skillFileName(p.id);
85168
85301
  if (keep.has(fileName)) continue;
85169
85302
  keep.add(fileName);
85170
- writeFileSync18(join30(paths.skillsDir, fileName), p.markdown, "utf8");
85303
+ writeFileSync18(join31(paths.skillsDir, fileName), p.markdown, "utf8");
85171
85304
  rows.push({
85172
85305
  id: p.id,
85173
85306
  title: p.title,
@@ -85181,7 +85314,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
85181
85314
  if (!f.endsWith(".md")) continue;
85182
85315
  if (keep.has(basename7(f))) continue;
85183
85316
  try {
85184
- unlinkSync4(join30(paths.skillsDir, f));
85317
+ unlinkSync4(join31(paths.skillsDir, f));
85185
85318
  pruned++;
85186
85319
  } catch {
85187
85320
  }
@@ -85208,13 +85341,13 @@ import {
85208
85341
  symlinkSync,
85209
85342
  writeFileSync as writeFileSync19
85210
85343
  } from "node:fs";
85211
- import { join as join31 } from "node:path";
85344
+ import { join as join32 } from "node:path";
85212
85345
  var SKILL_NS = "errata-";
85213
85346
  var HARNESS_SKILL_DIRS = [
85214
- { configDir: ".claude", skillsDir: join31(".claude", "skills") },
85347
+ { configDir: ".claude", skillsDir: join32(".claude", "skills") },
85215
85348
  // Cursor adopted the standard; its exact project dir is still moving — kept
85216
85349
  // best-effort and gated on `.cursor/` presence so we never create it blind.
85217
- { configDir: ".cursor", skillsDir: join31(".cursor", "skills") }
85350
+ { configDir: ".cursor", skillsDir: join32(".cursor", "skills") }
85218
85351
  ];
85219
85352
  function skillSlug(title, id) {
85220
85353
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
@@ -85264,7 +85397,7 @@ function reconcileNamespaced(dir, keep) {
85264
85397
  for (const name2 of readdirSync10(dir)) {
85265
85398
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
85266
85399
  try {
85267
- rmSync3(join31(dir, name2), { recursive: true, force: true });
85400
+ rmSync3(join32(dir, name2), { recursive: true, force: true });
85268
85401
  pruned++;
85269
85402
  } catch {
85270
85403
  }
@@ -85294,7 +85427,7 @@ function safeLstat(p) {
85294
85427
  }
85295
85428
  }
85296
85429
  function emitAndProjectSkills(root, skills) {
85297
- const agentsSkillsDir = join31(root, ".agents", "skills");
85430
+ const agentsSkillsDir = join32(root, ".agents", "skills");
85298
85431
  mkdirSync8(agentsSkillsDir, { recursive: true });
85299
85432
  const slugs = [];
85300
85433
  const keep = /* @__PURE__ */ new Set();
@@ -85311,9 +85444,9 @@ function emitAndProjectSkills(root, skills) {
85311
85444
  keep.add(slug2);
85312
85445
  slugs.push(slug2);
85313
85446
  const description = deriveDescription(s.title, s.layer, body2);
85314
- mkdirSync8(join31(agentsSkillsDir, slug2), { recursive: true });
85447
+ mkdirSync8(join32(agentsSkillsDir, slug2), { recursive: true });
85315
85448
  writeFileSync19(
85316
- join31(agentsSkillsDir, slug2, "SKILL.md"),
85449
+ join32(agentsSkillsDir, slug2, "SKILL.md"),
85317
85450
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
85318
85451
  "utf8"
85319
85452
  );
@@ -85322,11 +85455,11 @@ function emitAndProjectSkills(root, skills) {
85322
85455
  reconcileNamespaced(agentsSkillsDir, keep);
85323
85456
  let projected = 0;
85324
85457
  for (const h of HARNESS_SKILL_DIRS) {
85325
- if (!existsSync26(join31(root, h.configDir))) continue;
85326
- const dir = join31(root, h.skillsDir);
85458
+ if (!existsSync26(join32(root, h.configDir))) continue;
85459
+ const dir = join32(root, h.skillsDir);
85327
85460
  mkdirSync8(dir, { recursive: true });
85328
85461
  for (const slug2 of slugs) {
85329
- linkOrCopy(join31(dir, slug2), join31(agentsSkillsDir, slug2));
85462
+ linkOrCopy(join32(dir, slug2), join32(agentsSkillsDir, slug2));
85330
85463
  projected++;
85331
85464
  }
85332
85465
  reconcileNamespaced(dir, keep);
@@ -85343,7 +85476,7 @@ function emitInputsFromManifest(erretaDir, manifestPath) {
85343
85476
  title: s.title ?? s.id,
85344
85477
  layer: s.layer ?? "technique",
85345
85478
  confidence: s.confidence ?? 0,
85346
- bodyPath: join31(erretaDir, s.file)
85479
+ bodyPath: join32(erretaDir, s.file)
85347
85480
  }));
85348
85481
  } catch {
85349
85482
  return [];
@@ -85357,7 +85490,7 @@ var GITIGNORE_LINES = [
85357
85490
  ".cursor/skills/errata-*/"
85358
85491
  ];
85359
85492
  function ensureSkillGitignore(root) {
85360
- const path3 = join31(root, ".gitignore");
85493
+ const path3 = join32(root, ".gitignore");
85361
85494
  let current = "";
85362
85495
  try {
85363
85496
  current = existsSync26(path3) ? readFileSync28(path3, "utf8") : "";
@@ -85464,12 +85597,12 @@ init_profile2();
85464
85597
 
85465
85598
  // src/witness-queue.ts
85466
85599
  import { readFileSync as readFileSync29, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "node:fs";
85467
- import { dirname as dirname12, join as join32 } from "node:path";
85600
+ import { dirname as dirname12, join as join33 } from "node:path";
85468
85601
  var WITNESS_QUEUE_CAP = 500;
85469
85602
  var WITNESS_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
85470
85603
  var WITNESS_MAX_ATTEMPTS = 5;
85471
85604
  function witnessQueuePath(workspaceConfigDir) {
85472
- return join32(workspaceConfigDir, "witness-queue.json");
85605
+ return join33(workspaceConfigDir, "witness-queue.json");
85473
85606
  }
85474
85607
  function loadWitnessQueueWithLosses(path3) {
85475
85608
  let raw2;
@@ -85487,7 +85620,7 @@ function loadWitnessQueueWithLosses(path3) {
85487
85620
  }
85488
85621
  function saveWitnessQueue(path3, queue) {
85489
85622
  try {
85490
- const tmp = join32(dirname12(path3), `.${Date.now()}.witness-queue.tmp`);
85623
+ const tmp = join33(dirname12(path3), `.${Date.now()}.witness-queue.tmp`);
85491
85624
  writeFileSync20(tmp, JSON.stringify(queue), "utf8");
85492
85625
  renameSync3(tmp, path3);
85493
85626
  } catch {
@@ -85798,7 +85931,7 @@ function maybeFlushDigests() {
85798
85931
  // src/liveness-watch.ts
85799
85932
  init_src5();
85800
85933
  import { readFileSync as readFileSync31, writeFileSync as writeFileSync22 } from "node:fs";
85801
- import { join as join34 } from "node:path";
85934
+ import { join as join35 } from "node:path";
85802
85935
 
85803
85936
  // src/loop-lag.ts
85804
85937
  var HEARTBEAT_MS = 500;
@@ -85929,7 +86062,7 @@ function watchCensusLine(c = watchCensus(), now = Date.now()) {
85929
86062
  var LIVENESS_WATCH_INTERVAL_MS = 60 * 60 * 1e3;
85930
86063
  var ALARM_RENOTIFY_MS = 24 * 60 * 60 * 1e3;
85931
86064
  function alarmStatePath(configDir) {
85932
- return join34(configDir, "liveness-alarms.json");
86065
+ return join35(configDir, "liveness-alarms.json");
85933
86066
  }
85934
86067
  function loadAlarmState(path3) {
85935
86068
  try {
@@ -86169,7 +86302,7 @@ function createWatchBreaker(deps) {
86169
86302
  }
86170
86303
 
86171
86304
  // src/engine.ts
86172
- var DAEMON_VERSION = true ? "2.0.22-dev.4186" : "2.0.0-alpha.0";
86305
+ var DAEMON_VERSION = true ? "2.0.22-dev.4293" : "2.0.0-alpha.0";
86173
86306
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
86174
86307
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
86175
86308
  var GIT_OP_MUTE_MS = 4e3;
@@ -86181,7 +86314,7 @@ var CODEX_SWEEP_LOOKBACK_MS = 10 * 6e4;
86181
86314
  function appendIdentityAudit(path3, record2, line) {
86182
86315
  if (!record2.accepted && record2.score <= 0) return;
86183
86316
  try {
86184
- if (existsSync28(path3) && statSync9(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
86317
+ if (existsSync28(path3) && statSync10(path3).size >= IDENTITY_AUDIT_MAX_BYTES) {
86185
86318
  renameSync4(path3, `${path3}.1`);
86186
86319
  }
86187
86320
  appendFileSync4(path3, line);
@@ -86224,7 +86357,7 @@ function saveTurnCursors(path3, cursors, offsets) {
86224
86357
  function gitSourceWatchTargets(root) {
86225
86358
  const SOURCE = /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i;
86226
86359
  try {
86227
- const lsOut = execFileSync5("git", ["-C", root, "ls-files", "-z"], {
86360
+ const lsOut = execFileSync6("git", ["-C", root, "ls-files", "-z"], {
86228
86361
  encoding: "utf8",
86229
86362
  maxBuffer: 128 * 1024 * 1024,
86230
86363
  windowsHide: true,
@@ -86234,12 +86367,12 @@ function gitSourceWatchTargets(root) {
86234
86367
  if (sourceFiles.length === 0) throw new Error("no tracked source");
86235
86368
  let ignoredDirs = [];
86236
86369
  try {
86237
- const igOut = execFileSync5(
86370
+ const igOut = execFileSync6(
86238
86371
  "git",
86239
86372
  ["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
86240
86373
  { encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
86241
86374
  );
86242
- ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join35(root, d) + sep4));
86375
+ ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join36(root, d) + sep4));
86243
86376
  } catch {
86244
86377
  }
86245
86378
  const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
@@ -86251,19 +86384,19 @@ function gitSourceWatchTargets(root) {
86251
86384
  if (!f.startsWith(prefix)) continue;
86252
86385
  const rest2 = f.slice(prefix.length);
86253
86386
  if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
86254
- else targets.add(join35(root, f));
86387
+ else targets.add(join36(root, f));
86255
86388
  }
86256
86389
  for (const c of children) {
86257
- if (IGNORED_PATH.test(join35(root, c) + sep4)) continue;
86390
+ if (IGNORED_PATH.test(join36(root, c) + sep4)) continue;
86258
86391
  if (hasIgnoredChild(c)) addUnder(c);
86259
- else targets.add(join35(root, c));
86392
+ else targets.add(join36(root, c));
86260
86393
  }
86261
86394
  };
86262
86395
  addUnder("");
86263
86396
  if (targets.size > 0) return [...targets];
86264
86397
  } catch {
86265
86398
  }
86266
- return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join35(root, String(e.name)) + sep4)).map((e) => join35(root, String(e.name)));
86399
+ return readdirSync11(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join36(root, String(e.name)) + sep4)).map((e) => join36(root, String(e.name)));
86267
86400
  }
86268
86401
  function createWorkspaceEngine(opts) {
86269
86402
  const paths = workspacePaths(opts.workspaceRoot);
@@ -86355,7 +86488,7 @@ function createWorkspaceEngine(opts) {
86355
86488
  }
86356
86489
  let size = 0;
86357
86490
  try {
86358
- size = statSync9(path3).size;
86491
+ size = statSync10(path3).size;
86359
86492
  } catch {
86360
86493
  }
86361
86494
  lastActivityTs = Date.now();
@@ -86462,7 +86595,7 @@ function createWorkspaceEngine(opts) {
86462
86595
  const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
86463
86596
  let episodeId2;
86464
86597
  if (srcPaths.length > 0) {
86465
- const abs = srcPaths.map((p) => join35(opts.workspaceRoot, p));
86598
+ const abs = srcPaths.map((p) => join36(opts.workspaceRoot, p));
86466
86599
  try {
86467
86600
  const r = await runReindexPass(
86468
86601
  `git-reindex:${profile.name} (${abs.length} files)`,
@@ -86498,7 +86631,7 @@ function createWorkspaceEngine(opts) {
86498
86631
  `[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
86499
86632
  );
86500
86633
  };
86501
- const gitDir = join35(opts.workspaceRoot, ".git");
86634
+ const gitDir = join36(opts.workspaceRoot, ".git");
86502
86635
  if (existsSync28(gitDir)) {
86503
86636
  stopGit = startGitSensor(gitDir, (ev) => {
86504
86637
  void handleGitEvent(ev).catch((err2) => {
@@ -86555,7 +86688,7 @@ function createWorkspaceEngine(opts) {
86555
86688
  },
86556
86689
  onAlarms: (alarms) => {
86557
86690
  toastLivenessAlarms(
86558
- sharedAlarmToastGate(join35(globalDir(), "liveness-toasts.json")),
86691
+ sharedAlarmToastGate(join36(globalDir(), "liveness-toasts.json")),
86559
86692
  { root: opts.workspaceRoot, name: profile.name },
86560
86693
  alarms,
86561
86694
  (body2, key) => notifyEvent("mechanism-stalled", body2, { key }),
@@ -86572,7 +86705,7 @@ function createWorkspaceEngine(opts) {
86572
86705
  let subagentBase = null;
86573
86706
  let subagentBaseVersion = 0;
86574
86707
  const subagentRenders = /* @__PURE__ */ new Map();
86575
- const sessions = createSessionRegistry({ originsPath: join35(paths.configDir, "session-origins.json") });
86708
+ const sessions = createSessionRegistry({ originsPath: join36(paths.configDir, "session-origins.json") });
86576
86709
  const sessionRenders = /* @__PURE__ */ new Map();
86577
86710
  const selfCiteSkipsBySession = /* @__PURE__ */ new Map();
86578
86711
  const toolRuns = createToolRunState();
@@ -86664,7 +86797,7 @@ function createWorkspaceEngine(opts) {
86664
86797
  const elicit = isEdgeElicitationEnabled();
86665
86798
  const snapOpts = {
86666
86799
  profile,
86667
- atCommit: readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0,
86800
+ atCommit: readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0,
86668
86801
  reviewCount: pendingCount(paths),
86669
86802
  reviewUiUrl: opts.reviewUrl(),
86670
86803
  workingFile: workingFiles.mostRecent() ?? void 0,
@@ -86678,7 +86811,7 @@ function createWorkspaceEngine(opts) {
86678
86811
  );
86679
86812
  return null;
86680
86813
  }) : null;
86681
- if (snapOpts.atCommit !== (readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0)) {
86814
+ if (snapOpts.atCommit !== (readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0)) {
86682
86815
  contextDirty = true;
86683
86816
  return;
86684
86817
  }
@@ -86724,10 +86857,10 @@ function createWorkspaceEngine(opts) {
86724
86857
  } catch (err2) {
86725
86858
  console.warn("[errata] context card failed:", err2.message?.slice(0, 120));
86726
86859
  }
86727
- const target = join35(opts.workspaceRoot, "AGENTS.md");
86860
+ const target = join36(opts.workspaceRoot, "AGENTS.md");
86728
86861
  writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
86729
86862
  if (elicit) {
86730
- writePrimingHandles(join35(paths.configDir, "priming-handles.json"), [
86863
+ writePrimingHandles(join36(paths.configDir, "priming-handles.json"), [
86731
86864
  ...snapshot.recentProblems.map((r) => r.node),
86732
86865
  // Resolved-band handles: the ✓ problem AND its Solution are citable
86733
86866
  // (a fix tag on an already-resolved problem no-ops idempotently; the
@@ -87035,8 +87168,8 @@ function createWorkspaceEngine(opts) {
87035
87168
  const cached2 = subagentRenders.get(a.agentId);
87036
87169
  if (cached2?.key === key) return cached2.block;
87037
87170
  const elicit = isEdgeElicitationEnabled();
87038
- const handlesPath = join35(paths.configDir, "priming-handles.json");
87039
- const atCommit = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
87171
+ const handlesPath = join36(paths.configDir, "priming-handles.json");
87172
+ const atCommit = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
87040
87173
  const block = renderSubagentBlock({
87041
87174
  store,
87042
87175
  entry,
@@ -87090,7 +87223,7 @@ function createWorkspaceEngine(opts) {
87090
87223
  const cached2 = sessionRenders.get(sessionId);
87091
87224
  if (cached2?.key === key) return cached2.block;
87092
87225
  const elicit = isEdgeElicitationEnabled();
87093
- const atCommit = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
87226
+ const atCommit = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
87094
87227
  const scoped = scopeSnapshot(structuredClone(subagentBase), (n) => !hiddenFrom(n, sessionId, sessions, now));
87095
87228
  delete scoped.workingFile;
87096
87229
  if (workingFile) {
@@ -87131,7 +87264,7 @@ function createWorkspaceEngine(opts) {
87131
87264
  ]
87132
87265
  };
87133
87266
  if (elicit && block.handleNodes.length) {
87134
- writePrimingHandles(join35(paths.configDir, "priming-handles.json"), block.handleNodes);
87267
+ writePrimingHandles(join36(paths.configDir, "priming-handles.json"), block.handleNodes);
87135
87268
  }
87136
87269
  sessionRenders.delete(sessionId);
87137
87270
  sessionRenders.set(sessionId, { key, block });
@@ -87191,7 +87324,7 @@ function createWorkspaceEngine(opts) {
87191
87324
  resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
87192
87325
  });
87193
87326
  };
87194
- const turnCursorPath = join35(paths.configDir, "turn-cursors.json");
87327
+ const turnCursorPath = join36(paths.configDir, "turn-cursors.json");
87195
87328
  const lastTurnUuid = loadTurnCursors(turnCursorPath);
87196
87329
  const turnOffset = loadTurnOffsets(turnCursorPath);
87197
87330
  const readLosses = { parseFailures: 0, ioFailures: 0, bytesUnreachable: 0, sliceGuardHits: 0 };
@@ -87253,7 +87386,7 @@ function createWorkspaceEngine(opts) {
87253
87386
  let processedTurns = 0;
87254
87387
  const seqAtStart = store.currentIngestSeq();
87255
87388
  const elicit = isEdgeElicitationEnabled();
87256
- const handleMap = elicit ? readPrimingHandles(join35(paths.configDir, "priming-handles.json")) : {};
87389
+ const handleMap = elicit ? readPrimingHandles(join36(paths.configDir, "priming-handles.json")) : {};
87257
87390
  const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
87258
87391
  const toRel = (abs) => {
87259
87392
  const p = abs.replace(/\\/g, "/");
@@ -87464,7 +87597,7 @@ function createWorkspaceEngine(opts) {
87464
87597
  let anchorReadFailed = false;
87465
87598
  if (p.location) {
87466
87599
  try {
87467
- fileText = readFileSync32(join35(opts.workspaceRoot, p.location.path), "utf8");
87600
+ fileText = readFileSync32(join36(opts.workspaceRoot, p.location.path), "utf8");
87468
87601
  } catch {
87469
87602
  anchorReadFailed = true;
87470
87603
  }
@@ -87626,10 +87759,10 @@ function createWorkspaceEngine(opts) {
87626
87759
  let enclosing = {};
87627
87760
  if (p.location?.line !== void 0) {
87628
87761
  try {
87629
- const headSha = readGitRefState(join35(opts.workspaceRoot, ".git")).sha ?? void 0;
87762
+ const headSha = readGitRefState(join36(opts.workspaceRoot, ".git")).sha ?? void 0;
87630
87763
  enclosing = {
87631
87764
  line: p.location.line,
87632
- fileText: readFileSync32(join35(opts.workspaceRoot, anchorPath), "utf8"),
87765
+ fileText: readFileSync32(join36(opts.workspaceRoot, anchorPath), "utf8"),
87633
87766
  ...headSha ? { headSha } : {}
87634
87767
  };
87635
87768
  } catch {
@@ -88468,7 +88601,7 @@ B: ${b}`,
88468
88601
  try {
88469
88602
  const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
88470
88603
  emitAndProjectSkills(opts.workspaceRoot, inputs);
88471
- writePrimingHandles(join35(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
88604
+ writePrimingHandles(join36(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
88472
88605
  } catch (err2) {
88473
88606
  console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
88474
88607
  }
@@ -89161,7 +89294,7 @@ async function linkRegisteredWorkspaces(cfg, loggedInProfile = cfg.activeInstall
89161
89294
 
89162
89295
  // src/edge-park.ts
89163
89296
  import { readFileSync as readFileSync33, renameSync as renameSync5, writeFileSync as writeFileSync25 } from "node:fs";
89164
- import { dirname as dirname13, join as join36 } from "node:path";
89297
+ import { dirname as dirname13, join as join37 } from "node:path";
89165
89298
  var EDGE_PARK_CAP = 2e3;
89166
89299
  var EDGE_PARK_TTL_MS = 14 * 24 * 60 * 60 * 1e3;
89167
89300
  var EDGE_PARK_MAX_ATTEMPTS = 6;
@@ -89176,7 +89309,7 @@ function wireEdgeKey(from, type, to) {
89176
89309
  return JSON.stringify([from, type, to]);
89177
89310
  }
89178
89311
  function edgeParkPath(workspaceConfigDir, destinationKey) {
89179
- return join36(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89312
+ return join37(workspaceConfigDir, `edge-park.${destinationKey.slice(0, 16)}.json`);
89180
89313
  }
89181
89314
  function loadEdgePark(path3) {
89182
89315
  let raw2;
@@ -89192,7 +89325,7 @@ function loadEdgePark(path3) {
89192
89325
  }
89193
89326
  function saveEdgePark(path3, queue) {
89194
89327
  try {
89195
- const tmp = join36(dirname13(path3), `.${Date.now()}.edge-park.tmp`);
89328
+ const tmp = join37(dirname13(path3), `.${Date.now()}.edge-park.tmp`);
89196
89329
  writeFileSync25(tmp, JSON.stringify(queue), "utf8");
89197
89330
  renameSync5(tmp, path3);
89198
89331
  } catch {
@@ -89536,7 +89669,7 @@ init_reconcile();
89536
89669
  // src/lockfile-auto.ts
89537
89670
  init_src();
89538
89671
  import { existsSync as existsSync30, readFileSync as readFileSync34 } from "node:fs";
89539
- import { join as join37 } from "node:path";
89672
+ import { join as join38 } from "node:path";
89540
89673
 
89541
89674
  // src/package-index.ts
89542
89675
  init_src();
@@ -89688,7 +89821,7 @@ function runLockfilePass(opts) {
89688
89821
  { file: "package-lock.json", parse: parsePackageLockJson }
89689
89822
  ];
89690
89823
  for (const c of candidates) {
89691
- const p = join37(opts.root, c.file);
89824
+ const p = join38(opts.root, c.file);
89692
89825
  if (!existsSync30(p)) continue;
89693
89826
  let sbom;
89694
89827
  try {
@@ -89754,7 +89887,7 @@ init_session_registry();
89754
89887
 
89755
89888
  // src/public-symbols.ts
89756
89889
  import { readFileSync as readFileSync35, readdirSync as readdirSync12, existsSync as existsSync31 } from "node:fs";
89757
- import { join as join38 } from "node:path";
89890
+ import { join as join39 } from "node:path";
89758
89891
  var HEAD_BYTES = 8 * 1024;
89759
89892
  var INDEX_TTL_MS = 10 * 60 * 1e3;
89760
89893
  var MIN_SYMBOL_LEN = 4;
@@ -89787,7 +89920,7 @@ function bindingNames(clause) {
89787
89920
  function internalPackageNames(workspaceRoot) {
89788
89921
  const names = /* @__PURE__ */ new Set();
89789
89922
  const tryRead = (dir) => {
89790
- const pj = join38(dir, "package.json");
89923
+ const pj = join39(dir, "package.json");
89791
89924
  if (!existsSync31(pj)) return;
89792
89925
  try {
89793
89926
  const name2 = JSON.parse(readFileSync35(pj, "utf8")).name;
@@ -89797,10 +89930,10 @@ function internalPackageNames(workspaceRoot) {
89797
89930
  };
89798
89931
  tryRead(workspaceRoot);
89799
89932
  for (const group of ["packages", "apps"]) {
89800
- const groupDir = join38(workspaceRoot, group);
89933
+ const groupDir = join39(workspaceRoot, group);
89801
89934
  if (!existsSync31(groupDir)) continue;
89802
89935
  try {
89803
- for (const entry of readdirSync12(groupDir)) tryRead(join38(groupDir, entry));
89936
+ for (const entry of readdirSync12(groupDir)) tryRead(join39(groupDir, entry));
89804
89937
  } catch {
89805
89938
  }
89806
89939
  }
@@ -89839,7 +89972,7 @@ function publicSymbolIndex(store, workspaceRoot, deps = {}) {
89839
89972
  }
89840
89973
  const symbols = /* @__PURE__ */ new Set();
89841
89974
  for (const rel of files) {
89842
- const head2 = readHead(join38(workspaceRoot, rel));
89975
+ const head2 = readHead(join39(workspaceRoot, rel));
89843
89976
  if (!head2) continue;
89844
89977
  for (const re of [NAMED_IMPORT_RE, REQUIRE_RE]) {
89845
89978
  re.lastIndex = 0;
@@ -90824,7 +90957,7 @@ init_config();
90824
90957
 
90825
90958
  // src/update.ts
90826
90959
  import { spawn as spawn2 } from "node:child_process";
90827
- import { isAbsolute as isAbsolute6, join as join39 } from "node:path";
90960
+ import { isAbsolute as isAbsolute6, join as join40 } from "node:path";
90828
90961
  var PACKAGE_NAME = "@inerrata-corporation/errata";
90829
90962
  function parse3(v) {
90830
90963
  const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z][0-9A-Za-z.-]*))?/.exec(v.trim());
@@ -90971,7 +91104,7 @@ async function runInstalledHookRefresh() {
90971
91104
  });
90972
91105
  if (!isAbsolute6(root)) return 1;
90973
91106
  return new Promise((resolve10) => {
90974
- const child = spawn2(process.execPath, [join39(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
91107
+ const child = spawn2(process.execPath, [join40(root, PACKAGE_NAME, "errata.mjs"), "install-hooks", "codex", "--refresh-existing"], {
90975
91108
  windowsHide: true,
90976
91109
  stdio: "inherit",
90977
91110
  timeout: 3e4
@@ -91118,11 +91251,11 @@ function landCloudEdge(store, e, from, to) {
91118
91251
 
91119
91252
  // src/causal-edge-queue.ts
91120
91253
  import { readFileSync as readFileSync36, renameSync as renameSync6, writeFileSync as writeFileSync26 } from "node:fs";
91121
- import { dirname as dirname14, join as join40 } from "node:path";
91254
+ import { dirname as dirname14, join as join41 } from "node:path";
91122
91255
  var CAUSAL_EDGE_QUEUE_CAP = 5e3;
91123
91256
  var CAUSAL_EDGE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
91124
91257
  function causalEdgeQueuePath(workspaceConfigDir) {
91125
- return join40(workspaceConfigDir, "causal-edge-queue.json");
91258
+ return join41(workspaceConfigDir, "causal-edge-queue.json");
91126
91259
  }
91127
91260
  function parkedEdgeKey(e) {
91128
91261
  return `${e.from}|${e.type}|${e.to}`;
@@ -91141,7 +91274,7 @@ function loadCausalEdgeQueue(path3) {
91141
91274
  }
91142
91275
  function saveCausalEdgeQueue(path3, queue) {
91143
91276
  try {
91144
- const tmp = join40(dirname14(path3), `.${Date.now()}.causal-edge-queue.tmp`);
91277
+ const tmp = join41(dirname14(path3), `.${Date.now()}.causal-edge-queue.tmp`);
91145
91278
  writeFileSync26(tmp, JSON.stringify(queue), "utf8");
91146
91279
  renameSync6(tmp, path3);
91147
91280
  } catch {
@@ -91815,7 +91948,7 @@ init_src7();
91815
91948
  init_src();
91816
91949
  import { execFile as execFile6 } from "node:child_process";
91817
91950
  import { readFileSync as readFileSync37 } from "node:fs";
91818
- import { join as join41 } from "node:path";
91951
+ import { join as join42 } from "node:path";
91819
91952
  import { promisify as promisify5 } from "node:util";
91820
91953
 
91821
91954
  // src/history-walk.ts
@@ -92367,7 +92500,7 @@ async function defaultGit(root, args2) {
92367
92500
  function readIgnoreLines(root, profile) {
92368
92501
  let lines = [];
92369
92502
  try {
92370
- lines = readFileSync37(join41(root, ".errataignore"), "utf8").split("\n");
92503
+ lines = readFileSync37(join42(root, ".errataignore"), "utf8").split("\n");
92371
92504
  } catch {
92372
92505
  }
92373
92506
  return [...lines, ...profile.ignoreExtra ?? []].map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
@@ -92942,9 +93075,9 @@ async function startHistoryStage(root, input, client, walk11 = {}) {
92942
93075
  // src/link-flow.ts
92943
93076
  init_cloud_auth();
92944
93077
  import { createHash as createHash19 } from "node:crypto";
92945
- import { execFileSync as execFileSync6 } from "node:child_process";
93078
+ import { execFileSync as execFileSync7 } from "node:child_process";
92946
93079
  import { existsSync as existsSync32, writeFileSync as writeFileSync27 } from "node:fs";
92947
- import { join as join42 } from "node:path";
93080
+ import { join as join43 } from "node:path";
92948
93081
 
92949
93082
  // src/device-poll.ts
92950
93083
  var THROTTLED_POLL_MIN_WAIT_MS = 11e3;
@@ -93331,7 +93464,7 @@ async function linkThroughConsole(opts) {
93331
93464
  function collectRepoFacts(root) {
93332
93465
  const git3 = (args2) => {
93333
93466
  try {
93334
- return execFileSync6("git", args2, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
93467
+ return execFileSync7("git", args2, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
93335
93468
  } catch {
93336
93469
  return null;
93337
93470
  }
@@ -93403,7 +93536,7 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
93403
93536
  delete nextProfile.projectLinkHold;
93404
93537
  let wroteIgnore = false;
93405
93538
  if (decision.writeIgnoreStarter !== false) {
93406
- const target = join42(root, ".errataignore");
93539
+ const target = join43(root, ".errataignore");
93407
93540
  if (!existsSync32(target)) {
93408
93541
  writeFileSync27(target, IGNORE_STARTER, "utf8");
93409
93542
  wroteIgnore = true;
@@ -93419,11 +93552,11 @@ init_registry();
93419
93552
  // src/adopt.ts
93420
93553
  init_git_remote();
93421
93554
  import { existsSync as existsSync33 } from "node:fs";
93422
- import { dirname as dirname15, join as join43 } from "node:path";
93555
+ import { dirname as dirname15, join as join44 } from "node:path";
93423
93556
  function findGitRoot(absPath) {
93424
93557
  let dir = absPath;
93425
93558
  for (let depth = 0; depth < 64; depth++) {
93426
- if (existsSync33(join43(dir, ".git"))) return dir;
93559
+ if (existsSync33(join44(dir, ".git"))) return dir;
93427
93560
  const parent = dirname15(dir);
93428
93561
  if (parent === dir) return null;
93429
93562
  dir = parent;
@@ -96047,15 +96180,15 @@ function shouldUseOAuthLogin(flags2, env2 = process.env) {
96047
96180
  import { spawnSync as spawnSync2 } from "node:child_process";
96048
96181
 
96049
96182
  // src/codex-runtime.ts
96050
- import { readdirSync as readdirSync13, statSync as statSync10 } from "node:fs";
96051
- import { join as join44 } from "node:path";
96183
+ import { readdirSync as readdirSync13, statSync as statSync11 } from "node:fs";
96184
+ import { join as join45 } from "node:path";
96052
96185
  function resolveCodexExecutable(options = {}) {
96053
96186
  const platform = options.platform ?? process.platform;
96054
96187
  const env2 = options.env ?? process.env;
96055
96188
  if (platform !== "win32") return "codex";
96056
96189
  const fileTime = (path3) => {
96057
96190
  try {
96058
- const s = statSync10(path3);
96191
+ const s = statSync11(path3);
96059
96192
  return s.isFile() ? s.mtimeMs : null;
96060
96193
  } catch {
96061
96194
  return null;
@@ -96063,13 +96196,13 @@ function resolveCodexExecutable(options = {}) {
96063
96196
  };
96064
96197
  for (const dir of (env2["PATH"] ?? env2["Path"] ?? "").split(";")) {
96065
96198
  if (!dir.trim()) continue;
96066
- const path3 = join44(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96199
+ const path3 = join45(dir.trim().replace(/^"|"$/g, ""), "codex.exe");
96067
96200
  if (fileTime(path3) !== null) return path3;
96068
96201
  }
96069
96202
  if (!env2["LOCALAPPDATA"]) return "codex";
96070
- const root = join44(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96203
+ const root = join45(env2["LOCALAPPDATA"], "OpenAI", "Codex", "bin");
96071
96204
  try {
96072
- const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join44(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
96205
+ const candidates = readdirSync13(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join45(root, entry.name, "codex.exe")).map((path3) => ({ path: path3, mtime: fileTime(path3) })).filter((candidate) => candidate.mtime !== null).sort((a, b) => b.mtime - a.mtime || a.path.localeCompare(b.path));
96073
96206
  return candidates[0]?.path ?? "codex";
96074
96207
  } catch {
96075
96208
  return "codex";
@@ -96126,6 +96259,7 @@ async function diagnoseInstallation(cfg, dependencies) {
96126
96259
  checks.push(
96127
96260
  credentialType === "none" ? { id: "credential", status: "fail", detail: "No credential is installed" } : { id: "credential", status: "pass", detail: `${credentialType} credential is present` }
96128
96261
  );
96262
+ if (dependencies.credentialHygiene) checks.push(dependencies.credentialHygiene());
96129
96263
  const authorityMatches = !profile || profile.cloudUrl === cfg.cloudUrl && profile.apiKey === cfg.apiKey && profile.accessToken === cfg.accessToken && profile.refreshToken === cfg.refreshToken;
96130
96264
  checks.push(
96131
96265
  authorityMatches ? {
@@ -96206,16 +96340,219 @@ async function diagnoseInstallation(cfg, dependencies) {
96206
96340
  };
96207
96341
  }
96208
96342
 
96343
+ // src/credential-scan.ts
96344
+ import { readFileSync as readFileSync39, statSync as statSync12 } from "node:fs";
96345
+ import { homedir as homedir8 } from "node:os";
96346
+ import { join as join47 } from "node:path";
96347
+
96348
+ // src/claude-statusline.ts
96349
+ import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync38, writeFileSync as writeFileSync29 } from "node:fs";
96350
+ import { homedir as homedir7 } from "node:os";
96351
+ import { dirname as dirname16, join as join46 } from "node:path";
96352
+ var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
96353
+ import { readFileSync } from 'node:fs';
96354
+
96355
+ try {
96356
+ const port = Number(process.argv[2]);
96357
+ const route = process.argv[3] === 'subagents' ? '/api/statusline/subagents' : '/api/statusline';
96358
+ if (Number.isInteger(port) && port > 0 && port < 65536) {
96359
+ const response = await fetch('http://127.0.0.1:' + port + route, {
96360
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
96361
+ body: readFileSync(0, 'utf8') || '{}', signal: AbortSignal.timeout(800),
96362
+ });
96363
+ if (response.ok) process.stdout.write(await response.text());
96364
+ }
96365
+ } catch { /* An unavailable daemon leaves the status line empty. */ }
96366
+ `;
96367
+ var STATUSLINE_RELAY_FILE = "errata-statusline.mjs";
96368
+ function buildStatusLine(port, nodePath, relayPath) {
96369
+ return { type: "command", command: relayCommand(port, nodePath, relayPath), padding: 0 };
96370
+ }
96371
+ function buildSubagentStatusLine(port, nodePath, relayPath) {
96372
+ return { type: "command", command: `${relayCommand(port, nodePath, relayPath)} subagents` };
96373
+ }
96374
+ function relayCommand(port, nodePath, relayPath) {
96375
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid status line port");
96376
+ const q = (p) => {
96377
+ if (/["$`\r\n]/.test(p)) throw new Error("Unsupported character in status line path");
96378
+ return `"${p.replace(/\\/g, "/")}"`;
96379
+ };
96380
+ return `${q(nodePath)} ${q(relayPath)} ${port}`;
96381
+ }
96382
+ function isErrataStatusLine(value) {
96383
+ return !!value && typeof value === "object" && typeof value["command"] === "string" && value["command"].includes(STATUSLINE_RELAY_FILE);
96384
+ }
96385
+ function removeProjectStatusLine(settings) {
96386
+ let removed = false;
96387
+ for (const key of ["statusLine", "subagentStatusLine"]) {
96388
+ if (!isErrataStatusLine(settings[key])) continue;
96389
+ delete settings[key];
96390
+ removed = true;
96391
+ }
96392
+ return removed;
96393
+ }
96394
+ function isSameInstall(value, relay) {
96395
+ const command = value["command"].replace(/\\/g, "/").toLowerCase();
96396
+ return command.includes(relay.replace(/\\/g, "/").toLowerCase());
96397
+ }
96398
+ function userClaudeSettingsPath() {
96399
+ const base = process.env["CLAUDE_CONFIG_DIR"] ?? join46(homedir7(), ".claude");
96400
+ return join46(base, "settings.json");
96401
+ }
96402
+ function ensureUserStatusLine(opts) {
96403
+ const env2 = opts.env ?? process.env;
96404
+ const off2 = (env2["ERRATA_STATUSLINE"] ?? "").trim().toLowerCase();
96405
+ if (off2 === "0" || off2 === "off" || off2 === "false" || off2 === "no") return "disabled";
96406
+ const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
96407
+ let settings = {};
96408
+ if (existsSync35(settingsPath)) {
96409
+ try {
96410
+ const parsed = JSON.parse(readFileSync38(settingsPath, "utf8"));
96411
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
96412
+ settings = parsed;
96413
+ } catch {
96414
+ return "unreadable";
96415
+ }
96416
+ }
96417
+ const relay = join46(opts.relayDir, STATUSLINE_RELAY_FILE);
96418
+ const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
96419
+ const ownMain = keep(settings["statusLine"]);
96420
+ const ownRows = keep(settings["subagentStatusLine"]);
96421
+ if (ownMain && ownRows) return "kept-own";
96422
+ mkdirSync9(opts.relayDir, { recursive: true });
96423
+ if (!existsSync35(relay) || readFileSync38(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
96424
+ writeFileSync29(relay, STATUSLINE_RELAY_SOURCE, "utf8");
96425
+ }
96426
+ const nodePath = opts.nodePath ?? process.execPath;
96427
+ const next = {
96428
+ ...ownMain ? {} : { statusLine: buildStatusLine(opts.port, nodePath, relay) },
96429
+ ...ownRows ? {} : { subagentStatusLine: buildSubagentStatusLine(opts.port, nodePath, relay) }
96430
+ };
96431
+ if (Object.entries(next).every(([k, v]) => JSON.stringify(settings[k]) === JSON.stringify(v))) {
96432
+ return ownMain ? "kept-own" : "unchanged";
96433
+ }
96434
+ Object.assign(settings, next);
96435
+ mkdirSync9(dirname16(settingsPath), { recursive: true });
96436
+ writeFileSync29(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
96437
+ return "installed";
96438
+ }
96439
+ function describeStatusLineOutcome(outcome) {
96440
+ switch (outcome) {
96441
+ case "installed":
96442
+ return "status line: errata recall card in colour (user settings; ERRATA_STATUSLINE=off opts out)";
96443
+ case "unchanged":
96444
+ return "status line: errata recall card already set up";
96445
+ case "kept-own":
96446
+ return "status line: kept your own \u2014 errata's recall card shows inline only";
96447
+ case "disabled":
96448
+ return "status line: skipped (ERRATA_STATUSLINE=off)";
96449
+ case "unreadable":
96450
+ return "status line: skipped \u2014 ~/.claude/settings.json is not valid JSON";
96451
+ }
96452
+ }
96453
+
96454
+ // src/credential-scan.ts
96455
+ var KEY_RE = /(?<![A-Za-z0-9_-])(?:errk_[A-Za-z0-9_-]{32,}|err_[a-f0-9]{6}_[a-f0-9]{32})(?![A-Za-z0-9_-])/;
96456
+ var ENV_ASSIGNMENT_RE = /(?:^|[\s{,"'])INERRATA_API_KEY["']?\s*[:=]\s*["']([^"']*)["']/;
96457
+ function isReference(value) {
96458
+ return value.trim() === "" || /[$<{]/.test(value);
96459
+ }
96460
+ var MAX_SCAN_BYTES = 8 * 1024 * 1024;
96461
+ var MAX_LISTED_FINDINGS = 5;
96462
+ function findCredentialLines(text) {
96463
+ const lines = [];
96464
+ text.split(/\r?\n/).forEach((line, index) => {
96465
+ if (KEY_RE.test(line)) {
96466
+ lines.push(index + 1);
96467
+ return;
96468
+ }
96469
+ const assignment = ENV_ASSIGNMENT_RE.exec(line);
96470
+ if (assignment && !isReference(assignment[1])) lines.push(index + 1);
96471
+ });
96472
+ return lines;
96473
+ }
96474
+ function harnessConfigPaths(root) {
96475
+ const env2 = process.env;
96476
+ const home = homedir8();
96477
+ const codexHome = env2["CODEX_HOME"] || join47(home, ".codex");
96478
+ const geminiHome = join47(env2["GEMINI_CLI_HOME"] ?? home, ".gemini");
96479
+ return [
96480
+ // Claude Code: user settings, `claude mcp add` (local/user scope), project.
96481
+ userClaudeSettingsPath(),
96482
+ join47(env2["CLAUDE_CONFIG_DIR"] ?? home, ".claude.json"),
96483
+ join47(root, ".claude", "settings.json"),
96484
+ join47(root, ".claude", "settings.local.json"),
96485
+ join47(root, ".mcp.json"),
96486
+ // Codex
96487
+ join47(codexHome, "config.toml"),
96488
+ join47(root, ".codex", "config.toml"),
96489
+ // Gemini CLI
96490
+ join47(geminiHome, "settings.json"),
96491
+ join47(root, ".gemini", "settings.json"),
96492
+ // Cursor
96493
+ join47(home, ".cursor", "mcp.json"),
96494
+ join47(root, ".cursor", "mcp.json"),
96495
+ // VS Code (user profile mcp.json + workspace)
96496
+ join47(vscodeUserDir(home, env2), "mcp.json"),
96497
+ join47(root, ".vscode", "mcp.json"),
96498
+ // OpenCode (XDG on every platform; the daemon's installer writes the project one)
96499
+ join47(env2["XDG_CONFIG_HOME"] ?? join47(home, ".config"), "opencode", "opencode.json"),
96500
+ join47(root, "opencode.json")
96501
+ ];
96502
+ }
96503
+ function vscodeUserDir(home, env2) {
96504
+ if (process.platform === "win32") return join47(env2["APPDATA"] ?? join47(home, "AppData", "Roaming"), "Code", "User");
96505
+ if (process.platform === "darwin") return join47(home, "Library", "Application Support", "Code", "User");
96506
+ return join47(env2["XDG_CONFIG_HOME"] ?? join47(home, ".config"), "Code", "User");
96507
+ }
96508
+ function scanHarnessConfigs(paths, read2 = readBounded) {
96509
+ const findings = [];
96510
+ let scanned = 0;
96511
+ for (const file2 of new Set(paths)) {
96512
+ const text = read2(file2);
96513
+ if (text === null) continue;
96514
+ scanned++;
96515
+ for (const line of findCredentialLines(text)) findings.push({ file: file2, line });
96516
+ }
96517
+ return { scanned, findings };
96518
+ }
96519
+ function readBounded(path3) {
96520
+ try {
96521
+ const stat4 = statSync12(path3);
96522
+ if (!stat4.isFile() || stat4.size > MAX_SCAN_BYTES) return null;
96523
+ return readFileSync39(path3, "utf8");
96524
+ } catch {
96525
+ return null;
96526
+ }
96527
+ }
96528
+ function credentialHygieneCheck(scan2) {
96529
+ if (scan2.findings.length === 0) {
96530
+ return {
96531
+ id: "credential_hygiene",
96532
+ status: "pass",
96533
+ detail: `No plaintext errata credentials in ${scan2.scanned} harness config file(s)`
96534
+ };
96535
+ }
96536
+ const shown = scan2.findings.slice(0, MAX_LISTED_FINDINGS).map((finding) => `${finding.file}:${finding.line}`);
96537
+ const more = scan2.findings.length - shown.length;
96538
+ const where = shown.join(", ") + (more > 0 ? ` (+${more} more)` : "");
96539
+ return {
96540
+ id: "credential_hygiene",
96541
+ status: "warn",
96542
+ detail: `Plaintext errata credential in ${where} \u2014 remove it, revoke that key in the console, and run errata login (or reference an environment variable set outside committed/synced settings)`
96543
+ };
96544
+ }
96545
+
96209
96546
  // src/codex-doctor.ts
96210
96547
  import { spawn as spawn4 } from "node:child_process";
96211
- import { readFileSync as readFileSync39, statSync as statSync11 } from "node:fs";
96212
- import { join as join46 } from "node:path";
96548
+ import { readFileSync as readFileSync41, statSync as statSync13 } from "node:fs";
96549
+ import { join as join49 } from "node:path";
96213
96550
  import { createInterface } from "node:readline";
96214
96551
 
96215
96552
  // src/codex-hooks.ts
96216
- import { existsSync as existsSync35, mkdirSync as mkdirSync9, readFileSync as readFileSync38, renameSync as renameSync7, unlinkSync as unlinkSync5, writeFileSync as writeFileSync29 } from "node:fs";
96217
- import { homedir as homedir7 } from "node:os";
96218
- import { join as join45 } from "node:path";
96553
+ import { existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync40, renameSync as renameSync7, unlinkSync as unlinkSync5, writeFileSync as writeFileSync30 } from "node:fs";
96554
+ import { homedir as homedir9 } from "node:os";
96555
+ import { join as join48 } from "node:path";
96219
96556
 
96220
96557
  // src/hook-commands.ts
96221
96558
  function hookCurlCommand(port, path3 = "/api/hook") {
@@ -96419,34 +96756,34 @@ function buildCodexRelaySource(workspaceRoot) {
96419
96756
  init_checkout_root();
96420
96757
  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.";
96421
96758
  function writeRelay(file2, source) {
96422
- if (existsSync35(file2) && readFileSync38(file2, "utf8") === source) return;
96759
+ if (existsSync36(file2) && readFileSync40(file2, "utf8") === source) return;
96423
96760
  const temp = `${file2}.${process.pid}.tmp`;
96424
96761
  try {
96425
- writeFileSync29(temp, source, { encoding: "utf8", mode: 384 });
96762
+ writeFileSync30(temp, source, { encoding: "utf8", mode: 384 });
96426
96763
  renameSync7(temp, file2);
96427
96764
  } finally {
96428
- if (existsSync35(temp)) unlinkSync5(temp);
96765
+ if (existsSync36(temp)) unlinkSync5(temp);
96429
96766
  }
96430
96767
  }
96431
96768
  function refreshCodexRelay(root) {
96432
- const config2 = join45(root, ".codex", "config.toml");
96433
- if (!existsSync35(config2)) return "absent";
96434
- const existing = readFileSync38(config2, "utf8");
96769
+ const config2 = join48(root, ".codex", "config.toml");
96770
+ if (!existsSync36(config2)) return "absent";
96771
+ const existing = readFileSync40(config2, "utf8");
96435
96772
  if (!existing.includes(CODEX_HOOKS_BEGIN) && !existing.includes(CODEX_HOOKS_END)) return "absent";
96436
96773
  replaceCodexHooks(existing, "");
96437
- const relay = join45(root, ".codex", "hooks", "errata-relay.mjs");
96438
- const prior = existsSync35(relay) ? readFileSync38(relay, "utf8") : "";
96774
+ const relay = join48(root, ".codex", "hooks", "errata-relay.mjs");
96775
+ const prior = existsSync36(relay) ? readFileSync40(relay, "utf8") : "";
96439
96776
  if (prior && !prior.startsWith("// errata-managed: regenerated by errata install-hooks codex")) {
96440
96777
  throw new Error("Codex relay is not Errata-managed; preserved it. Run errata install-hooks codex to explicitly replace it.");
96441
96778
  }
96442
96779
  const source = buildCodexRelaySource(checkoutRootOf(root));
96443
96780
  if (prior === source) return "current";
96444
- mkdirSync9(join45(root, ".codex", "hooks"), { recursive: true });
96781
+ mkdirSync10(join48(root, ".codex", "hooks"), { recursive: true });
96445
96782
  writeRelay(relay, source);
96446
96783
  return "updated";
96447
96784
  }
96448
- function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join45(homedir7(), ".codex")) {
96449
- return existsSync35(join45(root, ".codex")) || existsSync35(codexHome);
96785
+ function hasCodexConfig(root, codexHome = process.env["CODEX_HOME"] || join48(homedir9(), ".codex")) {
96786
+ return existsSync36(join48(root, ".codex")) || existsSync36(codexHome);
96450
96787
  }
96451
96788
  function replaceCodexHooks(existing, block) {
96452
96789
  const begin = existing.indexOf(CODEX_HOOKS_BEGIN);
@@ -96462,14 +96799,14 @@ function replaceCodexHooks(existing, block) {
96462
96799
  return existing.trimEnd() + (existing.trim() ? "\n\n" : "") + block;
96463
96800
  }
96464
96801
  function writeCodexHooks(root, port, nodePath = process.execPath) {
96465
- const dir = join45(root, ".codex");
96466
- const file2 = join45(dir, "config.toml");
96467
- const relay = join45(dir, "hooks", "errata-relay.mjs");
96802
+ const dir = join48(root, ".codex");
96803
+ const file2 = join48(dir, "config.toml");
96804
+ const relay = join48(dir, "hooks", "errata-relay.mjs");
96468
96805
  const block = buildCodexHooksToml(port, { nodePath, relayPath: relay });
96469
- const final = replaceCodexHooks(existsSync35(file2) ? readFileSync38(file2, "utf8") : "", block);
96470
- mkdirSync9(join45(dir, "hooks"), { recursive: true });
96806
+ const final = replaceCodexHooks(existsSync36(file2) ? readFileSync40(file2, "utf8") : "", block);
96807
+ mkdirSync10(join48(dir, "hooks"), { recursive: true });
96471
96808
  writeRelay(relay, buildCodexRelaySource(checkoutRootOf(root)));
96472
- if (!existsSync35(file2) || readFileSync38(file2, "utf8") !== final) writeFileSync29(file2, final, "utf8");
96809
+ if (!existsSync36(file2) || readFileSync40(file2, "utf8") !== final) writeFileSync30(file2, final, "utf8");
96473
96810
  return file2;
96474
96811
  }
96475
96812
 
@@ -96478,7 +96815,7 @@ init_checkout_root();
96478
96815
  function inspectCodexRelay(cwd) {
96479
96816
  const root = nearestGitRoot(cwd) ?? cwd;
96480
96817
  try {
96481
- const source = readFileSync39(join46(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
96818
+ const source = readFileSync41(join49(root, ".codex", "hooks", "errata-relay.mjs"), "utf8");
96482
96819
  if (source === buildCodexRelaySource(checkoutRootOf(root))) {
96483
96820
  return { id: "codex_relay", status: "pass", detail: "Installed Codex relay matches this Errata version" };
96484
96821
  }
@@ -96489,8 +96826,8 @@ function inspectCodexRelay(cwd) {
96489
96826
  function inspectCodexContext(cwd) {
96490
96827
  const root = checkoutRootOf(nearestGitRoot(cwd) ?? cwd);
96491
96828
  try {
96492
- const file2 = join46(root, ".errata", "context.md");
96493
- if (statSync11(file2).size <= 128 * 1024 && readFileSync39(file2, "utf8").trim()) {
96829
+ const file2 = join49(root, ".errata", "context.md");
96830
+ if (statSync13(file2).size <= 128 * 1024 && readFileSync41(file2, "utf8").trim()) {
96494
96831
  return { id: "codex_context", status: "pass", detail: "Saved workspace context is readable by the relay; this does not prove live daemon freshness" };
96495
96832
  }
96496
96833
  } catch {
@@ -96668,9 +97005,9 @@ function consolidationGapMs(lastPassMs, policy) {
96668
97005
 
96669
97006
  // src/codex-context-plugin.ts
96670
97007
  import { createHash as createHash20 } from "node:crypto";
96671
- import { cpSync as cpSync2, existsSync as existsSync36, mkdirSync as mkdirSync10, readFileSync as readFileSync40, renameSync as renameSync8, writeFileSync as writeFileSync30 } from "node:fs";
96672
- import { homedir as homedir8 } from "node:os";
96673
- import { join as join47 } from "node:path";
97008
+ import { cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync11, readFileSync as readFileSync42, renameSync as renameSync8, writeFileSync as writeFileSync31 } from "node:fs";
97009
+ import { homedir as homedir10 } from "node:os";
97010
+ import { join as join50 } from "node:path";
96674
97011
  import { fileURLToPath as fileURLToPath2 } from "node:url";
96675
97012
 
96676
97013
  // ../../node_modules/.pnpm/smol-toml@1.6.1/node_modules/smol-toml/dist/error.js
@@ -97368,23 +97705,23 @@ var NAME = "errata-context";
97368
97705
  var PREFIX2 = `./.errata/plugins/${NAME}/`;
97369
97706
  var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
97370
97707
  function readText(file2) {
97371
- return existsSync36(file2) ? readFileSync40(file2, "utf8") : "";
97708
+ return existsSync37(file2) ? readFileSync42(file2, "utf8") : "";
97372
97709
  }
97373
97710
  function writeChanged(file2, content) {
97374
97711
  if (readText(file2) === content) return;
97375
97712
  const temp = `${file2}.${process.pid}.tmp`;
97376
- writeFileSync30(temp, content, "utf8");
97713
+ writeFileSync31(temp, content, "utf8");
97377
97714
  renameSync8(temp, file2);
97378
97715
  }
97379
97716
  function bundledContextPlugin() {
97380
97717
  const packaged = fileURLToPath2(new URL("./resources/context-plugin/", import.meta.url));
97381
- if (existsSync36(join47(packaged, ".codex-plugin/plugin.json"))) return packaged;
97718
+ if (existsSync37(join50(packaged, ".codex-plugin/plugin.json"))) return packaged;
97382
97719
  return fileURLToPath2(new URL("../dist/resources/context-plugin/", import.meta.url));
97383
97720
  }
97384
97721
  function refreshCodexContextPlugin(root) {
97385
- const file2 = join47(root, ".agents", "plugins", "marketplace.json");
97386
- if (!existsSync36(file2)) return false;
97387
- const marketplace = JSON.parse(readFileSync40(file2, "utf8"));
97722
+ const file2 = join50(root, ".agents", "plugins", "marketplace.json");
97723
+ if (!existsSync37(file2)) return false;
97724
+ const marketplace = JSON.parse(readFileSync42(file2, "utf8"));
97388
97725
  const entries = Array.isArray(marketplace.plugins) ? marketplace.plugins : [];
97389
97726
  const entry = entries.map(object2).find((value) => value.name === NAME && String(object2(value.source).path).startsWith(PREFIX2));
97390
97727
  if (!entry) return false;
@@ -97395,24 +97732,24 @@ function refreshCodexContextPlugin(root) {
97395
97732
  function installCodexContextPlugin(root, options = {}) {
97396
97733
  const bundle = options.bundle ?? bundledContextPlugin();
97397
97734
  const manifest = JSON.parse(
97398
- readFileSync40(join47(bundle, ".codex-plugin/plugin.json"), "utf8")
97735
+ readFileSync42(join50(bundle, ".codex-plugin/plugin.json"), "utf8")
97399
97736
  );
97400
97737
  if (manifest.name !== NAME || typeof manifest.version !== "string" || !/^[\w.-]+$/.test(manifest.version)) {
97401
97738
  throw new Error("Invalid bundled Errata Context manifest.");
97402
97739
  }
97403
- const checksums = readFileSync40(join47(bundle, "SHA256SUMS"), "utf8");
97740
+ const checksums = readFileSync42(join50(bundle, "SHA256SUMS"), "utf8");
97404
97741
  for (const line of checksums.trim().split("\n")) {
97405
97742
  const match2 = /^([a-f0-9]{64}) ([\w./-]+)$/.exec(line);
97406
97743
  if (!match2 || match2[2].startsWith("/") || match2[2].split("/").includes("..")) {
97407
97744
  throw new Error("Invalid bundled Errata Context checksum manifest.");
97408
97745
  }
97409
- const actual = createHash20("sha256").update(readFileSync40(join47(bundle, match2[2]))).digest("hex");
97746
+ const actual = createHash20("sha256").update(readFileSync42(join50(bundle, match2[2]))).digest("hex");
97410
97747
  if (actual !== match2[1])
97411
97748
  throw new Error(`Bundled Errata Context checksum mismatch: ${match2[2]}`);
97412
97749
  }
97413
97750
  const release = `${manifest.version}-${createHash20("sha256").update(checksums).digest("hex").slice(0, 12)}`;
97414
- const plugin = join47(root, ".errata", "plugins", NAME, release);
97415
- const marketplaceFile = join47(root, ".agents", "plugins", "marketplace.json");
97751
+ const plugin = join50(root, ".errata", "plugins", NAME, release);
97752
+ const marketplaceFile = join50(root, ".agents", "plugins", "marketplace.json");
97416
97753
  const priorMarketplace = readText(marketplaceFile);
97417
97754
  const marketplace = priorMarketplace ? JSON.parse(priorMarketplace) : {
97418
97755
  name: "errata-local",
@@ -97433,12 +97770,12 @@ function installCodexContextPlugin(root, options = {}) {
97433
97770
  );
97434
97771
  }
97435
97772
  const key = `${NAME}@${marketplace.name}`;
97436
- const configFile = join47(root, ".codex", "config.toml");
97773
+ const configFile = join50(root, ".codex", "config.toml");
97437
97774
  const config2 = readText(configFile);
97438
97775
  const parsed = parse4(config2);
97439
97776
  const plugins = object2(parsed.plugins);
97440
- const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join47(homedir8(), ".codex");
97441
- const globalPlugins = object2(parse4(readText(join47(codexHome, "config.toml"))).plugins);
97777
+ const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? join50(homedir10(), ".codex");
97778
+ const globalPlugins = object2(parse4(readText(join50(codexHome, "config.toml"))).plugins);
97442
97779
  const disabledGlobally = Object.entries(globalPlugins).some(
97443
97780
  ([name2, value]) => (name2 === NAME || name2.startsWith(`${NAME}@`)) && object2(value).enabled === false
97444
97781
  );
@@ -97459,16 +97796,16 @@ enabled = ${enabled}
97459
97796
  category: prior?.category ?? "Productivity"
97460
97797
  };
97461
97798
  marketplace.plugins = [...entries.filter((item2) => item2.name !== NAME), entry];
97462
- mkdirSync10(plugin, { recursive: true });
97799
+ mkdirSync11(plugin, { recursive: true });
97463
97800
  cpSync2(bundle, plugin, { recursive: true });
97464
97801
  writeChanged(
97465
- join47(plugin, ".mcp.json"),
97802
+ join50(plugin, ".mcp.json"),
97466
97803
  JSON.stringify(
97467
97804
  {
97468
97805
  mcpServers: {
97469
97806
  errata_context: {
97470
97807
  command: options.nodePath ?? process.execPath,
97471
- args: [join47(plugin, "dist", "mcp-server.mjs")],
97808
+ args: [join50(plugin, "dist", "mcp-server.mjs")],
97472
97809
  env: { ERRATA_WORKSPACE: root, ERRATA_CONTEXT_VERSION: manifest.version }
97473
97810
  }
97474
97811
  }
@@ -97477,8 +97814,8 @@ enabled = ${enabled}
97477
97814
  2
97478
97815
  ) + "\n"
97479
97816
  );
97480
- mkdirSync10(join47(root, ".agents", "plugins"), { recursive: true });
97481
- mkdirSync10(join47(root, ".codex"), { recursive: true });
97817
+ mkdirSync11(join50(root, ".agents", "plugins"), { recursive: true });
97818
+ mkdirSync11(join50(root, ".codex"), { recursive: true });
97482
97819
  writeChanged(marketplaceFile, JSON.stringify(marketplace, null, 2) + "\n");
97483
97820
  writeChanged(configFile, nextConfig);
97484
97821
  return { plugin, enabled, marketplace: marketplaceFile };
@@ -97486,16 +97823,16 @@ enabled = ${enabled}
97486
97823
 
97487
97824
  // src/codex-hook-refresh.ts
97488
97825
  init_checkout_root();
97489
- import { existsSync as existsSync37, readdirSync as readdirSync14, readFileSync as readFileSync41 } from "node:fs";
97490
- import { dirname as dirname16, join as join48, resolve as resolve8 } from "node:path";
97826
+ import { existsSync as existsSync38, readdirSync as readdirSync14, readFileSync as readFileSync43 } from "node:fs";
97827
+ import { dirname as dirname17, join as join51, resolve as resolve8 } from "node:path";
97491
97828
  init_registry();
97492
97829
  function codexHookRoots(roots) {
97493
97830
  const found = new Set(roots.map((root) => resolve8(root)));
97494
97831
  for (const root of [...found]) {
97495
97832
  const main2 = mainCheckoutOfWorktree(root) ?? root;
97496
97833
  found.add(main2);
97497
- const dir = join48(main2, ".git", "worktrees");
97498
- if (!existsSync37(dir)) continue;
97834
+ const dir = join51(main2, ".git", "worktrees");
97835
+ if (!existsSync38(dir)) continue;
97499
97836
  let names;
97500
97837
  try {
97501
97838
  names = readdirSync14(dir);
@@ -97504,7 +97841,7 @@ function codexHookRoots(roots) {
97504
97841
  }
97505
97842
  for (const name2 of names) {
97506
97843
  try {
97507
- const checkout = dirname16(readFileSync41(join48(dir, name2, "gitdir"), "utf8").trim());
97844
+ const checkout = dirname17(readFileSync43(join51(dir, name2, "gitdir"), "utf8").trim());
97508
97845
  if (mainCheckoutOfWorktree(checkout) === main2) found.add(checkout);
97509
97846
  } catch {
97510
97847
  }
@@ -97525,116 +97862,10 @@ function refreshInstalledCodexRelays(roots = listWorkspaceEntries().map((entry)
97525
97862
  return results;
97526
97863
  }
97527
97864
 
97528
- // src/claude-statusline.ts
97529
- import { existsSync as existsSync38, mkdirSync as mkdirSync11, readFileSync as readFileSync42, writeFileSync as writeFileSync31 } from "node:fs";
97530
- import { homedir as homedir9 } from "node:os";
97531
- import { dirname as dirname17, join as join49 } from "node:path";
97532
- var STATUSLINE_RELAY_SOURCE = String.raw`// errata-managed: regenerated by errata init / install-hooks claude
97533
- import { readFileSync } from 'node:fs';
97534
-
97535
- try {
97536
- const port = Number(process.argv[2]);
97537
- const route = process.argv[3] === 'subagents' ? '/api/statusline/subagents' : '/api/statusline';
97538
- if (Number.isInteger(port) && port > 0 && port < 65536) {
97539
- const response = await fetch('http://127.0.0.1:' + port + route, {
97540
- method: 'POST', headers: { 'Content-Type': 'application/json' },
97541
- body: readFileSync(0, 'utf8') || '{}', signal: AbortSignal.timeout(800),
97542
- });
97543
- if (response.ok) process.stdout.write(await response.text());
97544
- }
97545
- } catch { /* An unavailable daemon leaves the status line empty. */ }
97546
- `;
97547
- var STATUSLINE_RELAY_FILE = "errata-statusline.mjs";
97548
- function buildStatusLine(port, nodePath, relayPath) {
97549
- return { type: "command", command: relayCommand(port, nodePath, relayPath), padding: 0 };
97550
- }
97551
- function buildSubagentStatusLine(port, nodePath, relayPath) {
97552
- return { type: "command", command: `${relayCommand(port, nodePath, relayPath)} subagents` };
97553
- }
97554
- function relayCommand(port, nodePath, relayPath) {
97555
- if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Invalid status line port");
97556
- const q = (p) => {
97557
- if (/["$`\r\n]/.test(p)) throw new Error("Unsupported character in status line path");
97558
- return `"${p.replace(/\\/g, "/")}"`;
97559
- };
97560
- return `${q(nodePath)} ${q(relayPath)} ${port}`;
97561
- }
97562
- function isErrataStatusLine(value) {
97563
- return !!value && typeof value === "object" && typeof value["command"] === "string" && value["command"].includes(STATUSLINE_RELAY_FILE);
97564
- }
97565
- function removeProjectStatusLine(settings) {
97566
- let removed = false;
97567
- for (const key of ["statusLine", "subagentStatusLine"]) {
97568
- if (!isErrataStatusLine(settings[key])) continue;
97569
- delete settings[key];
97570
- removed = true;
97571
- }
97572
- return removed;
97573
- }
97574
- function isSameInstall(value, relay) {
97575
- const command = value["command"].replace(/\\/g, "/").toLowerCase();
97576
- return command.includes(relay.replace(/\\/g, "/").toLowerCase());
97577
- }
97578
- function userClaudeSettingsPath() {
97579
- const base = process.env["CLAUDE_CONFIG_DIR"] ?? join49(homedir9(), ".claude");
97580
- return join49(base, "settings.json");
97581
- }
97582
- function ensureUserStatusLine(opts) {
97583
- const env2 = opts.env ?? process.env;
97584
- const off2 = (env2["ERRATA_STATUSLINE"] ?? "").trim().toLowerCase();
97585
- if (off2 === "0" || off2 === "off" || off2 === "false" || off2 === "no") return "disabled";
97586
- const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
97587
- let settings = {};
97588
- if (existsSync38(settingsPath)) {
97589
- try {
97590
- const parsed = JSON.parse(readFileSync42(settingsPath, "utf8"));
97591
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return "unreadable";
97592
- settings = parsed;
97593
- } catch {
97594
- return "unreadable";
97595
- }
97596
- }
97597
- const relay = join49(opts.relayDir, STATUSLINE_RELAY_FILE);
97598
- const keep = (value) => value !== void 0 && (!isErrataStatusLine(value) || !isSameInstall(value, relay));
97599
- const ownMain = keep(settings["statusLine"]);
97600
- const ownRows = keep(settings["subagentStatusLine"]);
97601
- if (ownMain && ownRows) return "kept-own";
97602
- mkdirSync11(opts.relayDir, { recursive: true });
97603
- if (!existsSync38(relay) || readFileSync42(relay, "utf8") !== STATUSLINE_RELAY_SOURCE) {
97604
- writeFileSync31(relay, STATUSLINE_RELAY_SOURCE, "utf8");
97605
- }
97606
- const nodePath = opts.nodePath ?? process.execPath;
97607
- const next = {
97608
- ...ownMain ? {} : { statusLine: buildStatusLine(opts.port, nodePath, relay) },
97609
- ...ownRows ? {} : { subagentStatusLine: buildSubagentStatusLine(opts.port, nodePath, relay) }
97610
- };
97611
- if (Object.entries(next).every(([k, v]) => JSON.stringify(settings[k]) === JSON.stringify(v))) {
97612
- return ownMain ? "kept-own" : "unchanged";
97613
- }
97614
- Object.assign(settings, next);
97615
- mkdirSync11(dirname17(settingsPath), { recursive: true });
97616
- writeFileSync31(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
97617
- return "installed";
97618
- }
97619
- function describeStatusLineOutcome(outcome) {
97620
- switch (outcome) {
97621
- case "installed":
97622
- return "status line: errata recall card in colour (user settings; ERRATA_STATUSLINE=off opts out)";
97623
- case "unchanged":
97624
- return "status line: errata recall card already set up";
97625
- case "kept-own":
97626
- return "status line: kept your own \u2014 errata's recall card shows inline only";
97627
- case "disabled":
97628
- return "status line: skipped (ERRATA_STATUSLINE=off)";
97629
- case "unreadable":
97630
- return "status line: skipped \u2014 ~/.claude/settings.json is not valid JSON";
97631
- }
97632
- }
97633
-
97634
97865
  // src/claude-mods.ts
97635
97866
  import { createHash as createHash21 } from "node:crypto";
97636
- import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync43, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync12, writeFileSync as writeFileSync32 } from "node:fs";
97637
- import { delimiter as delimiter2, dirname as dirname18, join as join50, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
97867
+ import { cpSync as cpSync3, existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync44, readdirSync as readdirSync15, rmSync as rmSync4, statSync as statSync14, writeFileSync as writeFileSync32 } from "node:fs";
97868
+ import { delimiter as delimiter2, dirname as dirname18, join as join52, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
97638
97869
  import { fileURLToPath as fileURLToPath3 } from "node:url";
97639
97870
  var CLAUDE_PLUGIN_DIRS_ENV = "CLAUDE_CODE_PLUGIN_DIRS";
97640
97871
  var HASH_FILE = ".errata-mod-hash";
@@ -97649,9 +97880,9 @@ function isEngineOwned(relPath) {
97649
97880
  function listFiles(root, dir = root) {
97650
97881
  const out2 = [];
97651
97882
  for (const name2 of readdirSync15(dir)) {
97652
- const abs = join50(dir, name2);
97883
+ const abs = join52(dir, name2);
97653
97884
  if (isEngineOwned(relative8(root, abs))) continue;
97654
- if (statSync12(abs).isDirectory()) out2.push(...listFiles(root, abs));
97885
+ if (statSync14(abs).isDirectory()) out2.push(...listFiles(root, abs));
97655
97886
  else out2.push(abs);
97656
97887
  }
97657
97888
  return out2;
@@ -97661,14 +97892,14 @@ function modHash(dir) {
97661
97892
  for (const abs of listFiles(dir).sort()) {
97662
97893
  h.update(relative8(dir, abs).split(sep5).join("/"));
97663
97894
  h.update("\0");
97664
- h.update(readFileSync43(abs));
97895
+ h.update(readFileSync44(abs));
97665
97896
  h.update("\0");
97666
97897
  }
97667
97898
  return h.digest("hex");
97668
97899
  }
97669
97900
  function bundledMods(bundleDir) {
97670
97901
  if (!existsSync39(bundleDir)) return [];
97671
- return readdirSync15(bundleDir).filter((name2) => existsSync39(join50(bundleDir, name2, ".claude-plugin", "plugin.json")));
97902
+ return readdirSync15(bundleDir).filter((name2) => existsSync39(join52(bundleDir, name2, ".claude-plugin", "plugin.json")));
97672
97903
  }
97673
97904
  function sameDir(a, b) {
97674
97905
  const norm = (p) => resolve9(p).replace(/[\\/]+$/, "").toLowerCase();
@@ -97685,7 +97916,7 @@ function off(env2) {
97685
97916
  function readSettings(path3) {
97686
97917
  if (!existsSync39(path3)) return {};
97687
97918
  try {
97688
- const parsed = JSON.parse(readFileSync43(path3, "utf8"));
97919
+ const parsed = JSON.parse(readFileSync44(path3, "utf8"));
97689
97920
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
97690
97921
  return parsed;
97691
97922
  } catch {
@@ -97715,7 +97946,7 @@ function writeSettings(path3, settings) {
97715
97946
  function ensureClaudeMods(opts) {
97716
97947
  const env2 = opts.env ?? process.env;
97717
97948
  const settingsPath = opts.userSettingsPath ?? userClaudeSettingsPath();
97718
- const modsRoot = join50(opts.installRoot, "claude-mods");
97949
+ const modsRoot = join52(opts.installRoot, "claude-mods");
97719
97950
  if (off(env2)) {
97720
97951
  const settings2 = readSettings(settingsPath);
97721
97952
  if (!settings2) return { kind: "unreadable" };
@@ -97732,11 +97963,11 @@ function ensureClaudeMods(opts) {
97732
97963
  let changed = false;
97733
97964
  const installed = [];
97734
97965
  for (const name2 of names) {
97735
- const src = join50(bundleDir, name2);
97736
- const dest = join50(modsRoot, name2);
97966
+ const src = join52(bundleDir, name2);
97967
+ const dest = join52(modsRoot, name2);
97737
97968
  const hash2 = modHash(src);
97738
- const hashFile = join50(dest, HASH_FILE);
97739
- if (!existsSync39(hashFile) || readFileSync43(hashFile, "utf8") !== hash2) {
97969
+ const hashFile = join52(dest, HASH_FILE);
97970
+ if (!existsSync39(hashFile) || readFileSync44(hashFile, "utf8") !== hash2) {
97740
97971
  rmSync4(dest, { recursive: true, force: true });
97741
97972
  cpSync3(src, dest, { recursive: true, filter: (p) => !isEngineOwned(relative8(src, p)) });
97742
97973
  writeFileSync32(hashFile, hash2, "utf8");
@@ -98160,9 +98391,9 @@ function resolveHookPort(explicit) {
98160
98391
  }
98161
98392
  }
98162
98393
  }
98163
- const settingsPath = join51(ROOT, ".claude", "settings.json");
98394
+ const settingsPath = join53(ROOT, ".claude", "settings.json");
98164
98395
  try {
98165
- if (existsSync40(settingsPath)) return installedHookPort(readFileSync44(settingsPath, "utf8")) ?? 7891;
98396
+ if (existsSync40(settingsPath)) return installedHookPort(readFileSync45(settingsPath, "utf8")) ?? 7891;
98166
98397
  } catch {
98167
98398
  }
98168
98399
  return 7891;
@@ -98188,13 +98419,13 @@ async function cmdInit() {
98188
98419
  console.log("");
98189
98420
  console.log("installing harness hooks...");
98190
98421
  const { existsSync: existsSync41 } = await import("node:fs");
98191
- const { join: join52 } = await import("node:path");
98422
+ const { join: join54 } = await import("node:path");
98192
98423
  try {
98193
98424
  await installClaudeHooks(port);
98194
98425
  } catch (err2) {
98195
98426
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
98196
98427
  }
98197
- if (existsSync41(join52(ROOT, ".cursor"))) {
98428
+ if (existsSync41(join54(ROOT, ".cursor"))) {
98198
98429
  try {
98199
98430
  await installCursorMcpConfig();
98200
98431
  } catch (err2) {
@@ -98696,6 +98927,7 @@ async function cmdDoctor(args2) {
98696
98927
  const lock = readDaemonLock(lockPath);
98697
98928
  return daemonDoctorCheck({ lock, state: daemonLockState(lock, true), selfVersion: DAEMON_VERSION, lockPath });
98698
98929
  },
98930
+ credentialHygiene: () => credentialHygieneCheck(scanHarnessConfigs(harnessConfigPaths(ROOT))),
98699
98931
  inspect: () => inspectCloudEndpoint(cfg.cloudUrl),
98700
98932
  authenticate: async () => {
98701
98933
  const me = await authedCloudClient(cfg).me();
@@ -99416,7 +99648,7 @@ async function cmdReview() {
99416
99648
  console.log("(review queue empty)");
99417
99649
  return;
99418
99650
  }
99419
- const queue = JSON.parse(readFileSync44(paths.reviewQueue, "utf8"));
99651
+ const queue = JSON.parse(readFileSync45(paths.reviewQueue, "utf8"));
99420
99652
  if (queue.length === 0) {
99421
99653
  console.log("(review queue empty)");
99422
99654
  return;
@@ -100168,8 +100400,8 @@ async function cmdReport(args2) {
100168
100400
  const outDir = workspacePaths(ROOT).configDir;
100169
100401
  mkdirSync13(outDir, { recursive: true });
100170
100402
  const files = renderReport2(data, { includeFutureVerbs });
100171
- for (const f of files) writeFileSync33(join51(outDir, f.name), f.html, "utf8");
100172
- const indexPath = join51(outDir, "report.html");
100403
+ for (const f of files) writeFileSync33(join53(outDir, f.name), f.html, "utf8");
100404
+ const indexPath = join53(outDir, "report.html");
100173
100405
  console.log(`report \u2192 ${indexPath}`);
100174
100406
  console.log(
100175
100407
  ` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
@@ -100225,7 +100457,7 @@ function spawnDaemonDetached(options = {}) {
100225
100457
  try {
100226
100458
  const logPath = daemonLogPath();
100227
100459
  try {
100228
- if (statSync13(logPath).size > 5 * 1024 * 1024) renameSync9(logPath, `${logPath}.1`);
100460
+ if (statSync15(logPath).size > 5 * 1024 * 1024) renameSync9(logPath, `${logPath}.1`);
100229
100461
  } catch {
100230
100462
  }
100231
100463
  out2 = openSync3(logPath, "a");
@@ -100294,24 +100526,24 @@ async function cmdInstallHooks(args2) {
100294
100526
  }
100295
100527
  }
100296
100528
  async function installOpencodePlugin(port) {
100297
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100298
- const { join: join52 } = await import("node:path");
100299
- const dir = join52(ROOT, ".opencode", "plugin");
100529
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100530
+ const { join: join54 } = await import("node:path");
100531
+ const dir = join54(ROOT, ".opencode", "plugin");
100300
100532
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100301
- const file2 = join52(dir, "inerrata.js");
100533
+ const file2 = join54(dir, "inerrata.js");
100302
100534
  if (existsSync41(file2)) {
100303
- const head2 = readFileSync45(file2, "utf8").split("\n")[0] ?? "";
100535
+ const head2 = readFileSync46(file2, "utf8").split("\n")[0] ?? "";
100304
100536
  if (head2.trim() !== OPENCODE_PLUGIN_MARKER) {
100305
100537
  console.error(`refusing to overwrite ${file2}: not an errata-managed plugin (line 1 lacks the marker)`);
100306
100538
  process.exit(2);
100307
100539
  }
100308
100540
  }
100309
100541
  writeFileSync33(file2, buildOpencodePluginSource(port, { version: DAEMON_VERSION }), "utf8");
100310
- const cfgFile = join52(ROOT, "opencode.json");
100542
+ const cfgFile = join54(ROOT, "opencode.json");
100311
100543
  let cfg = { $schema: "https://opencode.ai/config.json" };
100312
100544
  if (existsSync41(cfgFile)) {
100313
100545
  try {
100314
- cfg = JSON.parse(readFileSync45(cfgFile, "utf8"));
100546
+ cfg = JSON.parse(readFileSync46(cfgFile, "utf8"));
100315
100547
  } catch {
100316
100548
  console.error(`refusing to touch invalid JSON at ${cfgFile} \u2014 fix it and re-run`);
100317
100549
  process.exit(2);
@@ -100357,15 +100589,15 @@ function installClaudeMods() {
100357
100589
  }
100358
100590
  }
100359
100591
  async function installClaudeHooks(port) {
100360
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100361
- const { join: join52 } = await import("node:path");
100362
- const dir = join52(ROOT, ".claude");
100592
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100593
+ const { join: join54 } = await import("node:path");
100594
+ const dir = join54(ROOT, ".claude");
100363
100595
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100364
- const file2 = join52(dir, "settings.json");
100596
+ const file2 = join54(dir, "settings.json");
100365
100597
  let settings = {};
100366
100598
  if (existsSync41(file2)) {
100367
100599
  try {
100368
- settings = JSON.parse(readFileSync45(file2, "utf8"));
100600
+ settings = JSON.parse(readFileSync46(file2, "utf8"));
100369
100601
  } catch {
100370
100602
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100371
100603
  process.exit(2);
@@ -100419,7 +100651,7 @@ async function installClaudeHooks(port) {
100419
100651
  console.log(` ${ensureStatusLine(port)}`);
100420
100652
  console.log(` ${installClaudeMods().line}`);
100421
100653
  await installClaudeMcpConfig();
100422
- const claudeMd = join52(ROOT, "CLAUDE.md");
100654
+ const claudeMd = join54(ROOT, "CLAUDE.md");
100423
100655
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
100424
100656
  if (recall.kind === "collision") {
100425
100657
  console.warn(
@@ -100431,15 +100663,15 @@ async function installClaudeHooks(port) {
100431
100663
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
100432
100664
  }
100433
100665
  async function installClaudeMcpConfig() {
100434
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100435
- const { join: join52, dirname: dirname19 } = await import("node:path");
100436
- const file2 = join52(ROOT, ".mcp.json");
100666
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100667
+ const { join: join54, dirname: dirname19 } = await import("node:path");
100668
+ const file2 = join54(ROOT, ".mcp.json");
100437
100669
  const dir = dirname19(file2);
100438
100670
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100439
100671
  let cfg = {};
100440
100672
  if (existsSync41(file2)) {
100441
100673
  try {
100442
- cfg = JSON.parse(readFileSync45(file2, "utf8"));
100674
+ cfg = JSON.parse(readFileSync46(file2, "utf8"));
100443
100675
  } catch {
100444
100676
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100445
100677
  process.exit(2);
@@ -100453,15 +100685,15 @@ async function installClaudeMcpConfig() {
100453
100685
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
100454
100686
  }
100455
100687
  async function installCursorMcpConfig() {
100456
- const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync45, writeFileSync: writeFileSync33 } = await import("node:fs");
100457
- const { join: join52 } = await import("node:path");
100458
- const dir = join52(ROOT, ".cursor");
100688
+ const { mkdirSync: mkdirSync13, existsSync: existsSync41, readFileSync: readFileSync46, writeFileSync: writeFileSync33 } = await import("node:fs");
100689
+ const { join: join54 } = await import("node:path");
100690
+ const dir = join54(ROOT, ".cursor");
100459
100691
  if (!existsSync41(dir)) mkdirSync13(dir, { recursive: true });
100460
- const file2 = join52(dir, "mcp.json");
100692
+ const file2 = join54(dir, "mcp.json");
100461
100693
  let cfg = {};
100462
100694
  if (existsSync41(file2)) {
100463
100695
  try {
100464
- cfg = JSON.parse(readFileSync45(file2, "utf8"));
100696
+ cfg = JSON.parse(readFileSync46(file2, "utf8"));
100465
100697
  } catch {
100466
100698
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
100467
100699
  process.exit(2);
@@ -100480,7 +100712,7 @@ async function installCodexHooks(port) {
100480
100712
  const gitRoot = nearestGitRoot(process.cwd());
100481
100713
  const hookRoot = gitRoot && mainCheckoutOfWorktree(gitRoot) ? gitRoot : ROOT;
100482
100714
  const file2 = writeCodexHooks(hookRoot, port);
100483
- const instructions = writeManagedBlock(join51(hookRoot, "AGENTS.md"), {
100715
+ const instructions = writeManagedBlock(join53(hookRoot, "AGENTS.md"), {
100484
100716
  body: AGENTS_POINTER_BODY,
100485
100717
  stable: true
100486
100718
  });
@@ -100926,9 +101158,9 @@ async function cmdDash(args2) {
100926
101158
  await yieldToLoop2();
100927
101159
  try {
100928
101160
  const items = selectDurableMemory(handle2.sharedStore, r.engine.profile, {
100929
- atCommit: readGitRefState(join51(r.root, ".git")).sha ?? void 0
101161
+ atCommit: readGitRefState(join53(r.root, ".git")).sha ?? void 0
100930
101162
  });
100931
- const res = bleedRules(join51(r.root, ".claude", "rules"), items);
101163
+ const res = bleedRules(join53(r.root, ".claude", "rules"), items);
100932
101164
  if (res.written || res.pruned) {
100933
101165
  console.log(
100934
101166
  `[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")