@inerrata-corporation/errata 2.0.0-dev.89 → 2.0.0-dev.91

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 (3) hide show
  1. package/errata.mjs +368 -294
  2. package/package.json +1 -1
  3. package/pass-worker.mjs +14 -0
package/errata.mjs CHANGED
@@ -16024,7 +16024,7 @@ function writeManagedBlock(filePath, opts) {
16024
16024
  const newBody = opts.body.trim();
16025
16025
  const newHash = blockHash(newBody);
16026
16026
  const generated = opts.generatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
16027
- const startMarker = `<!-- ERRATA:START version=2 generated=${generated} hash=${newHash} -->`;
16027
+ const startMarker = opts.stable ? `<!-- ERRATA:START version=2 hash=${newHash} -->` : `<!-- ERRATA:START version=2 generated=${generated} hash=${newHash} -->`;
16028
16028
  const endMarker = `<!-- ERRATA:END -->`;
16029
16029
  const blockText = `${startMarker}
16030
16030
 
@@ -16053,6 +16053,9 @@ ${blockText}`, "utf8");
16053
16053
  if (expectedHash && expectedHash !== actualHash && !opts.force) {
16054
16054
  return { kind: "collision", expectedHash, actualHash };
16055
16055
  }
16056
+ if (opts.stable && existingBody === newBody && startM[0] === startMarker) {
16057
+ return { kind: "written", previousHash: actualHash, newHash };
16058
+ }
16056
16059
  const before = current.slice(0, startM.index);
16057
16060
  const after = current.slice(endM.index + endM[0].length).replace(/^\s*/, "");
16058
16061
  const written = after ? `${before}${blockText.trim()}
@@ -16062,21 +16065,6 @@ ${after}` : `${before}${blockText.trim()}
16062
16065
  writeFileSync(filePath, written, "utf8");
16063
16066
  return { kind: "written", previousHash: expectedHash ?? null, newHash };
16064
16067
  }
16065
- function readManagedBlock(filePath) {
16066
- if (!existsSync(filePath)) return null;
16067
- const current = readFileSync(filePath, "utf8");
16068
- const startM = current.match(START_RE);
16069
- const endM = current.match(END_RE);
16070
- if (!startM || !endM || startM.index === void 0 || endM.index === void 0) {
16071
- return null;
16072
- }
16073
- return current.slice(startM.index + startM[0].length, endM.index).trim();
16074
- }
16075
- function readManagedBlockWithHash(filePath) {
16076
- const body2 = readManagedBlock(filePath);
16077
- if (body2 === null) return null;
16078
- return { body: body2, hash: sha256(body2).slice(0, 16) };
16079
- }
16080
16068
  var START_RE, END_RE, blockHash;
16081
16069
  var init_agents_md = __esm({
16082
16070
  "../../packages/context-writer/src/agents-md.ts"() {
@@ -16088,9 +16076,57 @@ var init_agents_md = __esm({
16088
16076
  }
16089
16077
  });
16090
16078
 
16091
- // ../../packages/context-writer/src/redirectors.ts
16092
- import { existsSync as existsSync2, mkdirSync, writeFileSync as writeFileSync2 } from "node:fs";
16079
+ // ../../packages/context-writer/src/context-file.ts
16080
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
16093
16081
  import { dirname, join } from "node:path";
16082
+ function contextFilePath(root) {
16083
+ return join(root, ".errata", "context.md");
16084
+ }
16085
+ function writeContextFile(root, body2) {
16086
+ const path2 = contextFilePath(root);
16087
+ mkdirSync(dirname(path2), { recursive: true });
16088
+ const text = `${body2.trim()}
16089
+ `;
16090
+ writeFileSync2(path2, text, "utf8");
16091
+ return contextHash(text);
16092
+ }
16093
+ function contextHash(body2) {
16094
+ return sha256(body2.replace(/\r\n?/g, "\n").trim()).slice(0, 16);
16095
+ }
16096
+ function readContextFileWithHash(root) {
16097
+ const path2 = contextFilePath(root);
16098
+ if (!existsSync2(path2)) return null;
16099
+ try {
16100
+ const raw2 = readFileSync2(path2, "utf8");
16101
+ const body2 = raw2.trim();
16102
+ if (!body2) return null;
16103
+ return { body: body2, hash: contextHash(raw2) };
16104
+ } catch {
16105
+ return null;
16106
+ }
16107
+ }
16108
+ var AGENTS_POINTER_BODY;
16109
+ var init_context_file = __esm({
16110
+ "../../packages/context-writer/src/context-file.ts"() {
16111
+ "use strict";
16112
+ init_src();
16113
+ AGENTS_POINTER_BODY = [
16114
+ "## Errata context",
16115
+ "",
16116
+ "Live agent context for this checkout \u2014 priors, open problems, the capture",
16117
+ "protocol \u2014 is maintained by the errata daemon at `.errata/context.md`.",
16118
+ "",
16119
+ "It is gitignored ON PURPOSE: it is this machine's runtime state, not repo",
16120
+ "content. Committing it would prime your teammates with your graph.",
16121
+ "",
16122
+ "@.errata/context.md"
16123
+ ].join("\n");
16124
+ }
16125
+ });
16126
+
16127
+ // ../../packages/context-writer/src/redirectors.ts
16128
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
16129
+ import { dirname as dirname2, join as join2 } from "node:path";
16094
16130
  function defaultRedirectors() {
16095
16131
  return [
16096
16132
  {
@@ -16122,13 +16158,13 @@ function installRedirectors(workspaceRoot, redirectors = defaultRedirectors()) {
16122
16158
  const written = [];
16123
16159
  const skipped = [];
16124
16160
  for (const r of redirectors) {
16125
- const abs = join(workspaceRoot, r.relPath);
16126
- if (existsSync2(abs)) {
16161
+ const abs = join2(workspaceRoot, r.relPath);
16162
+ if (existsSync3(abs)) {
16127
16163
  skipped.push(r.relPath);
16128
16164
  continue;
16129
16165
  }
16130
- mkdirSync(dirname(abs), { recursive: true });
16131
- writeFileSync2(abs, r.content, "utf8");
16166
+ mkdirSync2(dirname2(abs), { recursive: true });
16167
+ writeFileSync3(abs, r.content, "utf8");
16132
16168
  written.push(r.relPath);
16133
16169
  }
16134
16170
  return { written, skipped };
@@ -21118,8 +21154,8 @@ var init_bleed_memory = __esm({
21118
21154
  });
21119
21155
 
21120
21156
  // ../../packages/context-writer/src/bleed-rules.ts
21121
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
21122
- import { join as join2 } from "node:path";
21157
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync3, rmSync, writeFileSync as writeFileSync4 } from "node:fs";
21158
+ import { join as join3 } from "node:path";
21123
21159
  function formatRuleFile(item) {
21124
21160
  const frontmatter = item.paths && item.paths.length > 0 ? `---
21125
21161
  paths:
@@ -21132,21 +21168,21 @@ ${item.body.trim()}
21132
21168
  `;
21133
21169
  }
21134
21170
  function bleedRules(rulesDir, items) {
21135
- if (!existsSync3(rulesDir)) mkdirSync2(rulesDir, { recursive: true });
21171
+ if (!existsSync4(rulesDir)) mkdirSync3(rulesDir, { recursive: true });
21136
21172
  const wanted = new Map(items.map((i2) => [fileFor(i2.slug), i2]));
21137
21173
  let written = 0;
21138
21174
  let created = 0;
21139
21175
  for (const [file2, item] of wanted) {
21140
- const path2 = join2(rulesDir, file2);
21141
- if (!existsSync3(path2)) created++;
21142
- writeFileSync3(path2, formatRuleFile(item), "utf8");
21176
+ const path2 = join3(rulesDir, file2);
21177
+ if (!existsSync4(path2)) created++;
21178
+ writeFileSync4(path2, formatRuleFile(item), "utf8");
21143
21179
  written++;
21144
21180
  }
21145
21181
  let pruned = 0;
21146
21182
  for (const f of readdirSync(rulesDir)) {
21147
21183
  if (!f.startsWith(PREFIX) || !f.endsWith(".md") || wanted.has(f)) continue;
21148
- if (readFileSync2(join2(rulesDir, f), "utf8").includes(MARKER)) {
21149
- rmSync(join2(rulesDir, f));
21184
+ if (readFileSync3(join3(rulesDir, f), "utf8").includes(MARKER)) {
21185
+ rmSync(join3(rulesDir, f));
21150
21186
  pruned++;
21151
21187
  }
21152
21188
  }
@@ -21233,6 +21269,7 @@ var init_src5 = __esm({
21233
21269
  "../../packages/context-writer/src/index.ts"() {
21234
21270
  "use strict";
21235
21271
  init_agents_md();
21272
+ init_context_file();
21236
21273
  init_redirectors();
21237
21274
  init_render();
21238
21275
  init_bleed_memory();
@@ -22150,34 +22187,34 @@ __export(paths_exports, {
22150
22187
  workspaceDir: () => workspaceDir,
22151
22188
  workspacePaths: () => workspacePaths
22152
22189
  });
22153
- import { mkdirSync as mkdirSync3 } from "node:fs";
22154
- import { dirname as dirname2, join as join3 } from "node:path";
22190
+ import { mkdirSync as mkdirSync4 } from "node:fs";
22191
+ import { dirname as dirname3, join as join4 } from "node:path";
22155
22192
  function globalDir() {
22156
22193
  const p = envPaths("errata", { suffix: "" });
22157
22194
  return p.config;
22158
22195
  }
22159
22196
  function globalConfigPath() {
22160
- return process.env["ERRATA_CONFIG_PATH"] ?? join3(globalDir(), "config.json");
22197
+ return process.env["ERRATA_CONFIG_PATH"] ?? join4(globalDir(), "config.json");
22161
22198
  }
22162
22199
  function daemonLogPath() {
22163
- mkdirSync3(globalDir(), { recursive: true });
22164
- return join3(globalDir(), "daemon.log");
22200
+ mkdirSync4(globalDir(), { recursive: true });
22201
+ return join4(globalDir(), "daemon.log");
22165
22202
  }
22166
22203
  function globalDaemonLock() {
22167
- return process.env["ERRATA_DAEMON_LOCK"] ?? join3(globalDir(), "daemon.lock");
22204
+ return process.env["ERRATA_DAEMON_LOCK"] ?? join4(globalDir(), "daemon.lock");
22168
22205
  }
22169
22206
  function sharedStorePath() {
22170
- return process.env["ERRATA_SHARED_DB"] ?? join3(globalDir(), "shared", "graph.db");
22207
+ return process.env["ERRATA_SHARED_DB"] ?? join4(globalDir(), "shared", "graph.db");
22171
22208
  }
22172
22209
  function workspaceDir(workspaceRoot) {
22173
- return join3(workspaceRoot, ".errata");
22210
+ return join4(workspaceRoot, ".errata");
22174
22211
  }
22175
22212
  function ensureDir(p) {
22176
- mkdirSync3(p, { recursive: true });
22213
+ mkdirSync4(p, { recursive: true });
22177
22214
  return p;
22178
22215
  }
22179
22216
  function ensureParent(p) {
22180
- mkdirSync3(dirname2(p), { recursive: true });
22217
+ mkdirSync4(dirname3(p), { recursive: true });
22181
22218
  return p;
22182
22219
  }
22183
22220
  function workspacePaths(root) {
@@ -22185,15 +22222,15 @@ function workspacePaths(root) {
22185
22222
  return {
22186
22223
  root,
22187
22224
  configDir: dir,
22188
- workspaceJson: join3(dir, "workspace.json"),
22189
- eventLog: join3(dir, "eventlog.sqlite"),
22190
- castalia: join3(dir, "castalia.db"),
22191
- reviewQueue: join3(dir, "review-queue.json"),
22192
- outbox: join3(dir, "outbox"),
22193
- daemonLock: join3(dir, "daemon.lock"),
22194
- identityAudit: join3(dir, "identity-audit.log"),
22195
- skillsDir: join3(dir, "skills"),
22196
- skillsManifest: join3(dir, "skills.json")
22225
+ workspaceJson: join4(dir, "workspace.json"),
22226
+ eventLog: join4(dir, "eventlog.sqlite"),
22227
+ castalia: join4(dir, "castalia.db"),
22228
+ reviewQueue: join4(dir, "review-queue.json"),
22229
+ outbox: join4(dir, "outbox"),
22230
+ daemonLock: join4(dir, "daemon.lock"),
22231
+ identityAudit: join4(dir, "identity-audit.log"),
22232
+ skillsDir: join4(dir, "skills"),
22233
+ skillsManifest: join4(dir, "skills.json")
22197
22234
  };
22198
22235
  }
22199
22236
  var init_paths = __esm({
@@ -22204,7 +22241,7 @@ var init_paths = __esm({
22204
22241
  });
22205
22242
 
22206
22243
  // src/config.ts
22207
- import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
22244
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
22208
22245
  import { randomUUID as randomUUID2 } from "node:crypto";
22209
22246
  function defaultConfig() {
22210
22247
  return {
@@ -22230,13 +22267,13 @@ function defaultConfig() {
22230
22267
  }
22231
22268
  function loadConfig() {
22232
22269
  const p = globalConfigPath();
22233
- if (!existsSync4(p)) {
22270
+ if (!existsSync5(p)) {
22234
22271
  ensureDir(globalDir());
22235
22272
  const cfg = defaultConfig();
22236
22273
  saveConfig({ ...cfg, cloudUrl: DEFAULT_CLOUD_URL });
22237
22274
  return cfg;
22238
22275
  }
22239
- const raw2 = readFileSync3(p, "utf8").replace(/^\uFEFF/, "");
22276
+ const raw2 = readFileSync4(p, "utf8").replace(/^\uFEFF/, "");
22240
22277
  const parsed = JSON.parse(raw2);
22241
22278
  const base = defaultConfig();
22242
22279
  const envCloudUrl = process.env["ERRATA_CLOUD_URL"];
@@ -22257,7 +22294,7 @@ function loadConfig() {
22257
22294
  }
22258
22295
  function saveConfig(cfg) {
22259
22296
  ensureDir(globalDir());
22260
- writeFileSync4(globalConfigPath(), JSON.stringify(cfg, null, 2), { encoding: "utf8", mode: 384 });
22297
+ writeFileSync5(globalConfigPath(), JSON.stringify(cfg, null, 2), { encoding: "utf8", mode: 384 });
22261
22298
  }
22262
22299
  function machineId() {
22263
22300
  const fromEnv = process.env["ERRATA_MACHINE_ID"];
@@ -24889,17 +24926,17 @@ var init_agent_signals = __esm({
24889
24926
  });
24890
24927
 
24891
24928
  // src/review.ts
24892
- import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "node:fs";
24929
+ import { existsSync as existsSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
24893
24930
  function loadReviewQueue(paths) {
24894
- if (!existsSync5(paths.reviewQueue)) return [];
24931
+ if (!existsSync6(paths.reviewQueue)) return [];
24895
24932
  try {
24896
- return JSON.parse(readFileSync4(paths.reviewQueue, "utf8"));
24933
+ return JSON.parse(readFileSync5(paths.reviewQueue, "utf8"));
24897
24934
  } catch {
24898
24935
  return [];
24899
24936
  }
24900
24937
  }
24901
24938
  function saveReviewQueue(paths, queue) {
24902
- writeFileSync5(paths.reviewQueue, JSON.stringify(queue, null, 2), "utf8");
24939
+ writeFileSync6(paths.reviewQueue, JSON.stringify(queue, null, 2), "utf8");
24903
24940
  }
24904
24941
  function addProposal(paths, store, node2, reason, surprise) {
24905
24942
  const queue = loadReviewQueue(paths);
@@ -25497,9 +25534,9 @@ var init_dual_augment = __esm({
25497
25534
  });
25498
25535
 
25499
25536
  // ../../packages/embedding/src/model.ts
25500
- import { mkdirSync as mkdirSync4, existsSync as existsSync6 } from "node:fs";
25537
+ import { mkdirSync as mkdirSync5, existsSync as existsSync7 } from "node:fs";
25501
25538
  import { homedir as homedir2 } from "node:os";
25502
- import { dirname as dirname3, join as join4 } from "node:path";
25539
+ import { dirname as dirname4, join as join5 } from "node:path";
25503
25540
  import { createRequire } from "node:module";
25504
25541
  function semanticFloorFor(version2) {
25505
25542
  if (version2 === EMBEDDING_VERSION || version2 === MODEL_EMBEDDING_VERSION) return 0.25;
@@ -25514,7 +25551,7 @@ function noteHashFallback() {
25514
25551
  );
25515
25552
  }
25516
25553
  function getCacheDir() {
25517
- return process.env["ERRATA_MODEL_CACHE"] ?? join4(homedir2(), ".errata", "models");
25554
+ return process.env["ERRATA_MODEL_CACHE"] ?? join5(homedir2(), ".errata", "models");
25518
25555
  }
25519
25556
  async function loadTransformers() {
25520
25557
  try {
@@ -25523,9 +25560,9 @@ async function loadTransformers() {
25523
25560
  void err2;
25524
25561
  }
25525
25562
  try {
25526
- const seaResourceBase = join4(
25563
+ const seaResourceBase = join5(
25527
25564
  // execPath dir is where errata.exe lives; resources/ rides alongside.
25528
- dirname3(process.execPath),
25565
+ dirname4(process.execPath),
25529
25566
  "resources",
25530
25567
  "_resolve.js"
25531
25568
  );
@@ -25538,7 +25575,7 @@ async function loadTransformers() {
25538
25575
  }
25539
25576
  async function loadPipeline() {
25540
25577
  const cacheDir = getCacheDir();
25541
- if (!existsSync6(cacheDir)) mkdirSync4(cacheDir, { recursive: true });
25578
+ if (!existsSync7(cacheDir)) mkdirSync5(cacheDir, { recursive: true });
25542
25579
  try {
25543
25580
  const tx = await loadTransformers();
25544
25581
  if (!tx) {
@@ -25828,7 +25865,7 @@ var init_diagnostic_matcher = __esm({
25828
25865
  });
25829
25866
 
25830
25867
  // ../../packages/generalizer/src/generalizer.ts
25831
- import { isAbsolute, join as join5, relative } from "node:path";
25868
+ import { isAbsolute, join as join6, relative } from "node:path";
25832
25869
  async function runGeneralizer(opts) {
25833
25870
  const report = {
25834
25871
  eventsProcessed: 0,
@@ -25936,7 +25973,7 @@ function extractDiagnostics(ev) {
25936
25973
  function diagRelPath(file2, cwd, workspaceRoot) {
25937
25974
  const norm = (p) => p.replace(/\\/g, "/");
25938
25975
  if (!workspaceRoot) return norm(file2);
25939
- const abs = isAbsolute(file2) ? file2 : join5(cwd ?? workspaceRoot, file2);
25976
+ const abs = isAbsolute(file2) ? file2 : join6(cwd ?? workspaceRoot, file2);
25940
25977
  return norm(relative(workspaceRoot, abs));
25941
25978
  }
25942
25979
  function extractErrorSignature(ev) {
@@ -27308,16 +27345,16 @@ var init_src10 = __esm({
27308
27345
  });
27309
27346
 
27310
27347
  // src/symbol-summaries.ts
27311
- import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync6 } from "node:fs";
27312
- import { join as join6 } from "node:path";
27348
+ import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "node:fs";
27349
+ import { join as join7 } from "node:path";
27313
27350
  function symbolSummariesPath(configDir) {
27314
- return join6(configDir, "symbol-summaries.json");
27351
+ return join7(configDir, "symbol-summaries.json");
27315
27352
  }
27316
27353
  function loadSymbolSummaryCache(configDir) {
27317
27354
  const p = symbolSummariesPath(configDir);
27318
- if (existsSync7(p)) {
27355
+ if (existsSync8(p)) {
27319
27356
  try {
27320
- const raw2 = JSON.parse(readFileSync5(p, "utf8"));
27357
+ const raw2 = JSON.parse(readFileSync6(p, "utf8"));
27321
27358
  if (raw2 && raw2.version === 1 && raw2.entries && typeof raw2.entries === "object") {
27322
27359
  return { version: 1, entries: raw2.entries };
27323
27360
  }
@@ -27327,7 +27364,7 @@ function loadSymbolSummaryCache(configDir) {
27327
27364
  return { version: 1, entries: {} };
27328
27365
  }
27329
27366
  function saveSymbolSummaryCache(configDir, cache) {
27330
- writeFileSync6(symbolSummariesPath(configDir), JSON.stringify(cache, null, 2), "utf8");
27367
+ writeFileSync7(symbolSummariesPath(configDir), JSON.stringify(cache, null, 2), "utf8");
27331
27368
  }
27332
27369
  function summariesByBodyHash(cache) {
27333
27370
  const m = /* @__PURE__ */ new Map();
@@ -27401,7 +27438,7 @@ function readSnippet(workspaceRoot, attrs) {
27401
27438
  return void 0;
27402
27439
  }
27403
27440
  try {
27404
- const buf = readFileSync5(join6(workspaceRoot, ...relPath.split("/")));
27441
+ const buf = readFileSync6(join7(workspaceRoot, ...relPath.split("/")));
27405
27442
  const slice = buf.subarray(Math.max(0, startByte), Math.min(buf.length, endByte));
27406
27443
  const text = slice.toString("utf8");
27407
27444
  return text.length > MAX_SNIPPET_CHARS ? text.slice(0, MAX_SNIPPET_CHARS) : text;
@@ -27701,9 +27738,9 @@ var init_identity2 = __esm({
27701
27738
  });
27702
27739
 
27703
27740
  // ../../packages/indexer/src/pipeline.ts
27704
- import { appendFileSync, readFileSync as readFileSync6, statSync } from "node:fs";
27741
+ import { appendFileSync, readFileSync as readFileSync7, statSync } from "node:fs";
27705
27742
  import { readdir } from "node:fs/promises";
27706
- import { extname, join as join7, relative as relative2, sep } from "node:path";
27743
+ import { extname, join as join8, relative as relative2, sep } from "node:path";
27707
27744
  import { createHash as createHash3 } from "node:crypto";
27708
27745
  import { execFileSync } from "node:child_process";
27709
27746
  function nowTs() {
@@ -27836,7 +27873,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
27836
27873
  for (const rel of [...changedRelPaths]) {
27837
27874
  let h;
27838
27875
  try {
27839
- h = createHash3("sha256").update(readFileSync6(join7(rootPath, rel))).digest("hex");
27876
+ h = createHash3("sha256").update(readFileSync7(join8(rootPath, rel))).digest("hex");
27840
27877
  } catch {
27841
27878
  continue;
27842
27879
  }
@@ -27883,13 +27920,13 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
27883
27920
  let parsedFiles = 0;
27884
27921
  for (const rel of changedRelPaths) {
27885
27922
  if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
27886
- const abs = join7(rootPath, ...rel.split("/"));
27923
+ const abs = join8(rootPath, ...rel.split("/"));
27887
27924
  const ext = extname(abs).toLowerCase();
27888
27925
  const provider = providers.find((p) => p.fileExtensions.includes(ext));
27889
27926
  if (!provider) continue;
27890
27927
  let symbols;
27891
27928
  try {
27892
- symbols = provider.extractSymbols(readFileSync6(abs, "utf8"), abs);
27929
+ symbols = provider.extractSymbols(readFileSync7(abs, "utf8"), abs);
27893
27930
  } catch {
27894
27931
  continue;
27895
27932
  }
@@ -28195,7 +28232,7 @@ async function runIndexer(store, opts) {
28195
28232
  report.filesSkipped++;
28196
28233
  continue;
28197
28234
  }
28198
- source = readFileSync6(f.absPath, "utf8");
28235
+ source = readFileSync7(f.absPath, "utf8");
28199
28236
  } catch {
28200
28237
  report.filesSkipped++;
28201
28238
  continue;
@@ -28253,7 +28290,7 @@ async function runIndexer(store, opts) {
28253
28290
  const depth = fileNode.relPath.split("/").length;
28254
28291
  if (depth !== 3) continue;
28255
28292
  try {
28256
- const pkg = JSON.parse(readFileSync6(fileNode.absPath, "utf8"));
28293
+ const pkg = JSON.parse(readFileSync7(fileNode.absPath, "utf8"));
28257
28294
  if (!pkg.name) continue;
28258
28295
  const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
28259
28296
  const candidates = [
@@ -28635,7 +28672,7 @@ async function scan(root, current, ignores, providers, out2) {
28635
28672
  for (const ent of entries) {
28636
28673
  if (ignores.has(ent.name)) continue;
28637
28674
  if (ent.name.startsWith(".") && ent.name !== ".") continue;
28638
- const abs = join7(current, ent.name);
28675
+ const abs = join8(current, ent.name);
28639
28676
  if (ent.isDirectory()) {
28640
28677
  await scan(root, abs, ignores, providers, out2);
28641
28678
  } else if (ent.isFile()) {
@@ -28681,7 +28718,7 @@ function gitListFiles(root, ignores, providers) {
28681
28718
  if (segs.some((s) => ignores.has(s) || s.startsWith(".") && s.length > 1)) {
28682
28719
  continue;
28683
28720
  }
28684
- const abs = join7(root, rel);
28721
+ const abs = join8(root, rel);
28685
28722
  let size;
28686
28723
  try {
28687
28724
  size = statSync(abs).size;
@@ -28704,7 +28741,7 @@ function upsertFile(store, id, f, workspaceId2) {
28704
28741
  const now = nowTs();
28705
28742
  let contentHash;
28706
28743
  try {
28707
- contentHash = createHash3("sha256").update(readFileSync6(f.absPath)).digest("hex");
28744
+ contentHash = createHash3("sha256").update(readFileSync7(f.absPath)).digest("hex");
28708
28745
  } catch {
28709
28746
  }
28710
28747
  const node2 = {
@@ -33067,42 +33104,42 @@ ${JSON.stringify(symbolNames, null, 2)}`);
33067
33104
 
33068
33105
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
33069
33106
  import { fileURLToPath } from "node:url";
33070
- import { dirname as dirname4, join as join8 } from "node:path";
33071
- import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
33107
+ import { dirname as dirname5, join as join9 } from "node:path";
33108
+ import { existsSync as existsSync9, readdirSync as readdirSync2 } from "node:fs";
33072
33109
  import { createRequire as createRequire2 } from "node:module";
33073
33110
  function entryDir() {
33074
33111
  try {
33075
33112
  const url2 = import.meta?.url;
33076
33113
  if (typeof url2 === "string" && url2.length > 0) {
33077
- return dirname4(fileURLToPath(url2));
33114
+ return dirname5(fileURLToPath(url2));
33078
33115
  }
33079
33116
  } catch {
33080
33117
  }
33081
- return dirname4(process.execPath);
33118
+ return dirname5(process.execPath);
33082
33119
  }
33083
33120
  function findWasmDir() {
33084
33121
  const here = entryDir();
33085
- const seaWasm = join8(here, "resources", "wasm");
33086
- if (existsSync8(join8(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
33122
+ const seaWasm = join9(here, "resources", "wasm");
33123
+ if (existsSync9(join9(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
33087
33124
  let dir = here;
33088
33125
  for (let i2 = 0; i2 < 6; i2++) {
33089
- const flat = join8(
33126
+ const flat = join9(
33090
33127
  dir,
33091
33128
  "node_modules",
33092
33129
  "@vscode",
33093
33130
  "tree-sitter-wasm",
33094
33131
  "wasm"
33095
33132
  );
33096
- if (existsSync8(join8(flat, "tree-sitter-typescript.wasm"))) return flat;
33097
- dir = dirname4(dir);
33133
+ if (existsSync9(join9(flat, "tree-sitter-typescript.wasm"))) return flat;
33134
+ dir = dirname5(dir);
33098
33135
  }
33099
33136
  let root = here;
33100
33137
  for (let i2 = 0; i2 < 6; i2++) {
33101
- const pnpmDir = join8(root, "node_modules", ".pnpm");
33102
- if (existsSync8(pnpmDir)) {
33138
+ const pnpmDir = join9(root, "node_modules", ".pnpm");
33139
+ if (existsSync9(pnpmDir)) {
33103
33140
  for (const entry of readdirSync2(pnpmDir)) {
33104
33141
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
33105
- const candidate = join8(
33142
+ const candidate = join9(
33106
33143
  pnpmDir,
33107
33144
  entry,
33108
33145
  "node_modules",
@@ -33110,13 +33147,13 @@ function findWasmDir() {
33110
33147
  "tree-sitter-wasm",
33111
33148
  "wasm"
33112
33149
  );
33113
- if (existsSync8(join8(candidate, "tree-sitter-typescript.wasm"))) {
33150
+ if (existsSync9(join9(candidate, "tree-sitter-typescript.wasm"))) {
33114
33151
  return candidate;
33115
33152
  }
33116
33153
  }
33117
33154
  }
33118
33155
  }
33119
- root = dirname4(root);
33156
+ root = dirname5(root);
33120
33157
  }
33121
33158
  throw new Error(
33122
33159
  "@vscode/tree-sitter-wasm grammar files not found \u2014 is the package installed?"
@@ -33124,33 +33161,33 @@ function findWasmDir() {
33124
33161
  }
33125
33162
  function findRuntimeDir() {
33126
33163
  const here = entryDir();
33127
- const seaRuntime = join8(here, "resources", "wasm");
33128
- if (existsSync8(join8(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
33164
+ const seaRuntime = join9(here, "resources", "wasm");
33165
+ if (existsSync9(join9(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
33129
33166
  let dir = here;
33130
33167
  for (let i2 = 0; i2 < 6; i2++) {
33131
- const flat = join8(dir, "node_modules", "web-tree-sitter");
33132
- if (existsSync8(join8(flat, "web-tree-sitter.wasm"))) return flat;
33133
- dir = dirname4(dir);
33168
+ const flat = join9(dir, "node_modules", "web-tree-sitter");
33169
+ if (existsSync9(join9(flat, "web-tree-sitter.wasm"))) return flat;
33170
+ dir = dirname5(dir);
33134
33171
  }
33135
33172
  let root = here;
33136
33173
  for (let i2 = 0; i2 < 6; i2++) {
33137
- const pnpmDir = join8(root, "node_modules", ".pnpm");
33138
- if (existsSync8(pnpmDir)) {
33174
+ const pnpmDir = join9(root, "node_modules", ".pnpm");
33175
+ if (existsSync9(pnpmDir)) {
33139
33176
  for (const entry of readdirSync2(pnpmDir)) {
33140
33177
  if (entry.startsWith("web-tree-sitter@")) {
33141
- const candidate = join8(
33178
+ const candidate = join9(
33142
33179
  pnpmDir,
33143
33180
  entry,
33144
33181
  "node_modules",
33145
33182
  "web-tree-sitter"
33146
33183
  );
33147
- if (existsSync8(join8(candidate, "web-tree-sitter.wasm"))) {
33184
+ if (existsSync9(join9(candidate, "web-tree-sitter.wasm"))) {
33148
33185
  return candidate;
33149
33186
  }
33150
33187
  }
33151
33188
  }
33152
33189
  }
33153
- root = dirname4(root);
33190
+ root = dirname5(root);
33154
33191
  }
33155
33192
  throw new Error("web-tree-sitter runtime WASM not found");
33156
33193
  }
@@ -33161,7 +33198,7 @@ async function loadWebTreeSitter() {
33161
33198
  void err2;
33162
33199
  }
33163
33200
  const here = entryDir();
33164
- const seaResourceBase = join8(here, "resources", "_resolve.js");
33201
+ const seaResourceBase = join9(here, "resources", "_resolve.js");
33165
33202
  const resourceRequire = createRequire2(seaResourceBase);
33166
33203
  return resourceRequire("web-tree-sitter");
33167
33204
  }
@@ -33176,9 +33213,9 @@ async function ensureTreeSitterReady() {
33176
33213
  await Parser2.init({
33177
33214
  locateFile: (name2) => {
33178
33215
  if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
33179
- return join8(runtime, name2);
33216
+ return join9(runtime, name2);
33180
33217
  }
33181
- return join8(grammars, name2);
33218
+ return join9(grammars, name2);
33182
33219
  }
33183
33220
  });
33184
33221
  })();
@@ -33190,7 +33227,7 @@ async function loadGrammar(name2) {
33190
33227
  if (cached2) return cached2;
33191
33228
  if (!languageClass) throw new Error("tree-sitter not initialized");
33192
33229
  const grammars = findWasmDir();
33193
- const lang = await languageClass.load(join8(grammars, `${name2}.wasm`));
33230
+ const lang = await languageClass.load(join9(grammars, `${name2}.wasm`));
33194
33231
  grammarCache.set(name2, lang);
33195
33232
  return lang;
33196
33233
  }
@@ -36092,7 +36129,7 @@ var init_src11 = __esm({
36092
36129
  // src/reconcile.ts
36093
36130
  import { execFileSync as execFileSync2 } from "node:child_process";
36094
36131
  import { readdirSync as readdirSync3, statSync as statSync2 } from "node:fs";
36095
- import { join as join9, relative as relative3, sep as sep2 } from "node:path";
36132
+ import { join as join10, relative as relative3, sep as sep2 } from "node:path";
36096
36133
  function gitSourceFiles(root) {
36097
36134
  let stdout;
36098
36135
  try {
@@ -36107,7 +36144,7 @@ function gitSourceFiles(root) {
36107
36144
  const out2 = [];
36108
36145
  for (const rel of stdout.split("\0")) {
36109
36146
  if (!rel || !SOURCE_RE.test(rel)) continue;
36110
- const abs = join9(root, rel);
36147
+ const abs = join10(root, rel);
36111
36148
  if (IGNORED.test(abs)) continue;
36112
36149
  out2.push(abs);
36113
36150
  }
@@ -36122,7 +36159,7 @@ function* walkSource(dir) {
36122
36159
  }
36123
36160
  for (const e of entries) {
36124
36161
  const name2 = String(e.name);
36125
- const full = join9(dir, name2);
36162
+ const full = join10(dir, name2);
36126
36163
  if (IGNORED.test(full)) continue;
36127
36164
  if (e.isDirectory()) yield* walkSource(full);
36128
36165
  else if (SOURCE_RE.test(name2)) yield full;
@@ -36200,7 +36237,7 @@ __export(mcp_exports, {
36200
36237
  runTool: () => runTool,
36201
36238
  searchGraph: () => searchGraph
36202
36239
  });
36203
- import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
36240
+ import { existsSync as existsSync10, readFileSync as readFileSync8 } from "node:fs";
36204
36241
  import { resolve } from "node:path";
36205
36242
  function collectEnrichmentPulls(store, opts = {}) {
36206
36243
  const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
@@ -36313,10 +36350,10 @@ function showNode(store, node2, maxLines) {
36313
36350
  if (!relPath) return { found: false, reason: "no file owner for node" };
36314
36351
  const workspaceRoot = process.cwd();
36315
36352
  const absPath = resolve(workspaceRoot, relPath);
36316
- if (!existsSync9(absPath)) {
36353
+ if (!existsSync10(absPath)) {
36317
36354
  return { found: false, reason: `file not found on disk: ${absPath}` };
36318
36355
  }
36319
- const source = readFileSync7(absPath, "utf8");
36356
+ const source = readFileSync8(absPath, "utf8");
36320
36357
  const attrs = node2.attrs;
36321
36358
  let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
36322
36359
  let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
@@ -37549,7 +37586,7 @@ var init_mcp = __esm({
37549
37586
  inputSchema: { type: "object", properties: {} },
37550
37587
  handler: () => {
37551
37588
  const path2 = sharedStorePath();
37552
- if (!existsSync9(path2)) return { count: 0, pending: [] };
37589
+ if (!existsSync10(path2)) return { count: 0, pending: [] };
37553
37590
  const shared = openGraphStore({ path: path2 });
37554
37591
  try {
37555
37592
  const pending = pendingAbstractions(shared);
@@ -37580,7 +37617,7 @@ var init_mcp = __esm({
37580
37617
  },
37581
37618
  handler: (args2) => {
37582
37619
  const path2 = sharedStorePath();
37583
- if (!existsSync9(path2)) return { count: 0, routes: [] };
37620
+ if (!existsSync10(path2)) return { count: 0, routes: [] };
37584
37621
  const shared = openGraphStore({ path: path2 });
37585
37622
  try {
37586
37623
  const result = triageOf(shared, {
@@ -37965,8 +38002,8 @@ __export(vfile_exports, {
37965
38002
  resolvePath: () => resolvePath,
37966
38003
  segmentsOf: () => segmentsOf
37967
38004
  });
37968
- import { writeFileSync as writeFileSync7 } from "node:fs";
37969
- import { join as join10, resolve as resolve2, sep as sep3 } from "node:path";
38005
+ import { writeFileSync as writeFileSync8 } from "node:fs";
38006
+ import { join as join11, resolve as resolve2, sep as sep3 } from "node:path";
37970
38007
  function segmentsOf(rawPath) {
37971
38008
  let p = rawPath.replace(/\\/g, "/");
37972
38009
  p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
@@ -38040,14 +38077,14 @@ async function renderVFile(rawPath, store, ctx = {}) {
38040
38077
  }
38041
38078
  async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
38042
38079
  const segs = segmentsOf(rawPath);
38043
- const gRoot = join10(workspaceRoot, ".errata", "g");
38080
+ const gRoot = join11(workspaceRoot, ".errata", "g");
38044
38081
  const abs = resolve2(gRoot, ...segs.length ? segs : ["index"]);
38045
38082
  if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
38046
38083
  throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
38047
38084
  }
38048
38085
  const text = await renderVFile(rawPath, store, ctx);
38049
38086
  ensureParent(abs);
38050
- writeFileSync7(abs, text, "utf8");
38087
+ writeFileSync8(abs, text, "utf8");
38051
38088
  return abs;
38052
38089
  }
38053
38090
  async function materializeOverview(workspaceRoot, store, ctx = {}) {
@@ -45333,12 +45370,13 @@ function extractExecutables(command) {
45333
45370
  return out2;
45334
45371
  }
45335
45372
  function observeCommandTools(store, command, ts) {
45336
- const result = { minted: [], reinforced: [] };
45373
+ const result = { minted: [], reinforced: [], nodeIds: [] };
45337
45374
  const osName = currentOsName();
45338
45375
  for (const name2 of extractExecutables(command)) {
45339
45376
  if (!PUBLIC_TOOLS.has(name2)) continue;
45340
45377
  if (PLUMBING.has(name2)) continue;
45341
45378
  const id = toolNodeId(name2);
45379
+ result.nodeIds.push(id);
45342
45380
  const existing = store.getNode(id);
45343
45381
  if (existing) {
45344
45382
  store.updateNode(id, {
@@ -45370,23 +45408,23 @@ function observeCommandTools(store, command, ts) {
45370
45408
  attrs: { name: name2, canonicalId: toolCanonicalId(name2), public: true }
45371
45409
  });
45372
45410
  result.minted.push(name2);
45373
- if (osName) {
45374
- const os2 = resolveOsNode(store, osName, ts);
45375
- store.mergeEdge({
45376
- id: `edge_${digest({ from: id, type: "RUNS_ON", to: os2.id })}`.slice(0, 24),
45377
- from: id,
45378
- to: os2.id,
45379
- type: "RUNS_ON",
45380
- confidence: 1,
45381
- // observed
45382
- extractionSource: "daemon-extracted",
45383
- createdAt: ts,
45384
- lastSeenAt: ts,
45385
- navSuccesses: 0,
45386
- navFailures: 0,
45387
- attrs: { observed: true }
45388
- });
45389
- }
45411
+ }
45412
+ if (osName) {
45413
+ const os2 = resolveOsNode(store, osName, ts);
45414
+ store.mergeEdge({
45415
+ id: `edge_${digest({ from: id, type: "RUNS_ON", to: os2.id })}`.slice(0, 24),
45416
+ from: id,
45417
+ to: os2.id,
45418
+ type: "RUNS_ON",
45419
+ confidence: 1,
45420
+ // observed
45421
+ extractionSource: "daemon-extracted",
45422
+ createdAt: ts,
45423
+ lastSeenAt: ts,
45424
+ navSuccesses: 0,
45425
+ navFailures: 0,
45426
+ attrs: { observed: true }
45427
+ });
45390
45428
  }
45391
45429
  }
45392
45430
  return result;
@@ -45431,25 +45469,25 @@ var init_tool_index = __esm({
45431
45469
 
45432
45470
  // src/outbox.ts
45433
45471
  import {
45434
- existsSync as existsSync10,
45472
+ existsSync as existsSync11,
45435
45473
  readdirSync as readdirSync4,
45436
- readFileSync as readFileSync8,
45474
+ readFileSync as readFileSync9,
45437
45475
  renameSync,
45438
45476
  unlinkSync,
45439
- writeFileSync as writeFileSync8
45477
+ writeFileSync as writeFileSync9
45440
45478
  } from "node:fs";
45441
- import { join as join11 } from "node:path";
45479
+ import { join as join12 } from "node:path";
45442
45480
  import { createHash as createHash11 } from "node:crypto";
45443
45481
  function enqueueOutbox(paths, payload) {
45444
45482
  ensureDir(paths.outbox);
45445
45483
  const id = createHash11("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
45446
- const file2 = join11(paths.outbox, `${Date.now()}-${id}.json`);
45447
- writeFileSync8(file2, JSON.stringify(payload, null, 2), "utf8");
45484
+ const file2 = join12(paths.outbox, `${Date.now()}-${id}.json`);
45485
+ writeFileSync9(file2, JSON.stringify(payload, null, 2), "utf8");
45448
45486
  return file2;
45449
45487
  }
45450
45488
  async function flushOutbox(paths, client, store) {
45451
45489
  ensureDir(paths.outbox);
45452
- const entries = existsSync10(paths.outbox) ? readdirSync4(paths.outbox) : [];
45490
+ const entries = existsSync11(paths.outbox) ? readdirSync4(paths.outbox) : [];
45453
45491
  let uploaded = 0;
45454
45492
  let failed = 0;
45455
45493
  const quarantine = (abs, reason) => {
@@ -45460,10 +45498,10 @@ async function flushOutbox(paths, client, store) {
45460
45498
  }
45461
45499
  };
45462
45500
  for (const f of entries.filter((e) => e.endsWith(".json")).sort()) {
45463
- const abs = join11(paths.outbox, f);
45501
+ const abs = join12(paths.outbox, f);
45464
45502
  let payload;
45465
45503
  try {
45466
- payload = JSON.parse(readFileSync8(abs, "utf8"));
45504
+ payload = JSON.parse(readFileSync9(abs, "utf8"));
45467
45505
  } catch {
45468
45506
  failed++;
45469
45507
  quarantine(abs, "unparseable JSON");
@@ -45508,7 +45546,7 @@ async function flushOutbox(paths, client, store) {
45508
45546
  }
45509
45547
  }
45510
45548
  }
45511
- const remainingFiles = existsSync10(paths.outbox) ? readdirSync4(paths.outbox).filter((e) => e.endsWith(".json")) : [];
45549
+ const remainingFiles = existsSync11(paths.outbox) ? readdirSync4(paths.outbox).filter((e) => e.endsWith(".json")) : [];
45512
45550
  return { uploaded, failed, remaining: remainingFiles.length };
45513
45551
  }
45514
45552
  var init_outbox = __esm({
@@ -45528,7 +45566,6 @@ __export(webui_exports, {
45528
45566
  recallForFile: () => recallForFile,
45529
45567
  recallForTool: () => recallForTool
45530
45568
  });
45531
- import { join as join12 } from "node:path";
45532
45569
  function fileUriToFsPath(raw2) {
45533
45570
  let p = raw2.replace(/^file:\/\//, "").replace(/\\/g, "/");
45534
45571
  if (/^\/[A-Za-z]:/.test(p)) p = p.slice(1);
@@ -45826,7 +45863,8 @@ function buildWebUi(deps) {
45826
45863
  ts: Date.now()
45827
45864
  });
45828
45865
  try {
45829
- observeCommandTools(deps.store, input["command"], Date.now());
45866
+ const observed = observeCommandTools(deps.store, input["command"], Date.now());
45867
+ deps.onToolsObserved?.(String(body2["session_id"] ?? ""), observed.nodeIds);
45830
45868
  } catch {
45831
45869
  }
45832
45870
  if (failed) recallCtx = recallForError(deps.store, stderr || combined);
@@ -45940,7 +45978,7 @@ function buildWebUi(deps) {
45940
45978
  } catch {
45941
45979
  return c.json({});
45942
45980
  }
45943
- const block = readManagedBlockWithHash(join12(deps.paths.root, "AGENTS.md"));
45981
+ const block = readContextFileWithHash(deps.paths.root);
45944
45982
  const decision = decideContextInject({
45945
45983
  event: String(body2["hook_event_name"] ?? "UserPromptSubmit"),
45946
45984
  source: String(body2["source"] ?? ""),
@@ -46545,12 +46583,12 @@ var init_report_render = __esm({
46545
46583
 
46546
46584
  // src/cli.ts
46547
46585
  init_src5();
46548
- import { closeSync as closeSync2, existsSync as existsSync23, openSync as openSync2, readFileSync as readFileSync21, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
46586
+ import { closeSync as closeSync2, existsSync as existsSync24, openSync as openSync2, readFileSync as readFileSync22, renameSync as renameSync3, statSync as statSync6 } from "node:fs";
46549
46587
  import { join as join26 } from "node:path";
46550
46588
  import { spawn as spawn3 } from "node:child_process";
46551
46589
 
46552
46590
  // src/daemon.ts
46553
- import { existsSync as existsSync18, writeFileSync as writeFileSync14 } from "node:fs";
46591
+ import { existsSync as existsSync19, writeFileSync as writeFileSync15 } from "node:fs";
46554
46592
 
46555
46593
  // ../../node_modules/.pnpm/@hono+node-server@1.19.11_hono@4.12.8/node_modules/@hono/node-server/dist/index.mjs
46556
46594
  import { createServer as createServerHTTP } from "http";
@@ -47130,7 +47168,7 @@ init_config();
47130
47168
 
47131
47169
  // src/engine.ts
47132
47170
  import { execFileSync as execFileSync3 } from "node:child_process";
47133
- import { existsSync as existsSync17, statSync as statSync5, appendFileSync as appendFileSync2, readdirSync as readdirSync8, renameSync as renameSync2, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "node:fs";
47171
+ 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";
47134
47172
  import { join as join22, relative as relative6, sep as sep4 } from "node:path";
47135
47173
 
47136
47174
  // ../../node_modules/.pnpm/chokidar@4.0.3/node_modules/chokidar/esm/index.js
@@ -47862,9 +47900,9 @@ var NodeFsHandler = class {
47862
47900
  if (this.fsw.closed) {
47863
47901
  return;
47864
47902
  }
47865
- const dirname9 = sysPath.dirname(file2);
47903
+ const dirname10 = sysPath.dirname(file2);
47866
47904
  const basename5 = sysPath.basename(file2);
47867
- const parent = this.fsw._getWatchedDir(dirname9);
47905
+ const parent = this.fsw._getWatchedDir(dirname10);
47868
47906
  let prevStats = stats;
47869
47907
  if (parent.has(basename5))
47870
47908
  return;
@@ -47891,7 +47929,7 @@ var NodeFsHandler = class {
47891
47929
  prevStats = newStats2;
47892
47930
  }
47893
47931
  } catch (error48) {
47894
- this.fsw._remove(dirname9, basename5);
47932
+ this.fsw._remove(dirname10, basename5);
47895
47933
  }
47896
47934
  } else if (parent.has(basename5)) {
47897
47935
  const at = newStats.atimeMs;
@@ -48993,8 +49031,8 @@ init_src10();
48993
49031
  init_review2();
48994
49032
 
48995
49033
  // src/turn.ts
48996
- import { closeSync, existsSync as existsSync11, fstatSync, openSync, readdirSync as readdirSync5, readSync, statSync as statSync3 } from "node:fs";
48997
- import { basename as basename3, dirname as dirname7, join as join15 } from "node:path";
49034
+ import { closeSync, existsSync as existsSync12, fstatSync, openSync, readdirSync as readdirSync5, readSync, statSync as statSync3 } from "node:fs";
49035
+ import { basename as basename3, dirname as dirname8, join as join15 } from "node:path";
48998
49036
  import { homedir as homedir3 } from "node:os";
48999
49037
  function readTail(path2, maxBytes) {
49000
49038
  let fd;
@@ -49137,7 +49175,7 @@ function claudeProjectDir(cwd, home = homedir3()) {
49137
49175
  }
49138
49176
  function recentTranscripts(cwd, opts = {}) {
49139
49177
  const dir = claudeProjectDir(cwd, opts.home ?? homedir3());
49140
- if (!existsSync11(dir)) return [];
49178
+ if (!existsSync12(dir)) return [];
49141
49179
  let names;
49142
49180
  try {
49143
49181
  names = readdirSync5(dir);
@@ -49163,8 +49201,8 @@ function recentTranscripts(cwd, opts = {}) {
49163
49201
  }
49164
49202
  function subagentTranscripts(mainTranscriptPath, sessionId) {
49165
49203
  if (!mainTranscriptPath || !sessionId) return [];
49166
- const dir = join15(dirname7(mainTranscriptPath), sessionId, "subagents");
49167
- if (!existsSync11(dir)) return [];
49204
+ const dir = join15(dirname8(mainTranscriptPath), sessionId, "subagents");
49205
+ if (!existsSync12(dir)) return [];
49168
49206
  let names;
49169
49207
  try {
49170
49208
  names = readdirSync5(dir);
@@ -49193,7 +49231,7 @@ init_src2();
49193
49231
  init_agent_signals();
49194
49232
  init_tool_index();
49195
49233
  init_src4();
49196
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync9 } from "node:fs";
49234
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync10 } from "node:fs";
49197
49235
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
49198
49236
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
49199
49237
  var HANDLE_RE = /\[([a-z0-9][\w-]{0,40})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
@@ -49208,11 +49246,8 @@ var SUPERSEDES_PREFIX = /^\s*supersedes:(?:#([a-z][\w-]{0,63}))?\s*/i;
49208
49246
  var ALTERNATIVE_PREFIX = /^\s*alternative:(?:#([a-z][\w-]{0,63}))?\s*/i;
49209
49247
  var INSTANCE_PREFIX = /^\s*instance:\s*/i;
49210
49248
  var PATTERN_RE = /\(\s*pattern:\s*([^()\n]{3,}?)\s*\)/gi;
49211
- var PATTERN_TEXT_MAX = 120;
49212
49249
  var CAUSE_TEXT_MIN = 8;
49213
- var CAUSE_TEXT_MAX = 200;
49214
49250
  var FLAG_RE = /\[([!?])(?:#([a-z][\w-]{0,63})\s+)?\s*([^\]\n]{8,}?)\s*(?:@\s*([^\s\]]+?)(?::(\d+))?\s*)?\]/g;
49215
- var FLAG_MAX = 200;
49216
49251
  var CONSTRAINT_MIN = 8;
49217
49252
  function clauseBefore(sentence, idx) {
49218
49253
  const win = sentence.slice(Math.max(0, idx - 80), idx);
@@ -49287,7 +49322,7 @@ function parseInlineTags(text) {
49287
49322
  } else {
49288
49323
  const raw3 = content.replace(/\s+/g, " ").trim();
49289
49324
  if (raw3.length >= CAUSE_TEXT_MIN) {
49290
- const causeText = raw3.length > CAUSE_TEXT_MAX ? `${raw3.slice(0, CAUSE_TEXT_MAX - 1).trimEnd()}\u2026` : raw3;
49325
+ const causeText = raw3;
49291
49326
  out2.push({ kind: "triage", causeText, sentence: sfield, ...verbThread ? { threadId: verbThread } : {} });
49292
49327
  }
49293
49328
  }
@@ -49329,7 +49364,7 @@ function parseInlineTags(text) {
49329
49364
  if (raw3.length >= 8) {
49330
49365
  const segs = raw3.split(CAUSE_ARROW).map((s) => s.trim()).filter((s) => s.length > 0);
49331
49366
  const symptomRaw = segs.length > 1 ? segs[0] : raw3;
49332
- const statement = symptomRaw.length > FLAG_MAX ? `${symptomRaw.slice(0, FLAG_MAX - 1).trimEnd()}\u2026` : symptomRaw;
49367
+ const statement = symptomRaw;
49333
49368
  const asFix = f[1] === "!" && /^(?:fixed|resolved)\s*[:,-]\s*/i.exec(statement);
49334
49369
  if (asFix) {
49335
49370
  const note = statement.slice(asFix[0].length).trim();
@@ -49361,7 +49396,7 @@ function parseInlineTags(text) {
49361
49396
  while ((a = ATTEMPT_RE.exec(sentence)) !== null) {
49362
49397
  const raw3 = a[3].replace(/\s+/g, " ").trim();
49363
49398
  if (raw3.length >= CONSTRAINT_MIN) {
49364
- const statement = raw3.length > FLAG_MAX ? `${raw3.slice(0, FLAG_MAX - 1).trimEnd()}\u2026` : raw3;
49399
+ const statement = raw3;
49365
49400
  const isFailure = a[1].toLowerCase() === "failed";
49366
49401
  let refuteHandles;
49367
49402
  if (isFailure) {
@@ -49395,7 +49430,7 @@ function parseInlineTags(text) {
49395
49430
  } else {
49396
49431
  const raw3 = body2.replace(/\s+/g, " ").trim();
49397
49432
  if (raw3.length >= 3) {
49398
- const patternText = raw3.length > PATTERN_TEXT_MAX ? `${raw3.slice(0, PATTERN_TEXT_MAX - 1).trimEnd()}\u2026` : raw3;
49433
+ const patternText = raw3;
49399
49434
  out2.push({ kind: "pattern", patternText, sentence: sfield });
49400
49435
  }
49401
49436
  }
@@ -49405,7 +49440,7 @@ function parseInlineTags(text) {
49405
49440
  while ((c = CONSTRAINT_RE.exec(sentence)) !== null) {
49406
49441
  const raw3 = c[1].replace(/\s+/g, " ").trim();
49407
49442
  if (raw3.length >= CONSTRAINT_MIN) {
49408
- const statement = raw3.length > FLAG_MAX ? `${raw3.slice(0, FLAG_MAX - 1).trimEnd()}\u2026` : raw3;
49443
+ const statement = raw3;
49409
49444
  out2.push({ kind: "constraint", statement, sentence: sfield });
49410
49445
  }
49411
49446
  }
@@ -49481,13 +49516,13 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
49481
49516
  entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
49482
49517
  entries.length = HANDLE_MAP_MAX;
49483
49518
  }
49484
- writeFileSync9(path2, JSON.stringify(Object.fromEntries(entries)));
49519
+ writeFileSync10(path2, JSON.stringify(Object.fromEntries(entries)));
49485
49520
  } catch {
49486
49521
  }
49487
49522
  }
49488
49523
  function readPrimingHandles(path2) {
49489
49524
  try {
49490
- return JSON.parse(readFileSync9(path2, "utf8"));
49525
+ return JSON.parse(readFileSync10(path2, "utf8"));
49491
49526
  } catch {
49492
49527
  return {};
49493
49528
  }
@@ -49504,6 +49539,7 @@ function mintPriorEdge(store, source, target, sentence, touched, ts) {
49504
49539
  if (anchorIds.size === 0 && (target.label === "Language" || target.label === "Package")) {
49505
49540
  for (const e of store.inEdges(target.id, STACK_GROUNDING_EDGES)) anchorIds.add(e.from);
49506
49541
  }
49542
+ if (anchorIds.size === 0 && target.label === "Tool") anchorIds.add(target.id);
49507
49543
  const corroborated = tagEdgeCorroborated(anchorIds, touched, false);
49508
49544
  store.mergeEdge({
49509
49545
  id: `edge_${digest({ from: source.id, type, to: target.id, k: "priorTag" })}`.slice(0, 24),
@@ -49520,7 +49556,12 @@ function mintPriorEdge(store, source, target, sentence, touched, ts) {
49520
49556
  navFailures: 0,
49521
49557
  attrs: { provisional: true, priorTag: true, primingProvenance: true, corroborated }
49522
49558
  });
49523
- if (type === "CONCERNS") stampObservedOs(store, source.id, currentOsName(), ts);
49559
+ if (type === "CONCERNS") {
49560
+ try {
49561
+ stampObservedOs(store, source.id, currentOsName(), ts);
49562
+ } catch {
49563
+ }
49564
+ }
49524
49565
  return true;
49525
49566
  }
49526
49567
  function harvestInlineTags(store, text, opts) {
@@ -49971,11 +50012,11 @@ init_outbox();
49971
50012
  init_src8();
49972
50013
  init_src();
49973
50014
  init_src2();
49974
- import { readFileSync as readFileSync10 } from "node:fs";
50015
+ import { readFileSync as readFileSync11 } from "node:fs";
49975
50016
  import { join as join16 } from "node:path";
49976
50017
  function loadClaimIgnorePatterns(workspaceRoot) {
49977
50018
  try {
49978
- return readFileSync10(join16(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
50019
+ return readFileSync11(join16(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
49979
50020
  } catch {
49980
50021
  return [];
49981
50022
  }
@@ -50279,11 +50320,11 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
50279
50320
  }
50280
50321
 
50281
50322
  // src/git-sensor.ts
50282
- import { existsSync as existsSync12, readFileSync as readFileSync11, watch as fsWatch } from "node:fs";
50323
+ import { existsSync as existsSync13, readFileSync as readFileSync12, watch as fsWatch } from "node:fs";
50283
50324
  import { join as join17 } from "node:path";
50284
50325
  function readFirstLine(path2) {
50285
50326
  try {
50286
- return readFileSync11(path2, "utf8").split(/\r?\n/, 1)[0].trim();
50327
+ return readFileSync12(path2, "utf8").split(/\r?\n/, 1)[0].trim();
50287
50328
  } catch {
50288
50329
  return null;
50289
50330
  }
@@ -50302,13 +50343,13 @@ function readGitRefState(gitDir) {
50302
50343
  return {
50303
50344
  branch,
50304
50345
  sha: sha2,
50305
- mergeHeadExists: existsSync12(join17(gitDir, "MERGE_HEAD")),
50306
- origHeadExists: existsSync12(join17(gitDir, "ORIG_HEAD"))
50346
+ mergeHeadExists: existsSync13(join17(gitDir, "MERGE_HEAD")),
50347
+ origHeadExists: existsSync13(join17(gitDir, "ORIG_HEAD"))
50307
50348
  };
50308
50349
  }
50309
50350
  function shaFromPackedRefs(gitDir, ref) {
50310
50351
  try {
50311
- for (const line of readFileSync11(join17(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
50352
+ for (const line of readFileSync12(join17(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
50312
50353
  const [sha2, name2] = line.split(/\s+/);
50313
50354
  if (name2 === ref && sha2) return sha2;
50314
50355
  }
@@ -50342,7 +50383,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
50342
50383
  const settle = () => {
50343
50384
  if (timer) clearTimeout(timer);
50344
50385
  timer = setTimeout(() => {
50345
- if (existsSync12(join17(gitDir, "index.lock"))) {
50386
+ if (existsSync13(join17(gitDir, "index.lock"))) {
50346
50387
  settle();
50347
50388
  return;
50348
50389
  }
@@ -50578,21 +50619,21 @@ var TelemetryRecorder = class {
50578
50619
 
50579
50620
  // src/skills.ts
50580
50621
  import {
50581
- existsSync as existsSync13,
50582
- mkdirSync as mkdirSync5,
50583
- readFileSync as readFileSync12,
50622
+ existsSync as existsSync14,
50623
+ mkdirSync as mkdirSync6,
50624
+ readFileSync as readFileSync13,
50584
50625
  readdirSync as readdirSync6,
50585
50626
  unlinkSync as unlinkSync2,
50586
- writeFileSync as writeFileSync10
50627
+ writeFileSync as writeFileSync11
50587
50628
  } from "node:fs";
50588
50629
  import { basename as basename4, join as join18 } from "node:path";
50589
50630
  function skillFileName(id) {
50590
50631
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
50591
50632
  }
50592
50633
  function readSkillManifest(manifestPath) {
50593
- if (!existsSync13(manifestPath)) return [];
50634
+ if (!existsSync14(manifestPath)) return [];
50594
50635
  try {
50595
- const parsed = JSON.parse(readFileSync12(manifestPath, "utf8"));
50636
+ const parsed = JSON.parse(readFileSync13(manifestPath, "utf8"));
50596
50637
  return (parsed.skills ?? []).map((s) => ({
50597
50638
  title: s.title ?? "",
50598
50639
  layer: s.layer ?? "technique",
@@ -50606,7 +50647,7 @@ function readSkillManifest(manifestPath) {
50606
50647
  async function syncSkills(paths, client, seed, pins = []) {
50607
50648
  const res = await client.getSkills(void 0, seed);
50608
50649
  const staleDaemon = res.staleDaemon && res.latestDaemonVersion ? { latest: res.latestDaemonVersion } : void 0;
50609
- mkdirSync5(paths.skillsDir, { recursive: true });
50650
+ mkdirSync6(paths.skillsDir, { recursive: true });
50610
50651
  if (res.skills.length === 0 && pins.length === 0) {
50611
50652
  const existing = readdirSync6(paths.skillsDir).filter((f) => f.endsWith(".md"));
50612
50653
  if (existing.length > 0) return { written: 0, pruned: 0, ...staleDaemon ? { staleDaemon } : {} };
@@ -50616,7 +50657,7 @@ async function syncSkills(paths, client, seed, pins = []) {
50616
50657
  for (const s of res.skills) {
50617
50658
  const fileName = skillFileName(s.id);
50618
50659
  keep.add(fileName);
50619
- writeFileSync10(join18(paths.skillsDir, fileName), s.markdown, "utf8");
50660
+ writeFileSync11(join18(paths.skillsDir, fileName), s.markdown, "utf8");
50620
50661
  rows.push({
50621
50662
  id: s.id,
50622
50663
  title: s.title,
@@ -50629,7 +50670,7 @@ async function syncSkills(paths, client, seed, pins = []) {
50629
50670
  const fileName = skillFileName(p.id);
50630
50671
  if (keep.has(fileName)) continue;
50631
50672
  keep.add(fileName);
50632
- writeFileSync10(join18(paths.skillsDir, fileName), p.markdown, "utf8");
50673
+ writeFileSync11(join18(paths.skillsDir, fileName), p.markdown, "utf8");
50633
50674
  rows.push({
50634
50675
  id: p.id,
50635
50676
  title: p.title,
@@ -50649,7 +50690,7 @@ async function syncSkills(paths, client, seed, pins = []) {
50649
50690
  }
50650
50691
  }
50651
50692
  rows.sort((a, b) => a.id.localeCompare(b.id));
50652
- writeFileSync10(
50693
+ writeFileSync11(
50653
50694
  paths.skillsManifest,
50654
50695
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
50655
50696
  "utf8"
@@ -50660,14 +50701,14 @@ async function syncSkills(paths, client, seed, pins = []) {
50660
50701
  // src/agent-skills.ts
50661
50702
  import {
50662
50703
  cpSync,
50663
- existsSync as existsSync14,
50704
+ existsSync as existsSync15,
50664
50705
  lstatSync,
50665
- mkdirSync as mkdirSync6,
50666
- readFileSync as readFileSync13,
50706
+ mkdirSync as mkdirSync7,
50707
+ readFileSync as readFileSync14,
50667
50708
  readdirSync as readdirSync7,
50668
50709
  rmSync as rmSync2,
50669
50710
  symlinkSync,
50670
- writeFileSync as writeFileSync11
50711
+ writeFileSync as writeFileSync12
50671
50712
  } from "node:fs";
50672
50713
  import { join as join19 } from "node:path";
50673
50714
  var SKILL_NS = "errata-";
@@ -50700,7 +50741,7 @@ ${body2.trimEnd()}
50700
50741
  `;
50701
50742
  }
50702
50743
  function reconcileNamespaced(dir, keep) {
50703
- if (!existsSync14(dir)) return 0;
50744
+ if (!existsSync15(dir)) return 0;
50704
50745
  let pruned = 0;
50705
50746
  for (const name2 of readdirSync7(dir)) {
50706
50747
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
@@ -50714,7 +50755,7 @@ function reconcileNamespaced(dir, keep) {
50714
50755
  }
50715
50756
  function linkOrCopy(linkPath, target) {
50716
50757
  try {
50717
- if (existsSync14(linkPath) || safeLstat(linkPath)) rmSync2(linkPath, { recursive: true, force: true });
50758
+ if (existsSync15(linkPath) || safeLstat(linkPath)) rmSync2(linkPath, { recursive: true, force: true });
50718
50759
  } catch {
50719
50760
  }
50720
50761
  try {
@@ -50736,14 +50777,14 @@ function safeLstat(p) {
50736
50777
  }
50737
50778
  function emitAndProjectSkills(root, skills) {
50738
50779
  const agentsSkillsDir = join19(root, ".agents", "skills");
50739
- mkdirSync6(agentsSkillsDir, { recursive: true });
50780
+ mkdirSync7(agentsSkillsDir, { recursive: true });
50740
50781
  const slugs = [];
50741
50782
  const keep = /* @__PURE__ */ new Set();
50742
50783
  let emitted = 0;
50743
50784
  for (const s of skills) {
50744
50785
  let body2;
50745
50786
  try {
50746
- body2 = readFileSync13(s.bodyPath, "utf8");
50787
+ body2 = readFileSync14(s.bodyPath, "utf8");
50747
50788
  } catch {
50748
50789
  continue;
50749
50790
  }
@@ -50752,8 +50793,8 @@ function emitAndProjectSkills(root, skills) {
50752
50793
  keep.add(slug2);
50753
50794
  slugs.push(slug2);
50754
50795
  const description = deriveDescription(s.title, s.layer, body2);
50755
- mkdirSync6(join19(agentsSkillsDir, slug2), { recursive: true });
50756
- writeFileSync11(
50796
+ mkdirSync7(join19(agentsSkillsDir, slug2), { recursive: true });
50797
+ writeFileSync12(
50757
50798
  join19(agentsSkillsDir, slug2, "SKILL.md"),
50758
50799
  renderSkillMd(slug2, description, body2),
50759
50800
  "utf8"
@@ -50763,9 +50804,9 @@ function emitAndProjectSkills(root, skills) {
50763
50804
  reconcileNamespaced(agentsSkillsDir, keep);
50764
50805
  let projected = 0;
50765
50806
  for (const h of HARNESS_SKILL_DIRS) {
50766
- if (!existsSync14(join19(root, h.configDir))) continue;
50807
+ if (!existsSync15(join19(root, h.configDir))) continue;
50767
50808
  const dir = join19(root, h.skillsDir);
50768
- mkdirSync6(dir, { recursive: true });
50809
+ mkdirSync7(dir, { recursive: true });
50769
50810
  for (const slug2 of slugs) {
50770
50811
  linkOrCopy(join19(dir, slug2), join19(agentsSkillsDir, slug2));
50771
50812
  projected++;
@@ -50776,9 +50817,9 @@ function emitAndProjectSkills(root, skills) {
50776
50817
  return { slugs, emitted, projected };
50777
50818
  }
50778
50819
  function emitInputsFromManifest(erretaDir, manifestPath) {
50779
- if (!existsSync14(manifestPath)) return [];
50820
+ if (!existsSync15(manifestPath)) return [];
50780
50821
  try {
50781
- const parsed = JSON.parse(readFileSync13(manifestPath, "utf8"));
50822
+ const parsed = JSON.parse(readFileSync14(manifestPath, "utf8"));
50782
50823
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
50783
50824
  id: s.id,
50784
50825
  title: s.title ?? s.id,
@@ -50801,14 +50842,14 @@ function ensureSkillGitignore(root) {
50801
50842
  const path2 = join19(root, ".gitignore");
50802
50843
  let current = "";
50803
50844
  try {
50804
- current = existsSync14(path2) ? readFileSync13(path2, "utf8") : "";
50845
+ current = existsSync15(path2) ? readFileSync14(path2, "utf8") : "";
50805
50846
  } catch {
50806
50847
  return;
50807
50848
  }
50808
50849
  if (current.includes(GITIGNORE_MARK)) return;
50809
50850
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
50810
50851
  try {
50811
- writeFileSync11(path2, `${current}${prefix}
50852
+ writeFileSync12(path2, `${current}${prefix}
50812
50853
  ${GITIGNORE_LINES.join("\n")}
50813
50854
  `, "utf8");
50814
50855
  } catch {
@@ -50835,6 +50876,34 @@ function createWorkingFileState() {
50835
50876
  };
50836
50877
  }
50837
50878
 
50879
+ // src/tool-run-state.ts
50880
+ var MAX_SESSIONS = 64;
50881
+ var MAX_TOOLS_PER_SESSION = 64;
50882
+ function createToolRunState() {
50883
+ const bySession = /* @__PURE__ */ new Map();
50884
+ return {
50885
+ record(sessionId, toolNodeIds) {
50886
+ if (!sessionId || toolNodeIds.length === 0) return;
50887
+ let set2 = bySession.get(sessionId);
50888
+ if (!set2) {
50889
+ if (bySession.size >= MAX_SESSIONS) {
50890
+ const oldest = bySession.keys().next().value;
50891
+ if (oldest !== void 0) bySession.delete(oldest);
50892
+ }
50893
+ set2 = /* @__PURE__ */ new Set();
50894
+ bySession.set(sessionId, set2);
50895
+ }
50896
+ for (const id of toolNodeIds) {
50897
+ if (set2.size >= MAX_TOOLS_PER_SESSION) break;
50898
+ set2.add(id);
50899
+ }
50900
+ },
50901
+ get(sessionId) {
50902
+ return bySession.get(sessionId) ?? /* @__PURE__ */ new Set();
50903
+ }
50904
+ };
50905
+ }
50906
+
50838
50907
  // src/engine.ts
50839
50908
  init_paths();
50840
50909
 
@@ -50944,20 +51013,20 @@ var CausalBuffer = class {
50944
51013
  // src/profile.ts
50945
51014
  init_src2();
50946
51015
  init_paths();
50947
- import { existsSync as existsSync16, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "node:fs";
51016
+ import { existsSync as existsSync17, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "node:fs";
50948
51017
  import { createHash as createHash12 } from "node:crypto";
50949
51018
  import { join as join21 } from "node:path";
50950
51019
 
50951
51020
  // src/git-remote.ts
50952
51021
  init_src();
50953
- import { existsSync as existsSync15, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
51022
+ import { existsSync as existsSync16, readFileSync as readFileSync15, statSync as statSync4 } from "node:fs";
50954
51023
  import { isAbsolute as isAbsolute3, join as join20, resolve as resolve5 } from "node:path";
50955
51024
  function resolveGitDir(root) {
50956
51025
  const dotGit = join20(root, ".git");
50957
51026
  try {
50958
51027
  const st = statSync4(dotGit);
50959
51028
  if (st.isDirectory()) return dotGit;
50960
- const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync14(dotGit, "utf8"));
51029
+ const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync15(dotGit, "utf8"));
50961
51030
  if (!m) return null;
50962
51031
  const dir = m[1];
50963
51032
  return isAbsolute3(dir) ? dir : resolve5(root, dir);
@@ -50967,8 +51036,8 @@ function resolveGitDir(root) {
50967
51036
  }
50968
51037
  function gitConfigPath(gitDir) {
50969
51038
  const commondirFile = join20(gitDir, "commondir");
50970
- if (existsSync15(commondirFile)) {
50971
- const common = readFileSync14(commondirFile, "utf8").trim();
51039
+ if (existsSync16(commondirFile)) {
51040
+ const common = readFileSync15(commondirFile, "utf8").trim();
50972
51041
  const commonDir = isAbsolute3(common) ? common : resolve5(gitDir, common);
50973
51042
  return join20(commonDir, "config");
50974
51043
  }
@@ -50978,10 +51047,10 @@ function readRemotes(root) {
50978
51047
  const gitDir = resolveGitDir(root);
50979
51048
  if (!gitDir) return [];
50980
51049
  const cfgPath = gitConfigPath(gitDir);
50981
- if (!existsSync15(cfgPath)) return [];
51050
+ if (!existsSync16(cfgPath)) return [];
50982
51051
  let txt;
50983
51052
  try {
50984
- txt = readFileSync14(cfgPath, "utf8");
51053
+ txt = readFileSync15(cfgPath, "utf8");
50985
51054
  } catch {
50986
51055
  return [];
50987
51056
  }
@@ -51013,13 +51082,13 @@ function refreshRepoLocator(root, profile) {
51013
51082
  }
51014
51083
  function loadProfile(root) {
51015
51084
  const p = workspacePaths(root);
51016
- if (!existsSync16(p.workspaceJson)) return null;
51017
- return JSON.parse(readFileSync15(p.workspaceJson, "utf8"));
51085
+ if (!existsSync17(p.workspaceJson)) return null;
51086
+ return JSON.parse(readFileSync16(p.workspaceJson, "utf8"));
51018
51087
  }
51019
51088
  function saveProfile(root, profile) {
51020
51089
  const p = workspacePaths(root);
51021
51090
  ensureDir(p.configDir);
51022
- writeFileSync12(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
51091
+ writeFileSync13(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
51023
51092
  }
51024
51093
  function autodetectProfile(root) {
51025
51094
  const id = workspaceId(root);
@@ -51028,9 +51097,9 @@ function autodetectProfile(root) {
51028
51097
  const locator = detectRepoLocator(root);
51029
51098
  if (locator) p.repoLocator = locator;
51030
51099
  const pkgPath = join21(root, "package.json");
51031
- if (existsSync16(pkgPath)) {
51100
+ if (existsSync17(pkgPath)) {
51032
51101
  try {
51033
- const pkg = JSON.parse(readFileSync15(pkgPath, "utf8"));
51102
+ const pkg = JSON.parse(readFileSync16(pkgPath, "utf8"));
51034
51103
  p.languages.push("typescript", "javascript");
51035
51104
  const nodeVer = pkg.engines?.node ?? "node";
51036
51105
  p.stack.push(`node@${nodeVer}`);
@@ -51052,9 +51121,9 @@ function autodetectProfile(root) {
51052
51121
  }
51053
51122
  }
51054
51123
  const pyproject = join21(root, "pyproject.toml");
51055
- if (existsSync16(pyproject)) {
51124
+ if (existsSync17(pyproject)) {
51056
51125
  try {
51057
- const txt = readFileSync15(pyproject, "utf8");
51126
+ const txt = readFileSync16(pyproject, "utf8");
51058
51127
  const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
51059
51128
  p.languages.push("python");
51060
51129
  p.stack.push(`python@${py ?? "3"}`);
@@ -51066,15 +51135,15 @@ function autodetectProfile(root) {
51066
51135
  }
51067
51136
  }
51068
51137
  const reqs = join21(root, "requirements.txt");
51069
- if (existsSync16(reqs)) {
51138
+ if (existsSync17(reqs)) {
51070
51139
  if (!p.languages.includes("python")) p.languages.push("python");
51071
51140
  if (!p.stack.includes("python@3")) p.stack.push("python@3");
51072
51141
  }
51073
- if (existsSync16(join21(root, "go.mod"))) {
51142
+ if (existsSync17(join21(root, "go.mod"))) {
51074
51143
  p.languages.push("go");
51075
51144
  p.stack.push("go");
51076
51145
  }
51077
- if (existsSync16(join21(root, "Cargo.toml"))) {
51146
+ if (existsSync17(join21(root, "Cargo.toml"))) {
51078
51147
  p.languages.push("rust");
51079
51148
  p.stack.push("rust");
51080
51149
  }
@@ -51232,7 +51301,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
51232
51301
  }
51233
51302
 
51234
51303
  // src/engine.ts
51235
- var DAEMON_VERSION = true ? "2.0.0-dev.89" : "2.0.0-alpha.0";
51304
+ var DAEMON_VERSION = true ? "2.0.0-dev.91" : "2.0.0-alpha.0";
51236
51305
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
51237
51306
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
51238
51307
  var GIT_OP_MUTE_MS = 4e3;
@@ -51242,7 +51311,7 @@ var TURN_REPLAY_LOOKBACK_MS = 7 * 24 * 60 * 6e4;
51242
51311
  function appendIdentityAudit(path2, record2, line) {
51243
51312
  if (!record2.accepted && record2.score <= 0) return;
51244
51313
  try {
51245
- if (existsSync17(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
51314
+ if (existsSync18(path2) && statSync5(path2).size >= IDENTITY_AUDIT_MAX_BYTES) {
51246
51315
  renameSync2(path2, `${path2}.1`);
51247
51316
  }
51248
51317
  appendFileSync2(path2, line);
@@ -51252,14 +51321,14 @@ function appendIdentityAudit(path2, record2, line) {
51252
51321
  var yieldToLoop = () => new Promise((r) => setImmediate(r));
51253
51322
  function loadTurnCursors(path2) {
51254
51323
  try {
51255
- return new Map(Object.entries(JSON.parse(readFileSync16(path2, "utf8"))));
51324
+ return new Map(Object.entries(JSON.parse(readFileSync17(path2, "utf8"))));
51256
51325
  } catch {
51257
51326
  return /* @__PURE__ */ new Map();
51258
51327
  }
51259
51328
  }
51260
51329
  function saveTurnCursors(path2, cursors) {
51261
51330
  try {
51262
- writeFileSync13(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
51331
+ writeFileSync14(path2, JSON.stringify(Object.fromEntries(cursors)), "utf8");
51263
51332
  } catch {
51264
51333
  }
51265
51334
  }
@@ -51496,7 +51565,7 @@ function createWorkspaceEngine(opts) {
51496
51565
  );
51497
51566
  };
51498
51567
  const gitDir = join22(opts.workspaceRoot, ".git");
51499
- if (existsSync17(gitDir)) {
51568
+ if (existsSync18(gitDir)) {
51500
51569
  stopGit = startGitSensor(gitDir, (ev) => {
51501
51570
  void handleGitEvent(ev).catch((err2) => {
51502
51571
  console.warn("[errata] git event handler failed:", err2);
@@ -51513,6 +51582,7 @@ function createWorkspaceEngine(opts) {
51513
51582
  });
51514
51583
  }
51515
51584
  const workingFiles = createWorkingFileState();
51585
+ const toolRuns = createToolRunState();
51516
51586
  let ctxRefreshTimer = null;
51517
51587
  let contextDirty = false;
51518
51588
  let remotePriors = [];
@@ -51564,8 +51634,9 @@ function createWorkspaceEngine(opts) {
51564
51634
  ...pendingUpdate ? { pendingUpdate } : {}
51565
51635
  });
51566
51636
  doneRender?.();
51637
+ writeContextFile(opts.workspaceRoot, body2);
51567
51638
  const target = join22(opts.workspaceRoot, "AGENTS.md");
51568
- writeManagedBlock(target, { body: body2 });
51639
+ writeManagedBlock(target, { body: AGENTS_POINTER_BODY, stable: true, force: true });
51569
51640
  if (elicit) {
51570
51641
  writePrimingHandles(join22(paths.configDir, "priming-handles.json"), [
51571
51642
  ...snapshot.recentProblems.map((r) => r.node),
@@ -51881,12 +51952,14 @@ function createWorkspaceEngine(opts) {
51881
51952
  }
51882
51953
  try {
51883
51954
  const touchedFileId = turnFile ? resolveFileId(turnFile) : void 0;
51955
+ const touched = new Set(toolRuns.get(sessionId));
51956
+ if (touchedFileId) touched.add(touchedFileId);
51884
51957
  const plan = harvestInlineTags(store, turn.text, {
51885
51958
  sourceId: sessionLastProblem.get(sessionId),
51886
51959
  handleMap,
51887
51960
  ts: t,
51888
51961
  mintPriors: elicit,
51889
- ...touchedFileId ? { sessionTouchedIds: /* @__PURE__ */ new Set([touchedFileId]) } : {}
51962
+ ...touched.size > 0 ? { sessionTouchedIds: touched } : {}
51890
51963
  });
51891
51964
  priorEdges += plan.priorEdges;
51892
51965
  const wf = workingFiles.get(sessionId);
@@ -52288,6 +52361,7 @@ function createWorkspaceEngine(opts) {
52288
52361
  webHooks: {
52289
52362
  onWorkingFileChanged,
52290
52363
  onHook: () => telemetry.count("hooks_fired"),
52364
+ onToolsObserved: (sessionId, toolNodeIds) => toolRuns.record(sessionId, toolNodeIds),
52291
52365
  onHookEvent,
52292
52366
  onShellEvent,
52293
52367
  onToolError,
@@ -52459,7 +52533,7 @@ function createWorkspaceEngine(opts) {
52459
52533
  console.log(
52460
52534
  "[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
52461
52535
  );
52462
- const pending = existsSync17(paths.outbox) ? readdirSync8(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
52536
+ const pending = existsSync18(paths.outbox) ? readdirSync8(paths.outbox).filter((f) => f.endsWith(".json")).length : 0;
52463
52537
  return { uploaded: 0, failed: 0, remaining: pending };
52464
52538
  }
52465
52539
  try {
@@ -52546,7 +52620,7 @@ async function startDaemon(opts) {
52546
52620
  reviewUrl: () => webUiUrl + "/review"
52547
52621
  });
52548
52622
  const writeLockFile = (url2) => {
52549
- writeFileSync14(
52623
+ writeFileSync15(
52550
52624
  engine.paths.daemonLock,
52551
52625
  JSON.stringify({ pid: process.pid, webUiUrl: url2, startedAt: Date.now() }),
52552
52626
  "utf8"
@@ -52589,7 +52663,7 @@ async function startDaemon(opts) {
52589
52663
  );
52590
52664
  await engine.stop();
52591
52665
  try {
52592
- if (existsSync18(engine.paths.daemonLock)) {
52666
+ if (existsSync19(engine.paths.daemonLock)) {
52593
52667
  }
52594
52668
  } catch {
52595
52669
  }
@@ -52606,16 +52680,16 @@ async function listenServer(fetchFn, port) {
52606
52680
 
52607
52681
  // src/registry.ts
52608
52682
  init_paths();
52609
- import { existsSync as existsSync19, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
52683
+ import { existsSync as existsSync20, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "node:fs";
52610
52684
  import { join as join23 } from "node:path";
52611
52685
  function registryPath() {
52612
52686
  return process.env["ERRATA_REGISTRY_PATH"] ?? join23(globalDir(), "workspaces.json");
52613
52687
  }
52614
52688
  function read() {
52615
52689
  const p = registryPath();
52616
- if (!existsSync19(p)) return { version: 1, workspaces: {} };
52690
+ if (!existsSync20(p)) return { version: 1, workspaces: {} };
52617
52691
  try {
52618
- const parsed = JSON.parse(readFileSync17(p, "utf8"));
52692
+ const parsed = JSON.parse(readFileSync18(p, "utf8"));
52619
52693
  return { version: 1, workspaces: parsed.workspaces ?? {} };
52620
52694
  } catch {
52621
52695
  return { version: 1, workspaces: {} };
@@ -52623,7 +52697,7 @@ function read() {
52623
52697
  }
52624
52698
  function write(reg) {
52625
52699
  ensureDir(globalDir());
52626
- writeFileSync15(registryPath(), JSON.stringify(reg, null, 2), "utf8");
52700
+ writeFileSync16(registryPath(), JSON.stringify(reg, null, 2), "utf8");
52627
52701
  }
52628
52702
  function registerWorkspace(profile, root, now = Date.now()) {
52629
52703
  const reg = read();
@@ -52640,7 +52714,7 @@ function pruneMissingWorkspaces() {
52640
52714
  const reg = read();
52641
52715
  const removed = [];
52642
52716
  for (const [id, entry] of Object.entries(reg.workspaces)) {
52643
- if (!existsSync19(entry.path)) {
52717
+ if (!existsSync20(entry.path)) {
52644
52718
  removed.push(entry);
52645
52719
  delete reg.workspaces[id];
52646
52720
  }
@@ -52649,13 +52723,13 @@ function pruneMissingWorkspaces() {
52649
52723
  return removed;
52650
52724
  }
52651
52725
  function workspaceStatus(entry) {
52652
- const missing = !existsSync19(entry.path);
52726
+ const missing = !existsSync20(entry.path);
52653
52727
  const lockPath = workspacePaths(entry.path).daemonLock;
52654
52728
  let running = false;
52655
52729
  let webUiUrl = null;
52656
- if (existsSync19(lockPath)) {
52730
+ if (existsSync20(lockPath)) {
52657
52731
  try {
52658
- const lock = JSON.parse(readFileSync17(lockPath, "utf8"));
52732
+ const lock = JSON.parse(readFileSync18(lockPath, "utf8"));
52659
52733
  if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
52660
52734
  running = true;
52661
52735
  webUiUrl = lock.webUiUrl;
@@ -52683,7 +52757,7 @@ function pidAlive(pid) {
52683
52757
  // src/multi.ts
52684
52758
  init_dist();
52685
52759
  init_src4();
52686
- import { readFileSync as readFileSync20, unlinkSync as unlinkSync3, writeFileSync as writeFileSync16 } from "node:fs";
52760
+ import { readFileSync as readFileSync21, unlinkSync as unlinkSync3, writeFileSync as writeFileSync17 } from "node:fs";
52687
52761
 
52688
52762
  // src/principle-sync.ts
52689
52763
  init_src4();
@@ -52711,7 +52785,7 @@ init_reconcile();
52711
52785
 
52712
52786
  // src/lockfile-auto.ts
52713
52787
  init_src();
52714
- import { existsSync as existsSync20, readFileSync as readFileSync18 } from "node:fs";
52788
+ import { existsSync as existsSync21, readFileSync as readFileSync19 } from "node:fs";
52715
52789
  import { join as join24 } from "node:path";
52716
52790
 
52717
52791
  // src/package-index.ts
@@ -52847,10 +52921,10 @@ function runLockfilePass(opts) {
52847
52921
  ];
52848
52922
  for (const c of candidates) {
52849
52923
  const p = join24(opts.root, c.file);
52850
- if (!existsSync20(p)) continue;
52924
+ if (!existsSync21(p)) continue;
52851
52925
  let sbom;
52852
52926
  try {
52853
- sbom = c.parse(readFileSync18(p, "utf8"));
52927
+ sbom = c.parse(readFileSync19(p, "utf8"));
52854
52928
  } catch {
52855
52929
  continue;
52856
52930
  }
@@ -53171,7 +53245,7 @@ var ConsolidateWorker = class {
53171
53245
  init_paths();
53172
53246
 
53173
53247
  // src/lock.ts
53174
- import { existsSync as existsSync21, readFileSync as readFileSync19 } from "node:fs";
53248
+ import { existsSync as existsSync22, readFileSync as readFileSync20 } from "node:fs";
53175
53249
  function isProcessAlive(pid) {
53176
53250
  if (!pid || pid <= 0) return false;
53177
53251
  try {
@@ -53182,9 +53256,9 @@ function isProcessAlive(pid) {
53182
53256
  }
53183
53257
  }
53184
53258
  function readDaemonLock(lockPath) {
53185
- if (!existsSync21(lockPath)) return null;
53259
+ if (!existsSync22(lockPath)) return null;
53186
53260
  try {
53187
- const lock = JSON.parse(readFileSync19(lockPath, "utf8"));
53261
+ const lock = JSON.parse(readFileSync20(lockPath, "utf8"));
53188
53262
  return typeof lock.pid === "number" ? lock : null;
53189
53263
  } catch {
53190
53264
  return null;
@@ -53426,13 +53500,13 @@ async function reanchorProject(opts) {
53426
53500
  }
53427
53501
 
53428
53502
  // src/adopt.ts
53429
- import { existsSync as existsSync22 } from "node:fs";
53430
- import { dirname as dirname8, join as join25 } from "node:path";
53503
+ import { existsSync as existsSync23 } from "node:fs";
53504
+ import { dirname as dirname9, join as join25 } from "node:path";
53431
53505
  function findGitRoot(absPath) {
53432
53506
  let dir = absPath;
53433
53507
  for (let depth = 0; depth < 64; depth++) {
53434
- if (existsSync22(join25(dir, ".git"))) return dir;
53435
- const parent = dirname8(dir);
53508
+ if (existsSync23(join25(dir, ".git"))) return dir;
53509
+ const parent = dirname9(dir);
53436
53510
  if (parent === dir) return null;
53437
53511
  dir = parent;
53438
53512
  }
@@ -53627,7 +53701,7 @@ async function startMultiDaemon(opts = {}) {
53627
53701
  void ambientLinkAll();
53628
53702
  app.route(`/ws/${rec.id}`, rec.webApp);
53629
53703
  try {
53630
- writeFileSync16(
53704
+ writeFileSync17(
53631
53705
  rec.engine.paths.daemonLock,
53632
53706
  JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${rec.id}`, startedAt: Date.now() }),
53633
53707
  "utf8"
@@ -53813,7 +53887,7 @@ async function startMultiDaemon(opts = {}) {
53813
53887
  baseUrl = `http://127.0.0.1:${port}`;
53814
53888
  try {
53815
53889
  ensureDir(globalDir());
53816
- writeFileSync16(
53890
+ writeFileSync17(
53817
53891
  lockPath,
53818
53892
  JSON.stringify({ pid: process.pid, webUiUrl: baseUrl, startedAt: Date.now() }),
53819
53893
  "utf8"
@@ -53822,7 +53896,7 @@ async function startMultiDaemon(opts = {}) {
53822
53896
  }
53823
53897
  for (const r of records) {
53824
53898
  try {
53825
- writeFileSync16(
53899
+ writeFileSync17(
53826
53900
  r.engine.paths.daemonLock,
53827
53901
  JSON.stringify({ pid: process.pid, webUiUrl: `${baseUrl}/ws/${r.id}`, startedAt: Date.now() }),
53828
53902
  "utf8"
@@ -54221,7 +54295,7 @@ async function startMultiDaemon(opts = {}) {
54221
54295
  },
54222
54296
  async stop() {
54223
54297
  try {
54224
- const cur = readFileSync20(lockPath, "utf8");
54298
+ const cur = readFileSync21(lockPath, "utf8");
54225
54299
  if (JSON.parse(cur).pid === process.pid) unlinkSync3(lockPath);
54226
54300
  } catch {
54227
54301
  }
@@ -54816,21 +54890,21 @@ async function cmdInit() {
54816
54890
  if (!skipHooks) {
54817
54891
  console.log("");
54818
54892
  console.log("installing harness hooks...");
54819
- const { existsSync: existsSync24 } = await import("node:fs");
54893
+ const { existsSync: existsSync25 } = await import("node:fs");
54820
54894
  const { join: join27 } = await import("node:path");
54821
54895
  try {
54822
54896
  await installClaudeHooks(port);
54823
54897
  } catch (err2) {
54824
54898
  console.warn(` \u26A0\uFE0F Claude hook install failed: ${err2 instanceof Error ? err2.message : err2}`);
54825
54899
  }
54826
- if (existsSync24(join27(ROOT, ".cursor"))) {
54900
+ if (existsSync25(join27(ROOT, ".cursor"))) {
54827
54901
  try {
54828
54902
  await installCursorMcpConfig();
54829
54903
  } catch (err2) {
54830
54904
  console.warn(` \u26A0\uFE0F Cursor MCP config failed: ${err2 instanceof Error ? err2.message : err2}`);
54831
54905
  }
54832
54906
  }
54833
- if (existsSync24(join27(ROOT, ".codex"))) {
54907
+ if (existsSync25(join27(ROOT, ".codex"))) {
54834
54908
  try {
54835
54909
  await installCodexHooks(port);
54836
54910
  } catch (err2) {
@@ -54987,8 +55061,8 @@ async function cmdStatus() {
54987
55061
  console.log(` stack: ${profile.stack.join(", ") || "(none)"}`);
54988
55062
  console.log(` languages: ${profile.languages.join(", ") || "(none)"}`);
54989
55063
  }
54990
- console.log(` graph db: ${existsSync23(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
54991
- console.log(` event log: ${existsSync23(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
55064
+ console.log(` graph db: ${existsSync24(paths.castalia) ? "yes" : "no"} (${paths.castalia})`);
55065
+ console.log(` event log: ${existsSync24(paths.eventLog) ? "yes" : "no"} (${paths.eventLog})`);
54992
55066
  const lockPath = globalDaemonLock();
54993
55067
  const running = isDaemonAlive(lockPath) ? readDaemonLock(lockPath) : null;
54994
55068
  console.log(
@@ -55440,11 +55514,11 @@ async function cmdUse(args2) {
55440
55514
  }
55441
55515
  async function cmdReview() {
55442
55516
  const paths = workspacePaths(ROOT);
55443
- if (!existsSync23(paths.reviewQueue)) {
55517
+ if (!existsSync24(paths.reviewQueue)) {
55444
55518
  console.log("(review queue empty)");
55445
55519
  return;
55446
55520
  }
55447
- const queue = JSON.parse(readFileSync21(paths.reviewQueue, "utf8"));
55521
+ const queue = JSON.parse(readFileSync22(paths.reviewQueue, "utf8"));
55448
55522
  if (queue.length === 0) {
55449
55523
  console.log("(review queue empty)");
55450
55524
  return;
@@ -56098,7 +56172,7 @@ async function gatherRepo(store, ws) {
56098
56172
  };
56099
56173
  }
56100
56174
  async function gatherReportData(generatedAt) {
56101
- const { existsSync: existsSync24 } = await import("node:fs");
56175
+ const { existsSync: existsSync25 } = await import("node:fs");
56102
56176
  const { openGraphStore: openGraphStore2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
56103
56177
  const cfg = loadConfig();
56104
56178
  const outbound = cfg.consent.sync ? "auto" : "off";
@@ -56106,7 +56180,7 @@ async function gatherReportData(generatedAt) {
56106
56180
  for (const ws of listWorkspaces()) {
56107
56181
  if (ws.missing) continue;
56108
56182
  const dbPath = workspacePaths(ws.path).castalia;
56109
- if (!existsSync24(dbPath)) continue;
56183
+ if (!existsSync25(dbPath)) continue;
56110
56184
  let store = null;
56111
56185
  try {
56112
56186
  store = openGraphStore2({ path: dbPath });
@@ -56137,7 +56211,7 @@ async function gatherReportData(generatedAt) {
56137
56211
  };
56138
56212
  }
56139
56213
  async function cmdReport(args2) {
56140
- const { mkdirSync: mkdirSync7, writeFileSync: writeFileSync17 } = await import("node:fs");
56214
+ const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync18 } = await import("node:fs");
56141
56215
  const { renderReport: renderReport2 } = await Promise.resolve().then(() => (init_report_render(), report_render_exports));
56142
56216
  const includeFutureVerbs = args2.includes("--future-verbs");
56143
56217
  const now = /* @__PURE__ */ new Date();
@@ -56148,9 +56222,9 @@ async function cmdReport(args2) {
56148
56222
  process.exit(2);
56149
56223
  }
56150
56224
  const outDir = workspacePaths(ROOT).configDir;
56151
- mkdirSync7(outDir, { recursive: true });
56225
+ mkdirSync8(outDir, { recursive: true });
56152
56226
  const files = renderReport2(data, { includeFutureVerbs });
56153
- for (const f of files) writeFileSync17(join26(outDir, f.name), f.html, "utf8");
56227
+ for (const f of files) writeFileSync18(join26(outDir, f.name), f.html, "utf8");
56154
56228
  const indexPath = join26(outDir, "report.html");
56155
56229
  console.log(`report \u2192 ${indexPath}`);
56156
56230
  console.log(` ${data.repos.length} repo(s) \xB7 ${files.length} file(s) \xB7 ${data.rollup.nodes.toLocaleString("en-US")} nodes`);
@@ -56271,15 +56345,15 @@ function hookRelayCommand(port, path2) {
56271
56345
  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 '{}'`;
56272
56346
  }
56273
56347
  async function installClaudeHooks(port) {
56274
- const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
56348
+ const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
56275
56349
  const { join: join27 } = await import("node:path");
56276
56350
  const dir = join27(ROOT, ".claude");
56277
- if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
56351
+ if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
56278
56352
  const file2 = join27(dir, "settings.json");
56279
56353
  let settings = {};
56280
- if (existsSync24(file2)) {
56354
+ if (existsSync25(file2)) {
56281
56355
  try {
56282
- settings = JSON.parse(readFileSync22(file2, "utf8"));
56356
+ settings = JSON.parse(readFileSync23(file2, "utf8"));
56283
56357
  } catch {
56284
56358
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
56285
56359
  process.exit(2);
@@ -56325,7 +56399,7 @@ async function installClaudeHooks(port) {
56325
56399
  dropErrata(list);
56326
56400
  list.push({ hooks: [{ type: "command", command: injectCmd }] });
56327
56401
  }
56328
- writeFileSync17(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
56402
+ writeFileSync18(file2, JSON.stringify(settings, null, 2) + "\n", "utf8");
56329
56403
  console.log(`installed Claude Code hooks \u2192 ${file2}`);
56330
56404
  await installClaudeMcpConfig();
56331
56405
  const claudeMd = join27(ROOT, "CLAUDE.md");
@@ -56340,15 +56414,15 @@ async function installClaudeHooks(port) {
56340
56414
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
56341
56415
  }
56342
56416
  async function installClaudeMcpConfig() {
56343
- const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
56344
- const { join: join27, dirname: dirname9 } = await import("node:path");
56417
+ const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
56418
+ const { join: join27, dirname: dirname10 } = await import("node:path");
56345
56419
  const file2 = join27(ROOT, ".mcp.json");
56346
- const dir = dirname9(file2);
56347
- if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
56420
+ const dir = dirname10(file2);
56421
+ if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
56348
56422
  let cfg = {};
56349
- if (existsSync24(file2)) {
56423
+ if (existsSync25(file2)) {
56350
56424
  try {
56351
- cfg = JSON.parse(readFileSync22(file2, "utf8"));
56425
+ cfg = JSON.parse(readFileSync23(file2, "utf8"));
56352
56426
  } catch {
56353
56427
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
56354
56428
  process.exit(2);
@@ -56356,21 +56430,21 @@ async function installClaudeMcpConfig() {
56356
56430
  }
56357
56431
  cfg.mcpServers ??= {};
56358
56432
  cfg.mcpServers["errata"] = errataMcpInvocation();
56359
- writeFileSync17(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
56433
+ writeFileSync18(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
56360
56434
  console.log(`installed Claude Code MCP server config \u2192 ${file2}`);
56361
56435
  console.log(` Claude Code will spawn \`errata mcp\` on workspace open.`);
56362
56436
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses / show / similar`);
56363
56437
  }
56364
56438
  async function installCursorMcpConfig() {
56365
- const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
56439
+ const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
56366
56440
  const { join: join27 } = await import("node:path");
56367
56441
  const dir = join27(ROOT, ".cursor");
56368
- if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
56442
+ if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
56369
56443
  const file2 = join27(dir, "mcp.json");
56370
56444
  let cfg = {};
56371
- if (existsSync24(file2)) {
56445
+ if (existsSync25(file2)) {
56372
56446
  try {
56373
- cfg = JSON.parse(readFileSync22(file2, "utf8"));
56447
+ cfg = JSON.parse(readFileSync23(file2, "utf8"));
56374
56448
  } catch {
56375
56449
  console.error(`refusing to overwrite invalid JSON at ${file2}`);
56376
56450
  process.exit(2);
@@ -56378,7 +56452,7 @@ async function installCursorMcpConfig() {
56378
56452
  }
56379
56453
  cfg.mcpServers ??= {};
56380
56454
  cfg.mcpServers["errata"] = errataMcpInvocation();
56381
- writeFileSync17(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
56455
+ writeFileSync18(file2, JSON.stringify(cfg, null, 2) + "\n", "utf8");
56382
56456
  console.log(`installed Cursor MCP server config \u2192 ${file2}`);
56383
56457
  console.log(` Cursor will spawn \`errata mcp\` on workspace open.`);
56384
56458
  console.log(` Tools: errata.search / locate / neighbors / callers_of / what_uses`);
@@ -56386,16 +56460,16 @@ async function installCursorMcpConfig() {
56386
56460
  console.log(` \u26A0\uFE0F reload Cursor (Cmd/Ctrl-Shift-P \u2192 "Reload Window") to pick it up.`);
56387
56461
  }
56388
56462
  async function installCodexHooks(port) {
56389
- const { mkdirSync: mkdirSync7, existsSync: existsSync24, readFileSync: readFileSync22, writeFileSync: writeFileSync17 } = await import("node:fs");
56463
+ const { mkdirSync: mkdirSync8, existsSync: existsSync25, readFileSync: readFileSync23, writeFileSync: writeFileSync18 } = await import("node:fs");
56390
56464
  const { join: join27 } = await import("node:path");
56391
56465
  const dir = join27(ROOT, ".codex");
56392
- if (!existsSync24(dir)) mkdirSync7(dir, { recursive: true });
56466
+ if (!existsSync25(dir)) mkdirSync8(dir, { recursive: true });
56393
56467
  const file2 = join27(dir, "config.toml");
56394
56468
  const BEGIN = `# >>> errata hooks (errata-managed)`;
56395
56469
  const END = `# <<< errata hooks`;
56396
56470
  let existing = "";
56397
- if (existsSync24(file2)) {
56398
- existing = readFileSync22(file2, "utf8");
56471
+ if (existsSync25(file2)) {
56472
+ existing = readFileSync23(file2, "utf8");
56399
56473
  const beginIdx = existing.indexOf(BEGIN);
56400
56474
  const endIdx = existing.indexOf(END);
56401
56475
  if (beginIdx >= 0 && endIdx > beginIdx) {
@@ -56424,7 +56498,7 @@ ${END}
56424
56498
  const final = existing.length > 0 && !existing.endsWith("\n") ? `${existing}
56425
56499
 
56426
56500
  ${block}` : existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
56427
- writeFileSync17(file2, final, "utf8");
56501
+ writeFileSync18(file2, final, "utf8");
56428
56502
  console.log(`installed Codex hooks \u2192 ${file2}`);
56429
56503
  console.log(` endpoint: http://127.0.0.1:${port}/api/hook`);
56430
56504
  console.log("");