@inerrata-corporation/errata 2.0.6-dev.2564 → 2.0.6-dev.2568

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/errata.mjs +476 -426
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -28996,6 +28996,186 @@ var init_review2 = __esm({
28996
28996
  }
28997
28997
  });
28998
28998
 
28999
+ // src/consent.ts
29000
+ function effectiveConsent(config2, profile) {
29001
+ const c = profile?.consoleConsents;
29002
+ if (c) return { sync: c.sync, telemetry: c.telemetry, contributePackages: c.contributePackages };
29003
+ return {
29004
+ sync: config2.consent.sync,
29005
+ telemetry: config2.consent.telemetry,
29006
+ contributePackages: config2.consent.contributePackages
29007
+ };
29008
+ }
29009
+ var init_consent = __esm({
29010
+ "src/consent.ts"() {
29011
+ "use strict";
29012
+ }
29013
+ });
29014
+
29015
+ // src/git-remote.ts
29016
+ import { existsSync as existsSync8, readFileSync as readFileSync6, statSync } from "node:fs";
29017
+ import { isAbsolute, join as join6, resolve } from "node:path";
29018
+ function resolveGitDir(root) {
29019
+ const dotGit = join6(root, ".git");
29020
+ try {
29021
+ const st = statSync(dotGit);
29022
+ if (st.isDirectory()) return dotGit;
29023
+ const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync6(dotGit, "utf8"));
29024
+ if (!m) return null;
29025
+ const dir = m[1];
29026
+ return isAbsolute(dir) ? dir : resolve(root, dir);
29027
+ } catch {
29028
+ return null;
29029
+ }
29030
+ }
29031
+ function gitConfigPath(gitDir) {
29032
+ const commondirFile = join6(gitDir, "commondir");
29033
+ if (existsSync8(commondirFile)) {
29034
+ const common = readFileSync6(commondirFile, "utf8").trim();
29035
+ const commonDir = isAbsolute(common) ? common : resolve(gitDir, common);
29036
+ return join6(commonDir, "config");
29037
+ }
29038
+ return join6(gitDir, "config");
29039
+ }
29040
+ function readRemotes(root) {
29041
+ const gitDir = resolveGitDir(root);
29042
+ if (!gitDir) return [];
29043
+ const cfgPath = gitConfigPath(gitDir);
29044
+ if (!existsSync8(cfgPath)) return [];
29045
+ let txt;
29046
+ try {
29047
+ txt = readFileSync6(cfgPath, "utf8");
29048
+ } catch {
29049
+ return [];
29050
+ }
29051
+ const out2 = [];
29052
+ const sectionRe = /^\s*\[remote "([^"]+)"\]\s*$([\s\S]*?)(?=^\s*\[|\s*$(?![\s\S]))/gm;
29053
+ for (const m of txt.matchAll(sectionRe)) {
29054
+ const url2 = /^\s*url\s*=\s*(.+?)\s*$/m.exec(m[2])?.[1];
29055
+ if (url2) out2.push({ name: m[1], url: url2 });
29056
+ }
29057
+ return out2;
29058
+ }
29059
+ function detectRepoLocator(root, remote) {
29060
+ const remotes = readRemotes(root);
29061
+ if (remotes.length === 0) return null;
29062
+ const pick2 = remote ? remotes.find((r) => r.name === remote) ?? null : remotes.find((r) => r.name === "origin") ?? (remotes.length === 1 ? remotes[0] : null);
29063
+ return pick2 ? normalizeRepoLocator(pick2.url) : null;
29064
+ }
29065
+ var init_git_remote = __esm({
29066
+ "src/git-remote.ts"() {
29067
+ "use strict";
29068
+ init_src();
29069
+ }
29070
+ });
29071
+
29072
+ // src/profile.ts
29073
+ import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "node:fs";
29074
+ import { createHash as createHash3 } from "node:crypto";
29075
+ import { join as join7 } from "node:path";
29076
+ function workspaceId(root) {
29077
+ return "wp_" + createHash3("sha256").update(root).digest("hex").slice(0, 12);
29078
+ }
29079
+ function sessionOriginKey(sessionId) {
29080
+ if (!sessionId) return void 0;
29081
+ return "ws_" + createHash3("sha256").update(sessionId).digest("hex").slice(0, 12);
29082
+ }
29083
+ function refreshRepoLocator(root, profile) {
29084
+ const detected = detectRepoLocator(root, profile.repoRemote);
29085
+ if (!detected || detected === profile.repoLocator) return false;
29086
+ if (profile.repoLocator) {
29087
+ const aliases = new Set(profile.repoLocatorAliases ?? []);
29088
+ aliases.add(profile.repoLocator);
29089
+ aliases.delete(detected);
29090
+ profile.repoLocatorAliases = [...aliases];
29091
+ }
29092
+ profile.repoLocator = detected;
29093
+ saveProfile(root, profile);
29094
+ return true;
29095
+ }
29096
+ function loadProfile(root) {
29097
+ const p = workspacePaths(root);
29098
+ if (!existsSync9(p.workspaceJson)) return null;
29099
+ return JSON.parse(readFileSync7(p.workspaceJson, "utf8"));
29100
+ }
29101
+ function saveProfile(root, profile) {
29102
+ const p = workspacePaths(root);
29103
+ ensureDir(p.configDir);
29104
+ writeFileSync7(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
29105
+ }
29106
+ function autodetectProfile(root) {
29107
+ const id = workspaceId(root);
29108
+ const name2 = root.split(/[\\/]/).filter(Boolean).pop() ?? "workspace";
29109
+ const p = emptyProfile(id, name2);
29110
+ const locator = detectRepoLocator(root);
29111
+ if (locator) p.repoLocator = locator;
29112
+ const pkgPath = join7(root, "package.json");
29113
+ if (existsSync9(pkgPath)) {
29114
+ try {
29115
+ const pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
29116
+ const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
29117
+ p.languages.push("javascript");
29118
+ if (existsSync9(join7(root, "tsconfig.json")) || deps["typescript"]) {
29119
+ p.languages.push("typescript");
29120
+ }
29121
+ const nodeVer = pkg.engines?.node?.trim();
29122
+ p.stack.push(nodeVer ? `node@${nodeVer}` : "node");
29123
+ const interesting = [
29124
+ "next",
29125
+ "react",
29126
+ "vue",
29127
+ "svelte",
29128
+ "express",
29129
+ "hono",
29130
+ "fastify",
29131
+ "@modelcontextprotocol/sdk"
29132
+ ];
29133
+ for (const k of interesting) {
29134
+ if (deps[k]) p.stack.push(k);
29135
+ }
29136
+ } catch {
29137
+ }
29138
+ }
29139
+ const pyproject = join7(root, "pyproject.toml");
29140
+ if (existsSync9(pyproject)) {
29141
+ try {
29142
+ const txt = readFileSync7(pyproject, "utf8");
29143
+ const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
29144
+ p.languages.push("python");
29145
+ p.stack.push(`python@${py ?? "3"}`);
29146
+ const candidates = ["fastapi", "django", "flask", "mcp", "pytest"];
29147
+ for (const k of candidates) {
29148
+ if (new RegExp(`\\b${k}\\b`, "i").test(txt)) p.stack.push(k);
29149
+ }
29150
+ } catch {
29151
+ }
29152
+ }
29153
+ const reqs = join7(root, "requirements.txt");
29154
+ if (existsSync9(reqs)) {
29155
+ if (!p.languages.includes("python")) p.languages.push("python");
29156
+ if (!p.stack.includes("python@3")) p.stack.push("python@3");
29157
+ }
29158
+ if (existsSync9(join7(root, "go.mod"))) {
29159
+ p.languages.push("go");
29160
+ p.stack.push("go");
29161
+ }
29162
+ if (existsSync9(join7(root, "Cargo.toml"))) {
29163
+ p.languages.push("rust");
29164
+ p.stack.push("rust");
29165
+ }
29166
+ p.languages = [...new Set(p.languages)];
29167
+ p.stack = [...new Set(p.stack)];
29168
+ return p;
29169
+ }
29170
+ var init_profile2 = __esm({
29171
+ "src/profile.ts"() {
29172
+ "use strict";
29173
+ init_src2();
29174
+ init_paths();
29175
+ init_git_remote();
29176
+ }
29177
+ });
29178
+
28999
29179
  // src/identity.ts
29000
29180
  function resolveWorkspaceIdentity(cfg, entry, env2 = process.env) {
29001
29181
  if (env2["ERRATA_CONFIG_PATH"]) {
@@ -29071,70 +29251,13 @@ var init_identity2 = __esm({
29071
29251
  }
29072
29252
  });
29073
29253
 
29074
- // src/git-remote.ts
29075
- import { existsSync as existsSync8, readFileSync as readFileSync6, statSync } from "node:fs";
29076
- import { isAbsolute, join as join6, resolve } from "node:path";
29077
- function resolveGitDir(root) {
29078
- const dotGit = join6(root, ".git");
29079
- try {
29080
- const st = statSync(dotGit);
29081
- if (st.isDirectory()) return dotGit;
29082
- const m = /^gitdir:\s*(.+?)\s*$/m.exec(readFileSync6(dotGit, "utf8"));
29083
- if (!m) return null;
29084
- const dir = m[1];
29085
- return isAbsolute(dir) ? dir : resolve(root, dir);
29086
- } catch {
29087
- return null;
29088
- }
29089
- }
29090
- function gitConfigPath(gitDir) {
29091
- const commondirFile = join6(gitDir, "commondir");
29092
- if (existsSync8(commondirFile)) {
29093
- const common = readFileSync6(commondirFile, "utf8").trim();
29094
- const commonDir = isAbsolute(common) ? common : resolve(gitDir, common);
29095
- return join6(commonDir, "config");
29096
- }
29097
- return join6(gitDir, "config");
29098
- }
29099
- function readRemotes(root) {
29100
- const gitDir = resolveGitDir(root);
29101
- if (!gitDir) return [];
29102
- const cfgPath = gitConfigPath(gitDir);
29103
- if (!existsSync8(cfgPath)) return [];
29104
- let txt;
29105
- try {
29106
- txt = readFileSync6(cfgPath, "utf8");
29107
- } catch {
29108
- return [];
29109
- }
29110
- const out2 = [];
29111
- const sectionRe = /^\s*\[remote "([^"]+)"\]\s*$([\s\S]*?)(?=^\s*\[|\s*$(?![\s\S]))/gm;
29112
- for (const m of txt.matchAll(sectionRe)) {
29113
- const url2 = /^\s*url\s*=\s*(.+?)\s*$/m.exec(m[2])?.[1];
29114
- if (url2) out2.push({ name: m[1], url: url2 });
29115
- }
29116
- return out2;
29117
- }
29118
- function detectRepoLocator(root, remote) {
29119
- const remotes = readRemotes(root);
29120
- if (remotes.length === 0) return null;
29121
- const pick2 = remote ? remotes.find((r) => r.name === remote) ?? null : remotes.find((r) => r.name === "origin") ?? (remotes.length === 1 ? remotes[0] : null);
29122
- return pick2 ? normalizeRepoLocator(pick2.url) : null;
29123
- }
29124
- var init_git_remote = __esm({
29125
- "src/git-remote.ts"() {
29126
- "use strict";
29127
- init_src();
29128
- }
29129
- });
29130
-
29131
29254
  // src/checkout-root.ts
29132
- import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
29133
- import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute2, join as join7, resolve as resolve2 } from "node:path";
29255
+ import { existsSync as existsSync10, readFileSync as readFileSync8 } from "node:fs";
29256
+ import { basename as basename2, dirname as dirname6, isAbsolute as isAbsolute2, join as join8, resolve as resolve2 } from "node:path";
29134
29257
  function nearestGitRoot(dir) {
29135
29258
  let cur = resolve2(dir);
29136
29259
  for (; ; ) {
29137
- if (existsSync9(join7(cur, ".git"))) return cur;
29260
+ if (existsSync10(join8(cur, ".git"))) return cur;
29138
29261
  const parent = dirname6(cur);
29139
29262
  if (parent === cur) return null;
29140
29263
  cur = parent;
@@ -29142,19 +29265,19 @@ function nearestGitRoot(dir) {
29142
29265
  }
29143
29266
  function mainCheckoutOfWorktree(root) {
29144
29267
  const gitDir = resolveGitDir(root);
29145
- if (!gitDir || gitDir === join7(root, ".git")) return null;
29146
- const commondirFile = join7(gitDir, "commondir");
29147
- if (!existsSync9(commondirFile)) return null;
29268
+ if (!gitDir || gitDir === join8(root, ".git")) return null;
29269
+ const commondirFile = join8(gitDir, "commondir");
29270
+ if (!existsSync10(commondirFile)) return null;
29148
29271
  let common;
29149
29272
  try {
29150
- common = readFileSync7(commondirFile, "utf8").trim();
29273
+ common = readFileSync8(commondirFile, "utf8").trim();
29151
29274
  } catch {
29152
29275
  return null;
29153
29276
  }
29154
29277
  const commonDir = resolve2(isAbsolute2(common) ? common : resolve2(gitDir, common));
29155
29278
  if (basename2(commonDir) !== ".git") return null;
29156
29279
  const main2 = dirname6(commonDir);
29157
- return existsSync9(join7(main2, ".git")) ? main2 : null;
29280
+ return existsSync10(join8(main2, ".git")) ? main2 : null;
29158
29281
  }
29159
29282
  function checkoutRootOf(cwd) {
29160
29283
  const root = nearestGitRoot(cwd);
@@ -29172,16 +29295,16 @@ var init_checkout_root = __esm({
29172
29295
  });
29173
29296
 
29174
29297
  // src/registry.ts
29175
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
29176
- import { join as join8 } from "node:path";
29298
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "node:fs";
29299
+ import { join as join9 } from "node:path";
29177
29300
  function registryPath() {
29178
- return process.env["ERRATA_REGISTRY_PATH"] ?? join8(globalDir(), "workspaces.json");
29301
+ return process.env["ERRATA_REGISTRY_PATH"] ?? join9(globalDir(), "workspaces.json");
29179
29302
  }
29180
29303
  function read() {
29181
29304
  const p = registryPath();
29182
- if (!existsSync10(p)) return { version: 1, workspaces: {} };
29305
+ if (!existsSync11(p)) return { version: 1, workspaces: {} };
29183
29306
  try {
29184
- const parsed = JSON.parse(readFileSync8(p, "utf8"));
29307
+ const parsed = JSON.parse(readFileSync9(p, "utf8"));
29185
29308
  return { version: 1, workspaces: parsed.workspaces ?? {} };
29186
29309
  } catch {
29187
29310
  return { version: 1, workspaces: {} };
@@ -29189,9 +29312,9 @@ function read() {
29189
29312
  }
29190
29313
  function registryCorrupt() {
29191
29314
  const p = registryPath();
29192
- if (!existsSync10(p)) return false;
29315
+ if (!existsSync11(p)) return false;
29193
29316
  try {
29194
- JSON.parse(readFileSync8(p, "utf8"));
29317
+ JSON.parse(readFileSync9(p, "utf8"));
29195
29318
  return false;
29196
29319
  } catch {
29197
29320
  return true;
@@ -29199,7 +29322,7 @@ function registryCorrupt() {
29199
29322
  }
29200
29323
  function write(reg) {
29201
29324
  ensureDir(globalDir());
29202
- writeFileSync7(registryPath(), JSON.stringify(reg, null, 2), "utf8");
29325
+ writeFileSync8(registryPath(), JSON.stringify(reg, null, 2), "utf8");
29203
29326
  }
29204
29327
  function registerWorkspace(profile, root, now = Date.now()) {
29205
29328
  if (isLinkedWorktree(root)) return;
@@ -29244,7 +29367,7 @@ function pruneMissingWorkspaces() {
29244
29367
  const reg = read();
29245
29368
  const removed = [];
29246
29369
  for (const [id, entry] of Object.entries(reg.workspaces)) {
29247
- if (!existsSync10(entry.path)) {
29370
+ if (!existsSync11(entry.path)) {
29248
29371
  removed.push(entry);
29249
29372
  delete reg.workspaces[id];
29250
29373
  }
@@ -29253,13 +29376,13 @@ function pruneMissingWorkspaces() {
29253
29376
  return removed;
29254
29377
  }
29255
29378
  function workspaceStatus(entry) {
29256
- const missing = !existsSync10(entry.path);
29379
+ const missing = !existsSync11(entry.path);
29257
29380
  const lockPath = workspacePaths(entry.path).daemonLock;
29258
29381
  let running = false;
29259
29382
  let webUiUrl = null;
29260
- if (existsSync10(lockPath)) {
29383
+ if (existsSync11(lockPath)) {
29261
29384
  try {
29262
- const lock = JSON.parse(readFileSync8(lockPath, "utf8"));
29385
+ const lock = JSON.parse(readFileSync9(lockPath, "utf8"));
29263
29386
  if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
29264
29387
  running = true;
29265
29388
  webUiUrl = lock.webUiUrl;
@@ -30713,7 +30836,7 @@ var init_diagnostic_matcher = __esm({
30713
30836
  });
30714
30837
 
30715
30838
  // ../../packages/generalizer/src/generalizer.ts
30716
- import { isAbsolute as isAbsolute3, join as join9, relative } from "node:path";
30839
+ import { isAbsolute as isAbsolute3, join as join10, relative } from "node:path";
30717
30840
  async function runGeneralizer(opts) {
30718
30841
  const report = {
30719
30842
  eventsProcessed: 0,
@@ -30821,7 +30944,7 @@ function extractDiagnostics(ev) {
30821
30944
  function diagRelPath(file2, cwd, workspaceRoot) {
30822
30945
  const norm = (p) => p.replace(/\\/g, "/");
30823
30946
  if (!workspaceRoot) return norm(file2);
30824
- const abs = isAbsolute3(file2) ? file2 : join9(cwd ?? workspaceRoot, file2);
30947
+ const abs = isAbsolute3(file2) ? file2 : join10(cwd ?? workspaceRoot, file2);
30825
30948
  return norm(relative(workspaceRoot, abs));
30826
30949
  }
30827
30950
  function extractErrorSignature(ev) {
@@ -32463,23 +32586,23 @@ var init_src10 = __esm({
32463
32586
  });
32464
32587
 
32465
32588
  // ../../packages/indexer/src/parse-cache.ts
32466
- import { createHash as createHash3 } from "node:crypto";
32467
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync9, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync8 } from "node:fs";
32589
+ import { createHash as createHash4 } from "node:crypto";
32590
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync10, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync9 } from "node:fs";
32468
32591
  import { homedir as homedir3 } from "node:os";
32469
- import { join as join10 } from "node:path";
32592
+ import { join as join11 } from "node:path";
32470
32593
  function parseCacheDir() {
32471
- return process.env["ERRATA_PARSE_CACHE"] ?? join10(homedir3(), ".errata", "parse-cache");
32594
+ return process.env["ERRATA_PARSE_CACHE"] ?? join11(homedir3(), ".errata", "parse-cache");
32472
32595
  }
32473
32596
  function parseCacheKey(source, providerId) {
32474
- return createHash3("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
32597
+ return createHash4("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
32475
32598
  }
32476
32599
  function entryPath(dir, key) {
32477
- return join10(dir, key.slice(0, 2), `${key.slice(2)}.json`);
32600
+ return join11(dir, key.slice(0, 2), `${key.slice(2)}.json`);
32478
32601
  }
32479
32602
  function readParseCache(dir, key) {
32480
32603
  const file2 = entryPath(dir, key);
32481
32604
  try {
32482
- const raw2 = readFileSync9(file2, "utf8");
32605
+ const raw2 = readFileSync10(file2, "utf8");
32483
32606
  const parsed = JSON.parse(raw2);
32484
32607
  if (parsed.v !== PARSE_CACHE_VERSION || !Array.isArray(parsed.symbols)) return null;
32485
32608
  return { symbols: parsed.symbols, reExports: parsed.reExports ?? [] };
@@ -32498,8 +32621,8 @@ function writeParseCache(dir, key, providerId, value) {
32498
32621
  const body2 = JSON.stringify(envelope);
32499
32622
  if (body2.length > MAX_ENTRY_BYTES) return;
32500
32623
  const file2 = entryPath(dir, key);
32501
- mkdirSync6(join10(dir, key.slice(0, 2)), { recursive: true });
32502
- writeFileSync8(file2, body2);
32624
+ mkdirSync6(join11(dir, key.slice(0, 2)), { recursive: true });
32625
+ writeFileSync9(file2, body2);
32503
32626
  } catch {
32504
32627
  }
32505
32628
  }
@@ -32508,9 +32631,9 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
32508
32631
  sweptThisProcess = true;
32509
32632
  let removed = 0;
32510
32633
  try {
32511
- if (!existsSync11(dir)) return 0;
32634
+ if (!existsSync12(dir)) return 0;
32512
32635
  for (const bucket of readdirSync2(dir)) {
32513
- const bucketDir = join10(dir, bucket);
32636
+ const bucketDir = join11(dir, bucket);
32514
32637
  let names;
32515
32638
  try {
32516
32639
  names = readdirSync2(bucketDir);
@@ -32518,7 +32641,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
32518
32641
  continue;
32519
32642
  }
32520
32643
  for (const name2 of names) {
32521
- const file2 = join10(bucketDir, name2);
32644
+ const file2 = join11(bucketDir, name2);
32522
32645
  try {
32523
32646
  if (now - statSync2(file2).mtimeMs > ENTRY_TTL_MS) {
32524
32647
  rmSync2(file2, { force: true });
@@ -32766,10 +32889,10 @@ var init_identity3 = __esm({
32766
32889
  });
32767
32890
 
32768
32891
  // ../../packages/indexer/src/pipeline.ts
32769
- import { appendFileSync, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
32892
+ import { appendFileSync, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
32770
32893
  import { readdir } from "node:fs/promises";
32771
- import { extname, join as join11, relative as relative2, sep } from "node:path";
32772
- import { createHash as createHash4 } from "node:crypto";
32894
+ import { extname, join as join12, relative as relative2, sep } from "node:path";
32895
+ import { createHash as createHash5 } from "node:crypto";
32773
32896
  import { execFileSync } from "node:child_process";
32774
32897
  function nowTs() {
32775
32898
  return indexNow ?? Date.now();
@@ -32778,7 +32901,7 @@ function fingerprintOf(signature, bodyHash) {
32778
32901
  return `${signature ?? ""}|${bodyHash ?? ""}`;
32779
32902
  }
32780
32903
  function sha(s) {
32781
- return createHash4("sha256").update(s).digest("hex").slice(0, 16);
32904
+ return createHash5("sha256").update(s).digest("hex").slice(0, 16);
32782
32905
  }
32783
32906
  function fileNodeId(workspaceId2, relPath) {
32784
32907
  return `file_${sha(workspaceId2 + ":" + relPath.replace(/\\/g, "/"))}`;
@@ -32906,7 +33029,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
32906
33029
  for (const rel of [...changedRelPaths]) {
32907
33030
  let h;
32908
33031
  try {
32909
- h = createHash4("sha256").update(readFileSync10(join11(rootPath, rel))).digest("hex");
33032
+ h = createHash5("sha256").update(readFileSync11(join12(rootPath, rel))).digest("hex");
32910
33033
  } catch {
32911
33034
  continue;
32912
33035
  }
@@ -32955,13 +33078,13 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
32955
33078
  let parsedFiles = 0;
32956
33079
  for (const rel of changedRelPaths) {
32957
33080
  if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
32958
- const abs = join11(rootPath, ...rel.split("/"));
33081
+ const abs = join12(rootPath, ...rel.split("/"));
32959
33082
  const ext = extname(abs).toLowerCase();
32960
33083
  const provider = providers.find((p) => p.fileExtensions.includes(ext));
32961
33084
  if (!provider) continue;
32962
33085
  let symbols;
32963
33086
  try {
32964
- symbols = provider.extractSymbols(readFileSync10(abs, "utf8"), abs);
33087
+ symbols = provider.extractSymbols(readFileSync11(abs, "utf8"), abs);
32965
33088
  } catch {
32966
33089
  continue;
32967
33090
  }
@@ -33281,7 +33404,7 @@ async function runIndexer(store, opts) {
33281
33404
  report.filesSkipped++;
33282
33405
  continue;
33283
33406
  }
33284
- source = readFileSync10(f.absPath, "utf8");
33407
+ source = readFileSync11(f.absPath, "utf8");
33285
33408
  } catch {
33286
33409
  report.filesSkipped++;
33287
33410
  continue;
@@ -33353,7 +33476,7 @@ async function runIndexer(store, opts) {
33353
33476
  const depth = fileNode.relPath.split("/").length;
33354
33477
  if (depth !== 3) continue;
33355
33478
  try {
33356
- const pkg = JSON.parse(readFileSync10(fileNode.absPath, "utf8"));
33479
+ const pkg = JSON.parse(readFileSync11(fileNode.absPath, "utf8"));
33357
33480
  if (!pkg.name) continue;
33358
33481
  const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
33359
33482
  const candidates = [
@@ -33741,7 +33864,7 @@ async function scan(root, current, ignores, providers, out2) {
33741
33864
  for (const ent of entries) {
33742
33865
  if (ignores.has(ent.name)) continue;
33743
33866
  if (ent.name.startsWith(".") && ent.name !== ".") continue;
33744
- const abs = join11(current, ent.name);
33867
+ const abs = join12(current, ent.name);
33745
33868
  if (ent.isDirectory()) {
33746
33869
  await scan(root, abs, ignores, providers, out2);
33747
33870
  } else if (ent.isFile()) {
@@ -33796,7 +33919,7 @@ function gitListFiles(root, ignores, providers) {
33796
33919
  if (rels === null) return null;
33797
33920
  const out2 = [];
33798
33921
  for (const rel of rels) {
33799
- const abs = join11(root, rel);
33922
+ const abs = join12(root, rel);
33800
33923
  let size;
33801
33924
  try {
33802
33925
  size = statSync3(abs).size;
@@ -33819,7 +33942,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
33819
33942
  const now = nowTs();
33820
33943
  let contentHash;
33821
33944
  try {
33822
- contentHash = createHash4("sha256").update(readFileSync10(f.absPath)).digest("hex");
33945
+ contentHash = createHash5("sha256").update(readFileSync11(f.absPath)).digest("hex");
33823
33946
  } catch {
33824
33947
  }
33825
33948
  const carried = { ...store.getNode(id)?.attrs ?? {} };
@@ -38192,8 +38315,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
38192
38315
 
38193
38316
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
38194
38317
  import { fileURLToPath } from "node:url";
38195
- import { dirname as dirname7, join as join12 } from "node:path";
38196
- import { existsSync as existsSync12, readdirSync as readdirSync3 } from "node:fs";
38318
+ import { dirname as dirname7, join as join13 } from "node:path";
38319
+ import { existsSync as existsSync13, readdirSync as readdirSync3 } from "node:fs";
38197
38320
  import { createRequire as createRequire2 } from "node:module";
38198
38321
  function entryDir() {
38199
38322
  try {
@@ -38207,27 +38330,27 @@ function entryDir() {
38207
38330
  }
38208
38331
  function findWasmDir() {
38209
38332
  const here = entryDir();
38210
- const seaWasm = join12(here, "resources", "wasm");
38211
- if (existsSync12(join12(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
38333
+ const seaWasm = join13(here, "resources", "wasm");
38334
+ if (existsSync13(join13(seaWasm, "tree-sitter-typescript.wasm"))) return seaWasm;
38212
38335
  let dir = here;
38213
38336
  for (let i2 = 0; i2 < 6; i2++) {
38214
- const flat = join12(
38337
+ const flat = join13(
38215
38338
  dir,
38216
38339
  "node_modules",
38217
38340
  "@vscode",
38218
38341
  "tree-sitter-wasm",
38219
38342
  "wasm"
38220
38343
  );
38221
- if (existsSync12(join12(flat, "tree-sitter-typescript.wasm"))) return flat;
38344
+ if (existsSync13(join13(flat, "tree-sitter-typescript.wasm"))) return flat;
38222
38345
  dir = dirname7(dir);
38223
38346
  }
38224
38347
  let root = here;
38225
38348
  for (let i2 = 0; i2 < 6; i2++) {
38226
- const pnpmDir = join12(root, "node_modules", ".pnpm");
38227
- if (existsSync12(pnpmDir)) {
38349
+ const pnpmDir = join13(root, "node_modules", ".pnpm");
38350
+ if (existsSync13(pnpmDir)) {
38228
38351
  for (const entry of readdirSync3(pnpmDir)) {
38229
38352
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
38230
- const candidate = join12(
38353
+ const candidate = join13(
38231
38354
  pnpmDir,
38232
38355
  entry,
38233
38356
  "node_modules",
@@ -38235,7 +38358,7 @@ function findWasmDir() {
38235
38358
  "tree-sitter-wasm",
38236
38359
  "wasm"
38237
38360
  );
38238
- if (existsSync12(join12(candidate, "tree-sitter-typescript.wasm"))) {
38361
+ if (existsSync13(join13(candidate, "tree-sitter-typescript.wasm"))) {
38239
38362
  return candidate;
38240
38363
  }
38241
38364
  }
@@ -38249,27 +38372,27 @@ function findWasmDir() {
38249
38372
  }
38250
38373
  function findRuntimeDir() {
38251
38374
  const here = entryDir();
38252
- const seaRuntime = join12(here, "resources", "wasm");
38253
- if (existsSync12(join12(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
38375
+ const seaRuntime = join13(here, "resources", "wasm");
38376
+ if (existsSync13(join13(seaRuntime, "web-tree-sitter.wasm"))) return seaRuntime;
38254
38377
  let dir = here;
38255
38378
  for (let i2 = 0; i2 < 6; i2++) {
38256
- const flat = join12(dir, "node_modules", "web-tree-sitter");
38257
- if (existsSync12(join12(flat, "web-tree-sitter.wasm"))) return flat;
38379
+ const flat = join13(dir, "node_modules", "web-tree-sitter");
38380
+ if (existsSync13(join13(flat, "web-tree-sitter.wasm"))) return flat;
38258
38381
  dir = dirname7(dir);
38259
38382
  }
38260
38383
  let root = here;
38261
38384
  for (let i2 = 0; i2 < 6; i2++) {
38262
- const pnpmDir = join12(root, "node_modules", ".pnpm");
38263
- if (existsSync12(pnpmDir)) {
38385
+ const pnpmDir = join13(root, "node_modules", ".pnpm");
38386
+ if (existsSync13(pnpmDir)) {
38264
38387
  for (const entry of readdirSync3(pnpmDir)) {
38265
38388
  if (entry.startsWith("web-tree-sitter@")) {
38266
- const candidate = join12(
38389
+ const candidate = join13(
38267
38390
  pnpmDir,
38268
38391
  entry,
38269
38392
  "node_modules",
38270
38393
  "web-tree-sitter"
38271
38394
  );
38272
- if (existsSync12(join12(candidate, "web-tree-sitter.wasm"))) {
38395
+ if (existsSync13(join13(candidate, "web-tree-sitter.wasm"))) {
38273
38396
  return candidate;
38274
38397
  }
38275
38398
  }
@@ -38286,7 +38409,7 @@ async function loadWebTreeSitter() {
38286
38409
  void err2;
38287
38410
  }
38288
38411
  const here = entryDir();
38289
- const seaResourceBase = join12(here, "resources", "_resolve.js");
38412
+ const seaResourceBase = join13(here, "resources", "_resolve.js");
38290
38413
  const resourceRequire = createRequire2(seaResourceBase);
38291
38414
  return resourceRequire("web-tree-sitter");
38292
38415
  }
@@ -38301,9 +38424,9 @@ async function ensureTreeSitterReady() {
38301
38424
  await Parser2.init({
38302
38425
  locateFile: (name2) => {
38303
38426
  if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
38304
- return join12(runtime, name2);
38427
+ return join13(runtime, name2);
38305
38428
  }
38306
- return join12(grammars, name2);
38429
+ return join13(grammars, name2);
38307
38430
  }
38308
38431
  });
38309
38432
  })();
@@ -38315,7 +38438,7 @@ async function loadGrammar(name2) {
38315
38438
  if (cached2) return cached2;
38316
38439
  if (!languageClass) throw new Error("tree-sitter not initialized");
38317
38440
  const grammars = findWasmDir();
38318
- const lang = await languageClass.load(join12(grammars, `${name2}.wasm`));
38441
+ const lang = await languageClass.load(join13(grammars, `${name2}.wasm`));
38319
38442
  grammarCache.set(name2, lang);
38320
38443
  return lang;
38321
38444
  }
@@ -38338,7 +38461,7 @@ var init_tree_sitter_loader = __esm({
38338
38461
  });
38339
38462
 
38340
38463
  // ../../packages/indexer/src/languages/typescript-treesitter.ts
38341
- import { createHash as createHash5 } from "node:crypto";
38464
+ import { createHash as createHash6 } from "node:crypto";
38342
38465
  function extractNode(node2, source, containerQname, containerKind) {
38343
38466
  switch (node2.type) {
38344
38467
  case "function_declaration":
@@ -38551,7 +38674,7 @@ function scopeRecord(kind, name2, qname, node2, body2, source) {
38551
38674
  const sig = header.replace(/\s+/g, " ").trim();
38552
38675
  if (sig) rec.signature = sig;
38553
38676
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
38554
- rec.bodyHash = createHash5("sha256").update(bodyText).digest("hex").slice(0, 16);
38677
+ rec.bodyHash = createHash6("sha256").update(bodyText).digest("hex").slice(0, 16);
38555
38678
  rec.bodySimhash = toHex(simhash(bodyText));
38556
38679
  }
38557
38680
  }
@@ -38993,14 +39116,14 @@ var init_typescript_treesitter = __esm({
38993
39116
  });
38994
39117
 
38995
39118
  // ../../packages/indexer/src/languages/python-treesitter.ts
38996
- import { createHash as createHash6 } from "node:crypto";
39119
+ import { createHash as createHash7 } from "node:crypto";
38997
39120
  function sigAndHash(node2, body2, source) {
38998
39121
  if (!body2) return {};
38999
39122
  const out2 = {};
39000
39123
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
39001
39124
  if (sig) out2.signature = sig;
39002
39125
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
39003
- out2.bodyHash = createHash6("sha256").update(bodyText).digest("hex").slice(0, 16);
39126
+ out2.bodyHash = createHash7("sha256").update(bodyText).digest("hex").slice(0, 16);
39004
39127
  out2.bodySimhash = toHex(simhash(bodyText));
39005
39128
  return out2;
39006
39129
  }
@@ -39413,7 +39536,7 @@ var init_python_treesitter = __esm({
39413
39536
  });
39414
39537
 
39415
39538
  // ../../packages/indexer/src/languages/cpp-treesitter.ts
39416
- import { createHash as createHash7 } from "node:crypto";
39539
+ import { createHash as createHash8 } from "node:crypto";
39417
39540
  function extractNode3(node2, containerQname, containerIsClass, source) {
39418
39541
  switch (node2.type) {
39419
39542
  case "function_definition":
@@ -39597,7 +39720,7 @@ function sigAndHash2(node2, body2, source) {
39597
39720
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
39598
39721
  if (sig) out2.signature = sig;
39599
39722
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
39600
- out2.bodyHash = createHash7("sha256").update(bodyText).digest("hex").slice(0, 16);
39723
+ out2.bodyHash = createHash8("sha256").update(bodyText).digest("hex").slice(0, 16);
39601
39724
  out2.bodySimhash = toHex(simhash(bodyText));
39602
39725
  return out2;
39603
39726
  }
@@ -39758,7 +39881,7 @@ var init_cpp_treesitter = __esm({
39758
39881
  });
39759
39882
 
39760
39883
  // ../../packages/indexer/src/languages/go-treesitter.ts
39761
- import { createHash as createHash8 } from "node:crypto";
39884
+ import { createHash as createHash9 } from "node:crypto";
39762
39885
  function extractNode4(node2, containerQname, source) {
39763
39886
  switch (node2.type) {
39764
39887
  case "function_declaration": {
@@ -39920,7 +40043,7 @@ function sigAndHash3(node2, body2, source) {
39920
40043
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
39921
40044
  if (sig) out2.signature = sig;
39922
40045
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
39923
- out2.bodyHash = createHash8("sha256").update(bodyText).digest("hex").slice(0, 16);
40046
+ out2.bodyHash = createHash9("sha256").update(bodyText).digest("hex").slice(0, 16);
39924
40047
  out2.bodySimhash = toHex(simhash(bodyText));
39925
40048
  return out2;
39926
40049
  }
@@ -40064,7 +40187,7 @@ var init_go_treesitter = __esm({
40064
40187
  });
40065
40188
 
40066
40189
  // ../../packages/indexer/src/languages/rust-treesitter.ts
40067
- import { createHash as createHash9 } from "node:crypto";
40190
+ import { createHash as createHash10 } from "node:crypto";
40068
40191
  function extractNode5(node2, containerQname, containerIsClass, source) {
40069
40192
  switch (node2.type) {
40070
40193
  case "function_item":
@@ -40279,7 +40402,7 @@ function sigAndHash4(node2, body2, source) {
40279
40402
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
40280
40403
  if (sig) out2.signature = sig;
40281
40404
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
40282
- out2.bodyHash = createHash9("sha256").update(bodyText).digest("hex").slice(0, 16);
40405
+ out2.bodyHash = createHash10("sha256").update(bodyText).digest("hex").slice(0, 16);
40283
40406
  out2.bodySimhash = toHex(simhash(bodyText));
40284
40407
  return out2;
40285
40408
  }
@@ -40430,7 +40553,7 @@ var init_rust_treesitter = __esm({
40430
40553
  });
40431
40554
 
40432
40555
  // ../../packages/indexer/src/languages/ruby-treesitter.ts
40433
- import { createHash as createHash10 } from "node:crypto";
40556
+ import { createHash as createHash11 } from "node:crypto";
40434
40557
  function sigAndHash5(node2, body2, source) {
40435
40558
  if (!body2) {
40436
40559
  const sig2 = source.slice(node2.startIndex, node2.endIndex).replace(/\s+/g, " ").trim();
@@ -40440,7 +40563,7 @@ function sigAndHash5(node2, body2, source) {
40440
40563
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
40441
40564
  if (sig) out2.signature = sig;
40442
40565
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
40443
- out2.bodyHash = createHash10("sha256").update(bodyText).digest("hex").slice(0, 16);
40566
+ out2.bodyHash = createHash11("sha256").update(bodyText).digest("hex").slice(0, 16);
40444
40567
  out2.bodySimhash = toHex(simhash(bodyText));
40445
40568
  return out2;
40446
40569
  }
@@ -40786,7 +40909,7 @@ var init_ruby_treesitter = __esm({
40786
40909
  });
40787
40910
 
40788
40911
  // ../../packages/indexer/src/languages/csharp-treesitter.ts
40789
- import { createHash as createHash11 } from "node:crypto";
40912
+ import { createHash as createHash12 } from "node:crypto";
40790
40913
  function extractNode7(node2, containerQname, containerIsType, source, eof) {
40791
40914
  switch (node2.type) {
40792
40915
  case "method_declaration":
@@ -40988,7 +41111,7 @@ function sigAndHash6(node2, body2, source) {
40988
41111
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
40989
41112
  if (sig) out2.signature = sig;
40990
41113
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
40991
- out2.bodyHash = createHash11("sha256").update(bodyText).digest("hex").slice(0, 16);
41114
+ out2.bodyHash = createHash12("sha256").update(bodyText).digest("hex").slice(0, 16);
40992
41115
  out2.bodySimhash = toHex(simhash(bodyText));
40993
41116
  return out2;
40994
41117
  }
@@ -41219,7 +41342,7 @@ var init_src11 = __esm({
41219
41342
  // src/reconcile.ts
41220
41343
  import { execFileSync as execFileSync2 } from "node:child_process";
41221
41344
  import { readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
41222
- import { join as join13, relative as relative3, sep as sep2 } from "node:path";
41345
+ import { join as join14, relative as relative3, sep as sep2 } from "node:path";
41223
41346
  function indexerWouldScan(rel) {
41224
41347
  for (const seg of rel.split(/[\\/]/)) {
41225
41348
  if (seg.length === 0) continue;
@@ -41242,7 +41365,7 @@ function gitSourceFiles(root) {
41242
41365
  const out2 = [];
41243
41366
  for (const rel of stdout.split("\0")) {
41244
41367
  if (!rel || !SOURCE_RE.test(rel) || !indexerWouldScan(rel)) continue;
41245
- const abs = join13(root, rel);
41368
+ const abs = join14(root, rel);
41246
41369
  if (IGNORED.test(abs)) continue;
41247
41370
  out2.push(abs);
41248
41371
  }
@@ -41257,7 +41380,7 @@ function* walkSource(dir) {
41257
41380
  }
41258
41381
  for (const e of entries) {
41259
41382
  const name2 = String(e.name);
41260
- const full = join13(dir, name2);
41383
+ const full = join14(dir, name2);
41261
41384
  if (IGNORED.test(full)) continue;
41262
41385
  if (!indexerWouldScan(name2)) continue;
41263
41386
  if (e.isDirectory()) yield* walkSource(full);
@@ -41407,7 +41530,7 @@ __export(mcp_exports, {
41407
41530
  runTool: () => runTool,
41408
41531
  searchGraph: () => searchGraph
41409
41532
  });
41410
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
41533
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "node:fs";
41411
41534
  import { resolve as resolve3 } from "node:path";
41412
41535
  function collectEnrichmentPulls(store, opts = {}) {
41413
41536
  const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
@@ -41444,7 +41567,7 @@ function takeEnrichmentNudge(store) {
41444
41567
  ` + items;
41445
41568
  }
41446
41569
  function takeDiscriminatorNudge(path2) {
41447
- if (!path2 || !existsSync13(path2)) return null;
41570
+ if (!path2 || !existsSync14(path2)) return null;
41448
41571
  let shared;
41449
41572
  try {
41450
41573
  shared = openGraphStore({ path: path2 });
@@ -41575,10 +41698,10 @@ function showNode(store, node2, maxLines) {
41575
41698
  if (!relPath) return { found: false, reason: "no file owner for node" };
41576
41699
  const workspaceRoot = process.cwd();
41577
41700
  const absPath = resolve3(workspaceRoot, relPath);
41578
- if (!existsSync13(absPath)) {
41701
+ if (!existsSync14(absPath)) {
41579
41702
  return { found: false, reason: `file not found on disk: ${absPath}` };
41580
41703
  }
41581
- const source = readFileSync11(absPath, "utf8");
41704
+ const source = readFileSync12(absPath, "utf8");
41582
41705
  const attrs = node2.attrs;
41583
41706
  let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
41584
41707
  let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
@@ -41805,6 +41928,7 @@ function buildToolContext(workspaceRoot) {
41805
41928
  try {
41806
41929
  const cfg = loadConfig();
41807
41930
  const entry = workspaceRoot ? workspaceEntryForPath(resolve3(workspaceRoot)) : null;
41931
+ const syncOk = effectiveConsent(cfg, entry ? loadProfile(entry.path) : null).sync;
41808
41932
  const identity = resolveWorkspaceIdentity(cfg, entry);
41809
41933
  if (identity.invalid) {
41810
41934
  console.error(`[errata mcp] cloud DISABLED for this workspace: ${identity.reason}`);
@@ -41812,13 +41936,13 @@ function buildToolContext(workspaceRoot) {
41812
41936
  }
41813
41937
  if (identity.rule === "workspace-binding" && identity.profileName) {
41814
41938
  const profile = identity.profile;
41815
- if (cfg.consent.sync && (profile.accessToken || profile.apiKey)) {
41939
+ if (syncOk && (profile.accessToken || profile.apiKey)) {
41816
41940
  console.error(`[errata mcp] workspace identity: profile "${identity.profileName}"`);
41817
41941
  return { ...base, cloud: authedCloudClientForProfile(cfg, identity.profileName) };
41818
41942
  }
41819
41943
  return base;
41820
41944
  }
41821
- if (cfg.consent.sync && hasCloudCredential(cfg) && cfg.cloudUrl) {
41945
+ if (syncOk && hasCloudCredential(cfg) && cfg.cloudUrl) {
41822
41946
  return { ...base, cloud: authedCloudClient(cfg) };
41823
41947
  }
41824
41948
  } catch {
@@ -41865,6 +41989,8 @@ var init_mcp = __esm({
41865
41989
  "use strict";
41866
41990
  init_cloud_auth();
41867
41991
  init_config();
41992
+ init_consent();
41993
+ init_profile2();
41868
41994
  init_identity2();
41869
41995
  init_registry();
41870
41996
  init_dual_augment();
@@ -42332,7 +42458,7 @@ var init_mcp = __esm({
42332
42458
  const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
42333
42459
  try {
42334
42460
  const path2 = sharedStorePath();
42335
- if (!existsSync13(path2)) return { found: true, ...local };
42461
+ if (!existsSync14(path2)) return { found: true, ...local };
42336
42462
  const shared = openGraphStore({ path: path2 });
42337
42463
  try {
42338
42464
  if (!shared.getNode(id)) return { found: true, ...local };
@@ -42932,7 +43058,7 @@ var init_mcp = __esm({
42932
43058
  inputSchema: { type: "object", properties: {} },
42933
43059
  handler: () => {
42934
43060
  const path2 = sharedStorePath();
42935
- if (!existsSync13(path2)) return { count: 0, pending: [] };
43061
+ if (!existsSync14(path2)) return { count: 0, pending: [] };
42936
43062
  const shared = openGraphStore({ path: path2 });
42937
43063
  try {
42938
43064
  const pending = pendingAbstractions(shared);
@@ -42960,7 +43086,7 @@ var init_mcp = __esm({
42960
43086
  },
42961
43087
  handler: (args2) => {
42962
43088
  const path2 = sharedStorePath();
42963
- if (!existsSync13(path2)) return { count: 0, pending: [] };
43089
+ if (!existsSync14(path2)) return { count: 0, pending: [] };
42964
43090
  const shared = openGraphStore({ path: path2 });
42965
43091
  try {
42966
43092
  const pending = pendingDiscriminators(shared, {
@@ -43004,7 +43130,7 @@ var init_mcp = __esm({
43004
43130
  },
43005
43131
  handler: (args2) => {
43006
43132
  const path2 = sharedStorePath();
43007
- if (!existsSync13(path2)) return { count: 0, routes: [] };
43133
+ if (!existsSync14(path2)) return { count: 0, routes: [] };
43008
43134
  const shared = openGraphStore({ path: path2 });
43009
43135
  try {
43010
43136
  const result = triageOf(shared, {
@@ -43389,8 +43515,8 @@ __export(vfile_exports, {
43389
43515
  resolvePath: () => resolvePath,
43390
43516
  segmentsOf: () => segmentsOf
43391
43517
  });
43392
- import { writeFileSync as writeFileSync9 } from "node:fs";
43393
- import { join as join14, resolve as resolve4, sep as sep3 } from "node:path";
43518
+ import { writeFileSync as writeFileSync10 } from "node:fs";
43519
+ import { join as join15, resolve as resolve4, sep as sep3 } from "node:path";
43394
43520
  function segmentsOf(rawPath) {
43395
43521
  let p = rawPath.replace(/\\/g, "/");
43396
43522
  p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
@@ -43464,14 +43590,14 @@ async function renderVFile(rawPath, store, ctx = {}) {
43464
43590
  }
43465
43591
  async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
43466
43592
  const segs = segmentsOf(rawPath);
43467
- const gRoot = join14(workspaceRoot, ".errata", "g");
43593
+ const gRoot = join15(workspaceRoot, ".errata", "g");
43468
43594
  const abs = resolve4(gRoot, ...segs.length ? segs : ["index"]);
43469
43595
  if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
43470
43596
  throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
43471
43597
  }
43472
43598
  const text = await renderVFile(rawPath, store, ctx);
43473
43599
  ensureParent(abs);
43474
- writeFileSync9(abs, text, "utf8");
43600
+ writeFileSync10(abs, text, "utf8");
43475
43601
  return abs;
43476
43602
  }
43477
43603
  async function materializeOverview(workspaceRoot, store, ctx = {}) {
@@ -50891,25 +51017,25 @@ var init_tool_index = __esm({
50891
51017
 
50892
51018
  // src/outbox.ts
50893
51019
  import {
50894
- existsSync as existsSync14,
51020
+ existsSync as existsSync15,
50895
51021
  readdirSync as readdirSync5,
50896
- readFileSync as readFileSync12,
51022
+ readFileSync as readFileSync13,
50897
51023
  renameSync,
50898
51024
  unlinkSync,
50899
- writeFileSync as writeFileSync10
51025
+ writeFileSync as writeFileSync11
50900
51026
  } from "node:fs";
50901
- import { join as join15 } from "node:path";
50902
- import { createHash as createHash12 } from "node:crypto";
51027
+ import { join as join16 } from "node:path";
51028
+ import { createHash as createHash13 } from "node:crypto";
50903
51029
  function enqueueOutbox(paths, payload) {
50904
51030
  ensureDir(paths.outbox);
50905
- const id = createHash12("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
50906
- const file2 = join15(paths.outbox, `${Date.now()}-${id}.json`);
50907
- writeFileSync10(file2, JSON.stringify(payload, null, 2), "utf8");
51031
+ const id = createHash13("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
51032
+ const file2 = join16(paths.outbox, `${Date.now()}-${id}.json`);
51033
+ writeFileSync11(file2, JSON.stringify(payload, null, 2), "utf8");
50908
51034
  return file2;
50909
51035
  }
50910
51036
  async function flushOutbox(paths, client, store) {
50911
51037
  ensureDir(paths.outbox);
50912
- const entries = existsSync14(paths.outbox) ? readdirSync5(paths.outbox) : [];
51038
+ const entries = existsSync15(paths.outbox) ? readdirSync5(paths.outbox) : [];
50913
51039
  let uploaded = 0;
50914
51040
  let failed = 0;
50915
51041
  const quarantine = (abs, reason) => {
@@ -50920,10 +51046,10 @@ async function flushOutbox(paths, client, store) {
50920
51046
  }
50921
51047
  };
50922
51048
  for (const f of entries.filter((e) => e.endsWith(".json")).sort()) {
50923
- const abs = join15(paths.outbox, f);
51049
+ const abs = join16(paths.outbox, f);
50924
51050
  let payload;
50925
51051
  try {
50926
- payload = JSON.parse(readFileSync12(abs, "utf8"));
51052
+ payload = JSON.parse(readFileSync13(abs, "utf8"));
50927
51053
  } catch {
50928
51054
  failed++;
50929
51055
  quarantine(abs, "unparseable JSON");
@@ -50968,7 +51094,7 @@ async function flushOutbox(paths, client, store) {
50968
51094
  }
50969
51095
  }
50970
51096
  }
50971
- const remainingFiles = existsSync14(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
51097
+ const remainingFiles = existsSync15(paths.outbox) ? readdirSync5(paths.outbox).filter((e) => e.endsWith(".json")) : [];
50972
51098
  return { uploaded, failed, remaining: remainingFiles.length };
50973
51099
  }
50974
51100
  var init_outbox = __esm({
@@ -73447,10 +73573,10 @@ init_src10();
73447
73573
  init_review2();
73448
73574
 
73449
73575
  // src/turn.ts
73450
- import { closeSync, existsSync as existsSync15, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync5 } from "node:fs";
73451
- import { basename as basename5, delimiter, dirname as dirname10, join as join18, normalize as normalize3 } from "node:path";
73576
+ import { closeSync, existsSync as existsSync16, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync5 } from "node:fs";
73577
+ import { basename as basename5, delimiter, dirname as dirname10, join as join19, normalize as normalize3 } from "node:path";
73452
73578
  import { homedir as homedir4 } from "node:os";
73453
- import { createHash as createHash13 } from "node:crypto";
73579
+ import { createHash as createHash14 } from "node:crypto";
73454
73580
  function readFrom(path2, fromByte, maxBytes) {
73455
73581
  let fd;
73456
73582
  try {
@@ -73826,11 +73952,11 @@ function turnsSince(turns, mark) {
73826
73952
  return at >= 0 ? turns.slice(at + 1) : turns;
73827
73953
  }
73828
73954
  function claudeProjectDir(cwd, home = homedir4()) {
73829
- return join18(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
73955
+ return join19(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
73830
73956
  }
73831
73957
  function recentTranscripts(cwd, opts = {}) {
73832
73958
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
73833
- if (!existsSync15(dir)) return [];
73959
+ if (!existsSync16(dir)) return [];
73834
73960
  let names;
73835
73961
  try {
73836
73962
  names = readdirSync6(dir);
@@ -73841,7 +73967,7 @@ function recentTranscripts(cwd, opts = {}) {
73841
73967
  const refs = [];
73842
73968
  for (const name2 of names) {
73843
73969
  if (!name2.endsWith(".jsonl")) continue;
73844
- const path2 = join18(dir, name2);
73970
+ const path2 = join19(dir, name2);
73845
73971
  let mtimeMs;
73846
73972
  try {
73847
73973
  mtimeMs = statSync5(path2).mtimeMs;
@@ -73856,8 +73982,8 @@ function recentTranscripts(cwd, opts = {}) {
73856
73982
  }
73857
73983
  function subagentTranscripts(mainTranscriptPath, sessionId) {
73858
73984
  if (!mainTranscriptPath || !sessionId) return [];
73859
- const dir = join18(dirname10(mainTranscriptPath), sessionId, "subagents");
73860
- if (!existsSync15(dir)) return [];
73985
+ const dir = join19(dirname10(mainTranscriptPath), sessionId, "subagents");
73986
+ if (!existsSync16(dir)) return [];
73861
73987
  let names;
73862
73988
  try {
73863
73989
  names = readdirSync6(dir);
@@ -73867,7 +73993,7 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
73867
73993
  const refs = [];
73868
73994
  for (const name2 of names) {
73869
73995
  if (!name2.endsWith(".jsonl")) continue;
73870
- const path2 = join18(dir, name2);
73996
+ const path2 = join19(dir, name2);
73871
73997
  let mtimeMs;
73872
73998
  try {
73873
73999
  mtimeMs = statSync5(path2).mtimeMs;
@@ -73886,8 +74012,8 @@ function splitPathList(value, sep5 = delimiter) {
73886
74012
  function codexSessionRoots(env2 = process.env, home = homedir4()) {
73887
74013
  const roots = /* @__PURE__ */ new Set();
73888
74014
  for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
73889
- if (env2["CODEX_HOME"]) roots.add(join18(env2["CODEX_HOME"], "sessions"));
73890
- roots.add(join18(home, ".codex", "sessions"));
74015
+ if (env2["CODEX_HOME"]) roots.add(join19(env2["CODEX_HOME"], "sessions"));
74016
+ roots.add(join19(home, ".codex", "sessions"));
73891
74017
  return [...roots];
73892
74018
  }
73893
74019
  function readCodexRolloutCwd(path2) {
@@ -73932,7 +74058,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
73932
74058
  const limit = opts.limit ?? 25;
73933
74059
  const out2 = [];
73934
74060
  for (const root of codexSessionRoots(opts.env, opts.home)) {
73935
- if (!existsSync15(root)) continue;
74061
+ if (!existsSync16(root)) continue;
73936
74062
  const stack = [{ dir: root, depth: 0 }];
73937
74063
  while (stack.length > 0) {
73938
74064
  const { dir, depth } = stack.pop();
@@ -73943,7 +74069,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
73943
74069
  continue;
73944
74070
  }
73945
74071
  for (const name2 of names) {
73946
- const full = join18(dir, name2);
74072
+ const full = join19(dir, name2);
73947
74073
  let st;
73948
74074
  try {
73949
74075
  st = statSync5(full);
@@ -73968,12 +74094,12 @@ function codexRolloutsForCwd(cwd, opts = {}) {
73968
74094
  function geminiSessionRoots(env2 = process.env, home = homedir4()) {
73969
74095
  const roots = /* @__PURE__ */ new Set();
73970
74096
  for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
73971
- if (env2["GEMINI_CLI_HOME"]) roots.add(join18(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
73972
- roots.add(join18(home, ".gemini", "tmp"));
74097
+ if (env2["GEMINI_CLI_HOME"]) roots.add(join19(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
74098
+ roots.add(join19(home, ".gemini", "tmp"));
73973
74099
  return [...roots];
73974
74100
  }
73975
74101
  function geminiProjectHash(cwd) {
73976
- return createHash13("sha256").update(cwd).digest("hex");
74102
+ return createHash14("sha256").update(cwd).digest("hex");
73977
74103
  }
73978
74104
  function geminiHashesFor(cwd) {
73979
74105
  const variants = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
@@ -74009,7 +74135,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74009
74135
  const hashes = geminiHashesFor(cwd);
74010
74136
  const out2 = [];
74011
74137
  for (const root of geminiSessionRoots(opts.env, opts.home)) {
74012
- if (!existsSync15(root)) continue;
74138
+ if (!existsSync16(root)) continue;
74013
74139
  let slugs;
74014
74140
  try {
74015
74141
  slugs = readdirSync6(root);
@@ -74017,7 +74143,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74017
74143
  continue;
74018
74144
  }
74019
74145
  for (const slug2 of slugs) {
74020
- const chats = join18(root, slug2, "chats");
74146
+ const chats = join19(root, slug2, "chats");
74021
74147
  let names;
74022
74148
  try {
74023
74149
  names = readdirSync6(chats);
@@ -74026,7 +74152,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74026
74152
  }
74027
74153
  for (const name2 of names) {
74028
74154
  if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
74029
- const full = join18(chats, name2);
74155
+ const full = join19(chats, name2);
74030
74156
  let st;
74031
74157
  try {
74032
74158
  st = statSync5(full);
@@ -74046,8 +74172,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74046
74172
  function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
74047
74173
  const roots = /* @__PURE__ */ new Set();
74048
74174
  for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
74049
- if (env2["XDG_DATA_HOME"]) roots.add(join18(env2["XDG_DATA_HOME"], "opencode", "errata"));
74050
- roots.add(join18(home, ".local", "share", "opencode", "errata"));
74175
+ if (env2["XDG_DATA_HOME"]) roots.add(join19(env2["XDG_DATA_HOME"], "opencode", "errata"));
74176
+ roots.add(join19(home, ".local", "share", "opencode", "errata"));
74051
74177
  return [...roots];
74052
74178
  }
74053
74179
  function readOpencodeTranscriptDirectory(path2) {
@@ -74080,7 +74206,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
74080
74206
  }
74081
74207
  const out2 = [];
74082
74208
  for (const root of opencodeSessionRoots(opts.env, opts.home)) {
74083
- if (!existsSync15(root)) continue;
74209
+ if (!existsSync16(root)) continue;
74084
74210
  let names;
74085
74211
  try {
74086
74212
  names = readdirSync6(root);
@@ -74089,7 +74215,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
74089
74215
  }
74090
74216
  for (const name2 of names) {
74091
74217
  if (!name2.endsWith(".jsonl")) continue;
74092
- const full = join18(root, name2);
74218
+ const full = join19(root, name2);
74093
74219
  let st;
74094
74220
  try {
74095
74221
  st = statSync5(full);
@@ -74112,7 +74238,7 @@ init_src2();
74112
74238
  init_agent_signals();
74113
74239
  init_tool_index();
74114
74240
  init_src5();
74115
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync11 } from "node:fs";
74241
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "node:fs";
74116
74242
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
74117
74243
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
74118
74244
  var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
@@ -74791,13 +74917,13 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
74791
74917
  entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
74792
74918
  entries.length = HANDLE_MAP_MAX;
74793
74919
  }
74794
- writeFileSync11(path2, JSON.stringify(Object.fromEntries(entries)));
74920
+ writeFileSync12(path2, JSON.stringify(Object.fromEntries(entries)));
74795
74921
  } catch {
74796
74922
  }
74797
74923
  }
74798
74924
  function readPrimingHandles(path2) {
74799
74925
  try {
74800
- return JSON.parse(readFileSync13(path2, "utf8"));
74926
+ return JSON.parse(readFileSync14(path2, "utf8"));
74801
74927
  } catch {
74802
74928
  return {};
74803
74929
  }
@@ -75272,8 +75398,8 @@ ${conversation}` }]
75272
75398
  // src/constraint-backfill.ts
75273
75399
  init_src5();
75274
75400
  init_src2();
75275
- import { existsSync as existsSync16, readFileSync as readFileSync14, readdirSync as readdirSync7, writeFileSync as writeFileSync12 } from "node:fs";
75276
- import { join as join19 } from "node:path";
75401
+ import { existsSync as existsSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, writeFileSync as writeFileSync13 } from "node:fs";
75402
+ import { join as join20 } from "node:path";
75277
75403
  import { homedir as homedir5 } from "node:os";
75278
75404
  var BACKFILL_VERSION = 1;
75279
75405
  var EMPTY = {
@@ -75287,13 +75413,13 @@ var EMPTY = {
75287
75413
  recoverable: 0
75288
75414
  };
75289
75415
  function markerPath(configDir) {
75290
- return join19(configDir, "constraint-backfill.json");
75416
+ return join20(configDir, "constraint-backfill.json");
75291
75417
  }
75292
75418
  function alreadyDone(configDir) {
75293
75419
  const p = markerPath(configDir);
75294
- if (!existsSync16(p)) return false;
75420
+ if (!existsSync17(p)) return false;
75295
75421
  try {
75296
- const raw2 = JSON.parse(readFileSync14(p, "utf8"));
75422
+ const raw2 = JSON.parse(readFileSync15(p, "utf8"));
75297
75423
  return raw2?.version === BACKFILL_VERSION;
75298
75424
  } catch {
75299
75425
  return false;
@@ -75303,7 +75429,7 @@ function replay(root) {
75303
75429
  const statements = /* @__PURE__ */ new Set();
75304
75430
  const citedByFix = /* @__PURE__ */ new Set();
75305
75431
  const dir = claudeProjectDir(root, homedir5());
75306
- if (!existsSync16(dir)) return { statements, citedByFix };
75432
+ if (!existsSync17(dir)) return { statements, citedByFix };
75307
75433
  let names;
75308
75434
  try {
75309
75435
  names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
@@ -75313,7 +75439,7 @@ function replay(root) {
75313
75439
  for (const f of names) {
75314
75440
  let lines;
75315
75441
  try {
75316
- lines = readFileSync14(join19(dir, f), "utf8").split("\n");
75442
+ lines = readFileSync15(join20(dir, f), "utf8").split("\n");
75317
75443
  } catch {
75318
75444
  continue;
75319
75445
  }
@@ -75427,7 +75553,7 @@ function backfillConstraintKind(store, opts) {
75427
75553
  }
75428
75554
  });
75429
75555
  try {
75430
- writeFileSync12(
75556
+ writeFileSync13(
75431
75557
  markerPath(opts.configDir),
75432
75558
  JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
75433
75559
  "utf8"
@@ -75440,8 +75566,8 @@ function backfillConstraintKind(store, opts) {
75440
75566
  // src/edge-repair.ts
75441
75567
  init_src();
75442
75568
  init_src5();
75443
- import { existsSync as existsSync17, readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "node:fs";
75444
- import { join as join20 } from "node:path";
75569
+ import { existsSync as existsSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "node:fs";
75570
+ import { join as join21 } from "node:path";
75445
75571
  function citeEdgeId(from, type, to) {
75446
75572
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
75447
75573
  }
@@ -75456,13 +75582,13 @@ var EMPTY2 = {
75456
75582
  byType: {}
75457
75583
  };
75458
75584
  function markerPath2(configDir) {
75459
- return join20(configDir, "edge-repair.json");
75585
+ return join21(configDir, "edge-repair.json");
75460
75586
  }
75461
75587
  function alreadyDone2(configDir) {
75462
75588
  const p = markerPath2(configDir);
75463
- if (!existsSync17(p)) return false;
75589
+ if (!existsSync18(p)) return false;
75464
75590
  try {
75465
- return JSON.parse(readFileSync15(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
75591
+ return JSON.parse(readFileSync16(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
75466
75592
  } catch {
75467
75593
  return false;
75468
75594
  }
@@ -75511,7 +75637,7 @@ function repairInvalidEdges(store, opts) {
75511
75637
  });
75512
75638
  store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
75513
75639
  try {
75514
- writeFileSync13(
75640
+ writeFileSync14(
75515
75641
  markerPath2(opts.configDir),
75516
75642
  JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
75517
75643
  "utf8"
@@ -75525,8 +75651,8 @@ function repairInvalidEdges(store, opts) {
75525
75651
  init_reconcile();
75526
75652
 
75527
75653
  // src/pass-ledger.ts
75528
- import { appendFileSync as appendFileSync2, existsSync as existsSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "node:fs";
75529
- import { join as join21 } from "node:path";
75654
+ import { appendFileSync as appendFileSync2, existsSync as existsSync19, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "node:fs";
75655
+ import { join as join22 } from "node:path";
75530
75656
 
75531
75657
  // src/isolate-census.ts
75532
75658
  var live = 0;
@@ -75549,7 +75675,7 @@ var PER_KIND_MAX = 100;
75549
75675
  var TRIM_EVERY = 50;
75550
75676
  var appendsSinceTrim = /* @__PURE__ */ new Map();
75551
75677
  function passLedgerPath(configDir) {
75552
- return join21(configDir, "pass-ledger.jsonl");
75678
+ return join22(configDir, "pass-ledger.jsonl");
75553
75679
  }
75554
75680
  function appendPassLedger(configDir, kind, durationMs, counts) {
75555
75681
  const path2 = passLedgerPath(configDir);
@@ -75578,7 +75704,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
75578
75704
  return;
75579
75705
  }
75580
75706
  appendsSinceTrim.set(path2, 0);
75581
- const lines = readFileSync16(path2, "utf8").split("\n").filter(Boolean);
75707
+ const lines = readFileSync17(path2, "utf8").split("\n").filter(Boolean);
75582
75708
  const keptByKind = /* @__PURE__ */ new Map();
75583
75709
  const kept = [];
75584
75710
  for (let i2 = lines.length - 1; i2 >= 0; i2--) {
@@ -75594,16 +75720,16 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
75594
75720
  kept.push(lines[i2]);
75595
75721
  }
75596
75722
  if (kept.length < lines.length) {
75597
- writeFileSync14(path2, kept.reverse().join("\n") + "\n");
75723
+ writeFileSync15(path2, kept.reverse().join("\n") + "\n");
75598
75724
  }
75599
75725
  } catch {
75600
75726
  }
75601
75727
  }
75602
75728
  function readPassLedger(configDir) {
75603
75729
  const path2 = passLedgerPath(configDir);
75604
- if (!existsSync18(path2)) return [];
75730
+ if (!existsSync19(path2)) return [];
75605
75731
  try {
75606
- return readFileSync16(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
75732
+ return readFileSync17(path2, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l)).filter(
75607
75733
  (e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
75608
75734
  ).map((e) => ({ ...e, counts: e.counts ?? {} }));
75609
75735
  } catch {
@@ -75971,11 +76097,11 @@ init_outbox();
75971
76097
  init_src9();
75972
76098
  init_src();
75973
76099
  init_src2();
75974
- import { readFileSync as readFileSync17 } from "node:fs";
75975
- import { join as join22 } from "node:path";
76100
+ import { readFileSync as readFileSync18 } from "node:fs";
76101
+ import { join as join23 } from "node:path";
75976
76102
  function loadClaimIgnorePatterns(workspaceRoot) {
75977
76103
  try {
75978
- return readFileSync17(join22(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
76104
+ return readFileSync18(join23(workspaceRoot, ".errataignore"), "utf8").split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#")).map((l) => l.toLowerCase());
75979
76105
  } catch {
75980
76106
  return [];
75981
76107
  }
@@ -76338,9 +76464,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
76338
76464
  // src/retrieval-stack.ts
76339
76465
  init_src();
76340
76466
  import { execFileSync as execFileSync3 } from "node:child_process";
76341
- import { existsSync as existsSync19, readFileSync as readFileSync18, statSync as statSync6 } from "node:fs";
76467
+ import { existsSync as existsSync20, readFileSync as readFileSync19, statSync as statSync6 } from "node:fs";
76342
76468
  import { homedir as homedir6 } from "node:os";
76343
- import { join as join23 } from "node:path";
76469
+ import { join as join24 } from "node:path";
76344
76470
  var RETRIEVAL_STACK_CAP = 24;
76345
76471
  var MANIFEST_SCAN_CAP = 400;
76346
76472
  var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
@@ -76630,51 +76756,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
76630
76756
  function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
76631
76757
  const read2 = (p) => {
76632
76758
  try {
76633
- return readFileSync18(p, "utf8");
76759
+ return readFileSync19(p, "utf8");
76634
76760
  } catch {
76635
76761
  return null;
76636
76762
  }
76637
76763
  };
76638
76764
  const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
76639
76765
  const home = homedir6();
76640
- const npm = parseNpmrcPolicy(texts(join23(root, ".npmrc"), join23(home, ".npmrc")));
76766
+ const npm = parseNpmrcPolicy(texts(join24(root, ".npmrc"), join24(home, ".npmrc")));
76641
76767
  const blocked = /* @__PURE__ */ new Set();
76642
76768
  if (!npm.defaultPublic) blocked.add("npm");
76643
76769
  if (pypiIndexIsPrivate(
76644
76770
  texts(
76645
- join23(root, "pip.conf"),
76646
- join23(root, "pip.ini"),
76647
- join23(root, "pyproject.toml"),
76648
- join23(root, "requirements.txt"),
76649
- join23(home, ".pip", "pip.conf"),
76650
- join23(home, ".config", "pip", "pip.conf"),
76651
- join23(env2["APPDATA"] ?? home, "pip", "pip.ini")
76771
+ join24(root, "pip.conf"),
76772
+ join24(root, "pip.ini"),
76773
+ join24(root, "pyproject.toml"),
76774
+ join24(root, "requirements.txt"),
76775
+ join24(home, ".pip", "pip.conf"),
76776
+ join24(home, ".config", "pip", "pip.conf"),
76777
+ join24(env2["APPDATA"] ?? home, "pip", "pip.ini")
76652
76778
  )
76653
76779
  )) {
76654
76780
  blocked.add("pypi");
76655
76781
  }
76656
76782
  if (cargoRegistryIsPrivate(
76657
76783
  texts(
76658
- join23(root, ".cargo", "config.toml"),
76659
- join23(root, ".cargo", "config"),
76660
- join23(home, ".cargo", "config.toml"),
76661
- join23(home, ".cargo", "config")
76784
+ join24(root, ".cargo", "config.toml"),
76785
+ join24(root, ".cargo", "config"),
76786
+ join24(home, ".cargo", "config.toml"),
76787
+ join24(home, ".cargo", "config")
76662
76788
  )
76663
76789
  )) {
76664
76790
  blocked.add("cargo");
76665
76791
  }
76666
76792
  if (nugetSourcesArePrivate(
76667
76793
  texts(
76668
- join23(root, "NuGet.config"),
76669
- join23(root, "nuget.config"),
76670
- join23(root, "NuGet.Config"),
76671
- join23(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
76672
- join23(home, ".nuget", "NuGet", "NuGet.Config")
76794
+ join24(root, "NuGet.config"),
76795
+ join24(root, "nuget.config"),
76796
+ join24(root, "NuGet.Config"),
76797
+ join24(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
76798
+ join24(home, ".nuget", "NuGet", "NuGet.Config")
76673
76799
  )
76674
76800
  )) {
76675
76801
  blocked.add("nuget");
76676
76802
  }
76677
- const goEnvFile = env2["GOENV"] ?? join23(env2["APPDATA"] ?? join23(home, ".config"), "go", "env");
76803
+ const goEnvFile = env2["GOENV"] ?? join24(env2["APPDATA"] ?? join24(home, ".config"), "go", "env");
76678
76804
  const goEnvText = read2(goEnvFile) ?? "";
76679
76805
  const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
76680
76806
  (k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
@@ -76685,10 +76811,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
76685
76811
  env2["GONOSUMCHECK"],
76686
76812
  ...fromFile
76687
76813
  ]);
76688
- const gemfiles = texts(join23(root, "Gemfile"));
76814
+ const gemfiles = texts(join24(root, "Gemfile"));
76689
76815
  if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
76690
76816
  if (mavenReposArePrivate(
76691
- texts(join23(root, "pom.xml"), join23(home, ".m2", "settings.xml"))
76817
+ texts(join24(root, "pom.xml"), join24(home, ".m2", "settings.xml"))
76692
76818
  )) {
76693
76819
  blocked.add("maven");
76694
76820
  }
@@ -76855,8 +76981,8 @@ function readDirectDependencies(root) {
76855
76981
  const familiesSeen = /* @__PURE__ */ new Set();
76856
76982
  for (const c of LOCKFILES) {
76857
76983
  if (familiesSeen.has(c.family)) continue;
76858
- const p = join23(root, c.file);
76859
- if (!existsSync19(p)) continue;
76984
+ const p = join24(root, c.file);
76985
+ if (!existsSync20(p)) continue;
76860
76986
  try {
76861
76987
  const s = statSync6(p);
76862
76988
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
@@ -76876,7 +77002,7 @@ function readDirectDependencies(root) {
76876
77002
  const direct = [];
76877
77003
  for (const { c, path: path2 } of found) {
76878
77004
  try {
76879
- direct.push(...c.parse(readFileSync18(path2, "utf8")).direct ?? []);
77005
+ direct.push(...c.parse(readFileSync19(path2, "utf8")).direct ?? []);
76880
77006
  } catch {
76881
77007
  }
76882
77008
  }
@@ -76919,14 +77045,14 @@ function manifestPaths(root) {
76919
77045
  "project.godot"
76920
77046
  ];
76921
77047
  return {
76922
- paths: ROOT_MANIFESTS.filter((f) => existsSync19(join23(root, f))),
77048
+ paths: ROOT_MANIFESTS.filter((f) => existsSync20(join24(root, f))),
76923
77049
  tracked: false,
76924
77050
  truncated: false
76925
77051
  };
76926
77052
  }
76927
77053
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
76928
77054
  function rootDeclaresWorkspace(root, texts) {
76929
- if (WORKSPACE_MARKERS.some((f) => existsSync19(join23(root, f)))) return true;
77055
+ if (WORKSPACE_MARKERS.some((f) => existsSync20(join24(root, f)))) return true;
76930
77056
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
76931
77057
  }
76932
77058
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -76940,11 +77066,11 @@ function scanManifests(root) {
76940
77066
  const texts = /* @__PURE__ */ new Map();
76941
77067
  const stamps = [];
76942
77068
  for (const rel of paths) {
76943
- const abs = join23(root, rel);
77069
+ const abs = join24(root, rel);
76944
77070
  try {
76945
77071
  const s = statSync6(abs);
76946
77072
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
76947
- texts.set(rel, readFileSync18(abs, "utf8"));
77073
+ texts.set(rel, readFileSync19(abs, "utf8"));
76948
77074
  } catch {
76949
77075
  }
76950
77076
  }
@@ -76973,22 +77099,22 @@ function readManifestDependencies(root) {
76973
77099
  }
76974
77100
 
76975
77101
  // src/git-sensor.ts
76976
- import { existsSync as existsSync20, readFileSync as readFileSync19, watch as fsWatch } from "node:fs";
76977
- import { join as join24 } from "node:path";
77102
+ import { existsSync as existsSync21, readFileSync as readFileSync20, watch as fsWatch } from "node:fs";
77103
+ import { join as join25 } from "node:path";
76978
77104
  function readFirstLine(path2) {
76979
77105
  try {
76980
- return readFileSync19(path2, "utf8").split(/\r?\n/, 1)[0].trim();
77106
+ return readFileSync20(path2, "utf8").split(/\r?\n/, 1)[0].trim();
76981
77107
  } catch {
76982
77108
  return null;
76983
77109
  }
76984
77110
  }
76985
77111
  function readGitRefState(gitDir) {
76986
- const head2 = readFirstLine(join24(gitDir, "HEAD"));
77112
+ const head2 = readFirstLine(join25(gitDir, "HEAD"));
76987
77113
  const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
76988
77114
  const branch = m ? m[1] : null;
76989
77115
  let sha2 = null;
76990
77116
  if (branch) {
76991
- sha2 = readFirstLine(join24(gitDir, "refs", "heads", branch));
77117
+ sha2 = readFirstLine(join25(gitDir, "refs", "heads", branch));
76992
77118
  if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
76993
77119
  } else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
76994
77120
  sha2 = head2;
@@ -76996,13 +77122,13 @@ function readGitRefState(gitDir) {
76996
77122
  return {
76997
77123
  branch,
76998
77124
  sha: sha2,
76999
- mergeHeadExists: existsSync20(join24(gitDir, "MERGE_HEAD")),
77000
- origHeadExists: existsSync20(join24(gitDir, "ORIG_HEAD"))
77125
+ mergeHeadExists: existsSync21(join25(gitDir, "MERGE_HEAD")),
77126
+ origHeadExists: existsSync21(join25(gitDir, "ORIG_HEAD"))
77001
77127
  };
77002
77128
  }
77003
77129
  function shaFromPackedRefs(gitDir, ref) {
77004
77130
  try {
77005
- for (const line of readFileSync19(join24(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
77131
+ for (const line of readFileSync20(join25(gitDir, "packed-refs"), "utf8").split(/\r?\n/)) {
77006
77132
  const [sha2, name2] = line.split(/\s+/);
77007
77133
  if (name2 === ref && sha2) return sha2;
77008
77134
  }
@@ -77036,7 +77162,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
77036
77162
  const settle = () => {
77037
77163
  if (timer) clearTimeout(timer);
77038
77164
  timer = setTimeout(() => {
77039
- if (existsSync20(join24(gitDir, "index.lock"))) {
77165
+ if (existsSync21(join25(gitDir, "index.lock"))) {
77040
77166
  settle();
77041
77167
  return;
77042
77168
  }
@@ -77047,7 +77173,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
77047
77173
  }, debounceMs);
77048
77174
  };
77049
77175
  for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
77050
- const p = join24(gitDir, sub);
77176
+ const p = join25(gitDir, sub);
77051
77177
  try {
77052
77178
  watchers.push(fsWatch(p, settle));
77053
77179
  } catch {
@@ -77272,21 +77398,21 @@ var TelemetryRecorder = class {
77272
77398
 
77273
77399
  // src/skills.ts
77274
77400
  import {
77275
- existsSync as existsSync21,
77401
+ existsSync as existsSync22,
77276
77402
  mkdirSync as mkdirSync7,
77277
- readFileSync as readFileSync20,
77403
+ readFileSync as readFileSync21,
77278
77404
  readdirSync as readdirSync8,
77279
77405
  unlinkSync as unlinkSync2,
77280
- writeFileSync as writeFileSync15
77406
+ writeFileSync as writeFileSync16
77281
77407
  } from "node:fs";
77282
- import { basename as basename6, join as join25 } from "node:path";
77408
+ import { basename as basename6, join as join26 } from "node:path";
77283
77409
  function skillFileName(id) {
77284
77410
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
77285
77411
  }
77286
77412
  function readSkillManifest(manifestPath) {
77287
- if (!existsSync21(manifestPath)) return [];
77413
+ if (!existsSync22(manifestPath)) return [];
77288
77414
  try {
77289
- const parsed = JSON.parse(readFileSync20(manifestPath, "utf8"));
77415
+ const parsed = JSON.parse(readFileSync21(manifestPath, "utf8"));
77290
77416
  return (parsed.skills ?? []).map((s) => ({
77291
77417
  title: s.title ?? "",
77292
77418
  layer: s.layer ?? "technique",
@@ -77310,7 +77436,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77310
77436
  for (const s of res.skills) {
77311
77437
  const fileName = skillFileName(s.id);
77312
77438
  keep.add(fileName);
77313
- writeFileSync15(join25(paths.skillsDir, fileName), s.markdown, "utf8");
77439
+ writeFileSync16(join26(paths.skillsDir, fileName), s.markdown, "utf8");
77314
77440
  rows.push({
77315
77441
  id: s.id,
77316
77442
  title: s.title,
@@ -77323,7 +77449,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77323
77449
  const fileName = skillFileName(p.id);
77324
77450
  if (keep.has(fileName)) continue;
77325
77451
  keep.add(fileName);
77326
- writeFileSync15(join25(paths.skillsDir, fileName), p.markdown, "utf8");
77452
+ writeFileSync16(join26(paths.skillsDir, fileName), p.markdown, "utf8");
77327
77453
  rows.push({
77328
77454
  id: p.id,
77329
77455
  title: p.title,
@@ -77337,13 +77463,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77337
77463
  if (!f.endsWith(".md")) continue;
77338
77464
  if (keep.has(basename6(f))) continue;
77339
77465
  try {
77340
- unlinkSync2(join25(paths.skillsDir, f));
77466
+ unlinkSync2(join26(paths.skillsDir, f));
77341
77467
  pruned++;
77342
77468
  } catch {
77343
77469
  }
77344
77470
  }
77345
77471
  rows.sort((a, b) => a.id.localeCompare(b.id));
77346
- writeFileSync15(
77472
+ writeFileSync16(
77347
77473
  paths.skillsManifest,
77348
77474
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
77349
77475
  "utf8"
@@ -77355,22 +77481,22 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77355
77481
  init_src2();
77356
77482
  import {
77357
77483
  cpSync,
77358
- existsSync as existsSync22,
77484
+ existsSync as existsSync23,
77359
77485
  lstatSync,
77360
77486
  mkdirSync as mkdirSync8,
77361
- readFileSync as readFileSync21,
77487
+ readFileSync as readFileSync22,
77362
77488
  readdirSync as readdirSync9,
77363
77489
  rmSync as rmSync3,
77364
77490
  symlinkSync,
77365
- writeFileSync as writeFileSync16
77491
+ writeFileSync as writeFileSync17
77366
77492
  } from "node:fs";
77367
- import { join as join26 } from "node:path";
77493
+ import { join as join27 } from "node:path";
77368
77494
  var SKILL_NS = "errata-";
77369
77495
  var HARNESS_SKILL_DIRS = [
77370
- { configDir: ".claude", skillsDir: join26(".claude", "skills") },
77496
+ { configDir: ".claude", skillsDir: join27(".claude", "skills") },
77371
77497
  // Cursor adopted the standard; its exact project dir is still moving — kept
77372
77498
  // best-effort and gated on `.cursor/` presence so we never create it blind.
77373
- { configDir: ".cursor", skillsDir: join26(".cursor", "skills") }
77499
+ { configDir: ".cursor", skillsDir: join27(".cursor", "skills") }
77374
77500
  ];
77375
77501
  function skillSlug(title, id) {
77376
77502
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
@@ -77415,12 +77541,12 @@ function skillCiteHandle(s) {
77415
77541
  return priorHandle({ id: s.id, description: s.title });
77416
77542
  }
77417
77543
  function reconcileNamespaced(dir, keep) {
77418
- if (!existsSync22(dir)) return 0;
77544
+ if (!existsSync23(dir)) return 0;
77419
77545
  let pruned = 0;
77420
77546
  for (const name2 of readdirSync9(dir)) {
77421
77547
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
77422
77548
  try {
77423
- rmSync3(join26(dir, name2), { recursive: true, force: true });
77549
+ rmSync3(join27(dir, name2), { recursive: true, force: true });
77424
77550
  pruned++;
77425
77551
  } catch {
77426
77552
  }
@@ -77429,7 +77555,7 @@ function reconcileNamespaced(dir, keep) {
77429
77555
  }
77430
77556
  function linkOrCopy(linkPath, target) {
77431
77557
  try {
77432
- if (existsSync22(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
77558
+ if (existsSync23(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
77433
77559
  } catch {
77434
77560
  }
77435
77561
  try {
@@ -77450,7 +77576,7 @@ function safeLstat(p) {
77450
77576
  }
77451
77577
  }
77452
77578
  function emitAndProjectSkills(root, skills) {
77453
- const agentsSkillsDir = join26(root, ".agents", "skills");
77579
+ const agentsSkillsDir = join27(root, ".agents", "skills");
77454
77580
  mkdirSync8(agentsSkillsDir, { recursive: true });
77455
77581
  const slugs = [];
77456
77582
  const keep = /* @__PURE__ */ new Set();
@@ -77458,7 +77584,7 @@ function emitAndProjectSkills(root, skills) {
77458
77584
  for (const s of skills) {
77459
77585
  let body2;
77460
77586
  try {
77461
- body2 = readFileSync21(s.bodyPath, "utf8");
77587
+ body2 = readFileSync22(s.bodyPath, "utf8");
77462
77588
  } catch {
77463
77589
  continue;
77464
77590
  }
@@ -77467,9 +77593,9 @@ function emitAndProjectSkills(root, skills) {
77467
77593
  keep.add(slug2);
77468
77594
  slugs.push(slug2);
77469
77595
  const description = deriveDescription(s.title, s.layer, body2);
77470
- mkdirSync8(join26(agentsSkillsDir, slug2), { recursive: true });
77471
- writeFileSync16(
77472
- join26(agentsSkillsDir, slug2, "SKILL.md"),
77596
+ mkdirSync8(join27(agentsSkillsDir, slug2), { recursive: true });
77597
+ writeFileSync17(
77598
+ join27(agentsSkillsDir, slug2, "SKILL.md"),
77473
77599
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
77474
77600
  "utf8"
77475
77601
  );
@@ -77478,11 +77604,11 @@ function emitAndProjectSkills(root, skills) {
77478
77604
  reconcileNamespaced(agentsSkillsDir, keep);
77479
77605
  let projected = 0;
77480
77606
  for (const h of HARNESS_SKILL_DIRS) {
77481
- if (!existsSync22(join26(root, h.configDir))) continue;
77482
- const dir = join26(root, h.skillsDir);
77607
+ if (!existsSync23(join27(root, h.configDir))) continue;
77608
+ const dir = join27(root, h.skillsDir);
77483
77609
  mkdirSync8(dir, { recursive: true });
77484
77610
  for (const slug2 of slugs) {
77485
- linkOrCopy(join26(dir, slug2), join26(agentsSkillsDir, slug2));
77611
+ linkOrCopy(join27(dir, slug2), join27(agentsSkillsDir, slug2));
77486
77612
  projected++;
77487
77613
  }
77488
77614
  reconcileNamespaced(dir, keep);
@@ -77491,15 +77617,15 @@ function emitAndProjectSkills(root, skills) {
77491
77617
  return { slugs, emitted, projected };
77492
77618
  }
77493
77619
  function emitInputsFromManifest(erretaDir, manifestPath) {
77494
- if (!existsSync22(manifestPath)) return [];
77620
+ if (!existsSync23(manifestPath)) return [];
77495
77621
  try {
77496
- const parsed = JSON.parse(readFileSync21(manifestPath, "utf8"));
77622
+ const parsed = JSON.parse(readFileSync22(manifestPath, "utf8"));
77497
77623
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
77498
77624
  id: s.id,
77499
77625
  title: s.title ?? s.id,
77500
77626
  layer: s.layer ?? "technique",
77501
77627
  confidence: s.confidence ?? 0,
77502
- bodyPath: join26(erretaDir, s.file)
77628
+ bodyPath: join27(erretaDir, s.file)
77503
77629
  }));
77504
77630
  } catch {
77505
77631
  return [];
@@ -77513,17 +77639,17 @@ var GITIGNORE_LINES = [
77513
77639
  ".cursor/skills/errata-*/"
77514
77640
  ];
77515
77641
  function ensureSkillGitignore(root) {
77516
- const path2 = join26(root, ".gitignore");
77642
+ const path2 = join27(root, ".gitignore");
77517
77643
  let current = "";
77518
77644
  try {
77519
- current = existsSync22(path2) ? readFileSync21(path2, "utf8") : "";
77645
+ current = existsSync23(path2) ? readFileSync22(path2, "utf8") : "";
77520
77646
  } catch {
77521
77647
  return;
77522
77648
  }
77523
77649
  if (current.includes(GITIGNORE_MARK)) return;
77524
77650
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
77525
77651
  try {
77526
- writeFileSync16(path2, `${current}${prefix}
77652
+ writeFileSync17(path2, `${current}${prefix}
77527
77653
  ${GITIGNORE_LINES.join("\n")}
77528
77654
  `, "utf8");
77529
77655
  } catch {
@@ -77616,108 +77742,7 @@ function createToolRunState() {
77616
77742
  // src/engine.ts
77617
77743
  init_tool_index();
77618
77744
  init_paths();
77619
-
77620
- // src/profile.ts
77621
- init_src2();
77622
- init_paths();
77623
- init_git_remote();
77624
- import { existsSync as existsSync23, readFileSync as readFileSync22, writeFileSync as writeFileSync17 } from "node:fs";
77625
- import { createHash as createHash14 } from "node:crypto";
77626
- import { join as join27 } from "node:path";
77627
- function workspaceId(root) {
77628
- return "wp_" + createHash14("sha256").update(root).digest("hex").slice(0, 12);
77629
- }
77630
- function sessionOriginKey(sessionId) {
77631
- if (!sessionId) return void 0;
77632
- return "ws_" + createHash14("sha256").update(sessionId).digest("hex").slice(0, 12);
77633
- }
77634
- function refreshRepoLocator(root, profile) {
77635
- const detected = detectRepoLocator(root, profile.repoRemote);
77636
- if (!detected || detected === profile.repoLocator) return false;
77637
- if (profile.repoLocator) {
77638
- const aliases = new Set(profile.repoLocatorAliases ?? []);
77639
- aliases.add(profile.repoLocator);
77640
- aliases.delete(detected);
77641
- profile.repoLocatorAliases = [...aliases];
77642
- }
77643
- profile.repoLocator = detected;
77644
- saveProfile(root, profile);
77645
- return true;
77646
- }
77647
- function loadProfile(root) {
77648
- const p = workspacePaths(root);
77649
- if (!existsSync23(p.workspaceJson)) return null;
77650
- return JSON.parse(readFileSync22(p.workspaceJson, "utf8"));
77651
- }
77652
- function saveProfile(root, profile) {
77653
- const p = workspacePaths(root);
77654
- ensureDir(p.configDir);
77655
- writeFileSync17(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
77656
- }
77657
- function autodetectProfile(root) {
77658
- const id = workspaceId(root);
77659
- const name2 = root.split(/[\\/]/).filter(Boolean).pop() ?? "workspace";
77660
- const p = emptyProfile(id, name2);
77661
- const locator = detectRepoLocator(root);
77662
- if (locator) p.repoLocator = locator;
77663
- const pkgPath = join27(root, "package.json");
77664
- if (existsSync23(pkgPath)) {
77665
- try {
77666
- const pkg = JSON.parse(readFileSync22(pkgPath, "utf8"));
77667
- const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
77668
- p.languages.push("javascript");
77669
- if (existsSync23(join27(root, "tsconfig.json")) || deps["typescript"]) {
77670
- p.languages.push("typescript");
77671
- }
77672
- const nodeVer = pkg.engines?.node?.trim();
77673
- p.stack.push(nodeVer ? `node@${nodeVer}` : "node");
77674
- const interesting = [
77675
- "next",
77676
- "react",
77677
- "vue",
77678
- "svelte",
77679
- "express",
77680
- "hono",
77681
- "fastify",
77682
- "@modelcontextprotocol/sdk"
77683
- ];
77684
- for (const k of interesting) {
77685
- if (deps[k]) p.stack.push(k);
77686
- }
77687
- } catch {
77688
- }
77689
- }
77690
- const pyproject = join27(root, "pyproject.toml");
77691
- if (existsSync23(pyproject)) {
77692
- try {
77693
- const txt = readFileSync22(pyproject, "utf8");
77694
- const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
77695
- p.languages.push("python");
77696
- p.stack.push(`python@${py ?? "3"}`);
77697
- const candidates = ["fastapi", "django", "flask", "mcp", "pytest"];
77698
- for (const k of candidates) {
77699
- if (new RegExp(`\\b${k}\\b`, "i").test(txt)) p.stack.push(k);
77700
- }
77701
- } catch {
77702
- }
77703
- }
77704
- const reqs = join27(root, "requirements.txt");
77705
- if (existsSync23(reqs)) {
77706
- if (!p.languages.includes("python")) p.languages.push("python");
77707
- if (!p.stack.includes("python@3")) p.stack.push("python@3");
77708
- }
77709
- if (existsSync23(join27(root, "go.mod"))) {
77710
- p.languages.push("go");
77711
- p.stack.push("go");
77712
- }
77713
- if (existsSync23(join27(root, "Cargo.toml"))) {
77714
- p.languages.push("rust");
77715
- p.stack.push("rust");
77716
- }
77717
- p.languages = [...new Set(p.languages)];
77718
- p.stack = [...new Set(p.stack)];
77719
- return p;
77720
- }
77745
+ init_profile2();
77721
77746
 
77722
77747
  // src/witness-queue.ts
77723
77748
  import { readFileSync as readFileSync23, renameSync as renameSync2, writeFileSync as writeFileSync18 } from "node:fs";
@@ -77918,7 +77943,9 @@ var CausalBuffer = class {
77918
77943
  };
77919
77944
 
77920
77945
  // src/engine.ts
77946
+ init_profile2();
77921
77947
  init_config();
77948
+ init_consent();
77922
77949
  init_cloud_auth();
77923
77950
 
77924
77951
  // src/notify.ts
@@ -78335,7 +78362,7 @@ function createWatchBreaker(deps) {
78335
78362
  }
78336
78363
 
78337
78364
  // src/engine.ts
78338
- var DAEMON_VERSION = true ? "2.0.6-dev.2564" : "2.0.0-alpha.0";
78365
+ var DAEMON_VERSION = true ? "2.0.6-dev.2568" : "2.0.0-alpha.0";
78339
78366
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
78340
78367
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
78341
78368
  var GIT_OP_MUTE_MS = 4e3;
@@ -78442,6 +78469,7 @@ function createWorkspaceEngine(opts) {
78442
78469
  } else {
78443
78470
  refreshRepoLocator(opts.workspaceRoot, profile);
78444
78471
  }
78472
+ const consentNow = () => effectiveConsent(loadConfig(), profile);
78445
78473
  const store = openGraphStore({ path: paths.castalia });
78446
78474
  const witnessLoad = loadWitnessQueueWithLosses(witnessQueuePath(paths.configDir));
78447
78475
  const witnessPrune = pruneWitnessQueueWithDispositions(witnessLoad.queue, Date.now());
@@ -78870,7 +78898,7 @@ function createWorkspaceEngine(opts) {
78870
78898
  // resolves each token against both the Package and Language namespaces,
78871
78899
  // and the profile keeps them in separate fields.
78872
78900
  languages: profile?.languages ?? [],
78873
- contributePackages: loadConfig().consent.contributePackages,
78901
+ contributePackages: consentNow().contributePackages,
78874
78902
  // `repoLocator` feeds the Maven self-disclosure rule ONLY: a groupId
78875
78903
  // carrying this project's own owner/repo token is the project naming
78876
78904
  // itself, not a library it depends on.
@@ -78881,7 +78909,7 @@ function createWorkspaceEngine(opts) {
78881
78909
  if (opts.skipContextWriter || remoteInFlight) return;
78882
78910
  const now = Date.now();
78883
78911
  if (now - lastRemoteAt < REMOTE_REFRESH_MS) return;
78884
- const syncOk = opts.syncConsent ?? loadConfig().consent.sync;
78912
+ const syncOk = opts.syncConsent ?? consentNow().sync;
78885
78913
  if (!syncOk) return;
78886
78914
  if (typeof cloud.search !== "function") return;
78887
78915
  remoteInFlight = true;
@@ -78921,7 +78949,7 @@ function createWorkspaceEngine(opts) {
78921
78949
  const maybeRefreshIntentPriors = (liveIntent) => {
78922
78950
  if (!liveIntent || opts.skipContextWriter || intentRemoteInFlight) return;
78923
78951
  if (intentRemote?.forIntent === liveIntent) return;
78924
- const syncOk = opts.syncConsent ?? loadConfig().consent.sync;
78952
+ const syncOk = opts.syncConsent ?? consentNow().sync;
78925
78953
  if (!syncOk) return;
78926
78954
  if (typeof cloud.search !== "function") return;
78927
78955
  intentRemoteInFlight = true;
@@ -80227,7 +80255,7 @@ B: ${b}`,
80227
80255
  });
80228
80256
  }
80229
80257
  const pullSkills = async () => {
80230
- if ((opts.syncConsent ?? loadConfig().consent.sync) === true) {
80258
+ if ((opts.syncConsent ?? consentNow().sync) === true) {
80231
80259
  for (const req of communityInductionRequests(store)) {
80232
80260
  try {
80233
80261
  const r = await cloud.induceSkill({ members: req.members, context: req.context });
@@ -80247,7 +80275,7 @@ B: ${b}`,
80247
80275
  const pins = profile?.projectId ? await cloud.getSkillPins(profile.projectId).then((r) => r.pins).catch(() => []) : [];
80248
80276
  const anchorMap = buildBucketTokenAnchors(
80249
80277
  profile.languages ?? [],
80250
- loadConfig().consent.contributePackages ? store.findNodesByLabel("Package").map((p) => ({
80278
+ consentNow().contributePackages ? store.findNodesByLabel("Package").map((p) => ({
80251
80279
  name: String(p.attrs["name"] ?? ""),
80252
80280
  purl: String(p.attrs["purl"] ?? p.id)
80253
80281
  })) : []
@@ -80553,7 +80581,7 @@ B: ${b}`,
80553
80581
  };
80554
80582
  },
80555
80583
  async syncNow() {
80556
- const syncOk = opts.syncConsent ?? loadConfig().consent.sync;
80584
+ const syncOk = opts.syncConsent ?? consentNow().sync;
80557
80585
  if (!syncOk) {
80558
80586
  console.log(
80559
80587
  "[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
@@ -80584,14 +80612,14 @@ B: ${b}`,
80584
80612
  }
80585
80613
  try {
80586
80614
  const freshCfg = loadConfig();
80587
- if (freshCfg.consent.telemetry) {
80615
+ if (consentNow().telemetry) {
80588
80616
  telemetry.event("graph_snapshot", store.nodeCount(), {
80589
80617
  problemsLive: store.findNodesByLabel("Problem").length
80590
80618
  });
80591
80619
  telemetry.event("heartbeat");
80592
80620
  }
80593
80621
  const t = await telemetry.flush(cloud, {
80594
- consent: freshCfg.consent.telemetry,
80622
+ consent: consentNow().telemetry,
80595
80623
  credentialPresent: Boolean(opts.apiKey) || hasCloudCredential(freshCfg)
80596
80624
  });
80597
80625
  if (t.sent > 0) {
@@ -80953,6 +80981,9 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
80953
80981
  };
80954
80982
  }
80955
80983
 
80984
+ // src/instance-ingest.ts
80985
+ init_profile2();
80986
+
80956
80987
  // src/public-symbols.ts
80957
80988
  import { readFileSync as readFileSync27, readdirSync as readdirSync11, existsSync as existsSync28 } from "node:fs";
80958
80989
  import { join as join32 } from "node:path";
@@ -81972,6 +82003,7 @@ function liveCloudClient(src) {
81972
82003
  init_identity2();
81973
82004
 
81974
82005
  // src/project-link.ts
82006
+ init_profile2();
81975
82007
  async function ensureProjectLink(root, profile, client) {
81976
82008
  if (profile.projectLinkDisabled) return { linked: false, reason: "disabled" };
81977
82009
  const locator = profile.repoLocator;
@@ -81996,10 +82028,12 @@ async function ensureProjectLink(root, profile, client) {
81996
82028
 
81997
82029
  // src/project-hydrate.ts
81998
82030
  init_src11();
82031
+ init_profile2();
81999
82032
 
82000
82033
  // src/project-reanchor.ts
82001
82034
  init_src();
82002
82035
  init_src11();
82036
+ init_profile2();
82003
82037
  var DEFAULT_LIMIT = 50;
82004
82038
  var ANCHOR_SYMBOL_KINDS2 = [
82005
82039
  "Function",
@@ -83715,6 +83749,7 @@ async function buildUnitBundle(root, unit, opts = {}) {
83715
83749
  }
83716
83750
 
83717
83751
  // src/project-history.ts
83752
+ init_profile2();
83718
83753
  var execFileAsync = promisify(execFile3);
83719
83754
  var HISTORY_EXTRACTOR_VERSION = "history-1";
83720
83755
  var LEASE_POLL_MS = 2e4;
@@ -84455,18 +84490,16 @@ fixtures/
84455
84490
  *.sql.gz
84456
84491
  `;
84457
84492
  function applyConsents(profile, config2, c, decidedAt, now = Date.now) {
84458
- const nextConfig = {
84459
- ...config2,
84460
- consent: {
84461
- ...config2.consent,
84462
- sync: c.sync !== "off",
84463
- telemetry: c.telemetry,
84464
- contributePackages: c.packages && c.sync !== "off"
84465
- },
84466
- onboardedAt: config2.onboardedAt ?? now()
84493
+ const nextConfig = { ...config2, onboardedAt: config2.onboardedAt ?? now() };
84494
+ const consoleConsents = {
84495
+ sync: c.sync !== "off",
84496
+ telemetry: c.telemetry,
84497
+ contributePackages: c.packages && c.sync !== "off",
84498
+ decidedAt
84467
84499
  };
84468
84500
  const nextProfile = {
84469
84501
  ...profile,
84502
+ consoleConsents,
84470
84503
  syncConsent: c.sync === "automatic" ? "automatic" : c.sync === "ask" ? "ask-each-time" : "disabled",
84471
84504
  linkConsents: {
84472
84505
  structure: c.structure,
@@ -84476,7 +84509,8 @@ function applyConsents(profile, config2, c, decidedAt, now = Date.now) {
84476
84509
  }
84477
84510
  };
84478
84511
  const prev = profile.linkConsents;
84479
- const changed = profile.syncConsent !== nextProfile.syncConsent || config2.consent.sync !== nextConfig.consent.sync || config2.consent.telemetry !== nextConfig.consent.telemetry || config2.consent.contributePackages !== nextConfig.consent.contributePackages || !prev || prev.structure !== nextProfile.linkConsents.structure || prev.mineHistory !== nextProfile.linkConsents.mineHistory || prev.contributeHistory !== nextProfile.linkConsents.contributeHistory;
84512
+ const prevConsole = profile.consoleConsents;
84513
+ const changed = profile.syncConsent !== nextProfile.syncConsent || prevConsole?.sync !== consoleConsents.sync || prevConsole?.telemetry !== consoleConsents.telemetry || prevConsole?.contributePackages !== consoleConsents.contributePackages || !prev || prev.structure !== nextProfile.linkConsents.structure || prev.mineHistory !== nextProfile.linkConsents.mineHistory || prev.contributeHistory !== nextProfile.linkConsents.contributeHistory;
84480
84514
  return { profile: nextProfile, config: nextConfig, changed };
84481
84515
  }
84482
84516
  function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
@@ -84500,6 +84534,7 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
84500
84534
  }
84501
84535
 
84502
84536
  // src/multi.ts
84537
+ init_consent();
84503
84538
  init_registry();
84504
84539
 
84505
84540
  // src/adopt.ts
@@ -84696,6 +84731,9 @@ function codexWakeCandidates(input) {
84696
84731
  return out2;
84697
84732
  }
84698
84733
 
84734
+ // src/multi.ts
84735
+ init_profile2();
84736
+
84699
84737
  // src/hook-route.ts
84700
84738
  function msysToWindowsPath(p, platform = process.platform) {
84701
84739
  if (platform !== "win32") return p;
@@ -85512,11 +85550,11 @@ async function startMultiDaemon(opts = {}) {
85512
85550
  const ANCHOR_PULL_INTERVAL_MS = 10 * 60 * 1e3;
85513
85551
  const anchorPullAll = async () => {
85514
85552
  const c = loadConfig();
85515
- if (!c.consent.sync || !hasCloudCredential(c)) return;
85553
+ if (!hasCloudCredential(c)) return;
85516
85554
  const client = cloudNow();
85517
85555
  for (const r of records) {
85518
85556
  const projectId = r.engine.profile.projectId;
85519
- if (!projectId) continue;
85557
+ if (!projectId || !effectiveConsent(c, r.engine.profile).sync) continue;
85520
85558
  try {
85521
85559
  const { salt } = await resolveProjectSymbolSalt(client, projectId);
85522
85560
  await pullProjectAnchors(r, client, salt);
@@ -85530,9 +85568,10 @@ async function startMultiDaemon(opts = {}) {
85530
85568
  }, ANCHOR_PULL_INTERVAL_MS);
85531
85569
  const ambientLinkAll = async () => {
85532
85570
  const c = loadConfig();
85533
- if (!c.consent.sync || !hasCloudCredential(c)) return;
85571
+ if (!hasCloudCredential(c)) return;
85534
85572
  const client = cloudNow();
85535
85573
  for (const r of records) {
85574
+ if (!effectiveConsent(c, r.engine.profile).sync) continue;
85536
85575
  const out2 = await ensureProjectLink(r.root, r.engine.profile, client);
85537
85576
  if (out2.linked) {
85538
85577
  console.log(
@@ -85599,14 +85638,14 @@ async function startMultiDaemon(opts = {}) {
85599
85638
  };
85600
85639
  void startHistoryStage(root, engine.profile, client, {
85601
85640
  anchors: { index: anchorIndex, salt },
85602
- // PS-web projects: the console's consents (Privacy tab) win over
85603
- // the profile's memory; applied to config and profile here, with
85641
+ // PS-web projects: the console's consents (Privacy tab) are this
85642
+ // project's, applied to ITS profile only (DC-consent-scope), with
85604
85643
  // the change printed so a flipped switch is visible in the log.
85605
85644
  applyConsents: (p, consents) => {
85606
85645
  const cfg2 = loadConfig();
85607
85646
  const applied = applyConsents(p, cfg2, consents, (/* @__PURE__ */ new Date()).toISOString());
85608
85647
  if (applied.changed) {
85609
- saveConfig(applied.config);
85648
+ if (applied.config.onboardedAt !== cfg2.onboardedAt) saveConfig(applied.config);
85610
85649
  Object.assign(engine.profile, applied.profile);
85611
85650
  saveProfile(root, engine.profile);
85612
85651
  console.log(
@@ -85888,7 +85927,7 @@ async function startMultiDaemon(opts = {}) {
85888
85927
  const ignore2 = loadClaimIgnorePatterns(globalDir());
85889
85928
  const primaryLanguage = machineDominantLanguage();
85890
85929
  const languages = records.flatMap((r) => r.engine.profile.languages ?? []);
85891
- const packages = cfg2.consent.contributePackages ? records.flatMap(
85930
+ const packages = cfg2.consent.contributePackages ? records.filter((r) => effectiveConsent(cfg2, r.engine.profile).contributePackages).flatMap(
85892
85931
  (r) => r.engine.store.findNodesByLabel("Package").map((p) => ({
85893
85932
  name: String(p.attrs["name"] ?? ""),
85894
85933
  purl: String(p.attrs["purl"] ?? p.id)
@@ -85907,7 +85946,9 @@ async function startMultiDaemon(opts = {}) {
85907
85946
  },
85908
85947
  async syncInstancesPublic() {
85909
85948
  const cfg2 = loadConfig();
85910
- if (!cfg2.consent.sync) return { uploaded: 0, skipped: "consent-off" };
85949
+ if (!records.some((r) => effectiveConsent(cfg2, r.engine.profile).sync)) {
85950
+ return { uploaded: 0, skipped: "consent-off" };
85951
+ }
85911
85952
  if (registryCorrupt()) {
85912
85953
  const msg = "workspace registry unreadable \u2014 holding ALL per-workspace cloud push (bindings unprovable; fail-closed)";
85913
85954
  console.error(`[identity] ${msg}`);
@@ -85983,6 +86024,8 @@ async function startMultiDaemon(opts = {}) {
85983
86024
  }
85984
86025
  };
85985
86026
  for (const r of records) {
86027
+ const recordConsent = effectiveConsent(cfg2, r.engine.profile);
86028
+ if (!recordConsent.sync) continue;
85986
86029
  const recordIdentity = identityFor(liveWorkspaceEntry(r.entry));
85987
86030
  if (recordIdentity.invalid) {
85988
86031
  noteIdentityBlock(r.id, r.entry.name, recordIdentity);
@@ -86018,7 +86061,7 @@ async function startMultiDaemon(opts = {}) {
86018
86061
  profile: r.engine.profile,
86019
86062
  daemonVersion: DAEMON_VERSION,
86020
86063
  ignorePatterns: [...ignore2],
86021
- includePackages: cfg2.consent.contributePackages
86064
+ includePackages: recordConsent.contributePackages
86022
86065
  });
86023
86066
  if (context) {
86024
86067
  await lane("context", projectName, async () => {
@@ -86049,7 +86092,7 @@ async function startMultiDaemon(opts = {}) {
86049
86092
  profile: r.engine.profile,
86050
86093
  daemonVersion: DAEMON_VERSION,
86051
86094
  ignorePatterns: [...ignore2],
86052
- includePackages: cfg2.consent.contributePackages,
86095
+ includePackages: recordConsent.contributePackages,
86053
86096
  workspaceRoot: r.root,
86054
86097
  ...project ? { project } : {}
86055
86098
  });
@@ -86365,6 +86408,8 @@ async function startMultiDaemon(opts = {}) {
86365
86408
 
86366
86409
  // src/cli.ts
86367
86410
  init_src5();
86411
+ init_profile2();
86412
+ init_consent();
86368
86413
  init_git_remote();
86369
86414
  init_config();
86370
86415
  init_src7();
@@ -87707,8 +87752,14 @@ async function cmdStatus() {
87707
87752
  );
87708
87753
  const cs = cfg.consent;
87709
87754
  console.log(
87710
- ` consent: sync ${cs.sync ? "on" : "off"} \xB7 telemetry ${cs.telemetry ? "on" : "off"} \xB7 packages ${cs.contributePackages ? "on" : "off"}`
87755
+ ` consent: sync ${cs.sync ? "on" : "off"} \xB7 telemetry ${cs.telemetry ? "on" : "off"} \xB7 packages ${cs.contributePackages ? "on" : "off"} (machine default)`
87711
87756
  );
87757
+ const pc = profile?.consoleConsents;
87758
+ if (pc) {
87759
+ console.log(
87760
+ ` this project (console): sync ${pc.sync ? "on" : "off"} \xB7 telemetry ${pc.telemetry ? "on" : "off"} \xB7 packages ${pc.contributePackages ? "on" : "off"}`
87761
+ );
87762
+ }
87712
87763
  console.log(` cloud:`);
87713
87764
  console.log(` url: ${cfg.cloudUrl}`);
87714
87765
  if (daemonCloud) {
@@ -88157,12 +88208,11 @@ async function cmdLoginOAuthDevice(cfg, input) {
88157
88208
  }
88158
88209
  }
88159
88210
  async function linkRegisteredWorkspaces(cfg) {
88160
- if (!cfg.consent.sync) return;
88161
88211
  const client = authedCloudClient(cfg);
88162
88212
  for (const w of listWorkspaces()) {
88163
88213
  try {
88164
88214
  const profile = loadProfile(w.path);
88165
- if (!profile) continue;
88215
+ if (!profile || !effectiveConsent(cfg, profile).sync) continue;
88166
88216
  refreshRepoLocator(w.path, profile);
88167
88217
  const out2 = await ensureProjectLink(w.path, profile, client);
88168
88218
  if (out2.linked) {
@@ -88247,7 +88297,7 @@ async function cmdLink(args2) {
88247
88297
  `linked${d.existed ? "" : " (created)"}: ${d.locator} \u2192 project ${d.projectId} \xB7 ${where} \xB7 ${d.visibility} \xB7 grant v${d.grantVersion}`
88248
88298
  );
88249
88299
  console.log(
88250
- `consents: sync=${d.consents.sync} telemetry=${d.consents.telemetry ? "on" : "off"} packages=${applied.config.consent.contributePackages ? "on" : "off"} structure=${d.consents.structure ? "on" : "off"} history=${d.consents.mineHistory ? applied.profile.linkConsents?.contributeHistory ? "mine+contribute" : "mine" : "off"}`
88300
+ `consents (this project): sync=${d.consents.sync} telemetry=${d.consents.telemetry ? "on" : "off"} packages=${applied.profile.consoleConsents?.contributePackages ? "on" : "off"} structure=${d.consents.structure ? "on" : "off"} history=${d.consents.mineHistory ? applied.profile.linkConsents?.contributeHistory ? "mine+contribute" : "mine" : "off"}`
88251
88301
  );
88252
88302
  await refreshLinkedCodexHooks(args2);
88253
88303
  if (applied.wroteIgnore) console.log("wrote .errataignore (starter) \u2014 edit it; it is your hard control");