@inerrata-corporation/errata 2.0.2-dev.196 → 2.0.2-dev.201

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/errata.mjs +330 -174
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -47172,12 +47172,12 @@ var init_report_render = __esm({
47172
47172
 
47173
47173
  // src/cli.ts
47174
47174
  init_src5();
47175
- import { closeSync as closeSync2, existsSync as existsSync24, openSync as openSync2, readFileSync as readFileSync22, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
47176
- import { join as join26 } from "node:path";
47175
+ import { closeSync as closeSync2, existsSync as existsSync25, openSync as openSync2, readFileSync as readFileSync23, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
47176
+ import { join as join27 } from "node:path";
47177
47177
  import { spawn as spawn3 } from "node:child_process";
47178
47178
 
47179
47179
  // src/daemon.ts
47180
- import { existsSync as existsSync19, writeFileSync as writeFileSync15 } from "node:fs";
47180
+ import { existsSync as existsSync20, writeFileSync as writeFileSync16 } from "node:fs";
47181
47181
 
47182
47182
  // ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
47183
47183
  import { createServer as createServerHTTP } from "http";
@@ -47757,8 +47757,8 @@ init_config();
47757
47757
 
47758
47758
  // src/engine.ts
47759
47759
  import { execFileSync as execFileSync3 } from "node:child_process";
47760
- import { existsSync as existsSync18, statSync as statSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync8, renameSync as renameSync2, readFileSync as readFileSync17, writeFileSync as writeFileSync14 } from "node:fs";
47761
- import { join as join22, relative as relative6, sep as sep4 } from "node:path";
47760
+ import { existsSync as existsSync19, statSync as statSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync9, renameSync as renameSync2, readFileSync as readFileSync18, writeFileSync as writeFileSync15 } from "node:fs";
47761
+ import { join as join23, relative as relative6, sep as sep4 } from "node:path";
47762
47762
 
47763
47763
  // ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
47764
47764
  import { stat as statcb } from "fs";
@@ -50541,6 +50541,147 @@ ${conversation}` }]
50541
50541
  };
50542
50542
  }
50543
50543
 
50544
+ // src/constraint-backfill.ts
50545
+ init_src4();
50546
+ init_src2();
50547
+ import { existsSync as existsSync13, readFileSync as readFileSync11, readdirSync as readdirSync6, writeFileSync as writeFileSync11 } from "node:fs";
50548
+ import { join as join16 } from "node:path";
50549
+ import { homedir as homedir4 } from "node:os";
50550
+ var BACKFILL_VERSION = 1;
50551
+ var EMPTY = {
50552
+ skipped: true,
50553
+ stamped: 0,
50554
+ detached: 0,
50555
+ reopened: 0,
50556
+ witnessed: 0,
50557
+ cloudTwins: []
50558
+ };
50559
+ function markerPath(configDir) {
50560
+ return join16(configDir, "constraint-backfill.json");
50561
+ }
50562
+ function alreadyDone(configDir) {
50563
+ const p = markerPath(configDir);
50564
+ if (!existsSync13(p)) return false;
50565
+ try {
50566
+ const raw2 = JSON.parse(readFileSync11(p, "utf8"));
50567
+ return raw2?.version === BACKFILL_VERSION;
50568
+ } catch {
50569
+ return false;
50570
+ }
50571
+ }
50572
+ function replay(root) {
50573
+ const statements = /* @__PURE__ */ new Set();
50574
+ const citedByFix = /* @__PURE__ */ new Set();
50575
+ const dir = claudeProjectDir(root, homedir4());
50576
+ if (!existsSync13(dir)) return { statements, citedByFix };
50577
+ let names;
50578
+ try {
50579
+ names = readdirSync6(dir).filter((n) => n.endsWith(".jsonl"));
50580
+ } catch {
50581
+ return { statements, citedByFix };
50582
+ }
50583
+ for (const f of names) {
50584
+ let lines;
50585
+ try {
50586
+ lines = readFileSync11(join16(dir, f), "utf8").split("\n");
50587
+ } catch {
50588
+ continue;
50589
+ }
50590
+ for (const line of lines) {
50591
+ if (!line.trim()) continue;
50592
+ let rec;
50593
+ try {
50594
+ rec = JSON.parse(line);
50595
+ } catch {
50596
+ continue;
50597
+ }
50598
+ if (rec.type !== "assistant" || !Array.isArray(rec.message?.content)) continue;
50599
+ for (const b of rec.message.content) {
50600
+ if (b?.type !== "text" || typeof b.text !== "string") continue;
50601
+ for (const tag of parseInlineTags(b.text)) {
50602
+ if (tag.kind === "constraint" && tag.statement) statements.add(tag.statement);
50603
+ if (tag.kind === "fix") {
50604
+ const t = tag;
50605
+ if (t.handle) citedByFix.add(t.handle);
50606
+ if (t.threadId) citedByFix.add(t.threadId);
50607
+ }
50608
+ }
50609
+ }
50610
+ }
50611
+ }
50612
+ return { statements, citedByFix };
50613
+ }
50614
+ function backfillConstraintKind(store, opts) {
50615
+ if (!opts.force && !opts.dryRun && alreadyDone(opts.configDir)) return EMPTY;
50616
+ const { statements, citedByFix } = replay(opts.root);
50617
+ const report = {
50618
+ skipped: false,
50619
+ stamped: 0,
50620
+ detached: 0,
50621
+ reopened: 0,
50622
+ witnessed: 0,
50623
+ cloudTwins: []
50624
+ };
50625
+ const seen = /* @__PURE__ */ new Set();
50626
+ const work = [];
50627
+ for (const statement of statements) {
50628
+ const id = designProblemId(statement);
50629
+ if (seen.has(id)) continue;
50630
+ seen.add(id);
50631
+ const node2 = store.getNode(id);
50632
+ if (!node2 || node2.label !== "Problem") continue;
50633
+ const isWitnessed = citedByFix.has(priorHandle(node2)) || citedByFix.has(id) || [...citedByFix].some((c) => c && id.startsWith(c));
50634
+ const fabricated = [];
50635
+ for (const e of store.outEdges(id, ["SOLVED_BY"])) {
50636
+ const sol = store.getNode(e.to);
50637
+ if (!sol) continue;
50638
+ const auto = sol.description.startsWith(AUTO_MINT_PREFIX);
50639
+ if (!auto && isWitnessed) report.witnessed++;
50640
+ else fabricated.push(sol.id);
50641
+ }
50642
+ const stamp = node2.attrs["kind"] !== "constraint";
50643
+ if (stamp) report.stamped++;
50644
+ if (fabricated.length > 0) {
50645
+ report.detached += fabricated.length;
50646
+ report.reopened++;
50647
+ }
50648
+ const cloudNodeId = node2.attrs["cloudNodeId"];
50649
+ if (typeof cloudNodeId === "string" && (stamp || fabricated.length > 0)) {
50650
+ report.cloudTwins.push(cloudNodeId);
50651
+ }
50652
+ if (stamp || fabricated.length > 0) work.push({ id, fabricated, stamp });
50653
+ }
50654
+ if (opts.dryRun) return report;
50655
+ store.transaction(() => {
50656
+ for (const w of work) {
50657
+ const node2 = store.getNode(w.id);
50658
+ if (!node2) continue;
50659
+ const attrs = { ...node2.attrs, kind: "constraint" };
50660
+ if (w.fabricated.length > 0) {
50661
+ delete attrs["resolvedAt"];
50662
+ delete attrs["resolvedReason"];
50663
+ }
50664
+ store.updateNode(w.id, { attrs, lastUpdatedAt: opts.now });
50665
+ for (const solId of w.fabricated) {
50666
+ for (const e of store.outEdges(w.id, ["SOLVED_BY"])) {
50667
+ if (e.to === solId) store.closeEdge(e.id, opts.now);
50668
+ }
50669
+ const sol = store.getNode(solId);
50670
+ if (sol?.description.startsWith(AUTO_MINT_PREFIX)) store.closeNode(solId, opts.now);
50671
+ }
50672
+ }
50673
+ });
50674
+ try {
50675
+ writeFileSync11(
50676
+ markerPath(opts.configDir),
50677
+ JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
50678
+ "utf8"
50679
+ );
50680
+ } catch {
50681
+ }
50682
+ return report;
50683
+ }
50684
+
50544
50685
  // src/engine.ts
50545
50686
  init_symbol_summaries();
50546
50687
  init_reconcile();
@@ -50739,11 +50880,11 @@ init_outbox();
50739
50880
  init_src8();
50740
50881
  init_src();
50741
50882
  init_src2();
50742
- import { readFileSync as readFileSync11 } from "node:fs";
50743
- import { join as join16 } from "node:path";
50883
+ import { readFileSync as readFileSync12 } from "node:fs";
50884
+ import { join as join17 } from "node:path";
50744
50885
  function loadClaimIgnorePatterns(workspaceRoot) {
50745
50886
  try {
50746
- return readFileSync11(join16(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
50887
+ return readFileSync12(join17(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
50747
50888
  } catch {
50748
50889
  return [];
50749
50890
  }
@@ -51104,22 +51245,22 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
51104
51245
  }
51105
51246
 
51106
51247
  // src/git-sensor.ts
51107
- import { existsSync as existsSync13, readFileSync as readFileSync12, watch as fsWatch } from "node:fs";
51108
- import { join as join17 } from "node:path";
51248
+ import { existsSync as existsSync14, readFileSync as readFileSync13, watch as fsWatch } from "node:fs";
51249
+ import { join as join18 } from "node:path";
51109
51250
  function readFirstLine(path2) {
51110
51251
  try {
51111
- return readFileSync12(path2, "utf8").split(/\r?\n/, 1)[0].trim();
51252
+ return readFileSync13(path2, "utf8").split(/\r?\n/, 1)[0].trim();
51112
51253
  } catch {
51113
51254
  return null;
51114
51255
  }
51115
51256
  }
51116
51257
  function readGitRefState(gitDir) {
51117
- const head2 = readFirstLine(join17(gitDir, "HEAD"));
51258
+ const head2 = readFirstLine(join18(gitDir, "HEAD"));
51118
51259
  const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
51119
51260
  const branch = m ? m[1] : null;
51120
51261
  let sha2 = null;
51121
51262
  if (branch) {
51122
- sha2 = readFirstLine(join17(gitDir, "refs", "heads", branch));
51263
+ sha2 = readFirstLine(join18(gitDir, "refs", "heads", branch));
51123
51264
  if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
51124
51265
  } else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
51125
51266
  sha2 = head2;
@@ -51127,13 +51268,13 @@ function readGitRefState(gitDir) {
51127
51268
  return {
51128
51269
  branch,
51129
51270
  sha: sha2,
51130
- mergeHeadExists: existsSync13(join17(gitDir, "MERGE_HEAD")),
51131
- origHeadExists: existsSync13(join17(gitDir, "ORIG_HEAD"))
51271
+ mergeHeadExists: existsSync14(join18(gitDir, "MERGE_HEAD")),
51272
+ origHeadExists: existsSync14(join18(gitDir, "ORIG_HEAD"))
51132
51273
  };
51133
51274
  }
51134
51275
  function shaFromPackedRefs(gitDir, ref) {
51135
51276
  try {
51136
- for (const line of readFileSync12(join17(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
51277
+ for (const line of readFileSync13(join18(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
51137
51278
  const [sha2, name2] = line.split(/\s+/);
51138
51279
  if (name2 === ref && sha2) return sha2;
51139
51280
  }
@@ -51167,7 +51308,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
51167
51308
  const settle = () => {
51168
51309
  if (timer) clearTimeout(timer);
51169
51310
  timer = setTimeout(() => {
51170
- if (existsSync13(join17(gitDir, "index.lock"))) {
51311
+ if (existsSync14(join18(gitDir, "index.lock"))) {
51171
51312
  settle();
51172
51313
  return;
51173
51314
  }
@@ -51178,7 +51319,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
51178
51319
  }, debounceMs);
51179
51320
  };
51180
51321
  for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
51181
- const p = join17(gitDir, sub);
51322
+ const p = join18(gitDir, sub);
51182
51323
  try {
51183
51324
  watchers.push(fsWatch(p, settle));
51184
51325
  } catch {
@@ -51403,21 +51544,21 @@ var TelemetryRecorder = class {
51403
51544
 
51404
51545
  // src/skills.ts
51405
51546
  import {
51406
- existsSync as existsSync14,
51547
+ existsSync as existsSync15,
51407
51548
  mkdirSync as mkdirSync6,
51408
- readFileSync as readFileSync13,
51409
- readdirSync as readdirSync6,
51549
+ readFileSync as readFileSync14,
51550
+ readdirSync as readdirSync7,
51410
51551
  unlinkSync as unlinkSync2,
51411
- writeFileSync as writeFileSync11
51552
+ writeFileSync as writeFileSync12
51412
51553
  } from "node:fs";
51413
- import { basename as basename4, join as join18 } from "node:path";
51554
+ import { basename as basename4, join as join19 } from "node:path";
51414
51555
  function skillFileName(id) {
51415
51556
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
51416
51557
  }
51417
51558
  function readSkillManifest(manifestPath) {
51418
- if (!existsSync14(manifestPath)) return [];
51559
+ if (!existsSync15(manifestPath)) return [];
51419
51560
  try {
51420
- const parsed = JSON.parse(readFileSync13(manifestPath, "utf8"));
51561
+ const parsed = JSON.parse(readFileSync14(manifestPath, "utf8"));
51421
51562
  return (parsed.skills ?? []).map((s) => ({
51422
51563
  title: s.title ?? "",
51423
51564
  layer: s.layer ?? "technique",
@@ -51433,7 +51574,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
51433
51574
  const staleDaemon = res.staleDaemon && res.latestDaemonVersion ? { latest: res.latestDaemonVersion } : void 0;
51434
51575
  mkdirSync6(paths.skillsDir, { recursive: true });
51435
51576
  if (res.skills.length === 0 && pins.length === 0) {
51436
- const existing = readdirSync6(paths.skillsDir).filter((f) => f.endsWith(".md"));
51577
+ const existing = readdirSync7(paths.skillsDir).filter((f) => f.endsWith(".md"));
51437
51578
  if (existing.length > 0) return { written: 0, pruned: 0, ...staleDaemon ? { staleDaemon } : {} };
51438
51579
  }
51439
51580
  const rows = [];
@@ -51441,7 +51582,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
51441
51582
  for (const s of res.skills) {
51442
51583
  const fileName = skillFileName(s.id);
51443
51584
  keep.add(fileName);
51444
- writeFileSync11(join18(paths.skillsDir, fileName), s.markdown, "utf8");
51585
+ writeFileSync12(join19(paths.skillsDir, fileName), s.markdown, "utf8");
51445
51586
  rows.push({
51446
51587
  id: s.id,
51447
51588
  title: s.title,
@@ -51454,7 +51595,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
51454
51595
  const fileName = skillFileName(p.id);
51455
51596
  if (keep.has(fileName)) continue;
51456
51597
  keep.add(fileName);
51457
- writeFileSync11(join18(paths.skillsDir, fileName), p.markdown, "utf8");
51598
+ writeFileSync12(join19(paths.skillsDir, fileName), p.markdown, "utf8");
51458
51599
  rows.push({
51459
51600
  id: p.id,
51460
51601
  title: p.title,
@@ -51464,17 +51605,17 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
51464
51605
  });
51465
51606
  }
51466
51607
  let pruned = 0;
51467
- for (const f of readdirSync6(paths.skillsDir)) {
51608
+ for (const f of readdirSync7(paths.skillsDir)) {
51468
51609
  if (!f.endsWith(".md")) continue;
51469
51610
  if (keep.has(basename4(f))) continue;
51470
51611
  try {
51471
- unlinkSync2(join18(paths.skillsDir, f));
51612
+ unlinkSync2(join19(paths.skillsDir, f));
51472
51613
  pruned++;
51473
51614
  } catch {
51474
51615
  }
51475
51616
  }
51476
51617
  rows.sort((a, b) => a.id.localeCompare(b.id));
51477
- writeFileSync11(
51618
+ writeFileSync12(
51478
51619
  paths.skillsManifest,
51479
51620
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
51480
51621
  "utf8"
@@ -51486,22 +51627,22 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
51486
51627
  init_src2();
51487
51628
  import {
51488
51629
  cpSync,
51489
- existsSync as existsSync15,
51630
+ existsSync as existsSync16,
51490
51631
  lstatSync,
51491
51632
  mkdirSync as mkdirSync7,
51492
- readFileSync as readFileSync14,
51493
- readdirSync as readdirSync7,
51633
+ readFileSync as readFileSync15,
51634
+ readdirSync as readdirSync8,
51494
51635
  rmSync as rmSync2,
51495
51636
  symlinkSync,
51496
- writeFileSync as writeFileSync12
51637
+ writeFileSync as writeFileSync13
51497
51638
  } from "node:fs";
51498
- import { join as join19 } from "node:path";
51639
+ import { join as join20 } from "node:path";
51499
51640
  var SKILL_NS = "errata-";
51500
51641
  var HARNESS_SKILL_DIRS = [
51501
- { configDir: ".claude", skillsDir: join19(".claude", "skills") },
51642
+ { configDir: ".claude", skillsDir: join20(".claude", "skills") },
51502
51643
  // Cursor adopted the standard; its exact project dir is still moving — kept
51503
51644
  // best-effort and gated on `.cursor/` presence so we never create it blind.
51504
- { configDir: ".cursor", skillsDir: join19(".cursor", "skills") }
51645
+ { configDir: ".cursor", skillsDir: join20(".cursor", "skills") }
51505
51646
  ];
51506
51647
  function skillSlug(title, id) {
51507
51648
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
@@ -51546,12 +51687,12 @@ function skillCiteHandle(s) {
51546
51687
  return priorHandle({ id: s.id, description: s.title });
51547
51688
  }
51548
51689
  function reconcileNamespaced(dir, keep) {
51549
- if (!existsSync15(dir)) return 0;
51690
+ if (!existsSync16(dir)) return 0;
51550
51691
  let pruned = 0;
51551
- for (const name2 of readdirSync7(dir)) {
51692
+ for (const name2 of readdirSync8(dir)) {
51552
51693
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
51553
51694
  try {
51554
- rmSync2(join19(dir, name2), { recursive: true, force: true });
51695
+ rmSync2(join20(dir, name2), { recursive: true, force: true });
51555
51696
  pruned++;
51556
51697
  } catch {
51557
51698
  }
@@ -51560,7 +51701,7 @@ function reconcileNamespaced(dir, keep) {
51560
51701
  }
51561
51702
  function linkOrCopy(linkPath, target) {
51562
51703
  try {
51563
- if (existsSync15(linkPath) || safeLstat(linkPath)) rmSync2(linkPath, { recursive: true, force: true });
51704
+ if (existsSync16(linkPath) || safeLstat(linkPath)) rmSync2(linkPath, { recursive: true, force: true });
51564
51705
  } catch {
51565
51706
  }
51566
51707
  try {
@@ -51581,7 +51722,7 @@ function safeLstat(p) {
51581
51722
  }
51582
51723
  }
51583
51724
  function emitAndProjectSkills(root, skills) {
51584
- const agentsSkillsDir = join19(root, ".agents", "skills");
51725
+ const agentsSkillsDir = join20(root, ".agents", "skills");
51585
51726
  mkdirSync7(agentsSkillsDir, { recursive: true });
51586
51727
  const slugs = [];
51587
51728
  const keep = /* @__PURE__ */ new Set();
@@ -51589,7 +51730,7 @@ function emitAndProjectSkills(root, skills) {
51589
51730
  for (const s of skills) {
51590
51731
  let body2;
51591
51732
  try {
51592
- body2 = readFileSync14(s.bodyPath, "utf8");
51733
+ body2 = readFileSync15(s.bodyPath, "utf8");
51593
51734
  } catch {
51594
51735
  continue;
51595
51736
  }
@@ -51598,9 +51739,9 @@ function emitAndProjectSkills(root, skills) {
51598
51739
  keep.add(slug2);
51599
51740
  slugs.push(slug2);
51600
51741
  const description = deriveDescription(s.title, s.layer, body2);
51601
- mkdirSync7(join19(agentsSkillsDir, slug2), { recursive: true });
51602
- writeFileSync12(
51603
- join19(agentsSkillsDir, slug2, "SKILL.md"),
51742
+ mkdirSync7(join20(agentsSkillsDir, slug2), { recursive: true });
51743
+ writeFileSync13(
51744
+ join20(agentsSkillsDir, slug2, "SKILL.md"),
51604
51745
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
51605
51746
  "utf8"
51606
51747
  );
@@ -51609,11 +51750,11 @@ function emitAndProjectSkills(root, skills) {
51609
51750
  reconcileNamespaced(agentsSkillsDir, keep);
51610
51751
  let projected = 0;
51611
51752
  for (const h of HARNESS_SKILL_DIRS) {
51612
- if (!existsSync15(join19(root, h.configDir))) continue;
51613
- const dir = join19(root, h.skillsDir);
51753
+ if (!existsSync16(join20(root, h.configDir))) continue;
51754
+ const dir = join20(root, h.skillsDir);
51614
51755
  mkdirSync7(dir, { recursive: true });
51615
51756
  for (const slug2 of slugs) {
51616
- linkOrCopy(join19(dir, slug2), join19(agentsSkillsDir, slug2));
51757
+ linkOrCopy(join20(dir, slug2), join20(agentsSkillsDir, slug2));
51617
51758
  projected++;
51618
51759
  }
51619
51760
  reconcileNamespaced(dir, keep);
@@ -51622,15 +51763,15 @@ function emitAndProjectSkills(root, skills) {
51622
51763
  return { slugs, emitted, projected };
51623
51764
  }
51624
51765
  function emitInputsFromManifest(erretaDir, manifestPath) {
51625
- if (!existsSync15(manifestPath)) return [];
51766
+ if (!existsSync16(manifestPath)) return [];
51626
51767
  try {
51627
- const parsed = JSON.parse(readFileSync14(manifestPath, "utf8"));
51768
+ const parsed = JSON.parse(readFileSync15(manifestPath, "utf8"));
51628
51769
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
51629
51770
  id: s.id,
51630
51771
  title: s.title ?? s.id,
51631
51772
  layer: s.layer ?? "technique",
51632
51773
  confidence: s.confidence ?? 0,
51633
- bodyPath: join19(erretaDir, s.file)
51774
+ bodyPath: join20(erretaDir, s.file)
51634
51775
  }));
51635
51776
  } catch {
51636
51777
  return [];
@@ -51644,17 +51785,17 @@ var GITIGNORE_LINES = [
51644
51785
  ".cursor/skills/errata-*/"
51645
51786
  ];
51646
51787
  function ensureSkillGitignore(root) {
51647
- const path2 = join19(root, ".gitignore");
51788
+ const path2 = join20(root, ".gitignore");
51648
51789
  let current = "";
51649
51790
  try {
51650
- current = existsSync15(path2) ? readFileSync14(path2, "utf8") : "";
51791
+ current = existsSync16(path2) ? readFileSync15(path2, "utf8") : "";
51651
51792
  } catch {
51652
51793
  return;
51653
51794
  }
51654
51795
  if (current.includes(GITIGNORE_MARK)) return;
51655
51796
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
51656
51797
  try {
51657
- writeFileSync12(path2, `${current}${prefix}
51798
+ writeFileSync13(path2, `${current}${prefix}
51658
51799
  ${GITIGNORE_LINES.join("\n")}
51659
51800
  `, "utf8");
51660
51801
  } catch {
@@ -51818,20 +51959,20 @@ var CausalBuffer = class {
51818
51959
  // src/profile.ts
51819
51960
  init_src2();
51820
51961
  init_paths();
51821
- import { existsSync as existsSync17, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "node:fs";
51962
+ import { existsSync as existsSync18, readFileSync as readFileSync17, writeFileSync as writeFileSync14 } from "node:fs";
51822
51963
  import { createHash as createHash12 } from "node:crypto";
51823
- import { join as join21 } from "node:path";
51964
+ import { join as join22 } from "node:path";
51824
51965
 
51825
51966
  // src/git-remote.ts
51826
51967
  init_src();
51827
- import { existsSync as existsSync16, readFileSync as readFileSync15, statSync as statSync4 } from "node:fs";
51828
- import { isAbsolute as isAbsolute3, join as join20, resolve as resolve5 } from "node:path";
51968
+ import { existsSync as existsSync17, readFileSync as readFileSync16, statSync as statSync4 } from "node:fs";
51969
+ import { isAbsolute as isAbsolute3, join as join21, resolve as resolve5 } from "node:path";
51829
51970
  function resolveGitDir(root) {
51830
- const dotGit = join20(root, ".git");
51971
+ const dotGit = join21(root, ".git");
51831
51972
  try {
51832
51973
  const st = statSync4(dotGit);
51833
51974
  if (st.isDirectory()) return dotGit;
51834
- const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync15(dotGit, "utf8"));
51975
+ const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync16(dotGit, "utf8"));
51835
51976
  if (!m) return null;
51836
51977
  const dir = m[1];
51837
51978
  return isAbsolute3(dir) ? dir : resolve5(root, dir);
@@ -51840,22 +51981,22 @@ function resolveGitDir(root) {
51840
51981
  }
51841
51982
  }
51842
51983
  function gitConfigPath(gitDir) {
51843
- const commondirFile = join20(gitDir, "commondir");
51844
- if (existsSync16(commondirFile)) {
51845
- const common = readFileSync15(commondirFile, "utf8").trim();
51984
+ const commondirFile = join21(gitDir, "commondir");
51985
+ if (existsSync17(commondirFile)) {
51986
+ const common = readFileSync16(commondirFile, "utf8").trim();
51846
51987
  const commonDir = isAbsolute3(common) ? common : resolve5(gitDir, common);
51847
- return join20(commonDir, "config");
51988
+ return join21(commonDir, "config");
51848
51989
  }
51849
- return join20(gitDir, "config");
51990
+ return join21(gitDir, "config");
51850
51991
  }
51851
51992
  function readRemotes(root) {
51852
51993
  const gitDir = resolveGitDir(root);
51853
51994
  if (!gitDir) return [];
51854
51995
  const cfgPath = gitConfigPath(gitDir);
51855
- if (!existsSync16(cfgPath)) return [];
51996
+ if (!existsSync17(cfgPath)) return [];
51856
51997
  let txt;
51857
51998
  try {
51858
- txt = readFileSync15(cfgPath, "utf8");
51999
+ txt = readFileSync16(cfgPath, "utf8");
51859
52000
  } catch {
51860
52001
  return [];
51861
52002
  }
@@ -51887,13 +52028,13 @@ function refreshRepoLocator(root, profile) {
51887
52028
  }
51888
52029
  function loadProfile(root) {
51889
52030
  const p = workspacePaths(root);
51890
- if (!existsSync17(p.workspaceJson)) return null;
51891
- return JSON.parse(readFileSync16(p.workspaceJson, "utf8"));
52031
+ if (!existsSync18(p.workspaceJson)) return null;
52032
+ return JSON.parse(readFileSync17(p.workspaceJson, "utf8"));
51892
52033
  }
51893
52034
  function saveProfile(root, profile) {
51894
52035
  const p = workspacePaths(root);
51895
52036
  ensureDir(p.configDir);
51896
- writeFileSync13(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
52037
+ writeFileSync14(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
51897
52038
  }
51898
52039
  function autodetectProfile(root) {
51899
52040
  const id = workspaceId(root);
@@ -51901,10 +52042,10 @@ function autodetectProfile(root) {
51901
52042
  const p = emptyProfile(id, name2);
51902
52043
  const locator = detectRepoLocator(root);
51903
52044
  if (locator) p.repoLocator = locator;
51904
- const pkgPath = join21(root, "package.json");
51905
- if (existsSync17(pkgPath)) {
52045
+ const pkgPath = join22(root, "package.json");
52046
+ if (existsSync18(pkgPath)) {
51906
52047
  try {
51907
- const pkg = JSON.parse(readFileSync16(pkgPath, "utf8"));
52048
+ const pkg = JSON.parse(readFileSync17(pkgPath, "utf8"));
51908
52049
  p.languages.push("typescript", "javascript");
51909
52050
  const nodeVer = pkg.engines?.node ?? "node";
51910
52051
  p.stack.push(`node@${nodeVer}`);
@@ -51925,10 +52066,10 @@ function autodetectProfile(root) {
51925
52066
  } catch {
51926
52067
  }
51927
52068
  }
51928
- const pyproject = join21(root, "pyproject.toml");
51929
- if (existsSync17(pyproject)) {
52069
+ const pyproject = join22(root, "pyproject.toml");
52070
+ if (existsSync18(pyproject)) {
51930
52071
  try {
51931
- const txt = readFileSync16(pyproject, "utf8");
52072
+ const txt = readFileSync17(pyproject, "utf8");
51932
52073
  const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
51933
52074
  p.languages.push("python");
51934
52075
  p.stack.push(`python@${py ?? "3"}`);
@@ -51939,16 +52080,16 @@ function autodetectProfile(root) {
51939
52080
  } catch {
51940
52081
  }
51941
52082
  }
51942
- const reqs = join21(root, "requirements.txt");
51943
- if (existsSync17(reqs)) {
52083
+ const reqs = join22(root, "requirements.txt");
52084
+ if (existsSync18(reqs)) {
51944
52085
  if (!p.languages.includes("python")) p.languages.push("python");
51945
52086
  if (!p.stack.includes("python@3")) p.stack.push("python@3");
51946
52087
  }
51947
- if (existsSync17(join21(root, "go.mod"))) {
52088
+ if (existsSync18(join22(root, "go.mod"))) {
51948
52089
  p.languages.push("go");
51949
52090
  p.stack.push("go");
51950
52091
  }
51951
- if (existsSync17(join21(root, "Cargo.toml"))) {
52092
+ if (existsSync18(join22(root, "Cargo.toml"))) {
51952
52093
  p.languages.push("rust");
51953
52094
  p.stack.push("rust");
51954
52095
  }
@@ -52106,7 +52247,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
52106
52247
  }
52107
52248
 
52108
52249
  // src/engine.ts
52109
- var DAEMON_VERSION = true ? "2.0.2-dev.196" : "2.0.0-alpha.0";
52250
+ var DAEMON_VERSION = true ? "2.0.2-dev.201" : "2.0.0-alpha.0";
52110
52251
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
52111
52252
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
52112
52253
  var GIT_OP_MUTE_MS = 4e3;
@@ -52116,7 +52257,7 @@ var TURN_REPLAY_LOOKBACK_MS = 7 * 24 * 60 * 6e4;
52116
52257
  function appendIdentityAudit(path2, record2, line) {
52117
52258
  if (!record2.accepted && record2.score <= 0) return;
52118
52259
  try {
52119
- if (existsSync18(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
52260
+ if (existsSync19(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
52120
52261
  renameSync2(path2, `${path2}.1`);
52121
52262
  }
52122
52263
  appendFileSync2(path2, line);
@@ -52126,14 +52267,14 @@ function appendIdentityAudit(path2, record2, line) {
52126
52267
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
52127
52268
  function loadTurnCursors(path2) {
52128
52269
  try {
52129
- return new Map(Object.entries(JSON.parse(readFileSync17(path2, "utf8"))));
52270
+ return new Map(Object.entries(JSON.parse(readFileSync18(path2, "utf8"))));
52130
52271
  } catch {
52131
52272
  return /* @__PURE__ */ new Map();
52132
52273
  }
52133
52274
  }
52134
52275
  function saveTurnCursors(path2, cursors) {
52135
52276
  try {
52136
- writeFileSync14(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
52277
+ writeFileSync15(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
52137
52278
  } catch {
52138
52279
  }
52139
52280
  }
@@ -52155,7 +52296,7 @@ function gitSourceWatchTargets(root) {
52155
52296
  ["-C", root, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"],
52156
52297
  { encoding: "utf8", maxBuffer: 256 * 1024 * 1024, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] }
52157
52298
  );
52158
- ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join22(root, d) + sep4));
52299
+ ignoredDirs = igOut.split("\0").filter(Boolean).map((d) => d.replace(/\/+$/, "")).filter((d) => !IGNORED_PATH.test(join23(root, d) + sep4));
52159
52300
  } catch {
52160
52301
  }
52161
52302
  const hasIgnoredChild = (dir) => ignoredDirs.some((ig) => ig.startsWith(dir + "/"));
@@ -52167,19 +52308,19 @@ function gitSourceWatchTargets(root) {
52167
52308
  if (!f.startsWith(prefix)) continue;
52168
52309
  const rest2 = f.slice(prefix.length);
52169
52310
  if (rest2.includes("/")) children.add(dir === "" ? rest2.slice(0, rest2.indexOf("/")) : dir + "/" + rest2.slice(0, rest2.indexOf("/")));
52170
- else targets.add(join22(root, f));
52311
+ else targets.add(join23(root, f));
52171
52312
  }
52172
52313
  for (const c of children) {
52173
- if (IGNORED_PATH.test(join22(root, c) + sep4)) continue;
52314
+ if (IGNORED_PATH.test(join23(root, c) + sep4)) continue;
52174
52315
  if (hasIgnoredChild(c)) addUnder(c);
52175
- else targets.add(join22(root, c));
52316
+ else targets.add(join23(root, c));
52176
52317
  }
52177
52318
  };
52178
52319
  addUnder("");
52179
52320
  if (targets.size > 0) return [...targets];
52180
52321
  } catch {
52181
52322
  }
52182
- return readdirSync8(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join22(root, String(e.name)) + sep4)).map((e) => join22(root, String(e.name)));
52323
+ return readdirSync9(root, { withFileTypes: true }).filter((e) => e.isDirectory() && !IGNORED_PATH.test(join23(root, String(e.name)) + sep4)).map((e) => join23(root, String(e.name)));
52183
52324
  }
52184
52325
  function createWorkspaceEngine(opts) {
52185
52326
  const paths = workspacePaths(opts.workspaceRoot);
@@ -52333,7 +52474,7 @@ function createWorkspaceEngine(opts) {
52333
52474
  const srcPaths = diff.changedPaths.filter((p) => /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(p));
52334
52475
  let episodeId2;
52335
52476
  if (srcPaths.length > 0) {
52336
- const abs = srcPaths.map((p) => join22(opts.workspaceRoot, p));
52477
+ const abs = srcPaths.map((p) => join23(opts.workspaceRoot, p));
52337
52478
  try {
52338
52479
  const r = await runReindexPass(
52339
52480
  `git-reindex:${profile.name} (${abs.length} files)`,
@@ -52369,8 +52510,8 @@ function createWorkspaceEngine(opts) {
52369
52510
  `[errata] git: ${ev.kind} ${ev.newSha.slice(0, 7)} by ${meta3.authorName} \u2014 ${diff.changedPaths.length} file(s), ${diff.renames.length} rename(s)`
52370
52511
  );
52371
52512
  };
52372
- const gitDir = join22(opts.workspaceRoot, ".git");
52373
- if (existsSync18(gitDir)) {
52513
+ const gitDir = join23(opts.workspaceRoot, ".git");
52514
+ if (existsSync19(gitDir)) {
52374
52515
  stopGit = startGitSensor(gitDir, (ev) => {
52375
52516
  void handleGitEvent(ev).catch((err2) => {
52376
52517
  console.warn("[errata] git event handler failed:", err2);
@@ -52440,10 +52581,10 @@ function createWorkspaceEngine(opts) {
52440
52581
  });
52441
52582
  doneRender?.();
52442
52583
  writeContextFile(opts.workspaceRoot, body2);
52443
- const target = join22(opts.workspaceRoot, "AGENTS.md");
52584
+ const target = join23(opts.workspaceRoot, "AGENTS.md");
52444
52585
  writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
52445
52586
  if (elicit) {
52446
- writePrimingHandles(join22(paths.configDir, "priming-handles.json"), [
52587
+ writePrimingHandles(join23(paths.configDir, "priming-handles.json"), [
52447
52588
  ...snapshot.recentProblems.map((r) => r.node),
52448
52589
  // Resolved-band handles: the ✓ problem AND its Solution are citable
52449
52590
  // (a fix tag on an already-resolved problem no-ops idempotently; the
@@ -52534,6 +52675,21 @@ function createWorkspaceEngine(opts) {
52534
52675
  } catch (err2) {
52535
52676
  console.warn("[errata] anchor backfill failed:", err2);
52536
52677
  }
52678
+ try {
52679
+ const c = backfillConstraintKind(store, {
52680
+ root: opts.workspaceRoot,
52681
+ configDir: paths.configDir,
52682
+ now: Date.now()
52683
+ });
52684
+ if (!c.skipped && (c.stamped > 0 || c.detached > 0)) {
52685
+ console.log(
52686
+ `[errata] constraint backfill: ${c.stamped} design tension(s) marked` + (c.detached > 0 ? `; ${c.detached} fabricated resolution(s) detached, ${c.reopened} reopened` : "") + (c.witnessed > 0 ? `; ${c.witnessed} cited discharge(s) kept` : "") + (c.cloudTwins.length > 0 ? ` \u2014 ${c.cloudTwins.length} already contributed; run scripts/repair-cloud-constraints.ts to repair the cloud twins` : "")
52687
+ );
52688
+ refreshContextNow();
52689
+ }
52690
+ } catch (err2) {
52691
+ console.warn("[errata] constraint backfill failed:", err2);
52692
+ }
52537
52693
  const report = runNightlyPipeline(store);
52538
52694
  try {
52539
52695
  const m = mergeDuplicateProblems(store, { ts: Date.now() });
@@ -52633,7 +52789,7 @@ function createWorkspaceEngine(opts) {
52633
52789
  resultSummary: { exitCode: e.exitCode ?? 1, errorTokens: e.errorTokens }
52634
52790
  });
52635
52791
  };
52636
- const turnCursorPath = join22(paths.configDir, "turn-cursors.json");
52792
+ const turnCursorPath = join23(paths.configDir, "turn-cursors.json");
52637
52793
  const lastTurnUuid = loadTurnCursors(turnCursorPath);
52638
52794
  const sessionLastProblem = /* @__PURE__ */ new Map();
52639
52795
  const sessionThreads = /* @__PURE__ */ new Map();
@@ -52656,7 +52812,7 @@ function createWorkspaceEngine(opts) {
52656
52812
  const t = Date.now();
52657
52813
  let processedTurns = 0;
52658
52814
  const elicit = isEdgeElicitationEnabled();
52659
- const handleMap = elicit ? readPrimingHandles(join22(paths.configDir, "priming-handles.json")) : {};
52815
+ const handleMap = elicit ? readPrimingHandles(join23(paths.configDir, "priming-handles.json")) : {};
52660
52816
  const wsRoot = (opts.workspaceRoot ?? "").replace(/\\/g, "/");
52661
52817
  const toRel = (abs) => {
52662
52818
  const p = abs.replace(/\\/g, "/");
@@ -53191,7 +53347,7 @@ function createWorkspaceEngine(opts) {
53191
53347
  try {
53192
53348
  const inputs = emitInputsFromManifest(paths.configDir, paths.skillsManifest);
53193
53349
  emitAndProjectSkills(opts.workspaceRoot, inputs);
53194
- writePrimingHandles(join22(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
53350
+ writePrimingHandles(join23(paths.configDir, "priming-handles.json"), skillHandleNodes(inputs));
53195
53351
  } catch (err2) {
53196
53352
  console.warn("[skills] agent-skills projection failed (non-fatal):", err2 instanceof Error ? err2.message : err2);
53197
53353
  }
@@ -53378,7 +53534,7 @@ function createWorkspaceEngine(opts) {
53378
53534
  console.log(
53379
53535
  "[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
53380
53536
  );
53381
- const pending = existsSync18(paths.outbox) ? readdirSync8(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
53537
+ const pending = existsSync19(paths.outbox) ? readdirSync9(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
53382
53538
  return { uploaded: 0, failed: 0, remaining: pending };
53383
53539
  }
53384
53540
  try {
@@ -53465,7 +53621,7 @@ async function startDaemon(opts) {
53465
53621
  reviewUrl: () => webUiUrl + "/review"
53466
53622
  });
53467
53623
  const writeLockFile = (url2) => {
53468
- writeFileSync15(
53624
+ writeFileSync16(
53469
53625
  engine.paths.daemonLock,
53470
53626
  JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
53471
53627
  "utf8"
@@ -53508,7 +53664,7 @@ async function startDaemon(opts) {
53508
53664
  );
53509
53665
  await engine.stop();
53510
53666
  try {
53511
- if (existsSync19(engine.paths.daemonLock)) {
53667
+ if (existsSync20(engine.paths.daemonLock)) {
53512
53668
  }
53513
53669
  } catch {
53514
53670
  }
@@ -53525,16 +53681,16 @@ async function listenServer(fetchFn, port) {
53525
53681
 
53526
53682
  // src/registry.ts
53527
53683
  init_paths();
53528
- import { existsSync as existsSync20, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "node:fs";
53529
- import { join as join23 } from "node:path";
53684
+ import { existsSync as existsSync21, readFileSync as readFileSync19, writeFileSync as writeFileSync17 } from "node:fs";
53685
+ import { join as join24 } from "node:path";
53530
53686
  function registryPath() {
53531
- return process.env["ERRATA_REGISTRY_PATH"] ?? join23(globalDir(), "workspaces.json");
53687
+ return process.env["ERRATA_REGISTRY_PATH"] ?? join24(globalDir(), "workspaces.json");
53532
53688
  }
53533
53689
  function read() {
53534
53690
  const p = registryPath();
53535
- if (!existsSync20(p)) return { version: 1, workspaces: {} };
53691
+ if (!existsSync21(p)) return { version: 1, workspaces: {} };
53536
53692
  try {
53537
- const parsed = JSON.parse(readFileSync18(p, "utf8"));
53693
+ const parsed = JSON.parse(readFileSync19(p, "utf8"));
53538
53694
  return { version: 1, workspaces: parsed.workspaces ?? {} };
53539
53695
  } catch {
53540
53696
  return { version: 1, workspaces: {} };
@@ -53542,7 +53698,7 @@ function read() {
53542
53698
  }
53543
53699
  function write(reg) {
53544
53700
  ensureDir(globalDir());
53545
- writeFileSync16(registryPath(), JSON.stringify(reg, null, 2), "utf8");
53701
+ writeFileSync17(registryPath(), JSON.stringify(reg, null, 2), "utf8");
53546
53702
  }
53547
53703
  function registerWorkspace(profile, root, now = Date.now()) {
53548
53704
  const reg = read();
@@ -53559,7 +53715,7 @@ function pruneMissingWorkspaces() {
53559
53715
  const reg = read();
53560
53716
  const removed = [];
53561
53717
  for (const [id, entry] of Object.entries(reg.workspaces)) {
53562
- if (!existsSync20(entry.path)) {
53718
+ if (!existsSync21(entry.path)) {
53563
53719
  removed.push(entry);
53564
53720
  delete reg.workspaces[id];
53565
53721
  }
@@ -53568,13 +53724,13 @@ function pruneMissingWorkspaces() {
53568
53724
  return removed;
53569
53725
  }
53570
53726
  function workspaceStatus(entry) {
53571
- const missing = !existsSync20(entry.path);
53727
+ const missing = !existsSync21(entry.path);
53572
53728
  const lockPath = workspacePaths(entry.path).daemonLock;
53573
53729
  let running = false;
53574
53730
  let webUiUrl = null;
53575
- if (existsSync20(lockPath)) {
53731
+ if (existsSync21(lockPath)) {
53576
53732
  try {
53577
- const lock = JSON.parse(readFileSync18(lockPath, "utf8"));
53733
+ const lock = JSON.parse(readFileSync19(lockPath, "utf8"));
53578
53734
  if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
53579
53735
  running = true;
53580
53736
  webUiUrl = lock.webUiUrl;
@@ -53602,7 +53758,7 @@ function pidAlive(pid) {
53602
53758
  // src/multi.ts
53603
53759
  init_dist();
53604
53760
  init_src4();
53605
- import { readFileSync as readFileSync21, unlinkSync as unlinkSync3, writeFileSync as writeFileSync17 } from "node:fs";
53761
+ import { readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync18 } from "node:fs";
53606
53762
 
53607
53763
  // src/principle-sync.ts
53608
53764
  init_src4();
@@ -53630,8 +53786,8 @@ init_reconcile();
53630
53786
 
53631
53787
  // src/lockfile-auto.ts
53632
53788
  init_src();
53633
- import { existsSync as existsSync21, readFileSync as readFileSync19 } from "node:fs";
53634
- import { join as join24 } from "node:path";
53789
+ import { existsSync as existsSync22, readFileSync as readFileSync20 } from "node:fs";
53790
+ import { join as join25 } from "node:path";
53635
53791
 
53636
53792
  // src/package-index.ts
53637
53793
  init_src();
@@ -53777,11 +53933,11 @@ function runLockfilePass(opts) {
53777
53933
  { file: "package-lock.json", parse: parsePackageLockJson }
53778
53934
  ];
53779
53935
  for (const c of candidates) {
53780
- const p = join24(opts.root, c.file);
53781
- if (!existsSync21(p)) continue;
53936
+ const p = join25(opts.root, c.file);
53937
+ if (!existsSync22(p)) continue;
53782
53938
  let sbom;
53783
53939
  try {
53784
- sbom = c.parse(readFileSync19(p, "utf8"));
53940
+ sbom = c.parse(readFileSync20(p, "utf8"));
53785
53941
  } catch {
53786
53942
  continue;
53787
53943
  }
@@ -54224,7 +54380,7 @@ var ConsolidateWorker = class {
54224
54380
  init_paths();
54225
54381
 
54226
54382
  // src/lock.ts
54227
- import { existsSync as existsSync22, readFileSync as readFileSync20 } from "node:fs";
54383
+ import { existsSync as existsSync23, readFileSync as readFileSync21 } from "node:fs";
54228
54384
  function isProcessAlive(pid) {
54229
54385
  if (!pid || pid <= 0) return false;
54230
54386
  try {
@@ -54235,9 +54391,9 @@ function isProcessAlive(pid) {
54235
54391
  }
54236
54392
  }
54237
54393
  function readDaemonLock(lockPath) {
54238
- if (!existsSync22(lockPath)) return null;
54394
+ if (!existsSync23(lockPath)) return null;
54239
54395
  try {
54240
- const lock = JSON.parse(readFileSync20(lockPath, "utf8"));
54396
+ const lock = JSON.parse(readFileSync21(lockPath, "utf8"));
54241
54397
  return typeof lock.pid === "number" ? lock : null;
54242
54398
  } catch {
54243
54399
  return null;
@@ -54479,12 +54635,12 @@ async function reanchorProject(opts) {
54479
54635
  }
54480
54636
 
54481
54637
  // src/adopt.ts
54482
- import { existsSync as existsSync23 } from "node:fs";
54483
- import { dirname as dirname9, join as join25 } from "node:path";
54638
+ import { existsSync as existsSync24 } from "node:fs";
54639
+ import { dirname as dirname9, join as join26 } from "node:path";
54484
54640
  function findGitRoot(absPath) {
54485
54641
  let dir = absPath;
54486
54642
  for (let depth = 0; depth < 64; depth++) {
54487
- if (existsSync23(join25(dir, ".git"))) return dir;
54643
+ if (existsSync24(join26(dir, ".git"))) return dir;
54488
54644
  const parent = dirname9(dir);
54489
54645
  if (parent === dir) return null;
54490
54646
  dir = parent;
@@ -54706,7 +54862,7 @@ async function startMultiDaemon(opts = {}) {
54706
54862
  void ambientLinkAll();
54707
54863
  app.route(`/ws/${rec.id}`, rec.webApp);
54708
54864
  try {
54709
- writeFileSync17(
54865
+ writeFileSync18(
54710
54866
  rec.engine.paths.daemonLock,
54711
54867
  JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${rec.id}`, startedAt: Date.now() }),
54712
54868
  "utf8"
@@ -54895,7 +55051,7 @@ async function startMultiDaemon(opts = {}) {
54895
55051
  baseUrl = `http://127.0.0.1:${port}`;
54896
55052
  try {
54897
55053
  ensureDir(globalDir());
54898
- writeFileSync17(
55054
+ writeFileSync18(
54899
55055
  lockPath,
54900
55056
  JSON.stringify({ pid: process.pid, webUiUrl: baseUrl, startedAt: Date.now() }),
54901
55057
  "utf8"
@@ -54904,7 +55060,7 @@ async function startMultiDaemon(opts = {}) {
54904
55060
  }
54905
55061
  for (const r of records) {
54906
55062
  try {
54907
- writeFileSync17(
55063
+ writeFileSync18(
54908
55064
  r.engine.paths.daemonLock,
54909
55065
  JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${r.id}`, startedAt: Date.now() }),
54910
55066
  "utf8"
@@ -55372,7 +55528,7 @@ async function startMultiDaemon(opts = {}) {
55372
55528
  },
55373
55529
  async stop() {
55374
55530
  try {
55375
- const cur = readFileSync21(lockPath, "utf8");
55531
+ const cur = readFileSync22(lockPath, "utf8");
55376
55532
  if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
55377
55533
  } catch {
55378
55534
  }
@@ -56392,21 +56548,21 @@ async function cmdInit() {
56392
56548
  if (!skipHooks) {
56393
56549
  console.log("");
56394
56550
  console.log("installing harness hooks...");
56395
- const { existsSync: existsSync25 } = await import("node:fs");
56396
- const { join: join27 } = await import("node:path");
56551
+ const { existsSync: existsSync26 } = await import("node:fs");
56552
+ const { join: join28 } = await import("node:path");
56397
56553
  try {
56398
56554
  await installClaudeHooks(port);
56399
56555
  } catch (err2) {
56400
56556
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
56401
56557
  }
56402
- if (existsSync25(join27(ROOT, ".cursor"))) {
56558
+ if (existsSync26(join28(ROOT, ".cursor"))) {
56403
56559
  try {
56404
56560
  await installCursorMcpConfig();
56405
56561
  } catch (err2) {
56406
56562
  console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
56407
56563
  }
56408
56564
  }
56409
- if (existsSync25(join27(ROOT, ".codex"))) {
56565
+ if (existsSync26(join28(ROOT, ".codex"))) {
56410
56566
  try {
56411
56567
  await installCodexHooks(port);
56412
56568
  } catch (err2) {
@@ -56563,8 +56719,8 @@ async function cmdStatus() {
56563
56719
  console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
56564
56720
  console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
56565
56721
  }
56566
- console.log(` graph db: ${existsSync24(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
56567
- console.log(` event log: ${existsSync24(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
56722
+ console.log(` graph db: ${existsSync25(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
56723
+ console.log(` event log: ${existsSync25(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
56568
56724
  const lockPath = globalDaemonLock();
56569
56725
  const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
56570
56726
  console.log(
@@ -57194,11 +57350,11 @@ function cmdInstallationProfile(args2) {
57194
57350
  }
57195
57351
  async function cmdReview() {
57196
57352
  const paths = workspacePaths(ROOT);
57197
- if (!existsSync24(paths.reviewQueue)) {
57353
+ if (!existsSync25(paths.reviewQueue)) {
57198
57354
  console.log("(review queue empty)");
57199
57355
  return;
57200
57356
  }
57201
- const queue = JSON.parse(readFileSync22(paths.reviewQueue, "utf8"));
57357
+ const queue = JSON.parse(readFileSync23(paths.reviewQueue, "utf8"));
57202
57358
  if (queue.length === 0) {
57203
57359
  console.log("(review queue empty)");
57204
57360
  return;
@@ -57869,7 +58025,7 @@ async function gatherRepo(store, ws) {
57869
58025
  };
57870
58026
  }
57871
58027
  async function gatherReportData(generatedAt) {
57872
- const { existsSync: existsSync25 } = await import("node:fs");
58028
+ const { existsSync: existsSync26 } = await import("node:fs");
57873
58029
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
57874
58030
  const cfg = loadConfig();
57875
58031
  const outbound = cfg.consent.sync ? "auto" : "off";
@@ -57877,7 +58033,7 @@ async function gatherReportData(generatedAt) {
57877
58033
  for (const ws of listWorkspaces()) {
57878
58034
  if (ws.missing) continue;
57879
58035
  const dbPath = workspacePaths(ws.path).castalia;
57880
- if (!existsSync25(dbPath)) continue;
58036
+ if (!existsSync26(dbPath)) continue;
57881
58037
  let store = null;
57882
58038
  try {
57883
58039
  store = openGraphStore2({ path: dbPath });
@@ -57908,7 +58064,7 @@ async function gatherReportData(generatedAt) {
57908
58064
  };
57909
58065
  }
57910
58066
  async function cmdReport(args2) {
57911
- const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync18 } = await import("node:fs");
58067
+ const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync19 } = await import("node:fs");
57912
58068
  const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
57913
58069
  const includeFutureVerbs = args2.includes("--future-verbs");
57914
58070
  const now = /* @__PURE__ */ new Date();
@@ -57921,8 +58077,8 @@ async function cmdReport(args2) {
57921
58077
  const outDir = workspacePaths(ROOT).configDir;
57922
58078
  mkdirSync8(outDir, { recursive: true });
57923
58079
  const files = renderReport2(data, { includeFutureVerbs });
57924
- for (const f of files) writeFileSync18(join26(outDir, f.name), f.html, "utf8");
57925
- const indexPath = join26(outDir, "report.html");
58080
+ for (const f of files) writeFileSync19(join27(outDir, f.name), f.html, "utf8");
58081
+ const indexPath = join27(outDir, "report.html");
57926
58082
  console.log(`report \u2192 ${indexPath}`);
57927
58083
  console.log(
57928
58084
  ` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`
@@ -58040,15 +58196,15 @@ function hookRelayCommand(port, path2) {
58040
58196
  return process.platform === "win32" ? `cmd //c "curl -s --connect-timeout 1 --max-time 2 -X POST -H \\"Content-Type: application/json\\" --data-binary @- ${url2} 2>NUL || echo {}"` : `curl -s --connect-timeout 1 --max-time 2 -X POST -H 'Content-Type: application/json' --data-binary @- ${url2} 2>/dev/null || echo '{}'`;
58041
58197
  }
58042
58198
  async function installClaudeHooks(port) {
58043
- const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
58044
- const { join: join27 } = await import("node:path");
58045
- const dir = join27(ROOT, ".claude");
58046
- if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
58047
- const file2 = join27(dir, "settings.json");
58199
+ const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
58200
+ const { join: join28 } = await import("node:path");
58201
+ const dir = join28(ROOT, ".claude");
58202
+ if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
58203
+ const file2 = join28(dir, "settings.json");
58048
58204
  let settings = {};
58049
- if (existsSync25(file2)) {
58205
+ if (existsSync26(file2)) {
58050
58206
  try {
58051
- settings = JSON.parse(readFileSync23(file2, "utf8"));
58207
+ settings = JSON.parse(readFileSync24(file2, "utf8"));
58052
58208
  } catch {
58053
58209
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
58054
58210
  process.exit(2);
@@ -58094,10 +58250,10 @@ async function installClaudeHooks(port) {
58094
58250
  dropErrata(list);
58095
58251
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
58096
58252
  }
58097
- writeFileSync18(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
58253
+ writeFileSync19(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
58098
58254
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
58099
58255
  await installClaudeMcpConfig();
58100
- const claudeMd = join27(ROOT, "CLAUDE.md");
58256
+ const claudeMd = join28(ROOT, "CLAUDE.md");
58101
58257
  const recall = writeManagedBlock(claudeMd, { body: RECALL_FIRST_BLOCK });
58102
58258
  if (recall.kind === "collision") {
58103
58259
  console.warn(
@@ -58109,15 +58265,15 @@ async function installClaudeHooks(port) {
58109
58265
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
58110
58266
  }
58111
58267
  async function installClaudeMcpConfig() {
58112
- const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
58113
- const { join: join27, dirname: dirname10 } = await import("node:path");
58114
- const file2 = join27(ROOT, ".mcp.json");
58268
+ const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
58269
+ const { join: join28, dirname: dirname10 } = await import("node:path");
58270
+ const file2 = join28(ROOT, ".mcp.json");
58115
58271
  const dir = dirname10(file2);
58116
- if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
58272
+ if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
58117
58273
  let cfg = {};
58118
- if (existsSync25(file2)) {
58274
+ if (existsSync26(file2)) {
58119
58275
  try {
58120
- cfg = JSON.parse(readFileSync23(file2, "utf8"));
58276
+ cfg = JSON.parse(readFileSync24(file2, "utf8"));
58121
58277
  } catch {
58122
58278
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
58123
58279
  process.exit(2);
@@ -58125,21 +58281,21 @@ async function installClaudeMcpConfig() {
58125
58281
  }
58126
58282
  cfg.mcpServers ??= {};
58127
58283
  cfg.mcpServers["errata"] = errataMcpInvocation();
58128
- writeFileSync18(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
58284
+ writeFileSync19(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
58129
58285
  console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
58130
58286
  console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
58131
58287
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
58132
58288
  }
58133
58289
  async function installCursorMcpConfig() {
58134
- const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
58135
- const { join: join27 } = await import("node:path");
58136
- const dir = join27(ROOT, ".cursor");
58137
- if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
58138
- const file2 = join27(dir, "mcp.json");
58290
+ const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
58291
+ const { join: join28 } = await import("node:path");
58292
+ const dir = join28(ROOT, ".cursor");
58293
+ if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
58294
+ const file2 = join28(dir, "mcp.json");
58139
58295
  let cfg = {};
58140
- if (existsSync25(file2)) {
58296
+ if (existsSync26(file2)) {
58141
58297
  try {
58142
- cfg = JSON.parse(readFileSync23(file2, "utf8"));
58298
+ cfg = JSON.parse(readFileSync24(file2, "utf8"));
58143
58299
  } catch {
58144
58300
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
58145
58301
  process.exit(2);
@@ -58147,7 +58303,7 @@ async function installCursorMcpConfig() {
58147
58303
  }
58148
58304
  cfg.mcpServers ??= {};
58149
58305
  cfg.mcpServers["errata"] = errataMcpInvocation();
58150
- writeFileSync18(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
58306
+ writeFileSync19(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
58151
58307
  console.log(`installed Cursor MCP server config \u2192 ${file2}`);
58152
58308
  console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
58153
58309
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
@@ -58155,16 +58311,16 @@ async function installCursorMcpConfig() {
58155
58311
  console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
58156
58312
  }
58157
58313
  async function installCodexHooks(port) {
58158
- const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
58159
- const { join: join27 } = await import("node:path");
58160
- const dir = join27(ROOT, ".codex");
58161
- if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
58162
- const file2 = join27(dir, "config.toml");
58314
+ const { mkdirSync: mkdirSync8, existsSync: existsSync26, readFileSync: readFileSync24, writeFileSync: writeFileSync19 } = await import("node:fs");
58315
+ const { join: join28 } = await import("node:path");
58316
+ const dir = join28(ROOT, ".codex");
58317
+ if (!existsSync26(dir)) mkdirSync8(dir, { recursive: true });
58318
+ const file2 = join28(dir, "config.toml");
58163
58319
  const BEGIN = `# >>> errata hooks (errata-managed)`;
58164
58320
  const END = `# <<< errata hooks`;
58165
58321
  let existing = "";
58166
- if (existsSync25(file2)) {
58167
- existing = readFileSync23(file2, "utf8");
58322
+ if (existsSync26(file2)) {
58323
+ existing = readFileSync24(file2, "utf8");
58168
58324
  const beginIdx = existing.indexOf(BEGIN);
58169
58325
  const endIdx = existing.indexOf(END);
58170
58326
  if (beginIdx >= 0 && endIdx > beginIdx) {
@@ -58193,7 +58349,7 @@ ${END}
58193
58349
  const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
58194
58350
 
58195
58351
  ${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
58196
- writeFileSync18(file2, final, "utf8");
58352
+ writeFileSync19(file2, final, "utf8");
58197
58353
  console.log(`installed Codex hooks \u2192 ${file2}`);
58198
58354
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
58199
58355
  console.log("");
@@ -58483,7 +58639,7 @@ async function cmdDash(args2) {
58483
58639
  await yieldToLoop2();
58484
58640
  try {
58485
58641
  const items = selectDurableMemory(handle2.sharedStore, r.engine.profile);
58486
- const res = bleedRules(join26(r.root, ".claude", "rules"), items);
58642
+ const res = bleedRules(join27(r.root, ".claude", "rules"), items);
58487
58643
  if (res.written || res.pruned) {
58488
58644
  console.log(
58489
58645
  `[rules:${r.entry.name}] ${res.written} collective principle(s) \u2192 .claude/rules` + (res.pruned ? `, ${res.pruned} pruned` : "")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.196",
3
+ "version": "2.0.2-dev.201",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {