@inerrata-corporation/errata 2.0.6-dev.2563 → 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 +480 -427
  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;
@@ -29234,6 +29357,9 @@ function workspaceEntryForPath(absPath) {
29234
29357
  }
29235
29358
  return best;
29236
29359
  }
29360
+ function liveWorkspaceEntry(entry) {
29361
+ return read().workspaces[entry.id] ?? entry;
29362
+ }
29237
29363
  function boundWorkspaceEntries() {
29238
29364
  return Object.values(read().workspaces).filter((e) => e.installationProfile);
29239
29365
  }
@@ -29241,7 +29367,7 @@ function pruneMissingWorkspaces() {
29241
29367
  const reg = read();
29242
29368
  const removed = [];
29243
29369
  for (const [id, entry] of Object.entries(reg.workspaces)) {
29244
- if (!existsSync10(entry.path)) {
29370
+ if (!existsSync11(entry.path)) {
29245
29371
  removed.push(entry);
29246
29372
  delete reg.workspaces[id];
29247
29373
  }
@@ -29250,13 +29376,13 @@ function pruneMissingWorkspaces() {
29250
29376
  return removed;
29251
29377
  }
29252
29378
  function workspaceStatus(entry) {
29253
- const missing = !existsSync10(entry.path);
29379
+ const missing = !existsSync11(entry.path);
29254
29380
  const lockPath = workspacePaths(entry.path).daemonLock;
29255
29381
  let running = false;
29256
29382
  let webUiUrl = null;
29257
- if (existsSync10(lockPath)) {
29383
+ if (existsSync11(lockPath)) {
29258
29384
  try {
29259
- const lock = JSON.parse(readFileSync8(lockPath, "utf8"));
29385
+ const lock = JSON.parse(readFileSync9(lockPath, "utf8"));
29260
29386
  if (lock.pid && lock.webUiUrl && pidAlive(lock.pid)) {
29261
29387
  running = true;
29262
29388
  webUiUrl = lock.webUiUrl;
@@ -30710,7 +30836,7 @@ var init_diagnostic_matcher = __esm({
30710
30836
  });
30711
30837
 
30712
30838
  // ../../packages/generalizer/src/generalizer.ts
30713
- import { isAbsolute as isAbsolute3, join as join9, relative } from "node:path";
30839
+ import { isAbsolute as isAbsolute3, join as join10, relative } from "node:path";
30714
30840
  async function runGeneralizer(opts) {
30715
30841
  const report = {
30716
30842
  eventsProcessed: 0,
@@ -30818,7 +30944,7 @@ function extractDiagnostics(ev) {
30818
30944
  function diagRelPath(file2, cwd, workspaceRoot) {
30819
30945
  const norm = (p) => p.replace(/\\/g, "/");
30820
30946
  if (!workspaceRoot) return norm(file2);
30821
- const abs = isAbsolute3(file2) ? file2 : join9(cwd ?? workspaceRoot, file2);
30947
+ const abs = isAbsolute3(file2) ? file2 : join10(cwd ?? workspaceRoot, file2);
30822
30948
  return norm(relative(workspaceRoot, abs));
30823
30949
  }
30824
30950
  function extractErrorSignature(ev) {
@@ -32460,23 +32586,23 @@ var init_src10 = __esm({
32460
32586
  });
32461
32587
 
32462
32588
  // ../../packages/indexer/src/parse-cache.ts
32463
- import { createHash as createHash3 } from "node:crypto";
32464
- 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";
32465
32591
  import { homedir as homedir3 } from "node:os";
32466
- import { join as join10 } from "node:path";
32592
+ import { join as join11 } from "node:path";
32467
32593
  function parseCacheDir() {
32468
- return process.env["ERRATA_PARSE_CACHE"] ?? join10(homedir3(), ".errata", "parse-cache");
32594
+ return process.env["ERRATA_PARSE_CACHE"] ?? join11(homedir3(), ".errata", "parse-cache");
32469
32595
  }
32470
32596
  function parseCacheKey(source, providerId) {
32471
- return createHash3("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
32597
+ return createHash4("sha256").update(`${PARSE_CACHE_VERSION}:${providerId}:${source}`).digest("hex");
32472
32598
  }
32473
32599
  function entryPath(dir, key) {
32474
- return join10(dir, key.slice(0, 2), `${key.slice(2)}.json`);
32600
+ return join11(dir, key.slice(0, 2), `${key.slice(2)}.json`);
32475
32601
  }
32476
32602
  function readParseCache(dir, key) {
32477
32603
  const file2 = entryPath(dir, key);
32478
32604
  try {
32479
- const raw2 = readFileSync9(file2, "utf8");
32605
+ const raw2 = readFileSync10(file2, "utf8");
32480
32606
  const parsed = JSON.parse(raw2);
32481
32607
  if (parsed.v !== PARSE_CACHE_VERSION || !Array.isArray(parsed.symbols)) return null;
32482
32608
  return { symbols: parsed.symbols, reExports: parsed.reExports ?? [] };
@@ -32495,8 +32621,8 @@ function writeParseCache(dir, key, providerId, value) {
32495
32621
  const body2 = JSON.stringify(envelope);
32496
32622
  if (body2.length > MAX_ENTRY_BYTES) return;
32497
32623
  const file2 = entryPath(dir, key);
32498
- mkdirSync6(join10(dir, key.slice(0, 2)), { recursive: true });
32499
- writeFileSync8(file2, body2);
32624
+ mkdirSync6(join11(dir, key.slice(0, 2)), { recursive: true });
32625
+ writeFileSync9(file2, body2);
32500
32626
  } catch {
32501
32627
  }
32502
32628
  }
@@ -32505,9 +32631,9 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
32505
32631
  sweptThisProcess = true;
32506
32632
  let removed = 0;
32507
32633
  try {
32508
- if (!existsSync11(dir)) return 0;
32634
+ if (!existsSync12(dir)) return 0;
32509
32635
  for (const bucket of readdirSync2(dir)) {
32510
- const bucketDir = join10(dir, bucket);
32636
+ const bucketDir = join11(dir, bucket);
32511
32637
  let names;
32512
32638
  try {
32513
32639
  names = readdirSync2(bucketDir);
@@ -32515,7 +32641,7 @@ function sweepParseCacheOnce(dir, now = Date.now()) {
32515
32641
  continue;
32516
32642
  }
32517
32643
  for (const name2 of names) {
32518
- const file2 = join10(bucketDir, name2);
32644
+ const file2 = join11(bucketDir, name2);
32519
32645
  try {
32520
32646
  if (now - statSync2(file2).mtimeMs > ENTRY_TTL_MS) {
32521
32647
  rmSync2(file2, { force: true });
@@ -32763,10 +32889,10 @@ var init_identity3 = __esm({
32763
32889
  });
32764
32890
 
32765
32891
  // ../../packages/indexer/src/pipeline.ts
32766
- import { appendFileSync, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
32892
+ import { appendFileSync, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
32767
32893
  import { readdir } from "node:fs/promises";
32768
- import { extname, join as join11, relative as relative2, sep } from "node:path";
32769
- 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";
32770
32896
  import { execFileSync } from "node:child_process";
32771
32897
  function nowTs() {
32772
32898
  return indexNow ?? Date.now();
@@ -32775,7 +32901,7 @@ function fingerprintOf(signature, bodyHash) {
32775
32901
  return `${signature ?? ""}|${bodyHash ?? ""}`;
32776
32902
  }
32777
32903
  function sha(s) {
32778
- return createHash4("sha256").update(s).digest("hex").slice(0, 16);
32904
+ return createHash5("sha256").update(s).digest("hex").slice(0, 16);
32779
32905
  }
32780
32906
  function fileNodeId(workspaceId2, relPath) {
32781
32907
  return `file_${sha(workspaceId2 + ":" + relPath.replace(/\\/g, "/"))}`;
@@ -32903,7 +33029,7 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
32903
33029
  for (const rel of [...changedRelPaths]) {
32904
33030
  let h;
32905
33031
  try {
32906
- h = createHash4("sha256").update(readFileSync10(join11(rootPath, rel))).digest("hex");
33032
+ h = createHash5("sha256").update(readFileSync11(join12(rootPath, rel))).digest("hex");
32907
33033
  } catch {
32908
33034
  continue;
32909
33035
  }
@@ -32952,13 +33078,13 @@ async function incrementalReindex(store, rootPath, workspaceId2, changedAbsPaths
32952
33078
  let parsedFiles = 0;
32953
33079
  for (const rel of changedRelPaths) {
32954
33080
  if (parsedFiles++ > 0) await new Promise((r2) => setImmediate(r2));
32955
- const abs = join11(rootPath, ...rel.split("/"));
33081
+ const abs = join12(rootPath, ...rel.split("/"));
32956
33082
  const ext = extname(abs).toLowerCase();
32957
33083
  const provider = providers.find((p) => p.fileExtensions.includes(ext));
32958
33084
  if (!provider) continue;
32959
33085
  let symbols;
32960
33086
  try {
32961
- symbols = provider.extractSymbols(readFileSync10(abs, "utf8"), abs);
33087
+ symbols = provider.extractSymbols(readFileSync11(abs, "utf8"), abs);
32962
33088
  } catch {
32963
33089
  continue;
32964
33090
  }
@@ -33278,7 +33404,7 @@ async function runIndexer(store, opts) {
33278
33404
  report.filesSkipped++;
33279
33405
  continue;
33280
33406
  }
33281
- source = readFileSync10(f.absPath, "utf8");
33407
+ source = readFileSync11(f.absPath, "utf8");
33282
33408
  } catch {
33283
33409
  report.filesSkipped++;
33284
33410
  continue;
@@ -33350,7 +33476,7 @@ async function runIndexer(store, opts) {
33350
33476
  const depth = fileNode.relPath.split("/").length;
33351
33477
  if (depth !== 3) continue;
33352
33478
  try {
33353
- const pkg = JSON.parse(readFileSync10(fileNode.absPath, "utf8"));
33479
+ const pkg = JSON.parse(readFileSync11(fileNode.absPath, "utf8"));
33354
33480
  if (!pkg.name) continue;
33355
33481
  const pkgDir = fileNode.relPath.replace(/\/package\.json$/, "");
33356
33482
  const candidates = [
@@ -33738,7 +33864,7 @@ async function scan(root, current, ignores, providers, out2) {
33738
33864
  for (const ent of entries) {
33739
33865
  if (ignores.has(ent.name)) continue;
33740
33866
  if (ent.name.startsWith(".") && ent.name !== ".") continue;
33741
- const abs = join11(current, ent.name);
33867
+ const abs = join12(current, ent.name);
33742
33868
  if (ent.isDirectory()) {
33743
33869
  await scan(root, abs, ignores, providers, out2);
33744
33870
  } else if (ent.isFile()) {
@@ -33793,7 +33919,7 @@ function gitListFiles(root, ignores, providers) {
33793
33919
  if (rels === null) return null;
33794
33920
  const out2 = [];
33795
33921
  for (const rel of rels) {
33796
- const abs = join11(root, rel);
33922
+ const abs = join12(root, rel);
33797
33923
  let size;
33798
33924
  try {
33799
33925
  size = statSync3(abs).size;
@@ -33816,7 +33942,7 @@ function upsertFile(store, id, f, workspaceId2, skip) {
33816
33942
  const now = nowTs();
33817
33943
  let contentHash;
33818
33944
  try {
33819
- contentHash = createHash4("sha256").update(readFileSync10(f.absPath)).digest("hex");
33945
+ contentHash = createHash5("sha256").update(readFileSync11(f.absPath)).digest("hex");
33820
33946
  } catch {
33821
33947
  }
33822
33948
  const carried = { ...store.getNode(id)?.attrs ?? {} };
@@ -38189,8 +38315,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
38189
38315
 
38190
38316
  // ../../packages/indexer/src/languages/tree-sitter-loader.ts
38191
38317
  import { fileURLToPath } from "node:url";
38192
- import { dirname as dirname7, join as join12 } from "node:path";
38193
- 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";
38194
38320
  import { createRequire as createRequire2 } from "node:module";
38195
38321
  function entryDir() {
38196
38322
  try {
@@ -38204,27 +38330,27 @@ function entryDir() {
38204
38330
  }
38205
38331
  function findWasmDir() {
38206
38332
  const here = entryDir();
38207
- const seaWasm = join12(here, "resources", "wasm");
38208
- 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;
38209
38335
  let dir = here;
38210
38336
  for (let i2 = 0; i2 < 6; i2++) {
38211
- const flat = join12(
38337
+ const flat = join13(
38212
38338
  dir,
38213
38339
  "node_modules",
38214
38340
  "@vscode",
38215
38341
  "tree-sitter-wasm",
38216
38342
  "wasm"
38217
38343
  );
38218
- if (existsSync12(join12(flat, "tree-sitter-typescript.wasm"))) return flat;
38344
+ if (existsSync13(join13(flat, "tree-sitter-typescript.wasm"))) return flat;
38219
38345
  dir = dirname7(dir);
38220
38346
  }
38221
38347
  let root = here;
38222
38348
  for (let i2 = 0; i2 < 6; i2++) {
38223
- const pnpmDir = join12(root, "node_modules", ".pnpm");
38224
- if (existsSync12(pnpmDir)) {
38349
+ const pnpmDir = join13(root, "node_modules", ".pnpm");
38350
+ if (existsSync13(pnpmDir)) {
38225
38351
  for (const entry of readdirSync3(pnpmDir)) {
38226
38352
  if (entry.startsWith("@vscode+tree-sitter-wasm@")) {
38227
- const candidate = join12(
38353
+ const candidate = join13(
38228
38354
  pnpmDir,
38229
38355
  entry,
38230
38356
  "node_modules",
@@ -38232,7 +38358,7 @@ function findWasmDir() {
38232
38358
  "tree-sitter-wasm",
38233
38359
  "wasm"
38234
38360
  );
38235
- if (existsSync12(join12(candidate, "tree-sitter-typescript.wasm"))) {
38361
+ if (existsSync13(join13(candidate, "tree-sitter-typescript.wasm"))) {
38236
38362
  return candidate;
38237
38363
  }
38238
38364
  }
@@ -38246,27 +38372,27 @@ function findWasmDir() {
38246
38372
  }
38247
38373
  function findRuntimeDir() {
38248
38374
  const here = entryDir();
38249
- const seaRuntime = join12(here, "resources", "wasm");
38250
- 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;
38251
38377
  let dir = here;
38252
38378
  for (let i2 = 0; i2 < 6; i2++) {
38253
- const flat = join12(dir, "node_modules", "web-tree-sitter");
38254
- 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;
38255
38381
  dir = dirname7(dir);
38256
38382
  }
38257
38383
  let root = here;
38258
38384
  for (let i2 = 0; i2 < 6; i2++) {
38259
- const pnpmDir = join12(root, "node_modules", ".pnpm");
38260
- if (existsSync12(pnpmDir)) {
38385
+ const pnpmDir = join13(root, "node_modules", ".pnpm");
38386
+ if (existsSync13(pnpmDir)) {
38261
38387
  for (const entry of readdirSync3(pnpmDir)) {
38262
38388
  if (entry.startsWith("web-tree-sitter@")) {
38263
- const candidate = join12(
38389
+ const candidate = join13(
38264
38390
  pnpmDir,
38265
38391
  entry,
38266
38392
  "node_modules",
38267
38393
  "web-tree-sitter"
38268
38394
  );
38269
- if (existsSync12(join12(candidate, "web-tree-sitter.wasm"))) {
38395
+ if (existsSync13(join13(candidate, "web-tree-sitter.wasm"))) {
38270
38396
  return candidate;
38271
38397
  }
38272
38398
  }
@@ -38283,7 +38409,7 @@ async function loadWebTreeSitter() {
38283
38409
  void err2;
38284
38410
  }
38285
38411
  const here = entryDir();
38286
- const seaResourceBase = join12(here, "resources", "_resolve.js");
38412
+ const seaResourceBase = join13(here, "resources", "_resolve.js");
38287
38413
  const resourceRequire = createRequire2(seaResourceBase);
38288
38414
  return resourceRequire("web-tree-sitter");
38289
38415
  }
@@ -38298,9 +38424,9 @@ async function ensureTreeSitterReady() {
38298
38424
  await Parser2.init({
38299
38425
  locateFile: (name2) => {
38300
38426
  if (name2 === "tree-sitter.wasm" || name2 === "web-tree-sitter.wasm") {
38301
- return join12(runtime, name2);
38427
+ return join13(runtime, name2);
38302
38428
  }
38303
- return join12(grammars, name2);
38429
+ return join13(grammars, name2);
38304
38430
  }
38305
38431
  });
38306
38432
  })();
@@ -38312,7 +38438,7 @@ async function loadGrammar(name2) {
38312
38438
  if (cached2) return cached2;
38313
38439
  if (!languageClass) throw new Error("tree-sitter not initialized");
38314
38440
  const grammars = findWasmDir();
38315
- const lang = await languageClass.load(join12(grammars, `${name2}.wasm`));
38441
+ const lang = await languageClass.load(join13(grammars, `${name2}.wasm`));
38316
38442
  grammarCache.set(name2, lang);
38317
38443
  return lang;
38318
38444
  }
@@ -38335,7 +38461,7 @@ var init_tree_sitter_loader = __esm({
38335
38461
  });
38336
38462
 
38337
38463
  // ../../packages/indexer/src/languages/typescript-treesitter.ts
38338
- import { createHash as createHash5 } from "node:crypto";
38464
+ import { createHash as createHash6 } from "node:crypto";
38339
38465
  function extractNode(node2, source, containerQname, containerKind) {
38340
38466
  switch (node2.type) {
38341
38467
  case "function_declaration":
@@ -38548,7 +38674,7 @@ function scopeRecord(kind, name2, qname, node2, body2, source) {
38548
38674
  const sig = header.replace(/\s+/g, " ").trim();
38549
38675
  if (sig) rec.signature = sig;
38550
38676
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
38551
- rec.bodyHash = createHash5("sha256").update(bodyText).digest("hex").slice(0, 16);
38677
+ rec.bodyHash = createHash6("sha256").update(bodyText).digest("hex").slice(0, 16);
38552
38678
  rec.bodySimhash = toHex(simhash(bodyText));
38553
38679
  }
38554
38680
  }
@@ -38990,14 +39116,14 @@ var init_typescript_treesitter = __esm({
38990
39116
  });
38991
39117
 
38992
39118
  // ../../packages/indexer/src/languages/python-treesitter.ts
38993
- import { createHash as createHash6 } from "node:crypto";
39119
+ import { createHash as createHash7 } from "node:crypto";
38994
39120
  function sigAndHash(node2, body2, source) {
38995
39121
  if (!body2) return {};
38996
39122
  const out2 = {};
38997
39123
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
38998
39124
  if (sig) out2.signature = sig;
38999
39125
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
39000
- out2.bodyHash = createHash6("sha256").update(bodyText).digest("hex").slice(0, 16);
39126
+ out2.bodyHash = createHash7("sha256").update(bodyText).digest("hex").slice(0, 16);
39001
39127
  out2.bodySimhash = toHex(simhash(bodyText));
39002
39128
  return out2;
39003
39129
  }
@@ -39410,7 +39536,7 @@ var init_python_treesitter = __esm({
39410
39536
  });
39411
39537
 
39412
39538
  // ../../packages/indexer/src/languages/cpp-treesitter.ts
39413
- import { createHash as createHash7 } from "node:crypto";
39539
+ import { createHash as createHash8 } from "node:crypto";
39414
39540
  function extractNode3(node2, containerQname, containerIsClass, source) {
39415
39541
  switch (node2.type) {
39416
39542
  case "function_definition":
@@ -39594,7 +39720,7 @@ function sigAndHash2(node2, body2, source) {
39594
39720
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
39595
39721
  if (sig) out2.signature = sig;
39596
39722
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
39597
- out2.bodyHash = createHash7("sha256").update(bodyText).digest("hex").slice(0, 16);
39723
+ out2.bodyHash = createHash8("sha256").update(bodyText).digest("hex").slice(0, 16);
39598
39724
  out2.bodySimhash = toHex(simhash(bodyText));
39599
39725
  return out2;
39600
39726
  }
@@ -39755,7 +39881,7 @@ var init_cpp_treesitter = __esm({
39755
39881
  });
39756
39882
 
39757
39883
  // ../../packages/indexer/src/languages/go-treesitter.ts
39758
- import { createHash as createHash8 } from "node:crypto";
39884
+ import { createHash as createHash9 } from "node:crypto";
39759
39885
  function extractNode4(node2, containerQname, source) {
39760
39886
  switch (node2.type) {
39761
39887
  case "function_declaration": {
@@ -39917,7 +40043,7 @@ function sigAndHash3(node2, body2, source) {
39917
40043
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
39918
40044
  if (sig) out2.signature = sig;
39919
40045
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
39920
- out2.bodyHash = createHash8("sha256").update(bodyText).digest("hex").slice(0, 16);
40046
+ out2.bodyHash = createHash9("sha256").update(bodyText).digest("hex").slice(0, 16);
39921
40047
  out2.bodySimhash = toHex(simhash(bodyText));
39922
40048
  return out2;
39923
40049
  }
@@ -40061,7 +40187,7 @@ var init_go_treesitter = __esm({
40061
40187
  });
40062
40188
 
40063
40189
  // ../../packages/indexer/src/languages/rust-treesitter.ts
40064
- import { createHash as createHash9 } from "node:crypto";
40190
+ import { createHash as createHash10 } from "node:crypto";
40065
40191
  function extractNode5(node2, containerQname, containerIsClass, source) {
40066
40192
  switch (node2.type) {
40067
40193
  case "function_item":
@@ -40276,7 +40402,7 @@ function sigAndHash4(node2, body2, source) {
40276
40402
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
40277
40403
  if (sig) out2.signature = sig;
40278
40404
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
40279
- out2.bodyHash = createHash9("sha256").update(bodyText).digest("hex").slice(0, 16);
40405
+ out2.bodyHash = createHash10("sha256").update(bodyText).digest("hex").slice(0, 16);
40280
40406
  out2.bodySimhash = toHex(simhash(bodyText));
40281
40407
  return out2;
40282
40408
  }
@@ -40427,7 +40553,7 @@ var init_rust_treesitter = __esm({
40427
40553
  });
40428
40554
 
40429
40555
  // ../../packages/indexer/src/languages/ruby-treesitter.ts
40430
- import { createHash as createHash10 } from "node:crypto";
40556
+ import { createHash as createHash11 } from "node:crypto";
40431
40557
  function sigAndHash5(node2, body2, source) {
40432
40558
  if (!body2) {
40433
40559
  const sig2 = source.slice(node2.startIndex, node2.endIndex).replace(/\s+/g, " ").trim();
@@ -40437,7 +40563,7 @@ function sigAndHash5(node2, body2, source) {
40437
40563
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
40438
40564
  if (sig) out2.signature = sig;
40439
40565
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
40440
- out2.bodyHash = createHash10("sha256").update(bodyText).digest("hex").slice(0, 16);
40566
+ out2.bodyHash = createHash11("sha256").update(bodyText).digest("hex").slice(0, 16);
40441
40567
  out2.bodySimhash = toHex(simhash(bodyText));
40442
40568
  return out2;
40443
40569
  }
@@ -40783,7 +40909,7 @@ var init_ruby_treesitter = __esm({
40783
40909
  });
40784
40910
 
40785
40911
  // ../../packages/indexer/src/languages/csharp-treesitter.ts
40786
- import { createHash as createHash11 } from "node:crypto";
40912
+ import { createHash as createHash12 } from "node:crypto";
40787
40913
  function extractNode7(node2, containerQname, containerIsType, source, eof) {
40788
40914
  switch (node2.type) {
40789
40915
  case "method_declaration":
@@ -40985,7 +41111,7 @@ function sigAndHash6(node2, body2, source) {
40985
41111
  const sig = source.slice(node2.startIndex, body2.startIndex).replace(/\s+/g, " ").trim();
40986
41112
  if (sig) out2.signature = sig;
40987
41113
  const bodyText = source.slice(body2.startIndex, body2.endIndex);
40988
- out2.bodyHash = createHash11("sha256").update(bodyText).digest("hex").slice(0, 16);
41114
+ out2.bodyHash = createHash12("sha256").update(bodyText).digest("hex").slice(0, 16);
40989
41115
  out2.bodySimhash = toHex(simhash(bodyText));
40990
41116
  return out2;
40991
41117
  }
@@ -41216,7 +41342,7 @@ var init_src11 = __esm({
41216
41342
  // src/reconcile.ts
41217
41343
  import { execFileSync as execFileSync2 } from "node:child_process";
41218
41344
  import { readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
41219
- 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";
41220
41346
  function indexerWouldScan(rel) {
41221
41347
  for (const seg of rel.split(/[\\/]/)) {
41222
41348
  if (seg.length === 0) continue;
@@ -41239,7 +41365,7 @@ function gitSourceFiles(root) {
41239
41365
  const out2 = [];
41240
41366
  for (const rel of stdout.split("\0")) {
41241
41367
  if (!rel || !SOURCE_RE.test(rel) || !indexerWouldScan(rel)) continue;
41242
- const abs = join13(root, rel);
41368
+ const abs = join14(root, rel);
41243
41369
  if (IGNORED.test(abs)) continue;
41244
41370
  out2.push(abs);
41245
41371
  }
@@ -41254,7 +41380,7 @@ function* walkSource(dir) {
41254
41380
  }
41255
41381
  for (const e of entries) {
41256
41382
  const name2 = String(e.name);
41257
- const full = join13(dir, name2);
41383
+ const full = join14(dir, name2);
41258
41384
  if (IGNORED.test(full)) continue;
41259
41385
  if (!indexerWouldScan(name2)) continue;
41260
41386
  if (e.isDirectory()) yield* walkSource(full);
@@ -41404,7 +41530,7 @@ __export(mcp_exports, {
41404
41530
  runTool: () => runTool,
41405
41531
  searchGraph: () => searchGraph
41406
41532
  });
41407
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
41533
+ import { existsSync as existsSync14, readFileSync as readFileSync12 } from "node:fs";
41408
41534
  import { resolve as resolve3 } from "node:path";
41409
41535
  function collectEnrichmentPulls(store, opts = {}) {
41410
41536
  const pending = store.findNodesByLabel("Solution").filter((s) => s.attrs["enrichmentPending"] === true).filter((s) => !opts.onlyUnsurfaced || s.attrs["enrichmentSurfaced"] !== true);
@@ -41441,7 +41567,7 @@ function takeEnrichmentNudge(store) {
41441
41567
  ` + items;
41442
41568
  }
41443
41569
  function takeDiscriminatorNudge(path2) {
41444
- if (!path2 || !existsSync13(path2)) return null;
41570
+ if (!path2 || !existsSync14(path2)) return null;
41445
41571
  let shared;
41446
41572
  try {
41447
41573
  shared = openGraphStore({ path: path2 });
@@ -41572,10 +41698,10 @@ function showNode(store, node2, maxLines) {
41572
41698
  if (!relPath) return { found: false, reason: "no file owner for node" };
41573
41699
  const workspaceRoot = process.cwd();
41574
41700
  const absPath = resolve3(workspaceRoot, relPath);
41575
- if (!existsSync13(absPath)) {
41701
+ if (!existsSync14(absPath)) {
41576
41702
  return { found: false, reason: `file not found on disk: ${absPath}` };
41577
41703
  }
41578
- const source = readFileSync11(absPath, "utf8");
41704
+ const source = readFileSync12(absPath, "utf8");
41579
41705
  const attrs = node2.attrs;
41580
41706
  let startByte = attrs["bodyStartByte"] ?? attrs["startByte"];
41581
41707
  let endByte = attrs["bodyEndByte"] ?? attrs["endByte"];
@@ -41802,6 +41928,7 @@ function buildToolContext(workspaceRoot) {
41802
41928
  try {
41803
41929
  const cfg = loadConfig();
41804
41930
  const entry = workspaceRoot ? workspaceEntryForPath(resolve3(workspaceRoot)) : null;
41931
+ const syncOk = effectiveConsent(cfg, entry ? loadProfile(entry.path) : null).sync;
41805
41932
  const identity = resolveWorkspaceIdentity(cfg, entry);
41806
41933
  if (identity.invalid) {
41807
41934
  console.error(`[errata mcp] cloud DISABLED for this workspace: ${identity.reason}`);
@@ -41809,13 +41936,13 @@ function buildToolContext(workspaceRoot) {
41809
41936
  }
41810
41937
  if (identity.rule === "workspace-binding" && identity.profileName) {
41811
41938
  const profile = identity.profile;
41812
- if (cfg.consent.sync && (profile.accessToken || profile.apiKey)) {
41939
+ if (syncOk && (profile.accessToken || profile.apiKey)) {
41813
41940
  console.error(`[errata mcp] workspace identity: profile "${identity.profileName}"`);
41814
41941
  return { ...base, cloud: authedCloudClientForProfile(cfg, identity.profileName) };
41815
41942
  }
41816
41943
  return base;
41817
41944
  }
41818
- if (cfg.consent.sync && hasCloudCredential(cfg) && cfg.cloudUrl) {
41945
+ if (syncOk && hasCloudCredential(cfg) && cfg.cloudUrl) {
41819
41946
  return { ...base, cloud: authedCloudClient(cfg) };
41820
41947
  }
41821
41948
  } catch {
@@ -41862,6 +41989,8 @@ var init_mcp = __esm({
41862
41989
  "use strict";
41863
41990
  init_cloud_auth();
41864
41991
  init_config();
41992
+ init_consent();
41993
+ init_profile2();
41865
41994
  init_identity2();
41866
41995
  init_registry();
41867
41996
  init_dual_augment();
@@ -42329,7 +42458,7 @@ var init_mcp = __esm({
42329
42458
  const local = causalChain(store, { seedId: id, direction: "both", maxHops, limit });
42330
42459
  try {
42331
42460
  const path2 = sharedStorePath();
42332
- if (!existsSync13(path2)) return { found: true, ...local };
42461
+ if (!existsSync14(path2)) return { found: true, ...local };
42333
42462
  const shared = openGraphStore({ path: path2 });
42334
42463
  try {
42335
42464
  if (!shared.getNode(id)) return { found: true, ...local };
@@ -42929,7 +43058,7 @@ var init_mcp = __esm({
42929
43058
  inputSchema: { type: "object", properties: {} },
42930
43059
  handler: () => {
42931
43060
  const path2 = sharedStorePath();
42932
- if (!existsSync13(path2)) return { count: 0, pending: [] };
43061
+ if (!existsSync14(path2)) return { count: 0, pending: [] };
42933
43062
  const shared = openGraphStore({ path: path2 });
42934
43063
  try {
42935
43064
  const pending = pendingAbstractions(shared);
@@ -42957,7 +43086,7 @@ var init_mcp = __esm({
42957
43086
  },
42958
43087
  handler: (args2) => {
42959
43088
  const path2 = sharedStorePath();
42960
- if (!existsSync13(path2)) return { count: 0, pending: [] };
43089
+ if (!existsSync14(path2)) return { count: 0, pending: [] };
42961
43090
  const shared = openGraphStore({ path: path2 });
42962
43091
  try {
42963
43092
  const pending = pendingDiscriminators(shared, {
@@ -43001,7 +43130,7 @@ var init_mcp = __esm({
43001
43130
  },
43002
43131
  handler: (args2) => {
43003
43132
  const path2 = sharedStorePath();
43004
- if (!existsSync13(path2)) return { count: 0, routes: [] };
43133
+ if (!existsSync14(path2)) return { count: 0, routes: [] };
43005
43134
  const shared = openGraphStore({ path: path2 });
43006
43135
  try {
43007
43136
  const result = triageOf(shared, {
@@ -43386,8 +43515,8 @@ __export(vfile_exports, {
43386
43515
  resolvePath: () => resolvePath,
43387
43516
  segmentsOf: () => segmentsOf
43388
43517
  });
43389
- import { writeFileSync as writeFileSync9 } from "node:fs";
43390
- 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";
43391
43520
  function segmentsOf(rawPath) {
43392
43521
  let p = rawPath.replace(/\\/g, "/");
43393
43522
  p = p.replace(/^.*\.errata\/g\//, "").replace(/^\/?g\//, "").replace(/^\/+/, "");
@@ -43461,14 +43590,14 @@ async function renderVFile(rawPath, store, ctx = {}) {
43461
43590
  }
43462
43591
  async function materializeVFile(rawPath, workspaceRoot, store, ctx = {}) {
43463
43592
  const segs = segmentsOf(rawPath);
43464
- const gRoot = join14(workspaceRoot, ".errata", "g");
43593
+ const gRoot = join15(workspaceRoot, ".errata", "g");
43465
43594
  const abs = resolve4(gRoot, ...segs.length ? segs : ["index"]);
43466
43595
  if (abs !== gRoot && !abs.startsWith(gRoot + sep3)) {
43467
43596
  throw new Error(`refusing to materialize outside .errata/g: ${rawPath}`);
43468
43597
  }
43469
43598
  const text = await renderVFile(rawPath, store, ctx);
43470
43599
  ensureParent(abs);
43471
- writeFileSync9(abs, text, "utf8");
43600
+ writeFileSync10(abs, text, "utf8");
43472
43601
  return abs;
43473
43602
  }
43474
43603
  async function materializeOverview(workspaceRoot, store, ctx = {}) {
@@ -50888,25 +51017,25 @@ var init_tool_index = __esm({
50888
51017
 
50889
51018
  // src/outbox.ts
50890
51019
  import {
50891
- existsSync as existsSync14,
51020
+ existsSync as existsSync15,
50892
51021
  readdirSync as readdirSync5,
50893
- readFileSync as readFileSync12,
51022
+ readFileSync as readFileSync13,
50894
51023
  renameSync,
50895
51024
  unlinkSync,
50896
- writeFileSync as writeFileSync10
51025
+ writeFileSync as writeFileSync11
50897
51026
  } from "node:fs";
50898
- import { join as join15 } from "node:path";
50899
- import { createHash as createHash12 } from "node:crypto";
51027
+ import { join as join16 } from "node:path";
51028
+ import { createHash as createHash13 } from "node:crypto";
50900
51029
  function enqueueOutbox(paths, payload) {
50901
51030
  ensureDir(paths.outbox);
50902
- const id = createHash12("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 16);
50903
- const file2 = join15(paths.outbox, `${Date.now()}-${id}.json`);
50904
- 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");
50905
51034
  return file2;
50906
51035
  }
50907
51036
  async function flushOutbox(paths, client, store) {
50908
51037
  ensureDir(paths.outbox);
50909
- const entries = existsSync14(paths.outbox) ? readdirSync5(paths.outbox) : [];
51038
+ const entries = existsSync15(paths.outbox) ? readdirSync5(paths.outbox) : [];
50910
51039
  let uploaded = 0;
50911
51040
  let failed = 0;
50912
51041
  const quarantine = (abs, reason) => {
@@ -50917,10 +51046,10 @@ async function flushOutbox(paths, client, store) {
50917
51046
  }
50918
51047
  };
50919
51048
  for (const f of entries.filter((e) => e.endsWith(".json")).sort()) {
50920
- const abs = join15(paths.outbox, f);
51049
+ const abs = join16(paths.outbox, f);
50921
51050
  let payload;
50922
51051
  try {
50923
- payload = JSON.parse(readFileSync12(abs, "utf8"));
51052
+ payload = JSON.parse(readFileSync13(abs, "utf8"));
50924
51053
  } catch {
50925
51054
  failed++;
50926
51055
  quarantine(abs, "unparseable JSON");
@@ -50965,7 +51094,7 @@ async function flushOutbox(paths, client, store) {
50965
51094
  }
50966
51095
  }
50967
51096
  }
50968
- 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")) : [];
50969
51098
  return { uploaded, failed, remaining: remainingFiles.length };
50970
51099
  }
50971
51100
  var init_outbox = __esm({
@@ -73444,10 +73573,10 @@ init_src10();
73444
73573
  init_review2();
73445
73574
 
73446
73575
  // src/turn.ts
73447
- import { closeSync, existsSync as existsSync15, fstatSync, openSync, readdirSync as readdirSync6, readSync, realpathSync, statSync as statSync5 } from "node:fs";
73448
- 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";
73449
73578
  import { homedir as homedir4 } from "node:os";
73450
- import { createHash as createHash13 } from "node:crypto";
73579
+ import { createHash as createHash14 } from "node:crypto";
73451
73580
  function readFrom(path2, fromByte, maxBytes) {
73452
73581
  let fd;
73453
73582
  try {
@@ -73823,11 +73952,11 @@ function turnsSince(turns, mark) {
73823
73952
  return at >= 0 ? turns.slice(at + 1) : turns;
73824
73953
  }
73825
73954
  function claudeProjectDir(cwd, home = homedir4()) {
73826
- return join18(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
73955
+ return join19(home, ".claude", "projects", cwd.replace(/[\\/:.]/g, "-"));
73827
73956
  }
73828
73957
  function recentTranscripts(cwd, opts = {}) {
73829
73958
  const dir = claudeProjectDir(cwd, opts.home ?? homedir4());
73830
- if (!existsSync15(dir)) return [];
73959
+ if (!existsSync16(dir)) return [];
73831
73960
  let names;
73832
73961
  try {
73833
73962
  names = readdirSync6(dir);
@@ -73838,7 +73967,7 @@ function recentTranscripts(cwd, opts = {}) {
73838
73967
  const refs = [];
73839
73968
  for (const name2 of names) {
73840
73969
  if (!name2.endsWith(".jsonl")) continue;
73841
- const path2 = join18(dir, name2);
73970
+ const path2 = join19(dir, name2);
73842
73971
  let mtimeMs;
73843
73972
  try {
73844
73973
  mtimeMs = statSync5(path2).mtimeMs;
@@ -73853,8 +73982,8 @@ function recentTranscripts(cwd, opts = {}) {
73853
73982
  }
73854
73983
  function subagentTranscripts(mainTranscriptPath, sessionId) {
73855
73984
  if (!mainTranscriptPath || !sessionId) return [];
73856
- const dir = join18(dirname10(mainTranscriptPath), sessionId, "subagents");
73857
- if (!existsSync15(dir)) return [];
73985
+ const dir = join19(dirname10(mainTranscriptPath), sessionId, "subagents");
73986
+ if (!existsSync16(dir)) return [];
73858
73987
  let names;
73859
73988
  try {
73860
73989
  names = readdirSync6(dir);
@@ -73864,7 +73993,7 @@ function subagentTranscripts(mainTranscriptPath, sessionId) {
73864
73993
  const refs = [];
73865
73994
  for (const name2 of names) {
73866
73995
  if (!name2.endsWith(".jsonl")) continue;
73867
- const path2 = join18(dir, name2);
73996
+ const path2 = join19(dir, name2);
73868
73997
  let mtimeMs;
73869
73998
  try {
73870
73999
  mtimeMs = statSync5(path2).mtimeMs;
@@ -73883,8 +74012,8 @@ function splitPathList(value, sep5 = delimiter) {
73883
74012
  function codexSessionRoots(env2 = process.env, home = homedir4()) {
73884
74013
  const roots = /* @__PURE__ */ new Set();
73885
74014
  for (const d of splitPathList(env2["ERRATA_CODEX_SESSIONS_DIRS"])) roots.add(d);
73886
- if (env2["CODEX_HOME"]) roots.add(join18(env2["CODEX_HOME"], "sessions"));
73887
- 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"));
73888
74017
  return [...roots];
73889
74018
  }
73890
74019
  function readCodexRolloutCwd(path2) {
@@ -73929,7 +74058,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
73929
74058
  const limit = opts.limit ?? 25;
73930
74059
  const out2 = [];
73931
74060
  for (const root of codexSessionRoots(opts.env, opts.home)) {
73932
- if (!existsSync15(root)) continue;
74061
+ if (!existsSync16(root)) continue;
73933
74062
  const stack = [{ dir: root, depth: 0 }];
73934
74063
  while (stack.length > 0) {
73935
74064
  const { dir, depth } = stack.pop();
@@ -73940,7 +74069,7 @@ function codexRolloutsForCwd(cwd, opts = {}) {
73940
74069
  continue;
73941
74070
  }
73942
74071
  for (const name2 of names) {
73943
- const full = join18(dir, name2);
74072
+ const full = join19(dir, name2);
73944
74073
  let st;
73945
74074
  try {
73946
74075
  st = statSync5(full);
@@ -73965,12 +74094,12 @@ function codexRolloutsForCwd(cwd, opts = {}) {
73965
74094
  function geminiSessionRoots(env2 = process.env, home = homedir4()) {
73966
74095
  const roots = /* @__PURE__ */ new Set();
73967
74096
  for (const d of splitPathList(env2["ERRATA_GEMINI_SESSIONS_DIRS"])) roots.add(d);
73968
- if (env2["GEMINI_CLI_HOME"]) roots.add(join18(env2["GEMINI_CLI_HOME"], ".gemini", "tmp"));
73969
- 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"));
73970
74099
  return [...roots];
73971
74100
  }
73972
74101
  function geminiProjectHash(cwd) {
73973
- return createHash13("sha256").update(cwd).digest("hex");
74102
+ return createHash14("sha256").update(cwd).digest("hex");
73974
74103
  }
73975
74104
  function geminiHashesFor(cwd) {
73976
74105
  const variants = /* @__PURE__ */ new Set([cwd, cwd.replace(/\/+$/, "")]);
@@ -74006,7 +74135,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74006
74135
  const hashes = geminiHashesFor(cwd);
74007
74136
  const out2 = [];
74008
74137
  for (const root of geminiSessionRoots(opts.env, opts.home)) {
74009
- if (!existsSync15(root)) continue;
74138
+ if (!existsSync16(root)) continue;
74010
74139
  let slugs;
74011
74140
  try {
74012
74141
  slugs = readdirSync6(root);
@@ -74014,7 +74143,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74014
74143
  continue;
74015
74144
  }
74016
74145
  for (const slug2 of slugs) {
74017
- const chats = join18(root, slug2, "chats");
74146
+ const chats = join19(root, slug2, "chats");
74018
74147
  let names;
74019
74148
  try {
74020
74149
  names = readdirSync6(chats);
@@ -74023,7 +74152,7 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74023
74152
  }
74024
74153
  for (const name2 of names) {
74025
74154
  if (!name2.startsWith("session-") || !name2.endsWith(".jsonl")) continue;
74026
- const full = join18(chats, name2);
74155
+ const full = join19(chats, name2);
74027
74156
  let st;
74028
74157
  try {
74029
74158
  st = statSync5(full);
@@ -74043,8 +74172,8 @@ function geminiTranscriptsForCwd(cwd, opts = {}) {
74043
74172
  function opencodeSessionRoots(env2 = process.env, home = homedir4()) {
74044
74173
  const roots = /* @__PURE__ */ new Set();
74045
74174
  for (const d of splitPathList(env2["ERRATA_OPENCODE_SESSIONS_DIRS"])) roots.add(d);
74046
- if (env2["XDG_DATA_HOME"]) roots.add(join18(env2["XDG_DATA_HOME"], "opencode", "errata"));
74047
- 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"));
74048
74177
  return [...roots];
74049
74178
  }
74050
74179
  function readOpencodeTranscriptDirectory(path2) {
@@ -74077,7 +74206,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
74077
74206
  }
74078
74207
  const out2 = [];
74079
74208
  for (const root of opencodeSessionRoots(opts.env, opts.home)) {
74080
- if (!existsSync15(root)) continue;
74209
+ if (!existsSync16(root)) continue;
74081
74210
  let names;
74082
74211
  try {
74083
74212
  names = readdirSync6(root);
@@ -74086,7 +74215,7 @@ function opencodeTranscriptsForCwd(cwd, opts = {}) {
74086
74215
  }
74087
74216
  for (const name2 of names) {
74088
74217
  if (!name2.endsWith(".jsonl")) continue;
74089
- const full = join18(root, name2);
74218
+ const full = join19(root, name2);
74090
74219
  let st;
74091
74220
  try {
74092
74221
  st = statSync5(full);
@@ -74109,7 +74238,7 @@ init_src2();
74109
74238
  init_agent_signals();
74110
74239
  init_tool_index();
74111
74240
  init_src5();
74112
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync11 } from "node:fs";
74241
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync12 } from "node:fs";
74113
74242
  var NEG = /n['']t|\b(?:not|never|no|none|neither|nor|unrelated|irrelevant|would|might|could|if)\b/i;
74114
74243
  var CITE_GROUP_RE = /\(((?:[^()\n]|\([^()\n]*\)){1,200})\)/g;
74115
74244
  var HANDLE_RE = /\[([a-z0-9][\w-]{0,80})\]|((?:pat|sol|drc|dcause|dfix|dprob|prob|claim|err)_[0-9a-f]{6,})/gi;
@@ -74788,13 +74917,13 @@ function writePrimingHandles(path2, nodes, now = Date.now()) {
74788
74917
  entries.sort((a, b) => (b[1].seenAt ?? 0) - (a[1].seenAt ?? 0));
74789
74918
  entries.length = HANDLE_MAP_MAX;
74790
74919
  }
74791
- writeFileSync11(path2, JSON.stringify(Object.fromEntries(entries)));
74920
+ writeFileSync12(path2, JSON.stringify(Object.fromEntries(entries)));
74792
74921
  } catch {
74793
74922
  }
74794
74923
  }
74795
74924
  function readPrimingHandles(path2) {
74796
74925
  try {
74797
- return JSON.parse(readFileSync13(path2, "utf8"));
74926
+ return JSON.parse(readFileSync14(path2, "utf8"));
74798
74927
  } catch {
74799
74928
  return {};
74800
74929
  }
@@ -75269,8 +75398,8 @@ ${conversation}` }]
75269
75398
  // src/constraint-backfill.ts
75270
75399
  init_src5();
75271
75400
  init_src2();
75272
- import { existsSync as existsSync16, readFileSync as readFileSync14, readdirSync as readdirSync7, writeFileSync as writeFileSync12 } from "node:fs";
75273
- 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";
75274
75403
  import { homedir as homedir5 } from "node:os";
75275
75404
  var BACKFILL_VERSION = 1;
75276
75405
  var EMPTY = {
@@ -75284,13 +75413,13 @@ var EMPTY = {
75284
75413
  recoverable: 0
75285
75414
  };
75286
75415
  function markerPath(configDir) {
75287
- return join19(configDir, "constraint-backfill.json");
75416
+ return join20(configDir, "constraint-backfill.json");
75288
75417
  }
75289
75418
  function alreadyDone(configDir) {
75290
75419
  const p = markerPath(configDir);
75291
- if (!existsSync16(p)) return false;
75420
+ if (!existsSync17(p)) return false;
75292
75421
  try {
75293
- const raw2 = JSON.parse(readFileSync14(p, "utf8"));
75422
+ const raw2 = JSON.parse(readFileSync15(p, "utf8"));
75294
75423
  return raw2?.version === BACKFILL_VERSION;
75295
75424
  } catch {
75296
75425
  return false;
@@ -75300,7 +75429,7 @@ function replay(root) {
75300
75429
  const statements = /* @__PURE__ */ new Set();
75301
75430
  const citedByFix = /* @__PURE__ */ new Set();
75302
75431
  const dir = claudeProjectDir(root, homedir5());
75303
- if (!existsSync16(dir)) return { statements, citedByFix };
75432
+ if (!existsSync17(dir)) return { statements, citedByFix };
75304
75433
  let names;
75305
75434
  try {
75306
75435
  names = readdirSync7(dir).filter((n) => n.endsWith(".jsonl"));
@@ -75310,7 +75439,7 @@ function replay(root) {
75310
75439
  for (const f of names) {
75311
75440
  let lines;
75312
75441
  try {
75313
- lines = readFileSync14(join19(dir, f), "utf8").split("\n");
75442
+ lines = readFileSync15(join20(dir, f), "utf8").split("\n");
75314
75443
  } catch {
75315
75444
  continue;
75316
75445
  }
@@ -75424,7 +75553,7 @@ function backfillConstraintKind(store, opts) {
75424
75553
  }
75425
75554
  });
75426
75555
  try {
75427
- writeFileSync12(
75556
+ writeFileSync13(
75428
75557
  markerPath(opts.configDir),
75429
75558
  JSON.stringify({ version: BACKFILL_VERSION, at: opts.now, ...report, cloudTwins: report.cloudTwins.length }, null, 2),
75430
75559
  "utf8"
@@ -75437,8 +75566,8 @@ function backfillConstraintKind(store, opts) {
75437
75566
  // src/edge-repair.ts
75438
75567
  init_src();
75439
75568
  init_src5();
75440
- import { existsSync as existsSync17, readFileSync as readFileSync15, writeFileSync as writeFileSync13 } from "node:fs";
75441
- 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";
75442
75571
  function citeEdgeId(from, type, to) {
75443
75572
  return `edge_${digest({ from, type, to })}`.slice(0, 24);
75444
75573
  }
@@ -75453,13 +75582,13 @@ var EMPTY2 = {
75453
75582
  byType: {}
75454
75583
  };
75455
75584
  function markerPath2(configDir) {
75456
- return join20(configDir, "edge-repair.json");
75585
+ return join21(configDir, "edge-repair.json");
75457
75586
  }
75458
75587
  function alreadyDone2(configDir) {
75459
75588
  const p = markerPath2(configDir);
75460
- if (!existsSync17(p)) return false;
75589
+ if (!existsSync18(p)) return false;
75461
75590
  try {
75462
- return JSON.parse(readFileSync15(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
75591
+ return JSON.parse(readFileSync16(p, "utf8"))?.version === EDGE_REPAIR_VERSION;
75463
75592
  } catch {
75464
75593
  return false;
75465
75594
  }
@@ -75508,7 +75637,7 @@ function repairInvalidEdges(store, opts) {
75508
75637
  });
75509
75638
  store.pruneEdgeRejections(opts.now - REJECTION_RETENTION_MS);
75510
75639
  try {
75511
- writeFileSync13(
75640
+ writeFileSync14(
75512
75641
  markerPath2(opts.configDir),
75513
75642
  JSON.stringify({ version: EDGE_REPAIR_VERSION, at: opts.now, ...report }, null, 2),
75514
75643
  "utf8"
@@ -75522,8 +75651,8 @@ function repairInvalidEdges(store, opts) {
75522
75651
  init_reconcile();
75523
75652
 
75524
75653
  // src/pass-ledger.ts
75525
- import { appendFileSync as appendFileSync2, existsSync as existsSync18, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "node:fs";
75526
- 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";
75527
75656
 
75528
75657
  // src/isolate-census.ts
75529
75658
  var live = 0;
@@ -75546,7 +75675,7 @@ var PER_KIND_MAX = 100;
75546
75675
  var TRIM_EVERY = 50;
75547
75676
  var appendsSinceTrim = /* @__PURE__ */ new Map();
75548
75677
  function passLedgerPath(configDir) {
75549
- return join21(configDir, "pass-ledger.jsonl");
75678
+ return join22(configDir, "pass-ledger.jsonl");
75550
75679
  }
75551
75680
  function appendPassLedger(configDir, kind, durationMs, counts) {
75552
75681
  const path2 = passLedgerPath(configDir);
@@ -75575,7 +75704,7 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
75575
75704
  return;
75576
75705
  }
75577
75706
  appendsSinceTrim.set(path2, 0);
75578
- const lines = readFileSync16(path2, "utf8").split("\n").filter(Boolean);
75707
+ const lines = readFileSync17(path2, "utf8").split("\n").filter(Boolean);
75579
75708
  const keptByKind = /* @__PURE__ */ new Map();
75580
75709
  const kept = [];
75581
75710
  for (let i2 = lines.length - 1; i2 >= 0; i2--) {
@@ -75591,16 +75720,16 @@ function appendPassLedger(configDir, kind, durationMs, counts) {
75591
75720
  kept.push(lines[i2]);
75592
75721
  }
75593
75722
  if (kept.length < lines.length) {
75594
- writeFileSync14(path2, kept.reverse().join("\n") + "\n");
75723
+ writeFileSync15(path2, kept.reverse().join("\n") + "\n");
75595
75724
  }
75596
75725
  } catch {
75597
75726
  }
75598
75727
  }
75599
75728
  function readPassLedger(configDir) {
75600
75729
  const path2 = passLedgerPath(configDir);
75601
- if (!existsSync18(path2)) return [];
75730
+ if (!existsSync19(path2)) return [];
75602
75731
  try {
75603
- 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(
75604
75733
  (e) => typeof e?.ts === "number" && typeof e?.kind === "string" && typeof e?.durationMs === "number"
75605
75734
  ).map((e) => ({ ...e, counts: e.counts ?? {} }));
75606
75735
  } catch {
@@ -75968,11 +76097,11 @@ init_outbox();
75968
76097
  init_src9();
75969
76098
  init_src();
75970
76099
  init_src2();
75971
- import { readFileSync as readFileSync17 } from "node:fs";
75972
- import { join as join22 } from "node:path";
76100
+ import { readFileSync as readFileSync18 } from "node:fs";
76101
+ import { join as join23 } from "node:path";
75973
76102
  function loadClaimIgnorePatterns(workspaceRoot) {
75974
76103
  try {
75975
- 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());
75976
76105
  } catch {
75977
76106
  return [];
75978
76107
  }
@@ -76335,9 +76464,9 @@ async function pullCloudTriage(shared, cloud, profile, limit = 50) {
76335
76464
  // src/retrieval-stack.ts
76336
76465
  init_src();
76337
76466
  import { execFileSync as execFileSync3 } from "node:child_process";
76338
- 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";
76339
76468
  import { homedir as homedir6 } from "node:os";
76340
- import { join as join23 } from "node:path";
76469
+ import { join as join24 } from "node:path";
76341
76470
  var RETRIEVAL_STACK_CAP = 24;
76342
76471
  var MANIFEST_SCAN_CAP = 400;
76343
76472
  var RUNTIME_TOKENS = /* @__PURE__ */ new Set([
@@ -76627,51 +76756,51 @@ function mavenGroupIsSelfDisclosing(name2, selfTokens) {
76627
76756
  function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
76628
76757
  const read2 = (p) => {
76629
76758
  try {
76630
- return readFileSync18(p, "utf8");
76759
+ return readFileSync19(p, "utf8");
76631
76760
  } catch {
76632
76761
  return null;
76633
76762
  }
76634
76763
  };
76635
76764
  const texts = (...paths) => paths.map(read2).filter((t) => t !== null);
76636
76765
  const home = homedir6();
76637
- const npm = parseNpmrcPolicy(texts(join23(root, ".npmrc"), join23(home, ".npmrc")));
76766
+ const npm = parseNpmrcPolicy(texts(join24(root, ".npmrc"), join24(home, ".npmrc")));
76638
76767
  const blocked = /* @__PURE__ */ new Set();
76639
76768
  if (!npm.defaultPublic) blocked.add("npm");
76640
76769
  if (pypiIndexIsPrivate(
76641
76770
  texts(
76642
- join23(root, "pip.conf"),
76643
- join23(root, "pip.ini"),
76644
- join23(root, "pyproject.toml"),
76645
- join23(root, "requirements.txt"),
76646
- join23(home, ".pip", "pip.conf"),
76647
- join23(home, ".config", "pip", "pip.conf"),
76648
- 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")
76649
76778
  )
76650
76779
  )) {
76651
76780
  blocked.add("pypi");
76652
76781
  }
76653
76782
  if (cargoRegistryIsPrivate(
76654
76783
  texts(
76655
- join23(root, ".cargo", "config.toml"),
76656
- join23(root, ".cargo", "config"),
76657
- join23(home, ".cargo", "config.toml"),
76658
- 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")
76659
76788
  )
76660
76789
  )) {
76661
76790
  blocked.add("cargo");
76662
76791
  }
76663
76792
  if (nugetSourcesArePrivate(
76664
76793
  texts(
76665
- join23(root, "NuGet.config"),
76666
- join23(root, "nuget.config"),
76667
- join23(root, "NuGet.Config"),
76668
- join23(env2["APPDATA"] ?? home, "NuGet", "NuGet.Config"),
76669
- 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")
76670
76799
  )
76671
76800
  )) {
76672
76801
  blocked.add("nuget");
76673
76802
  }
76674
- 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");
76675
76804
  const goEnvText = read2(goEnvFile) ?? "";
76676
76805
  const fromFile = ["GOPRIVATE", "GONOSUMDB", "GONOSUMCHECK"].map(
76677
76806
  (k) => new RegExp(`^${k}=(.*)$`, "m").exec(goEnvText)?.[1]
@@ -76682,10 +76811,10 @@ function loadRegistryPolicy(root, env2 = process.env, repoLocator) {
76682
76811
  env2["GONOSUMCHECK"],
76683
76812
  ...fromFile
76684
76813
  ]);
76685
- const gemfiles = texts(join23(root, "Gemfile"));
76814
+ const gemfiles = texts(join24(root, "Gemfile"));
76686
76815
  if (gemSourceIsPrivate(gemfiles)) blocked.add("gem");
76687
76816
  if (mavenReposArePrivate(
76688
- texts(join23(root, "pom.xml"), join23(home, ".m2", "settings.xml"))
76817
+ texts(join24(root, "pom.xml"), join24(home, ".m2", "settings.xml"))
76689
76818
  )) {
76690
76819
  blocked.add("maven");
76691
76820
  }
@@ -76852,8 +76981,8 @@ function readDirectDependencies(root) {
76852
76981
  const familiesSeen = /* @__PURE__ */ new Set();
76853
76982
  for (const c of LOCKFILES) {
76854
76983
  if (familiesSeen.has(c.family)) continue;
76855
- const p = join23(root, c.file);
76856
- if (!existsSync19(p)) continue;
76984
+ const p = join24(root, c.file);
76985
+ if (!existsSync20(p)) continue;
76857
76986
  try {
76858
76987
  const s = statSync6(p);
76859
76988
  stamps.push(`${c.file}:${s.mtimeMs}:${s.size}`);
@@ -76873,7 +77002,7 @@ function readDirectDependencies(root) {
76873
77002
  const direct = [];
76874
77003
  for (const { c, path: path2 } of found) {
76875
77004
  try {
76876
- direct.push(...c.parse(readFileSync18(path2, "utf8")).direct ?? []);
77005
+ direct.push(...c.parse(readFileSync19(path2, "utf8")).direct ?? []);
76877
77006
  } catch {
76878
77007
  }
76879
77008
  }
@@ -76916,14 +77045,14 @@ function manifestPaths(root) {
76916
77045
  "project.godot"
76917
77046
  ];
76918
77047
  return {
76919
- paths: ROOT_MANIFESTS.filter((f) => existsSync19(join23(root, f))),
77048
+ paths: ROOT_MANIFESTS.filter((f) => existsSync20(join24(root, f))),
76920
77049
  tracked: false,
76921
77050
  truncated: false
76922
77051
  };
76923
77052
  }
76924
77053
  var WORKSPACE_MARKERS = ["pnpm-workspace.yaml", "lerna.json", "go.work", "settings.gradle", "settings.gradle.kts"];
76925
77054
  function rootDeclaresWorkspace(root, texts) {
76926
- if (WORKSPACE_MARKERS.some((f) => existsSync19(join23(root, f)))) return true;
77055
+ if (WORKSPACE_MARKERS.some((f) => existsSync20(join24(root, f)))) return true;
76927
77056
  return /"workspaces"\s*:/.test(texts.get("package.json") ?? "") || /<modules>/.test(texts.get("pom.xml") ?? "") || /^\s*\[workspace\]/m.test(texts.get("Cargo.toml") ?? "");
76928
77057
  }
76929
77058
  var EMPTY_SCAN = { deps: [], self: [], complete: true };
@@ -76937,11 +77066,11 @@ function scanManifests(root) {
76937
77066
  const texts = /* @__PURE__ */ new Map();
76938
77067
  const stamps = [];
76939
77068
  for (const rel of paths) {
76940
- const abs = join23(root, rel);
77069
+ const abs = join24(root, rel);
76941
77070
  try {
76942
77071
  const s = statSync6(abs);
76943
77072
  stamps.push(`${rel}:${s.mtimeMs}:${s.size}`);
76944
- texts.set(rel, readFileSync18(abs, "utf8"));
77073
+ texts.set(rel, readFileSync19(abs, "utf8"));
76945
77074
  } catch {
76946
77075
  }
76947
77076
  }
@@ -76970,22 +77099,22 @@ function readManifestDependencies(root) {
76970
77099
  }
76971
77100
 
76972
77101
  // src/git-sensor.ts
76973
- import { existsSync as existsSync20, readFileSync as readFileSync19, watch as fsWatch } from "node:fs";
76974
- 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";
76975
77104
  function readFirstLine(path2) {
76976
77105
  try {
76977
- return readFileSync19(path2, "utf8").split(/\r?\n/, 1)[0].trim();
77106
+ return readFileSync20(path2, "utf8").split(/\r?\n/, 1)[0].trim();
76978
77107
  } catch {
76979
77108
  return null;
76980
77109
  }
76981
77110
  }
76982
77111
  function readGitRefState(gitDir) {
76983
- const head2 = readFirstLine(join24(gitDir, "HEAD"));
77112
+ const head2 = readFirstLine(join25(gitDir, "HEAD"));
76984
77113
  const m = head2 ? /^ref:\s*refs\/heads\/(.+)$/.exec(head2) : null;
76985
77114
  const branch = m ? m[1] : null;
76986
77115
  let sha2 = null;
76987
77116
  if (branch) {
76988
- sha2 = readFirstLine(join24(gitDir, "refs", "heads", branch));
77117
+ sha2 = readFirstLine(join25(gitDir, "refs", "heads", branch));
76989
77118
  if (!sha2) sha2 = shaFromPackedRefs(gitDir, `refs/heads/${branch}`);
76990
77119
  } else if (head2 && /^[0-9a-f]{7,40}$/i.test(head2)) {
76991
77120
  sha2 = head2;
@@ -76993,13 +77122,13 @@ function readGitRefState(gitDir) {
76993
77122
  return {
76994
77123
  branch,
76995
77124
  sha: sha2,
76996
- mergeHeadExists: existsSync20(join24(gitDir, "MERGE_HEAD")),
76997
- origHeadExists: existsSync20(join24(gitDir, "ORIG_HEAD"))
77125
+ mergeHeadExists: existsSync21(join25(gitDir, "MERGE_HEAD")),
77126
+ origHeadExists: existsSync21(join25(gitDir, "ORIG_HEAD"))
76998
77127
  };
76999
77128
  }
77000
77129
  function shaFromPackedRefs(gitDir, ref) {
77001
77130
  try {
77002
- 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/)) {
77003
77132
  const [sha2, name2] = line.split(/\s+/);
77004
77133
  if (name2 === ref && sha2) return sha2;
77005
77134
  }
@@ -77033,7 +77162,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
77033
77162
  const settle = () => {
77034
77163
  if (timer) clearTimeout(timer);
77035
77164
  timer = setTimeout(() => {
77036
- if (existsSync20(join24(gitDir, "index.lock"))) {
77165
+ if (existsSync21(join25(gitDir, "index.lock"))) {
77037
77166
  settle();
77038
77167
  return;
77039
77168
  }
@@ -77044,7 +77173,7 @@ function startGitSensor(gitDir, onEvent, opts = {}) {
77044
77173
  }, debounceMs);
77045
77174
  };
77046
77175
  for (const sub of ["HEAD", "logs/HEAD", "MERGE_HEAD", "ORIG_HEAD"]) {
77047
- const p = join24(gitDir, sub);
77176
+ const p = join25(gitDir, sub);
77048
77177
  try {
77049
77178
  watchers.push(fsWatch(p, settle));
77050
77179
  } catch {
@@ -77269,21 +77398,21 @@ var TelemetryRecorder = class {
77269
77398
 
77270
77399
  // src/skills.ts
77271
77400
  import {
77272
- existsSync as existsSync21,
77401
+ existsSync as existsSync22,
77273
77402
  mkdirSync as mkdirSync7,
77274
- readFileSync as readFileSync20,
77403
+ readFileSync as readFileSync21,
77275
77404
  readdirSync as readdirSync8,
77276
77405
  unlinkSync as unlinkSync2,
77277
- writeFileSync as writeFileSync15
77406
+ writeFileSync as writeFileSync16
77278
77407
  } from "node:fs";
77279
- import { basename as basename6, join as join25 } from "node:path";
77408
+ import { basename as basename6, join as join26 } from "node:path";
77280
77409
  function skillFileName(id) {
77281
77410
  return `${id.replace(/[^A-Za-z0-9_.-]/g, "_")}.md`;
77282
77411
  }
77283
77412
  function readSkillManifest(manifestPath) {
77284
- if (!existsSync21(manifestPath)) return [];
77413
+ if (!existsSync22(manifestPath)) return [];
77285
77414
  try {
77286
- const parsed = JSON.parse(readFileSync20(manifestPath, "utf8"));
77415
+ const parsed = JSON.parse(readFileSync21(manifestPath, "utf8"));
77287
77416
  return (parsed.skills ?? []).map((s) => ({
77288
77417
  title: s.title ?? "",
77289
77418
  layer: s.layer ?? "technique",
@@ -77307,7 +77436,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77307
77436
  for (const s of res.skills) {
77308
77437
  const fileName = skillFileName(s.id);
77309
77438
  keep.add(fileName);
77310
- writeFileSync15(join25(paths.skillsDir, fileName), s.markdown, "utf8");
77439
+ writeFileSync16(join26(paths.skillsDir, fileName), s.markdown, "utf8");
77311
77440
  rows.push({
77312
77441
  id: s.id,
77313
77442
  title: s.title,
@@ -77320,7 +77449,7 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77320
77449
  const fileName = skillFileName(p.id);
77321
77450
  if (keep.has(fileName)) continue;
77322
77451
  keep.add(fileName);
77323
- writeFileSync15(join25(paths.skillsDir, fileName), p.markdown, "utf8");
77452
+ writeFileSync16(join26(paths.skillsDir, fileName), p.markdown, "utf8");
77324
77453
  rows.push({
77325
77454
  id: p.id,
77326
77455
  title: p.title,
@@ -77334,13 +77463,13 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77334
77463
  if (!f.endsWith(".md")) continue;
77335
77464
  if (keep.has(basename6(f))) continue;
77336
77465
  try {
77337
- unlinkSync2(join25(paths.skillsDir, f));
77466
+ unlinkSync2(join26(paths.skillsDir, f));
77338
77467
  pruned++;
77339
77468
  } catch {
77340
77469
  }
77341
77470
  }
77342
77471
  rows.sort((a, b) => a.id.localeCompare(b.id));
77343
- writeFileSync15(
77472
+ writeFileSync16(
77344
77473
  paths.skillsManifest,
77345
77474
  JSON.stringify({ generatedAt: Date.now(), skills: rows }, null, 2),
77346
77475
  "utf8"
@@ -77352,22 +77481,22 @@ async function syncSkills(paths, client, seed, pins = [], techSeed) {
77352
77481
  init_src2();
77353
77482
  import {
77354
77483
  cpSync,
77355
- existsSync as existsSync22,
77484
+ existsSync as existsSync23,
77356
77485
  lstatSync,
77357
77486
  mkdirSync as mkdirSync8,
77358
- readFileSync as readFileSync21,
77487
+ readFileSync as readFileSync22,
77359
77488
  readdirSync as readdirSync9,
77360
77489
  rmSync as rmSync3,
77361
77490
  symlinkSync,
77362
- writeFileSync as writeFileSync16
77491
+ writeFileSync as writeFileSync17
77363
77492
  } from "node:fs";
77364
- import { join as join26 } from "node:path";
77493
+ import { join as join27 } from "node:path";
77365
77494
  var SKILL_NS = "errata-";
77366
77495
  var HARNESS_SKILL_DIRS = [
77367
- { configDir: ".claude", skillsDir: join26(".claude", "skills") },
77496
+ { configDir: ".claude", skillsDir: join27(".claude", "skills") },
77368
77497
  // Cursor adopted the standard; its exact project dir is still moving — kept
77369
77498
  // best-effort and gated on `.cursor/` presence so we never create it blind.
77370
- { configDir: ".cursor", skillsDir: join26(".cursor", "skills") }
77499
+ { configDir: ".cursor", skillsDir: join27(".cursor", "skills") }
77371
77500
  ];
77372
77501
  function skillSlug(title, id) {
77373
77502
  const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || id.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
@@ -77412,12 +77541,12 @@ function skillCiteHandle(s) {
77412
77541
  return priorHandle({ id: s.id, description: s.title });
77413
77542
  }
77414
77543
  function reconcileNamespaced(dir, keep) {
77415
- if (!existsSync22(dir)) return 0;
77544
+ if (!existsSync23(dir)) return 0;
77416
77545
  let pruned = 0;
77417
77546
  for (const name2 of readdirSync9(dir)) {
77418
77547
  if (!name2.startsWith(SKILL_NS) || keep.has(name2)) continue;
77419
77548
  try {
77420
- rmSync3(join26(dir, name2), { recursive: true, force: true });
77549
+ rmSync3(join27(dir, name2), { recursive: true, force: true });
77421
77550
  pruned++;
77422
77551
  } catch {
77423
77552
  }
@@ -77426,7 +77555,7 @@ function reconcileNamespaced(dir, keep) {
77426
77555
  }
77427
77556
  function linkOrCopy(linkPath, target) {
77428
77557
  try {
77429
- if (existsSync22(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
77558
+ if (existsSync23(linkPath) || safeLstat(linkPath)) rmSync3(linkPath, { recursive: true, force: true });
77430
77559
  } catch {
77431
77560
  }
77432
77561
  try {
@@ -77447,7 +77576,7 @@ function safeLstat(p) {
77447
77576
  }
77448
77577
  }
77449
77578
  function emitAndProjectSkills(root, skills) {
77450
- const agentsSkillsDir = join26(root, ".agents", "skills");
77579
+ const agentsSkillsDir = join27(root, ".agents", "skills");
77451
77580
  mkdirSync8(agentsSkillsDir, { recursive: true });
77452
77581
  const slugs = [];
77453
77582
  const keep = /* @__PURE__ */ new Set();
@@ -77455,7 +77584,7 @@ function emitAndProjectSkills(root, skills) {
77455
77584
  for (const s of skills) {
77456
77585
  let body2;
77457
77586
  try {
77458
- body2 = readFileSync21(s.bodyPath, "utf8");
77587
+ body2 = readFileSync22(s.bodyPath, "utf8");
77459
77588
  } catch {
77460
77589
  continue;
77461
77590
  }
@@ -77464,9 +77593,9 @@ function emitAndProjectSkills(root, skills) {
77464
77593
  keep.add(slug2);
77465
77594
  slugs.push(slug2);
77466
77595
  const description = deriveDescription(s.title, s.layer, body2);
77467
- mkdirSync8(join26(agentsSkillsDir, slug2), { recursive: true });
77468
- writeFileSync16(
77469
- join26(agentsSkillsDir, slug2, "SKILL.md"),
77596
+ mkdirSync8(join27(agentsSkillsDir, slug2), { recursive: true });
77597
+ writeFileSync17(
77598
+ join27(agentsSkillsDir, slug2, "SKILL.md"),
77470
77599
  renderSkillMd(slug2, description, body2, skillCiteHandle(s)),
77471
77600
  "utf8"
77472
77601
  );
@@ -77475,11 +77604,11 @@ function emitAndProjectSkills(root, skills) {
77475
77604
  reconcileNamespaced(agentsSkillsDir, keep);
77476
77605
  let projected = 0;
77477
77606
  for (const h of HARNESS_SKILL_DIRS) {
77478
- if (!existsSync22(join26(root, h.configDir))) continue;
77479
- const dir = join26(root, h.skillsDir);
77607
+ if (!existsSync23(join27(root, h.configDir))) continue;
77608
+ const dir = join27(root, h.skillsDir);
77480
77609
  mkdirSync8(dir, { recursive: true });
77481
77610
  for (const slug2 of slugs) {
77482
- linkOrCopy(join26(dir, slug2), join26(agentsSkillsDir, slug2));
77611
+ linkOrCopy(join27(dir, slug2), join27(agentsSkillsDir, slug2));
77483
77612
  projected++;
77484
77613
  }
77485
77614
  reconcileNamespaced(dir, keep);
@@ -77488,15 +77617,15 @@ function emitAndProjectSkills(root, skills) {
77488
77617
  return { slugs, emitted, projected };
77489
77618
  }
77490
77619
  function emitInputsFromManifest(erretaDir, manifestPath) {
77491
- if (!existsSync22(manifestPath)) return [];
77620
+ if (!existsSync23(manifestPath)) return [];
77492
77621
  try {
77493
- const parsed = JSON.parse(readFileSync21(manifestPath, "utf8"));
77622
+ const parsed = JSON.parse(readFileSync22(manifestPath, "utf8"));
77494
77623
  return (parsed.skills ?? []).filter((s) => Boolean(s.id && s.file)).map((s) => ({
77495
77624
  id: s.id,
77496
77625
  title: s.title ?? s.id,
77497
77626
  layer: s.layer ?? "technique",
77498
77627
  confidence: s.confidence ?? 0,
77499
- bodyPath: join26(erretaDir, s.file)
77628
+ bodyPath: join27(erretaDir, s.file)
77500
77629
  }));
77501
77630
  } catch {
77502
77631
  return [];
@@ -77510,17 +77639,17 @@ var GITIGNORE_LINES = [
77510
77639
  ".cursor/skills/errata-*/"
77511
77640
  ];
77512
77641
  function ensureSkillGitignore(root) {
77513
- const path2 = join26(root, ".gitignore");
77642
+ const path2 = join27(root, ".gitignore");
77514
77643
  let current = "";
77515
77644
  try {
77516
- current = existsSync22(path2) ? readFileSync21(path2, "utf8") : "";
77645
+ current = existsSync23(path2) ? readFileSync22(path2, "utf8") : "";
77517
77646
  } catch {
77518
77647
  return;
77519
77648
  }
77520
77649
  if (current.includes(GITIGNORE_MARK)) return;
77521
77650
  const prefix = current.length > 0 && !current.endsWith("\n") ? "\n" : "";
77522
77651
  try {
77523
- writeFileSync16(path2, `${current}${prefix}
77652
+ writeFileSync17(path2, `${current}${prefix}
77524
77653
  ${GITIGNORE_LINES.join("\n")}
77525
77654
  `, "utf8");
77526
77655
  } catch {
@@ -77613,108 +77742,7 @@ function createToolRunState() {
77613
77742
  // src/engine.ts
77614
77743
  init_tool_index();
77615
77744
  init_paths();
77616
-
77617
- // src/profile.ts
77618
- init_src2();
77619
- init_paths();
77620
- init_git_remote();
77621
- import { existsSync as existsSync23, readFileSync as readFileSync22, writeFileSync as writeFileSync17 } from "node:fs";
77622
- import { createHash as createHash14 } from "node:crypto";
77623
- import { join as join27 } from "node:path";
77624
- function workspaceId(root) {
77625
- return "wp_" + createHash14("sha256").update(root).digest("hex").slice(0, 12);
77626
- }
77627
- function sessionOriginKey(sessionId) {
77628
- if (!sessionId) return void 0;
77629
- return "ws_" + createHash14("sha256").update(sessionId).digest("hex").slice(0, 12);
77630
- }
77631
- function refreshRepoLocator(root, profile) {
77632
- const detected = detectRepoLocator(root, profile.repoRemote);
77633
- if (!detected || detected === profile.repoLocator) return false;
77634
- if (profile.repoLocator) {
77635
- const aliases = new Set(profile.repoLocatorAliases ?? []);
77636
- aliases.add(profile.repoLocator);
77637
- aliases.delete(detected);
77638
- profile.repoLocatorAliases = [...aliases];
77639
- }
77640
- profile.repoLocator = detected;
77641
- saveProfile(root, profile);
77642
- return true;
77643
- }
77644
- function loadProfile(root) {
77645
- const p = workspacePaths(root);
77646
- if (!existsSync23(p.workspaceJson)) return null;
77647
- return JSON.parse(readFileSync22(p.workspaceJson, "utf8"));
77648
- }
77649
- function saveProfile(root, profile) {
77650
- const p = workspacePaths(root);
77651
- ensureDir(p.configDir);
77652
- writeFileSync17(p.workspaceJson, JSON.stringify(profile, null, 2), "utf8");
77653
- }
77654
- function autodetectProfile(root) {
77655
- const id = workspaceId(root);
77656
- const name2 = root.split(/[\\/]/).filter(Boolean).pop() ?? "workspace";
77657
- const p = emptyProfile(id, name2);
77658
- const locator = detectRepoLocator(root);
77659
- if (locator) p.repoLocator = locator;
77660
- const pkgPath = join27(root, "package.json");
77661
- if (existsSync23(pkgPath)) {
77662
- try {
77663
- const pkg = JSON.parse(readFileSync22(pkgPath, "utf8"));
77664
- const deps = { ...pkg.dependencies ?? {}, ...pkg.devDependencies ?? {} };
77665
- p.languages.push("javascript");
77666
- if (existsSync23(join27(root, "tsconfig.json")) || deps["typescript"]) {
77667
- p.languages.push("typescript");
77668
- }
77669
- const nodeVer = pkg.engines?.node?.trim();
77670
- p.stack.push(nodeVer ? `node@${nodeVer}` : "node");
77671
- const interesting = [
77672
- "next",
77673
- "react",
77674
- "vue",
77675
- "svelte",
77676
- "express",
77677
- "hono",
77678
- "fastify",
77679
- "@modelcontextprotocol/sdk"
77680
- ];
77681
- for (const k of interesting) {
77682
- if (deps[k]) p.stack.push(k);
77683
- }
77684
- } catch {
77685
- }
77686
- }
77687
- const pyproject = join27(root, "pyproject.toml");
77688
- if (existsSync23(pyproject)) {
77689
- try {
77690
- const txt = readFileSync22(pyproject, "utf8");
77691
- const py = /python\s*=\s*"([^"]+)"/.exec(txt)?.[1];
77692
- p.languages.push("python");
77693
- p.stack.push(`python@${py ?? "3"}`);
77694
- const candidates = ["fastapi", "django", "flask", "mcp", "pytest"];
77695
- for (const k of candidates) {
77696
- if (new RegExp(`\\b${k}\\b`, "i").test(txt)) p.stack.push(k);
77697
- }
77698
- } catch {
77699
- }
77700
- }
77701
- const reqs = join27(root, "requirements.txt");
77702
- if (existsSync23(reqs)) {
77703
- if (!p.languages.includes("python")) p.languages.push("python");
77704
- if (!p.stack.includes("python@3")) p.stack.push("python@3");
77705
- }
77706
- if (existsSync23(join27(root, "go.mod"))) {
77707
- p.languages.push("go");
77708
- p.stack.push("go");
77709
- }
77710
- if (existsSync23(join27(root, "Cargo.toml"))) {
77711
- p.languages.push("rust");
77712
- p.stack.push("rust");
77713
- }
77714
- p.languages = [...new Set(p.languages)];
77715
- p.stack = [...new Set(p.stack)];
77716
- return p;
77717
- }
77745
+ init_profile2();
77718
77746
 
77719
77747
  // src/witness-queue.ts
77720
77748
  import { readFileSync as readFileSync23, renameSync as renameSync2, writeFileSync as writeFileSync18 } from "node:fs";
@@ -77915,7 +77943,9 @@ var CausalBuffer = class {
77915
77943
  };
77916
77944
 
77917
77945
  // src/engine.ts
77946
+ init_profile2();
77918
77947
  init_config();
77948
+ init_consent();
77919
77949
  init_cloud_auth();
77920
77950
 
77921
77951
  // src/notify.ts
@@ -78332,7 +78362,7 @@ function createWatchBreaker(deps) {
78332
78362
  }
78333
78363
 
78334
78364
  // src/engine.ts
78335
- var DAEMON_VERSION = true ? "2.0.6-dev.2563" : "2.0.0-alpha.0";
78365
+ var DAEMON_VERSION = true ? "2.0.6-dev.2568" : "2.0.0-alpha.0";
78336
78366
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
78337
78367
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
78338
78368
  var GIT_OP_MUTE_MS = 4e3;
@@ -78439,6 +78469,7 @@ function createWorkspaceEngine(opts) {
78439
78469
  } else {
78440
78470
  refreshRepoLocator(opts.workspaceRoot, profile);
78441
78471
  }
78472
+ const consentNow = () => effectiveConsent(loadConfig(), profile);
78442
78473
  const store = openGraphStore({ path: paths.castalia });
78443
78474
  const witnessLoad = loadWitnessQueueWithLosses(witnessQueuePath(paths.configDir));
78444
78475
  const witnessPrune = pruneWitnessQueueWithDispositions(witnessLoad.queue, Date.now());
@@ -78867,7 +78898,7 @@ function createWorkspaceEngine(opts) {
78867
78898
  // resolves each token against both the Package and Language namespaces,
78868
78899
  // and the profile keeps them in separate fields.
78869
78900
  languages: profile?.languages ?? [],
78870
- contributePackages: loadConfig().consent.contributePackages,
78901
+ contributePackages: consentNow().contributePackages,
78871
78902
  // `repoLocator` feeds the Maven self-disclosure rule ONLY: a groupId
78872
78903
  // carrying this project's own owner/repo token is the project naming
78873
78904
  // itself, not a library it depends on.
@@ -78878,7 +78909,7 @@ function createWorkspaceEngine(opts) {
78878
78909
  if (opts.skipContextWriter || remoteInFlight) return;
78879
78910
  const now = Date.now();
78880
78911
  if (now - lastRemoteAt < REMOTE_REFRESH_MS) return;
78881
- const syncOk = opts.syncConsent ?? loadConfig().consent.sync;
78912
+ const syncOk = opts.syncConsent ?? consentNow().sync;
78882
78913
  if (!syncOk) return;
78883
78914
  if (typeof cloud.search !== "function") return;
78884
78915
  remoteInFlight = true;
@@ -78918,7 +78949,7 @@ function createWorkspaceEngine(opts) {
78918
78949
  const maybeRefreshIntentPriors = (liveIntent) => {
78919
78950
  if (!liveIntent || opts.skipContextWriter || intentRemoteInFlight) return;
78920
78951
  if (intentRemote?.forIntent === liveIntent) return;
78921
- const syncOk = opts.syncConsent ?? loadConfig().consent.sync;
78952
+ const syncOk = opts.syncConsent ?? consentNow().sync;
78922
78953
  if (!syncOk) return;
78923
78954
  if (typeof cloud.search !== "function") return;
78924
78955
  intentRemoteInFlight = true;
@@ -80224,7 +80255,7 @@ B: ${b}`,
80224
80255
  });
80225
80256
  }
80226
80257
  const pullSkills = async () => {
80227
- if ((opts.syncConsent ?? loadConfig().consent.sync) === true) {
80258
+ if ((opts.syncConsent ?? consentNow().sync) === true) {
80228
80259
  for (const req of communityInductionRequests(store)) {
80229
80260
  try {
80230
80261
  const r = await cloud.induceSkill({ members: req.members, context: req.context });
@@ -80244,7 +80275,7 @@ B: ${b}`,
80244
80275
  const pins = profile?.projectId ? await cloud.getSkillPins(profile.projectId).then((r) => r.pins).catch(() => []) : [];
80245
80276
  const anchorMap = buildBucketTokenAnchors(
80246
80277
  profile.languages ?? [],
80247
- loadConfig().consent.contributePackages ? store.findNodesByLabel("Package").map((p) => ({
80278
+ consentNow().contributePackages ? store.findNodesByLabel("Package").map((p) => ({
80248
80279
  name: String(p.attrs["name"] ?? ""),
80249
80280
  purl: String(p.attrs["purl"] ?? p.id)
80250
80281
  })) : []
@@ -80550,7 +80581,7 @@ B: ${b}`,
80550
80581
  };
80551
80582
  },
80552
80583
  async syncNow() {
80553
- const syncOk = opts.syncConsent ?? loadConfig().consent.sync;
80584
+ const syncOk = opts.syncConsent ?? consentNow().sync;
80554
80585
  if (!syncOk) {
80555
80586
  console.log(
80556
80587
  "[errata] sync skipped \u2014 cloud sync consent is off (enable with `errata consent sync on`)"
@@ -80581,14 +80612,14 @@ B: ${b}`,
80581
80612
  }
80582
80613
  try {
80583
80614
  const freshCfg = loadConfig();
80584
- if (freshCfg.consent.telemetry) {
80615
+ if (consentNow().telemetry) {
80585
80616
  telemetry.event("graph_snapshot", store.nodeCount(), {
80586
80617
  problemsLive: store.findNodesByLabel("Problem").length
80587
80618
  });
80588
80619
  telemetry.event("heartbeat");
80589
80620
  }
80590
80621
  const t = await telemetry.flush(cloud, {
80591
- consent: freshCfg.consent.telemetry,
80622
+ consent: consentNow().telemetry,
80592
80623
  credentialPresent: Boolean(opts.apiKey) || hasCloudCredential(freshCfg)
80593
80624
  });
80594
80625
  if (t.sent > 0) {
@@ -80950,6 +80981,9 @@ function noveltyAgainst(node2, neighbors, opts = {}) {
80950
80981
  };
80951
80982
  }
80952
80983
 
80984
+ // src/instance-ingest.ts
80985
+ init_profile2();
80986
+
80953
80987
  // src/public-symbols.ts
80954
80988
  import { readFileSync as readFileSync27, readdirSync as readdirSync11, existsSync as existsSync28 } from "node:fs";
80955
80989
  import { join as join32 } from "node:path";
@@ -81969,6 +82003,7 @@ function liveCloudClient(src) {
81969
82003
  init_identity2();
81970
82004
 
81971
82005
  // src/project-link.ts
82006
+ init_profile2();
81972
82007
  async function ensureProjectLink(root, profile, client) {
81973
82008
  if (profile.projectLinkDisabled) return { linked: false, reason: "disabled" };
81974
82009
  const locator = profile.repoLocator;
@@ -81993,10 +82028,12 @@ async function ensureProjectLink(root, profile, client) {
81993
82028
 
81994
82029
  // src/project-hydrate.ts
81995
82030
  init_src11();
82031
+ init_profile2();
81996
82032
 
81997
82033
  // src/project-reanchor.ts
81998
82034
  init_src();
81999
82035
  init_src11();
82036
+ init_profile2();
82000
82037
  var DEFAULT_LIMIT = 50;
82001
82038
  var ANCHOR_SYMBOL_KINDS2 = [
82002
82039
  "Function",
@@ -83712,6 +83749,7 @@ async function buildUnitBundle(root, unit, opts = {}) {
83712
83749
  }
83713
83750
 
83714
83751
  // src/project-history.ts
83752
+ init_profile2();
83715
83753
  var execFileAsync = promisify(execFile3);
83716
83754
  var HISTORY_EXTRACTOR_VERSION = "history-1";
83717
83755
  var LEASE_POLL_MS = 2e4;
@@ -84452,18 +84490,16 @@ fixtures/
84452
84490
  *.sql.gz
84453
84491
  `;
84454
84492
  function applyConsents(profile, config2, c, decidedAt, now = Date.now) {
84455
- const nextConfig = {
84456
- ...config2,
84457
- consent: {
84458
- ...config2.consent,
84459
- sync: c.sync !== "off",
84460
- telemetry: c.telemetry,
84461
- contributePackages: c.packages && c.sync !== "off"
84462
- },
84463
- 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
84464
84499
  };
84465
84500
  const nextProfile = {
84466
84501
  ...profile,
84502
+ consoleConsents,
84467
84503
  syncConsent: c.sync === "automatic" ? "automatic" : c.sync === "ask" ? "ask-each-time" : "disabled",
84468
84504
  linkConsents: {
84469
84505
  structure: c.structure,
@@ -84473,7 +84509,8 @@ function applyConsents(profile, config2, c, decidedAt, now = Date.now) {
84473
84509
  }
84474
84510
  };
84475
84511
  const prev = profile.linkConsents;
84476
- 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;
84477
84514
  return { profile: nextProfile, config: nextConfig, changed };
84478
84515
  }
84479
84516
  function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
@@ -84497,6 +84534,7 @@ function applyLinkDecision(root, profile, config2, decision, now = Date.now) {
84497
84534
  }
84498
84535
 
84499
84536
  // src/multi.ts
84537
+ init_consent();
84500
84538
  init_registry();
84501
84539
 
84502
84540
  // src/adopt.ts
@@ -84693,6 +84731,9 @@ function codexWakeCandidates(input) {
84693
84731
  return out2;
84694
84732
  }
84695
84733
 
84734
+ // src/multi.ts
84735
+ init_profile2();
84736
+
84696
84737
  // src/hook-route.ts
84697
84738
  function msysToWindowsPath(p, platform = process.platform) {
84698
84739
  if (platform !== "win32") return p;
@@ -85509,11 +85550,11 @@ async function startMultiDaemon(opts = {}) {
85509
85550
  const ANCHOR_PULL_INTERVAL_MS = 10 * 60 * 1e3;
85510
85551
  const anchorPullAll = async () => {
85511
85552
  const c = loadConfig();
85512
- if (!c.consent.sync || !hasCloudCredential(c)) return;
85553
+ if (!hasCloudCredential(c)) return;
85513
85554
  const client = cloudNow();
85514
85555
  for (const r of records) {
85515
85556
  const projectId = r.engine.profile.projectId;
85516
- if (!projectId) continue;
85557
+ if (!projectId || !effectiveConsent(c, r.engine.profile).sync) continue;
85517
85558
  try {
85518
85559
  const { salt } = await resolveProjectSymbolSalt(client, projectId);
85519
85560
  await pullProjectAnchors(r, client, salt);
@@ -85527,9 +85568,10 @@ async function startMultiDaemon(opts = {}) {
85527
85568
  }, ANCHOR_PULL_INTERVAL_MS);
85528
85569
  const ambientLinkAll = async () => {
85529
85570
  const c = loadConfig();
85530
- if (!c.consent.sync || !hasCloudCredential(c)) return;
85571
+ if (!hasCloudCredential(c)) return;
85531
85572
  const client = cloudNow();
85532
85573
  for (const r of records) {
85574
+ if (!effectiveConsent(c, r.engine.profile).sync) continue;
85533
85575
  const out2 = await ensureProjectLink(r.root, r.engine.profile, client);
85534
85576
  if (out2.linked) {
85535
85577
  console.log(
@@ -85596,14 +85638,14 @@ async function startMultiDaemon(opts = {}) {
85596
85638
  };
85597
85639
  void startHistoryStage(root, engine.profile, client, {
85598
85640
  anchors: { index: anchorIndex, salt },
85599
- // PS-web projects: the console's consents (Privacy tab) win over
85600
- // 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
85601
85643
  // the change printed so a flipped switch is visible in the log.
85602
85644
  applyConsents: (p, consents) => {
85603
85645
  const cfg2 = loadConfig();
85604
85646
  const applied = applyConsents(p, cfg2, consents, (/* @__PURE__ */ new Date()).toISOString());
85605
85647
  if (applied.changed) {
85606
- saveConfig(applied.config);
85648
+ if (applied.config.onboardedAt !== cfg2.onboardedAt) saveConfig(applied.config);
85607
85649
  Object.assign(engine.profile, applied.profile);
85608
85650
  saveProfile(root, engine.profile);
85609
85651
  console.log(
@@ -85885,7 +85927,7 @@ async function startMultiDaemon(opts = {}) {
85885
85927
  const ignore2 = loadClaimIgnorePatterns(globalDir());
85886
85928
  const primaryLanguage = machineDominantLanguage();
85887
85929
  const languages = records.flatMap((r) => r.engine.profile.languages ?? []);
85888
- const packages = cfg2.consent.contributePackages ? records.flatMap(
85930
+ const packages = cfg2.consent.contributePackages ? records.filter((r) => effectiveConsent(cfg2, r.engine.profile).contributePackages).flatMap(
85889
85931
  (r) => r.engine.store.findNodesByLabel("Package").map((p) => ({
85890
85932
  name: String(p.attrs["name"] ?? ""),
85891
85933
  purl: String(p.attrs["purl"] ?? p.id)
@@ -85904,7 +85946,9 @@ async function startMultiDaemon(opts = {}) {
85904
85946
  },
85905
85947
  async syncInstancesPublic() {
85906
85948
  const cfg2 = loadConfig();
85907
- 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
+ }
85908
85952
  if (registryCorrupt()) {
85909
85953
  const msg = "workspace registry unreadable \u2014 holding ALL per-workspace cloud push (bindings unprovable; fail-closed)";
85910
85954
  console.error(`[identity] ${msg}`);
@@ -85980,7 +86024,9 @@ async function startMultiDaemon(opts = {}) {
85980
86024
  }
85981
86025
  };
85982
86026
  for (const r of records) {
85983
- const recordIdentity = identityFor(r.entry);
86027
+ const recordConsent = effectiveConsent(cfg2, r.engine.profile);
86028
+ if (!recordConsent.sync) continue;
86029
+ const recordIdentity = identityFor(liveWorkspaceEntry(r.entry));
85984
86030
  if (recordIdentity.invalid) {
85985
86031
  noteIdentityBlock(r.id, r.entry.name, recordIdentity);
85986
86032
  errors.push(`[${r.entry.name}] identity: ${recordIdentity.reason}`);
@@ -86015,7 +86061,7 @@ async function startMultiDaemon(opts = {}) {
86015
86061
  profile: r.engine.profile,
86016
86062
  daemonVersion: DAEMON_VERSION,
86017
86063
  ignorePatterns: [...ignore2],
86018
- includePackages: cfg2.consent.contributePackages
86064
+ includePackages: recordConsent.contributePackages
86019
86065
  });
86020
86066
  if (context) {
86021
86067
  await lane("context", projectName, async () => {
@@ -86046,7 +86092,7 @@ async function startMultiDaemon(opts = {}) {
86046
86092
  profile: r.engine.profile,
86047
86093
  daemonVersion: DAEMON_VERSION,
86048
86094
  ignorePatterns: [...ignore2],
86049
- includePackages: cfg2.consent.contributePackages,
86095
+ includePackages: recordConsent.contributePackages,
86050
86096
  workspaceRoot: r.root,
86051
86097
  ...project ? { project } : {}
86052
86098
  });
@@ -86362,6 +86408,8 @@ async function startMultiDaemon(opts = {}) {
86362
86408
 
86363
86409
  // src/cli.ts
86364
86410
  init_src5();
86411
+ init_profile2();
86412
+ init_consent();
86365
86413
  init_git_remote();
86366
86414
  init_config();
86367
86415
  init_src7();
@@ -87704,8 +87752,14 @@ async function cmdStatus() {
87704
87752
  );
87705
87753
  const cs = cfg.consent;
87706
87754
  console.log(
87707
- ` 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)`
87708
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
+ }
87709
87763
  console.log(` cloud:`);
87710
87764
  console.log(` url: ${cfg.cloudUrl}`);
87711
87765
  if (daemonCloud) {
@@ -88154,12 +88208,11 @@ async function cmdLoginOAuthDevice(cfg, input) {
88154
88208
  }
88155
88209
  }
88156
88210
  async function linkRegisteredWorkspaces(cfg) {
88157
- if (!cfg.consent.sync) return;
88158
88211
  const client = authedCloudClient(cfg);
88159
88212
  for (const w of listWorkspaces()) {
88160
88213
  try {
88161
88214
  const profile = loadProfile(w.path);
88162
- if (!profile) continue;
88215
+ if (!profile || !effectiveConsent(cfg, profile).sync) continue;
88163
88216
  refreshRepoLocator(w.path, profile);
88164
88217
  const out2 = await ensureProjectLink(w.path, profile, client);
88165
88218
  if (out2.linked) {
@@ -88244,7 +88297,7 @@ async function cmdLink(args2) {
88244
88297
  `linked${d.existed ? "" : " (created)"}: ${d.locator} \u2192 project ${d.projectId} \xB7 ${where} \xB7 ${d.visibility} \xB7 grant v${d.grantVersion}`
88245
88298
  );
88246
88299
  console.log(
88247
- `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"}`
88248
88301
  );
88249
88302
  await refreshLinkedCodexHooks(args2);
88250
88303
  if (applied.wroteIgnore) console.log("wrote .errataignore (starter) \u2014 edit it; it is your hard control");