@massa-ai/mcp-client 1.35.1 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/config-cli.js +311 -183
  2. package/dist/index.js +339 -276
  3. package/package.json +3 -3
@@ -1162,7 +1162,8 @@ var init_config = __esm(() => {
1162
1162
  },
1163
1163
  logging: {
1164
1164
  level: process.env.LOG_LEVEL || fileConfig.logging?.level || "info",
1165
- enableMetrics: process.env.ENABLE_METRICS === "true" || process.env.ENABLE_METRICS === undefined && !!fileConfig.logging?.enableMetrics
1165
+ enableMetrics: process.env.ENABLE_METRICS === "true" || process.env.ENABLE_METRICS === undefined && !!fileConfig.logging?.enableMetrics,
1166
+ file: process.env.MASSA_AI_LOG_FILE || fileConfig.logging?.file || undefined
1166
1167
  },
1167
1168
  synapse: {
1168
1169
  enabled: process.env.SYNAPSE_ENABLED !== "false",
@@ -1316,20 +1317,25 @@ var init_types = __esm(() => {
1316
1317
  var init_interfaces = () => {};
1317
1318
 
1318
1319
  // ../../packages/shared/dist/utils/logger.js
1320
+ import fs2 from "fs";
1321
+
1319
1322
  class Logger {
1320
1323
  _level;
1321
1324
  _enableMetrics;
1325
+ _logFilePath;
1322
1326
  _initialized = false;
1323
1327
  constructor() {}
1324
1328
  ensureInitialized() {
1325
1329
  if (!this._initialized) {
1326
1330
  try {
1327
- const configLevel = config.get("logging").level;
1328
- this._level = this.parseLogLevel(configLevel);
1329
- this._enableMetrics = config.get("logging").enableMetrics;
1331
+ const loggingConfig = config.get("logging");
1332
+ this._level = this.parseLogLevel(loggingConfig.level);
1333
+ this._enableMetrics = loggingConfig.enableMetrics;
1334
+ this._logFilePath = loggingConfig.file;
1330
1335
  } catch {
1331
1336
  this._level = LogLevel.INFO;
1332
1337
  this._enableMetrics = false;
1338
+ this._logFilePath = undefined;
1333
1339
  }
1334
1340
  this._initialized = true;
1335
1341
  }
@@ -1342,6 +1348,10 @@ class Logger {
1342
1348
  this.ensureInitialized();
1343
1349
  return this._enableMetrics;
1344
1350
  }
1351
+ get logFilePath() {
1352
+ this.ensureInitialized();
1353
+ return this._logFilePath;
1354
+ }
1345
1355
  parseLogLevel(level) {
1346
1356
  const levels = {
1347
1357
  debug: LogLevel.DEBUG,
@@ -1361,6 +1371,13 @@ class Logger {
1361
1371
  }
1362
1372
  write(message, _level) {
1363
1373
  console.error(message);
1374
+ const filePath = this.logFilePath;
1375
+ if (filePath) {
1376
+ try {
1377
+ fs2.appendFileSync(filePath, message + `
1378
+ `);
1379
+ } catch {}
1380
+ }
1364
1381
  }
1365
1382
  debug(message, meta) {
1366
1383
  if (this.shouldLog(LogLevel.DEBUG)) {
@@ -1770,7 +1787,7 @@ var init_hosts = __esm(() => {
1770
1787
  });
1771
1788
 
1772
1789
  // ../../packages/shared/dist/profile-switch/state.js
1773
- import fs2 from "fs";
1790
+ import fs3 from "fs";
1774
1791
  import path6 from "path";
1775
1792
  function namedError(name, message) {
1776
1793
  const err = new InstallStateError(message);
@@ -1797,7 +1814,7 @@ function validateShape(raw2, filePath) {
1797
1814
  function readInstallState(filePath) {
1798
1815
  let text;
1799
1816
  try {
1800
- text = fs2.readFileSync(filePath, "utf-8");
1817
+ text = fs3.readFileSync(filePath, "utf-8");
1801
1818
  } catch (err) {
1802
1819
  const code = err.code;
1803
1820
  if (code === "ENOENT")
@@ -1817,8 +1834,8 @@ function writeInstallState(filePath, state) {
1817
1834
  const text = `${JSON.stringify(validated, null, 2)}
1818
1835
  `;
1819
1836
  try {
1820
- fs2.mkdirSync(path6.dirname(filePath), { recursive: true });
1821
- fs2.writeFileSync(filePath, text);
1837
+ fs3.mkdirSync(path6.dirname(filePath), { recursive: true });
1838
+ fs3.writeFileSync(filePath, text);
1822
1839
  } catch (err) {
1823
1840
  throw UnwritableInstallStateError(filePath, err.message);
1824
1841
  }
@@ -1845,7 +1862,7 @@ var init_state = __esm(() => {
1845
1862
  });
1846
1863
 
1847
1864
  // ../../packages/shared/dist/profile-switch/lock.js
1848
- import fs3 from "fs";
1865
+ import fs4 from "fs";
1849
1866
  import path7 from "path";
1850
1867
  import os4 from "os";
1851
1868
  import crypto3 from "crypto";
@@ -1858,7 +1875,7 @@ function namedError2(name, message) {
1858
1875
  function readOwner(ownerPath) {
1859
1876
  let raw2;
1860
1877
  try {
1861
- raw2 = JSON.parse(fs3.readFileSync(ownerPath, "utf-8"));
1878
+ raw2 = JSON.parse(fs4.readFileSync(ownerPath, "utf-8"));
1862
1879
  } catch {
1863
1880
  return null;
1864
1881
  }
@@ -1874,7 +1891,7 @@ function releaseIfOwned(lockDir, ownerPath, token) {
1874
1891
  const owner = readOwner(ownerPath);
1875
1892
  if (owner === null || owner.token !== token)
1876
1893
  return;
1877
- fs3.rmSync(lockDir, { recursive: true, force: true });
1894
+ fs4.rmSync(lockDir, { recursive: true, force: true });
1878
1895
  }
1879
1896
  function acquireLock(stateFilePath, options = {}) {
1880
1897
  const lockDir = `${stateFilePath}.switch.lock`;
@@ -1883,11 +1900,11 @@ function acquireLock(stateFilePath, options = {}) {
1883
1900
  const identity = options.identity ?? DEFAULT_IDENTITY;
1884
1901
  const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
1885
1902
  const createFresh = () => {
1886
- fs3.mkdirSync(lockDir);
1903
+ fs4.mkdirSync(lockDir);
1887
1904
  const pid = identity.pid();
1888
1905
  const startedAt = identity.processStart(pid);
1889
1906
  if (startedAt == null) {
1890
- fs3.rmSync(lockDir, { recursive: true, force: true });
1907
+ fs4.rmSync(lockDir, { recursive: true, force: true });
1891
1908
  throw LockAcquireError(lockDir, "could not determine this process's start-time identity");
1892
1909
  }
1893
1910
  const token = crypto3.randomUUID();
@@ -1898,8 +1915,8 @@ function acquireLock(stateFilePath, options = {}) {
1898
1915
  token,
1899
1916
  timestamp: clock.now()
1900
1917
  };
1901
- fs3.mkdirSync(path7.dirname(ownerPath), { recursive: true });
1902
- fs3.writeFileSync(ownerPath, JSON.stringify(record));
1918
+ fs4.mkdirSync(path7.dirname(ownerPath), { recursive: true });
1919
+ fs4.writeFileSync(ownerPath, JSON.stringify(record));
1903
1920
  return { lockDir, release: () => releaseIfOwned(lockDir, ownerPath, token) };
1904
1921
  };
1905
1922
  try {
@@ -1914,11 +1931,11 @@ function acquireLock(stateFilePath, options = {}) {
1914
1931
  throw LockHeldError(lockDir);
1915
1932
  const reclaimDir = `${lockDir}.reclaim.${owner.token}`;
1916
1933
  try {
1917
- fs3.renameSync(lockDir, reclaimDir);
1934
+ fs4.renameSync(lockDir, reclaimDir);
1918
1935
  } catch {
1919
1936
  throw LockHeldError(lockDir);
1920
1937
  }
1921
- fs3.rmSync(reclaimDir, { recursive: true, force: true });
1938
+ fs4.rmSync(reclaimDir, { recursive: true, force: true });
1922
1939
  try {
1923
1940
  return createFresh();
1924
1941
  } catch {
@@ -1952,7 +1969,7 @@ var init_lock = __esm(() => {
1952
1969
  });
1953
1970
 
1954
1971
  // ../../packages/shared/dist/profile-switch/engine.js
1955
- import fs4 from "fs";
1972
+ import fs5 from "fs";
1956
1973
  import path8 from "path";
1957
1974
  import os5 from "os";
1958
1975
  import crypto4 from "crypto";
@@ -1986,7 +2003,7 @@ function listProfiles(opts = {}) {
1986
2003
  availableProfiles: []
1987
2004
  };
1988
2005
  }
1989
- const installed = fs4.existsSync(layout.activeDir);
2006
+ const installed = fs5.existsSync(layout.activeDir);
1990
2007
  const availableProfiles = listVariantProfiles(layout);
1991
2008
  const platform = state.platforms[host];
1992
2009
  return {
@@ -2002,9 +2019,9 @@ function listProfiles(opts = {}) {
2002
2019
  return { hosts };
2003
2020
  }
2004
2021
  function listVariantProfiles(layout) {
2005
- if (!fs4.existsSync(layout.variantsRoot))
2022
+ if (!fs5.existsSync(layout.variantsRoot))
2006
2023
  return [];
2007
- return fs4.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
2024
+ return fs5.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
2008
2025
  }
2009
2026
  function matchesGlob(filename, glob) {
2010
2027
  const starIdx = glob.indexOf("*");
@@ -2017,32 +2034,32 @@ function matchesGlob(filename, glob) {
2017
2034
  function assertStateWritable(stateFilePath) {
2018
2035
  const dir = path8.dirname(stateFilePath);
2019
2036
  try {
2020
- fs4.mkdirSync(dir, { recursive: true });
2037
+ fs5.mkdirSync(dir, { recursive: true });
2021
2038
  } catch (err) {
2022
2039
  throw UnwritableInstallStateError(stateFilePath, err.message);
2023
2040
  }
2024
- const checkPath = fs4.existsSync(stateFilePath) ? stateFilePath : dir;
2041
+ const checkPath = fs5.existsSync(stateFilePath) ? stateFilePath : dir;
2025
2042
  try {
2026
- fs4.accessSync(checkPath, fs4.constants.W_OK);
2043
+ fs5.accessSync(checkPath, fs5.constants.W_OK);
2027
2044
  } catch (err) {
2028
2045
  throw UnwritableInstallStateError(stateFilePath, err.message);
2029
2046
  }
2030
2047
  }
2031
2048
  function copyFileRouteVariant(layout, variantDir) {
2032
- fs4.mkdirSync(layout.activeDir, { recursive: true });
2049
+ fs5.mkdirSync(layout.activeDir, { recursive: true });
2033
2050
  let changed = 0;
2034
- for (const entry of fs4.readdirSync(variantDir, { withFileTypes: true })) {
2051
+ for (const entry of fs5.readdirSync(variantDir, { withFileTypes: true })) {
2035
2052
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
2036
2053
  continue;
2037
- fs4.copyFileSync(path8.join(variantDir, entry.name), path8.join(layout.activeDir, entry.name));
2054
+ fs5.copyFileSync(path8.join(variantDir, entry.name), path8.join(layout.activeDir, entry.name));
2038
2055
  changed++;
2039
2056
  }
2040
2057
  return changed;
2041
2058
  }
2042
2059
  function repointOpencodeVariant(layout, variantDir) {
2043
- fs4.mkdirSync(layout.activeDir, { recursive: true });
2060
+ fs5.mkdirSync(layout.activeDir, { recursive: true });
2044
2061
  let changed = 0;
2045
- for (const entry of fs4.readdirSync(variantDir, { withFileTypes: true })) {
2062
+ for (const entry of fs5.readdirSync(variantDir, { withFileTypes: true })) {
2046
2063
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
2047
2064
  continue;
2048
2065
  const dest = path8.join(layout.activeDir, entry.name);
@@ -2050,15 +2067,15 @@ function repointOpencodeVariant(layout, variantDir) {
2050
2067
  let destExists = true;
2051
2068
  let destIsSymlink = false;
2052
2069
  try {
2053
- destIsSymlink = fs4.lstatSync(dest).isSymbolicLink();
2070
+ destIsSymlink = fs5.lstatSync(dest).isSymbolicLink();
2054
2071
  } catch {
2055
2072
  destExists = false;
2056
2073
  }
2057
2074
  if (destExists && !destIsSymlink)
2058
2075
  continue;
2059
2076
  const tmp = `${dest}.massa-ai-switch.${crypto4.randomUUID()}`;
2060
- fs4.symlinkSync(target, tmp);
2061
- fs4.renameSync(tmp, dest);
2077
+ fs5.symlinkSync(target, tmp);
2078
+ fs5.renameSync(tmp, dest);
2062
2079
  changed++;
2063
2080
  }
2064
2081
  return changed;
@@ -2080,13 +2097,13 @@ function switchProfile(opts) {
2080
2097
  if (fileHosts.length === 0) {
2081
2098
  return { profile: opts.profile, dryRun, hosts: orderRows(universe, skipRows), restartRequired: false };
2082
2099
  }
2083
- const installedFileHosts = fileHosts.filter((h) => fs4.existsSync(h.layout.activeDir));
2100
+ const installedFileHosts = fileHosts.filter((h) => fs5.existsSync(h.layout.activeDir));
2084
2101
  if (installedFileHosts.length === 0)
2085
2102
  throw NoHostsDetectedError();
2086
2103
  const withAvailability = fileHosts.map((h) => {
2087
- const variantsRootExists = fs4.existsSync(h.layout.variantsRoot);
2104
+ const variantsRootExists = fs5.existsSync(h.layout.variantsRoot);
2088
2105
  const variantDir = h.layout.variantDir(opts.profile);
2089
- const available = variantsRootExists && fs4.existsSync(variantDir) && fs4.statSync(variantDir).isDirectory();
2106
+ const available = variantsRootExists && fs5.existsSync(variantDir) && fs5.statSync(variantDir).isDirectory();
2090
2107
  return { ...h, variantsRootExists, variantDir, available };
2091
2108
  });
2092
2109
  if (!withAvailability.some((h) => h.available)) {
@@ -6300,8 +6317,8 @@ var init_esm4 = __esm(() => {
6300
6317
  #children;
6301
6318
  nocase;
6302
6319
  #fs;
6303
- constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs5 = defaultFS } = {}) {
6304
- this.#fs = fsFromOption(fs5);
6320
+ constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs6 = defaultFS } = {}) {
6321
+ this.#fs = fsFromOption(fs6);
6305
6322
  if (cwd instanceof URL || cwd.startsWith("file://")) {
6306
6323
  cwd = fileURLToPath(cwd);
6307
6324
  }
@@ -6776,8 +6793,8 @@ var init_esm4 = __esm(() => {
6776
6793
  parseRootPath(dir) {
6777
6794
  return win32.parse(dir).root.toUpperCase();
6778
6795
  }
6779
- newRoot(fs5) {
6780
- return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs5 });
6796
+ newRoot(fs6) {
6797
+ return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs6 });
6781
6798
  }
6782
6799
  isAbsolute(p) {
6783
6800
  return p.startsWith("/") || p.startsWith("\\") || /^[a-z]:(\/|\\)/i.test(p);
@@ -6793,8 +6810,8 @@ var init_esm4 = __esm(() => {
6793
6810
  parseRootPath(_dir) {
6794
6811
  return "/";
6795
6812
  }
6796
- newRoot(fs5) {
6797
- return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs5 });
6813
+ newRoot(fs6) {
6814
+ return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs6 });
6798
6815
  }
6799
6816
  isAbsolute(p) {
6800
6817
  return p.startsWith("/");
@@ -8200,7 +8217,7 @@ var init_capture_policy = __esm(() => {
8200
8217
  });
8201
8218
 
8202
8219
  // ../../packages/core/dist/services/search/ignore-patterns.js
8203
- import fs5 from "fs/promises";
8220
+ import fs6 from "fs/promises";
8204
8221
  import path10 from "path";
8205
8222
  function buildExtensionGlob(extensions) {
8206
8223
  return extensions.map((ext2) => `**/*${ext2}`);
@@ -8225,7 +8242,7 @@ async function loadProjectIgnore(projectPath) {
8225
8242
  ig.add(DEFAULT_IGNORES);
8226
8243
  try {
8227
8244
  const gitignorePath = path10.join(projectPath, ".gitignore");
8228
- const gitignoreContent = await fs5.readFile(gitignorePath, "utf8");
8245
+ const gitignoreContent = await fs6.readFile(gitignorePath, "utf8");
8229
8246
  const rules = gitignoreContent.split(`
8230
8247
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
8231
8248
  ig.add(rules);
@@ -9821,15 +9838,15 @@ var require_pg_connection_string = __commonJS((exports, module) => {
9821
9838
  if (config2.sslnegotiation === "direct" && config2.ssl === undefined) {
9822
9839
  config2.ssl = true;
9823
9840
  }
9824
- const fs6 = config2.sslcert || config2.sslkey || config2.sslrootcert ? __require("fs") : null;
9841
+ const fs7 = config2.sslcert || config2.sslkey || config2.sslrootcert ? __require("fs") : null;
9825
9842
  if (config2.sslcert) {
9826
- config2.ssl.cert = fs6.readFileSync(config2.sslcert).toString();
9843
+ config2.ssl.cert = fs7.readFileSync(config2.sslcert).toString();
9827
9844
  }
9828
9845
  if (config2.sslkey) {
9829
- config2.ssl.key = fs6.readFileSync(config2.sslkey).toString();
9846
+ config2.ssl.key = fs7.readFileSync(config2.sslkey).toString();
9830
9847
  }
9831
9848
  if (config2.sslrootcert) {
9832
- config2.ssl.ca = fs6.readFileSync(config2.sslrootcert).toString();
9849
+ config2.ssl.ca = fs7.readFileSync(config2.sslrootcert).toString();
9833
9850
  }
9834
9851
  if (options.useLibpqCompat && config2.uselibpqcompat) {
9835
9852
  throw new Error("Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.");
@@ -11708,15 +11725,15 @@ var require_helper = __commonJS((exports, module) => {
11708
11725
  // ../../node_modules/pgpass/lib/index.js
11709
11726
  var require_lib = __commonJS((exports, module) => {
11710
11727
  var path11 = __require("path");
11711
- var fs6 = __require("fs");
11728
+ var fs7 = __require("fs");
11712
11729
  var helper = require_helper();
11713
11730
  module.exports = function(connInfo, cb) {
11714
11731
  var file = helper.getFileName();
11715
- fs6.stat(file, function(err, stat) {
11732
+ fs7.stat(file, function(err, stat) {
11716
11733
  if (err || !helper.usePgPass(stat, file)) {
11717
11734
  return cb(undefined);
11718
11735
  }
11719
- var st = fs6.createReadStream(file);
11736
+ var st = fs7.createReadStream(file);
11720
11737
  helper.getPassword(connInfo, st, cb);
11721
11738
  });
11722
11739
  };
@@ -13246,6 +13263,89 @@ var init_db_connection = __esm(() => {
13246
13263
  init_config();
13247
13264
  });
13248
13265
 
13266
+ // ../../packages/core/dist/kernel/sanitize/credential-scrub.js
13267
+ function markerFor(id) {
13268
+ return `[REDACTED:${id}]`;
13269
+ }
13270
+ function fullMatchRule(id, pattern) {
13271
+ const marker = markerFor(id);
13272
+ return {
13273
+ id,
13274
+ replace(text) {
13275
+ let count = 0;
13276
+ const replaced = text.replace(pattern, () => {
13277
+ count++;
13278
+ return marker;
13279
+ });
13280
+ return { text: replaced, count };
13281
+ }
13282
+ };
13283
+ }
13284
+ function scrubCredentials(payloadJson) {
13285
+ const redactions = {};
13286
+ for (const id of RULE_IDS)
13287
+ redactions[id] = 0;
13288
+ let text = payloadJson;
13289
+ for (const rule of RULES) {
13290
+ const { text: next, count } = rule.replace(text);
13291
+ text = next;
13292
+ redactions[rule.id] += count;
13293
+ }
13294
+ const total = Object.values(redactions).reduce((sum, n) => sum + n, 0);
13295
+ return {
13296
+ sanitized: text,
13297
+ redactions,
13298
+ total
13299
+ };
13300
+ }
13301
+ var PEM_PATTERN, JWT_PATTERN, AWS_KEY_PATTERN, SK_KEY_PATTERN, GITHUB_TOKEN_PATTERN, SLACK_TOKEN_PATTERN, BEARER_PATTERN, RULES, RULE_IDS;
13302
+ var init_credential_scrub = __esm(() => {
13303
+ PEM_PATTERN = /-----BEGIN [A-Z ]{0,32}PRIVATE KEY-----[\s\S]{0,8192}?-----END [A-Z ]{0,32}PRIVATE KEY-----/g;
13304
+ JWT_PATTERN = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g;
13305
+ AWS_KEY_PATTERN = /\b(?:AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}\b/g;
13306
+ SK_KEY_PATTERN = /\bsk-[A-Za-z0-9_-]{20,}\b/g;
13307
+ GITHUB_TOKEN_PATTERN = /\bgh[pousr]_[A-Za-z0-9]{36,}\b|\bgithub_pat_[A-Za-z0-9_]{22,}\b/g;
13308
+ SLACK_TOKEN_PATTERN = /\bxox[baprs]-[A-Za-z0-9-]{18,}\b/g;
13309
+ BEARER_PATTERN = /(Bearer\s+)([A-Za-z0-9._~+/=-]{20,})/g;
13310
+ RULES = [
13311
+ fullMatchRule("pem", PEM_PATTERN),
13312
+ fullMatchRule("jwt", JWT_PATTERN),
13313
+ fullMatchRule("aws-key", AWS_KEY_PATTERN),
13314
+ fullMatchRule("sk-key", SK_KEY_PATTERN),
13315
+ fullMatchRule("github-token", GITHUB_TOKEN_PATTERN),
13316
+ fullMatchRule("slack-token", SLACK_TOKEN_PATTERN),
13317
+ {
13318
+ id: "bearer",
13319
+ replace(text) {
13320
+ let count = 0;
13321
+ const replaced = text.replace(BEARER_PATTERN, (_m, prefix) => {
13322
+ count++;
13323
+ return `${prefix}${markerFor("bearer")}`;
13324
+ });
13325
+ return { text: replaced, count };
13326
+ }
13327
+ }
13328
+ ];
13329
+ RULE_IDS = RULES.map((r) => r.id);
13330
+ });
13331
+
13332
+ // ../../packages/core/dist/kernel/sanitize/safe-error-summary.js
13333
+ function safeErrorSummary(error) {
13334
+ if (error instanceof Error) {
13335
+ return {
13336
+ name: error.name,
13337
+ message: scrubCredentials(error.message).sanitized
13338
+ };
13339
+ }
13340
+ return {
13341
+ name: "UnknownError",
13342
+ message: scrubCredentials(String(error)).sanitized
13343
+ };
13344
+ }
13345
+ var init_safe_error_summary = __esm(() => {
13346
+ init_credential_scrub();
13347
+ });
13348
+
13249
13349
  // ../../packages/core/dist/kernel/alias-resolver.js
13250
13350
  class ProjectIdentityAliasResolver {
13251
13351
  ttlMs;
@@ -13271,9 +13371,7 @@ class ProjectIdentityAliasResolver {
13271
13371
  this.cache.set(projectId, { canonical, expiresAt: this.now() + this.ttlMs });
13272
13372
  return canonical;
13273
13373
  } catch (error) {
13274
- logger.warn("[project-identity] alias resolution failed; using original id (sanitized)", {
13275
- name: error instanceof Error ? error.name : "unknown"
13276
- });
13374
+ logger.warn("[project-identity] alias resolution failed; using original id", safeErrorSummary(error));
13277
13375
  return projectId;
13278
13376
  }
13279
13377
  }
@@ -13330,10 +13428,11 @@ var DEFAULT_TTL_MS = 30000, DEFAULT_RESOLVE_TIMEOUT_MS = 250, sharedResolver = n
13330
13428
  var init_alias_resolver = __esm(() => {
13331
13429
  init_dist();
13332
13430
  init_db_connection();
13431
+ init_safe_error_summary();
13333
13432
  });
13334
13433
 
13335
13434
  // ../../packages/core/dist/services/search/index-manager.js
13336
- import fs6 from "fs";
13435
+ import fs7 from "fs";
13337
13436
  import path11 from "path";
13338
13437
 
13339
13438
  class IndexManager {
@@ -13429,7 +13528,7 @@ class IndexManager {
13429
13528
  for (const filePath of indexedFiles) {
13430
13529
  const fullPath = path11.join(projectPath, filePath);
13431
13530
  try {
13432
- const stat = await fs6.promises.stat(fullPath);
13531
+ const stat = await fs7.promises.stat(fullPath);
13433
13532
  fileMetadata[filePath] = {
13434
13533
  path: filePath,
13435
13534
  mtime: stat.mtimeMs,
@@ -13482,7 +13581,7 @@ class IndexManager {
13482
13581
  }
13483
13582
  const fullPath = path11.join(projectPath, match2);
13484
13583
  try {
13485
- const stat = await fs6.promises.stat(fullPath);
13584
+ const stat = await fs7.promises.stat(fullPath);
13486
13585
  files.set(match2, {
13487
13586
  path: match2,
13488
13587
  mtime: stat.mtimeMs,
@@ -35173,7 +35272,7 @@ var require_auth_config = __commonJS((exports, module) => {
35173
35272
  writeAuthConfig: () => writeAuthConfig
35174
35273
  });
35175
35274
  module.exports = __toCommonJS2(auth_config_exports);
35176
- var fs7 = __toESM2(__require("fs"));
35275
+ var fs8 = __toESM2(__require("fs"));
35177
35276
  var path12 = __toESM2(__require("path"));
35178
35277
  var import_token_util = require_token_util();
35179
35278
  function getAuthConfigPath() {
@@ -35186,10 +35285,10 @@ var require_auth_config = __commonJS((exports, module) => {
35186
35285
  function readAuthConfig() {
35187
35286
  try {
35188
35287
  const authPath = getAuthConfigPath();
35189
- if (!fs7.existsSync(authPath)) {
35288
+ if (!fs8.existsSync(authPath)) {
35190
35289
  return null;
35191
35290
  }
35192
- const content = fs7.readFileSync(authPath, "utf8");
35291
+ const content = fs8.readFileSync(authPath, "utf8");
35193
35292
  if (!content) {
35194
35293
  return null;
35195
35294
  }
@@ -35201,10 +35300,10 @@ var require_auth_config = __commonJS((exports, module) => {
35201
35300
  function writeAuthConfig(config3) {
35202
35301
  const authPath = getAuthConfigPath();
35203
35302
  const authDir = path12.dirname(authPath);
35204
- if (!fs7.existsSync(authDir)) {
35205
- fs7.mkdirSync(authDir, { mode: 504, recursive: true });
35303
+ if (!fs8.existsSync(authDir)) {
35304
+ fs8.mkdirSync(authDir, { mode: 504, recursive: true });
35206
35305
  }
35207
- fs7.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
35306
+ fs8.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
35208
35307
  }
35209
35308
  function isValidAccessToken(authConfig, expirationBufferMs = 0) {
35210
35309
  if (!authConfig.token)
@@ -35380,7 +35479,7 @@ var require_token_util = __commonJS((exports, module) => {
35380
35479
  });
35381
35480
  module.exports = __toCommonJS2(token_util_exports);
35382
35481
  var path12 = __toESM2(__require("path"));
35383
- var fs7 = __toESM2(__require("fs"));
35482
+ var fs8 = __toESM2(__require("fs"));
35384
35483
  var import_token_error = require_token_error();
35385
35484
  var import_token_io = require_token_io();
35386
35485
  var import_auth_config = require_auth_config();
@@ -35461,10 +35560,10 @@ var require_token_util = __commonJS((exports, module) => {
35461
35560
  throw new import_token_error.VercelOidcTokenError("Unable to find project root directory. Have you linked your project with `vc link?`");
35462
35561
  }
35463
35562
  const prjPath = path12.join(dir, ".vercel", "project.json");
35464
- if (!fs7.existsSync(prjPath)) {
35563
+ if (!fs8.existsSync(prjPath)) {
35465
35564
  throw new import_token_error.VercelOidcTokenError("project.json not found, have you linked your project with `vc link?`");
35466
35565
  }
35467
- const prj = JSON.parse(fs7.readFileSync(prjPath, "utf8"));
35566
+ const prj = JSON.parse(fs8.readFileSync(prjPath, "utf8"));
35468
35567
  if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
35469
35568
  throw new TypeError("Expected a string-valued projectId property. Try running `vc link` to re-link your project.");
35470
35569
  }
@@ -35477,9 +35576,9 @@ var require_token_util = __commonJS((exports, module) => {
35477
35576
  }
35478
35577
  const tokenPath = path12.join(dir, "com.vercel.token", `${projectId}.json`);
35479
35578
  const tokenJson = JSON.stringify(token);
35480
- fs7.mkdirSync(path12.dirname(tokenPath), { mode: 504, recursive: true });
35481
- fs7.writeFileSync(tokenPath, tokenJson);
35482
- fs7.chmodSync(tokenPath, 432);
35579
+ fs8.mkdirSync(path12.dirname(tokenPath), { mode: 504, recursive: true });
35580
+ fs8.writeFileSync(tokenPath, tokenJson);
35581
+ fs8.chmodSync(tokenPath, 432);
35483
35582
  return;
35484
35583
  }
35485
35584
  function loadToken(projectId) {
@@ -35488,10 +35587,10 @@ var require_token_util = __commonJS((exports, module) => {
35488
35587
  throw new import_token_error.VercelOidcTokenError("Unable to find user data directory. Please reach out to Vercel support.");
35489
35588
  }
35490
35589
  const tokenPath = path12.join(dir, "com.vercel.token", `${projectId}.json`);
35491
- if (!fs7.existsSync(tokenPath)) {
35590
+ if (!fs8.existsSync(tokenPath)) {
35492
35591
  return null;
35493
35592
  }
35494
- const token = JSON.parse(fs7.readFileSync(tokenPath, "utf8"));
35593
+ const token = JSON.parse(fs8.readFileSync(tokenPath, "utf8"));
35495
35594
  assertVercelOidcTokenResponse(token);
35496
35595
  return token;
35497
35596
  }
@@ -62921,26 +63020,26 @@ var require_process = __commonJS((exports, module) => {
62921
63020
 
62922
63021
  // ../../node_modules/detect-libc/lib/filesystem.js
62923
63022
  var require_filesystem = __commonJS((exports, module) => {
62924
- var fs7 = __require("fs");
63023
+ var fs8 = __require("fs");
62925
63024
  var LDD_PATH = "/usr/bin/ldd";
62926
63025
  var SELF_PATH = "/proc/self/exe";
62927
63026
  var MAX_LENGTH = 2048;
62928
63027
  var readFileSync2 = (path12) => {
62929
- const fd = fs7.openSync(path12, "r");
63028
+ const fd = fs8.openSync(path12, "r");
62930
63029
  const buffer = Buffer.alloc(MAX_LENGTH);
62931
- const bytesRead = fs7.readSync(fd, buffer, 0, MAX_LENGTH, 0);
62932
- fs7.close(fd, () => {});
63030
+ const bytesRead = fs8.readSync(fd, buffer, 0, MAX_LENGTH, 0);
63031
+ fs8.close(fd, () => {});
62933
63032
  return buffer.subarray(0, bytesRead);
62934
63033
  };
62935
63034
  var readFile = (path12) => new Promise((resolve4, reject) => {
62936
- fs7.open(path12, "r", (err, fd) => {
63035
+ fs8.open(path12, "r", (err, fd) => {
62937
63036
  if (err) {
62938
63037
  reject(err);
62939
63038
  } else {
62940
63039
  const buffer = Buffer.alloc(MAX_LENGTH);
62941
- fs7.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
63040
+ fs8.read(fd, buffer, 0, MAX_LENGTH, 0, (_, bytesRead) => {
62942
63041
  resolve4(buffer.subarray(0, bytesRead));
62943
- fs7.close(fd, () => {});
63042
+ fs8.close(fd, () => {});
62944
63043
  });
62945
63044
  }
62946
63045
  });
@@ -99603,10 +99702,10 @@ Note that ${s.bold("include")} statements only accept relation fields.`, a;
99603
99702
  super(t, "P2023", r);
99604
99703
  }
99605
99704
  };
99606
- var fs7 = new WeakMap;
99705
+ var fs8 = new WeakMap;
99607
99706
  function Ep(e) {
99608
- let t = fs7.get(e);
99609
- return t || (t = Object.entries(e), fs7.set(e, t)), t;
99707
+ let t = fs8.get(e);
99708
+ return t || (t = Object.entries(e), fs8.set(e, t)), t;
99610
99709
  }
99611
99710
  function hs(e, t, r) {
99612
99711
  switch (t.type) {
@@ -114415,6 +114514,89 @@ var init_reranker = __esm(() => {
114415
114514
  });
114416
114515
  });
114417
114516
 
114517
+ // ../../packages/core/dist/kernel/search-diagnostics.js
114518
+ function searchBackendUnavailable(component, cause) {
114519
+ return cause instanceof SearchServiceError ? cause : new SearchServiceError("SEARCH_BACKEND_UNAVAILABLE", component, { cause });
114520
+ }
114521
+ function storeCorruption(component, cause) {
114522
+ return cause instanceof SearchServiceError ? cause : new SearchServiceError("STORE_CORRUPTION", component, {
114523
+ cause,
114524
+ statusCode: 500
114525
+ });
114526
+ }
114527
+ function projectNotIndexed(projectId, message) {
114528
+ return new SearchServiceError("PROJECT_NOT_INDEXED", projectId, {
114529
+ message,
114530
+ statusCode: 404
114531
+ });
114532
+ }
114533
+ function recordSearchDegradation(code, component, projectId) {
114534
+ const degradation = {
114535
+ code,
114536
+ component,
114537
+ message: DEGRADATION_MESSAGES[code]
114538
+ };
114539
+ diagnostics.push({
114540
+ kind: "degradation",
114541
+ ...degradation,
114542
+ projectId,
114543
+ timestamp: new Date().toISOString()
114544
+ });
114545
+ if (diagnostics.length > MAX_DIAGNOSTICS) {
114546
+ diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
114547
+ }
114548
+ return degradation;
114549
+ }
114550
+ function recordSearchFailure(error51, projectId) {
114551
+ if (recordedFailures.has(error51))
114552
+ return;
114553
+ recordedFailures.add(error51);
114554
+ diagnostics.push({
114555
+ kind: "failure",
114556
+ code: error51.code,
114557
+ component: error51.component,
114558
+ message: error51.message,
114559
+ projectId,
114560
+ timestamp: new Date().toISOString()
114561
+ });
114562
+ if (diagnostics.length > MAX_DIAGNOSTICS) {
114563
+ diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
114564
+ }
114565
+ }
114566
+ function getSearchDiagnostics() {
114567
+ return diagnostics.map((diagnostic) => ({ ...diagnostic }));
114568
+ }
114569
+ function resetSearchDiagnosticsForTests() {
114570
+ diagnostics.length = 0;
114571
+ }
114572
+ var MAX_DIAGNOSTICS = 100, diagnostics, recordedFailures, DEGRADATION_MESSAGES, SearchServiceError;
114573
+ var init_search_diagnostics = __esm(() => {
114574
+ diagnostics = [];
114575
+ recordedFailures = new WeakSet;
114576
+ DEGRADATION_MESSAGES = {
114577
+ QUERY_UNDERSTANDING_UNAVAILABLE: "Query understanding was unavailable; original query used",
114578
+ TRIGRAM_UNAVAILABLE: "Trigram enrichment was unavailable",
114579
+ FUZZY_SEARCH_UNAVAILABLE: "Fuzzy enrichment was unavailable",
114580
+ PROXIMITY_RERANK_UNAVAILABLE: "Proximity reranking was unavailable; fused order preserved",
114581
+ GRAPH_AUGMENTATION_UNAVAILABLE: "Graph augmentation was unavailable",
114582
+ SYNAPSE_UNAVAILABLE: "Synapse enrichment was unavailable; stateless results used",
114583
+ SEARCH_AUDIT_UNAVAILABLE: "Search event auditing was unavailable",
114584
+ SEARCH_ANALYTICS_UNAVAILABLE: "Search analytics were unavailable"
114585
+ };
114586
+ SearchServiceError = class SearchServiceError extends Error {
114587
+ code;
114588
+ component;
114589
+ statusCode;
114590
+ constructor(code, component, options) {
114591
+ super(options?.message ?? (code === "STORE_CORRUPTION" ? "Stored data is invalid" : "A required search backend is unavailable"), options?.cause === undefined ? undefined : { cause: options.cause });
114592
+ this.code = code;
114593
+ this.component = component;
114594
+ this.name = "SearchServiceError";
114595
+ this.statusCode = options?.statusCode ?? 503;
114596
+ }
114597
+ };
114598
+ });
114599
+
114418
114600
  // ../../packages/core/dist/kernel/enum-validation.js
114419
114601
  function validateEnum(paramName, value, validValues) {
114420
114602
  if (typeof value !== "string" || !validValues.includes(value)) {
@@ -114523,7 +114705,7 @@ class SearchController {
114523
114705
  });
114524
114706
  const admission = await this.contextualSearch.checkSearchAdmission(projectId, projectPath);
114525
114707
  if (!admission.admitted) {
114526
- throw new Error(admission.error ?? `Project '${projectId}' is not indexed`);
114708
+ throw projectNotIndexed(projectId, admission.error ?? `Project '${projectId}' is not indexed`);
114527
114709
  }
114528
114710
  const staleWarning = admission.stale ?? null;
114529
114711
  let reindexInfo = null;
@@ -114747,6 +114929,7 @@ var init_search_controller = __esm(() => {
114747
114929
  init_contextual_search_rlm();
114748
114930
  init_event_bus();
114749
114931
  init_reranker();
114932
+ init_search_diagnostics();
114750
114933
  init_esm();
114751
114934
  init_filter_validation();
114752
114935
  });
@@ -115232,83 +115415,6 @@ var init_session_bias = __esm(() => {
115232
115415
  init_synapse();
115233
115416
  });
115234
115417
 
115235
- // ../../packages/core/dist/kernel/search-diagnostics.js
115236
- function searchBackendUnavailable(component, cause) {
115237
- return cause instanceof SearchServiceError ? cause : new SearchServiceError("SEARCH_BACKEND_UNAVAILABLE", component, { cause });
115238
- }
115239
- function storeCorruption(component, cause) {
115240
- return cause instanceof SearchServiceError ? cause : new SearchServiceError("STORE_CORRUPTION", component, {
115241
- cause,
115242
- statusCode: 500
115243
- });
115244
- }
115245
- function recordSearchDegradation(code, component, projectId) {
115246
- const degradation = {
115247
- code,
115248
- component,
115249
- message: DEGRADATION_MESSAGES[code]
115250
- };
115251
- diagnostics.push({
115252
- kind: "degradation",
115253
- ...degradation,
115254
- projectId,
115255
- timestamp: new Date().toISOString()
115256
- });
115257
- if (diagnostics.length > MAX_DIAGNOSTICS) {
115258
- diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
115259
- }
115260
- return degradation;
115261
- }
115262
- function recordSearchFailure(error51, projectId) {
115263
- if (recordedFailures.has(error51))
115264
- return;
115265
- recordedFailures.add(error51);
115266
- diagnostics.push({
115267
- kind: "failure",
115268
- code: error51.code,
115269
- component: error51.component,
115270
- message: error51.message,
115271
- projectId,
115272
- timestamp: new Date().toISOString()
115273
- });
115274
- if (diagnostics.length > MAX_DIAGNOSTICS) {
115275
- diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
115276
- }
115277
- }
115278
- function getSearchDiagnostics() {
115279
- return diagnostics.map((diagnostic) => ({ ...diagnostic }));
115280
- }
115281
- function resetSearchDiagnosticsForTests() {
115282
- diagnostics.length = 0;
115283
- }
115284
- var MAX_DIAGNOSTICS = 100, diagnostics, recordedFailures, DEGRADATION_MESSAGES, SearchServiceError;
115285
- var init_search_diagnostics = __esm(() => {
115286
- diagnostics = [];
115287
- recordedFailures = new WeakSet;
115288
- DEGRADATION_MESSAGES = {
115289
- QUERY_UNDERSTANDING_UNAVAILABLE: "Query understanding was unavailable; original query used",
115290
- TRIGRAM_UNAVAILABLE: "Trigram enrichment was unavailable",
115291
- FUZZY_SEARCH_UNAVAILABLE: "Fuzzy enrichment was unavailable",
115292
- PROXIMITY_RERANK_UNAVAILABLE: "Proximity reranking was unavailable; fused order preserved",
115293
- GRAPH_AUGMENTATION_UNAVAILABLE: "Graph augmentation was unavailable",
115294
- SYNAPSE_UNAVAILABLE: "Synapse enrichment was unavailable; stateless results used",
115295
- SEARCH_AUDIT_UNAVAILABLE: "Search event auditing was unavailable",
115296
- SEARCH_ANALYTICS_UNAVAILABLE: "Search analytics were unavailable"
115297
- };
115298
- SearchServiceError = class SearchServiceError extends Error {
115299
- code;
115300
- component;
115301
- statusCode;
115302
- constructor(code, component, options) {
115303
- super(code === "STORE_CORRUPTION" ? "Stored data is invalid" : "A required search backend is unavailable", options?.cause === undefined ? undefined : { cause: options.cause });
115304
- this.code = code;
115305
- this.component = component;
115306
- this.name = "SearchServiceError";
115307
- this.statusCode = options?.statusCode ?? 503;
115308
- }
115309
- };
115310
- });
115311
-
115312
115418
  // ../../packages/core/dist/services/search/hybrid-search.js
115313
115419
  async function search(deps, query, projectId, options = {}) {
115314
115420
  const maxResults = options.maxResults ?? 10;
@@ -116665,7 +116771,7 @@ var init_managed_run_repository_pg = __esm(() => {
116665
116771
  });
116666
116772
 
116667
116773
  // ../../packages/core/dist/services/search/project-indexer.js
116668
- import fs7 from "fs/promises";
116774
+ import fs8 from "fs/promises";
116669
116775
  import path13 from "path";
116670
116776
  import { randomUUID as randomUUID3 } from "crypto";
116671
116777
  async function runWithIndexLock(lockMap, projectId, work) {
@@ -116925,7 +117031,7 @@ async function checkSearchAdmission(deps, projectId, projectPath) {
116925
117031
  }
116926
117032
  async function indexFile(deps, filePath, projectId, projectRoot, centralityMap) {
116927
117033
  projectId = await getProjectIdentityAliasResolver().resolve(projectId);
116928
- const content = await fs7.readFile(filePath, "utf-8");
117034
+ const content = await fs8.readFile(filePath, "utf-8");
116929
117035
  const relativePath = path13.relative(projectRoot, filePath);
116930
117036
  const maxFileSize = config.get("security").maxFileSize || 1024 * 1024;
116931
117037
  if (content.length > maxFileSize) {
@@ -120524,7 +120630,7 @@ __export(exports_symbol_graph_service, {
120524
120630
  SymbolGraphService: () => SymbolGraphService
120525
120631
  });
120526
120632
  import path14 from "path";
120527
- import fs8 from "fs/promises";
120633
+ import fs9 from "fs/promises";
120528
120634
 
120529
120635
  class SymbolGraphService {
120530
120636
  identityLookup;
@@ -120852,7 +120958,7 @@ class SymbolGraphService {
120852
120958
  async readSnippet(relativePath, lineStart, lineEnd, projectId) {
120853
120959
  try {
120854
120960
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
120855
- const content = await fs8.readFile(absolutePath, "utf-8");
120961
+ const content = await fs9.readFile(absolutePath, "utf-8");
120856
120962
  const lines = content.split(`
120857
120963
  `);
120858
120964
  return lines.slice(Math.max(0, lineStart - 1), Math.min(lines.length, lineEnd)).join(`
@@ -120864,7 +120970,7 @@ class SymbolGraphService {
120864
120970
  async readContext(relativePath, lineNumber, contextLines, projectId) {
120865
120971
  try {
120866
120972
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
120867
- const content = await fs8.readFile(absolutePath, "utf-8");
120973
+ const content = await fs9.readFile(absolutePath, "utf-8");
120868
120974
  const lines = content.split(`
120869
120975
  `);
120870
120976
  const start = Math.max(0, lineNumber - contextLines - 1);
@@ -124673,7 +124779,7 @@ var init_l1_memory_cache = __esm(() => {
124673
124779
  });
124674
124780
 
124675
124781
  // ../../packages/core/dist/services/health/local-health-checker.js
124676
- import fs9 from "fs/promises";
124782
+ import fs10 from "fs/promises";
124677
124783
  import { existsSync as existsSync3 } from "fs";
124678
124784
  import path15 from "path";
124679
124785
 
@@ -124709,10 +124815,10 @@ class LocalHealthChecker {
124709
124815
  const start = Date.now();
124710
124816
  try {
124711
124817
  if (!existsSync3(this.dataDir))
124712
- await fs9.mkdir(this.dataDir, { recursive: true });
124818
+ await fs10.mkdir(this.dataDir, { recursive: true });
124713
124819
  const probe = path15.join(this.dataDir, ".health-check-test");
124714
- await fs9.writeFile(probe, "ok");
124715
- await fs9.unlink(probe);
124820
+ await fs10.writeFile(probe, "ok");
124821
+ await fs10.unlink(probe);
124716
124822
  return { available: true, latency: Date.now() - start, details: { path: this.dataDir, writable: true } };
124717
124823
  } catch (error51) {
124718
124824
  return { available: false, latency: Date.now() - start, error: `Data directory error: ${error51.message}` };
@@ -125291,6 +125397,7 @@ class IndexJobTracker {
125291
125397
  filesIndexed: r?.filesIndexed ?? 0,
125292
125398
  chunksIndexed: r?.chunksIndexed ?? 0,
125293
125399
  symbolsIndexed: 0,
125400
+ errors: r?.errors ?? 0,
125294
125401
  durationMs: r?.duration ?? 0,
125295
125402
  activatedGraphGenerationId: r?.activatedGraphGenerationId ?? ""
125296
125403
  });
@@ -127411,7 +127518,7 @@ var init_scheduler2 = __esm(() => {
127411
127518
  });
127412
127519
 
127413
127520
  // ../../packages/core/dist/services/pricing/models-dev-client.js
127414
- import fs10 from "fs/promises";
127521
+ import fs11 from "fs/promises";
127415
127522
  import { existsSync as existsSync4 } from "fs";
127416
127523
  import path16 from "path";
127417
127524
  function getModelsDevClient() {
@@ -127441,7 +127548,7 @@ var init_models_dev_client = __esm(() => {
127441
127548
  if (!existsSync4(cachePath)) {
127442
127549
  return null;
127443
127550
  }
127444
- const content = await fs10.readFile(cachePath, "utf-8");
127551
+ const content = await fs11.readFile(cachePath, "utf-8");
127445
127552
  const data = JSON.parse(content);
127446
127553
  const age = Date.now() - data.timestamp;
127447
127554
  if (age > ModelsDevClient.LOCAL_CACHE_TTL) {
@@ -127469,13 +127576,13 @@ var init_models_dev_client = __esm(() => {
127469
127576
  const cachePath = this.getLocalCachePath();
127470
127577
  try {
127471
127578
  const dir = path16.dirname(cachePath);
127472
- await fs10.mkdir(dir, { recursive: true });
127579
+ await fs11.mkdir(dir, { recursive: true });
127473
127580
  const data = {
127474
127581
  timestamp: Date.now(),
127475
127582
  version: "1.0.0",
127476
127583
  models: Object.fromEntries(models)
127477
127584
  };
127478
- await fs10.writeFile(cachePath, JSON.stringify(data), "utf-8");
127585
+ await fs11.writeFile(cachePath, JSON.stringify(data), "utf-8");
127479
127586
  logger.debug("Saved pricing to local cache", {
127480
127587
  models: models.size,
127481
127588
  path: cachePath
@@ -127804,7 +127911,7 @@ var init_models_dev_client = __esm(() => {
127804
127911
  const cachePath = this.getLocalCachePath();
127805
127912
  try {
127806
127913
  if (existsSync4(cachePath)) {
127807
- await fs10.unlink(cachePath);
127914
+ await fs11.unlink(cachePath);
127808
127915
  logger.debug("Local pricing cache file deleted");
127809
127916
  }
127810
127917
  } catch (error51) {
@@ -128782,8 +128889,13 @@ var init_auto_checkpointer = __esm(() => {
128782
128889
  };
128783
128890
  });
128784
128891
 
128892
+ // ../../packages/core/dist/kernel/sanitize/strip-nul.js
128893
+ function stripNul(content) {
128894
+ return content.includes("\x00") ? content.replaceAll("\x00", "") : content;
128895
+ }
128896
+
128785
128897
  // ../../packages/core/dist/services/etl/stages/discover.js
128786
- import fs11 from "fs/promises";
128898
+ import fs12 from "fs/promises";
128787
128899
  import path17 from "path";
128788
128900
  import { createHash as createHash8 } from "crypto";
128789
128901
 
@@ -128871,8 +128983,8 @@ class DiscoverStage {
128871
128983
  async processFile(ctx, relativePath, forceReindex) {
128872
128984
  const absolutePath = path17.join(ctx.projectPath, relativePath);
128873
128985
  try {
128874
- const stat = await fs11.stat(absolutePath);
128875
- const content = await fs11.readFile(absolutePath, "utf-8");
128986
+ const stat = await fs12.stat(absolutePath);
128987
+ const content = stripNul(await fs12.readFile(absolutePath, "utf-8"));
128876
128988
  const contentHash = createHash8("sha256").update(content).digest("hex");
128877
128989
  let needsReparse = forceReindex;
128878
128990
  if (!forceReindex) {
@@ -128916,7 +129028,7 @@ class DiscoverStage {
128916
129028
  }
128917
129029
  try {
128918
129030
  const gitignorePath = path17.join(projectPath, ".gitignore");
128919
- const gitignoreContent = await fs11.readFile(gitignorePath, "utf8");
129031
+ const gitignoreContent = await fs12.readFile(gitignorePath, "utf8");
128920
129032
  const rules = gitignoreContent.split(`
128921
129033
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
128922
129034
  ig.add(rules);
@@ -131245,7 +131357,7 @@ var init_structural_runtime = __esm(() => {
131245
131357
 
131246
131358
  // ../../packages/core/dist/services/etl/stages/parse.js
131247
131359
  import path18 from "path";
131248
- import fs12 from "fs/promises";
131360
+ import fs13 from "fs/promises";
131249
131361
  function resolveChunkerMaxChars() {
131250
131362
  const global2 = Number(process.env.EMBEDDING_MAX_CHARS);
131251
131363
  if (Number.isFinite(global2) && global2 > 0)
@@ -131337,7 +131449,7 @@ class ParseStage {
131337
131449
  if (!file2.needsReparse) {
131338
131450
  const extension = path18.extname(file2.relativePath).toLowerCase();
131339
131451
  if ([".c", ".cpp", ".hpp"].includes(extension)) {
131340
- const content = file2.snapshotContent ?? await fs12.readFile(file2.absolutePath, "utf8");
131452
+ const content = file2.snapshotContent ?? await fs13.readFile(file2.absolutePath, "utf8");
131341
131453
  const outcome = await this.runtime.parse({ extension, source: Buffer.from(content) });
131342
131454
  if (outcome.status === "failed")
131343
131455
  throw new StructuralEtlParseError(file2.relativePath, outcome.failureKind, `Structural evidence parse failed (${outcome.failureKind})`, outcome.diagnosticCount, outcome.diagnostics.slice(0, 10));
@@ -131349,7 +131461,7 @@ class ParseStage {
131349
131461
  return { file: file2, chunks: [], symbols: [], rawImports: [], rawEdges: [] };
131350
131462
  }
131351
131463
  try {
131352
- const content = file2.snapshotContent ?? await fs12.readFile(file2.absolutePath, "utf-8");
131464
+ const content = file2.snapshotContent ?? await fs13.readFile(file2.absolutePath, "utf-8");
131353
131465
  const ext2 = path18.extname(file2.relativePath).toLowerCase();
131354
131466
  const chunkerMaxChars = resolveChunkerMaxChars();
131355
131467
  const chunks = smartChunk(content, file2.relativePath, chunkerMaxChars ? { maxChunkChars: chunkerMaxChars } : {});
@@ -132390,7 +132502,7 @@ var init_data_document2 = __esm(() => {
132390
132502
 
132391
132503
  // ../../packages/core/dist/services/etl/stages/resolve.js
132392
132504
  import path21 from "path";
132393
- import fs13 from "fs";
132505
+ import fs14 from "fs";
132394
132506
 
132395
132507
  class ResolveStage {
132396
132508
  symbolRepository;
@@ -132707,7 +132819,7 @@ class ResolveStage {
132707
132819
  const aliases = [];
132708
132820
  const tsconfigPath = path21.join(projectPath, "tsconfig.json");
132709
132821
  try {
132710
- const raw2 = fs13.readFileSync(tsconfigPath, "utf-8");
132822
+ const raw2 = fs14.readFileSync(tsconfigPath, "utf-8");
132711
132823
  const stripped = raw2.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
132712
132824
  const tsconfig = JSON.parse(stripped);
132713
132825
  const paths = tsconfig?.compilerOptions?.paths ?? {};
@@ -132933,6 +133045,7 @@ class LoadStage {
132933
133045
  let chunksLoaded = 0;
132934
133046
  let symbolsLoaded = 0;
132935
133047
  let errors4 = 0;
133048
+ const fileErrors = [];
132936
133049
  let processedSinceStart = 0;
132937
133050
  let lastEtaLogAt = 0;
132938
133051
  const BATCH = 10;
@@ -133003,6 +133116,12 @@ class LoadStage {
133003
133116
  } catch (err) {
133004
133117
  errors4++;
133005
133118
  processedSinceStart++;
133119
+ if (fileErrors.length < MAX_FILE_ERRORS) {
133120
+ fileErrors.push({
133121
+ filePath: file2.file.relativePath,
133122
+ error: err.message
133123
+ });
133124
+ }
133006
133125
  if (emitLifecycle)
133007
133126
  ctx.emit({
133008
133127
  type: "file_error",
@@ -133068,7 +133187,7 @@ class LoadStage {
133068
133187
  duration: formatDuration(durationMs),
133069
133188
  filesPerSec: filesLoaded > 0 && durationMs > 0 ? Number((filesLoaded / durationMs * 1000).toFixed(2)) : 0
133070
133189
  });
133071
- return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors4 };
133190
+ return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors4, fileErrors };
133072
133191
  }
133073
133192
  async loadToSearchStores(ctx, file2) {
133074
133193
  if (file2.chunks.length === 0)
@@ -133140,6 +133259,7 @@ class LoadStage {
133140
133259
  return batch.definitions.length;
133141
133260
  }
133142
133261
  }
133262
+ var MAX_FILE_ERRORS = 50;
133143
133263
  var init_load = __esm(() => {
133144
133264
  init_dist();
133145
133265
  init_with_deadlock_retry();
@@ -133882,7 +134002,12 @@ var init_pipeline = __esm(() => {
133882
134002
  throw managedRunLeaseLost;
133883
134003
  stageTimings.load = Math.round(performance.now() - st4);
133884
134004
  if (loadResult.errors > 0) {
133885
- throw new Error(`ETL completed with ${loadResult.errors} file error${loadResult.errors === 1 ? "" : "s"}`);
134005
+ logger.warn("EtlPipeline: completed with file errors", {
134006
+ projectId,
134007
+ jobId,
134008
+ errors: loadResult.errors,
134009
+ fileErrors: (loadResult.fileErrors ?? []).slice(0, 10)
134010
+ });
133886
134011
  }
133887
134012
  const activationSnapshot = await abortable(this.discover.run(ctx, { forceReindex, includeTests: include_tests }), graphAbortController.signal);
133888
134013
  if (buildGraphInputSnapshotHash(activationSnapshot) !== graphGenerationLease.inputSnapshotHash) {
@@ -133939,6 +134064,7 @@ var init_pipeline = __esm(() => {
133939
134064
  filesIndexed: result.filesIndexed,
133940
134065
  chunksIndexed: result.chunksIndexed,
133941
134066
  errors: result.errors,
134067
+ fileErrors: loadResult.fileErrors ?? [],
133942
134068
  duration: durationMs,
133943
134069
  activatedGraphGenerationId: result.activatedGraphGenerationId,
133944
134070
  parserDiagnostics: result.parserDiagnostics
@@ -133949,6 +134075,7 @@ var init_pipeline = __esm(() => {
133949
134075
  filesIndexed: result.filesIndexed,
133950
134076
  chunksIndexed: result.chunksIndexed,
133951
134077
  symbolsIndexed: result.symbolsIndexed,
134078
+ errors: result.errors,
133952
134079
  durationMs,
133953
134080
  activatedGraphGenerationId: result.activatedGraphGenerationId
133954
134081
  });
@@ -151900,6 +152027,7 @@ var init_services = __esm(() => {
151900
152027
  init_search_analytics_pg();
151901
152028
  init_index_manager();
151902
152029
  init_search_diagnostics();
152030
+ init_safe_error_summary();
151903
152031
  init_memory_controller();
151904
152032
  init_llm_client();
151905
152033
  init_search_controller();