@massa-ai/tools-api 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 (2) hide show
  1. package/dist/index.js +368 -275
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1263,7 +1263,8 @@ var init_config = __esm(() => {
1263
1263
  },
1264
1264
  logging: {
1265
1265
  level: process.env.LOG_LEVEL || fileConfig.logging?.level || "info",
1266
- enableMetrics: process.env.ENABLE_METRICS === "true" || process.env.ENABLE_METRICS === undefined && !!fileConfig.logging?.enableMetrics
1266
+ enableMetrics: process.env.ENABLE_METRICS === "true" || process.env.ENABLE_METRICS === undefined && !!fileConfig.logging?.enableMetrics,
1267
+ file: process.env.MASSA_AI_LOG_FILE || fileConfig.logging?.file || undefined
1267
1268
  },
1268
1269
  synapse: {
1269
1270
  enabled: process.env.SYNAPSE_ENABLED !== "false",
@@ -6602,20 +6603,25 @@ var init_types = __esm(() => {
6602
6603
  var init_interfaces = () => {};
6603
6604
 
6604
6605
  // ../../packages/shared/dist/utils/logger.js
6606
+ import fs3 from "fs";
6607
+
6605
6608
  class Logger {
6606
6609
  _level;
6607
6610
  _enableMetrics;
6611
+ _logFilePath;
6608
6612
  _initialized = false;
6609
6613
  constructor() {}
6610
6614
  ensureInitialized() {
6611
6615
  if (!this._initialized) {
6612
6616
  try {
6613
- const configLevel = config.get("logging").level;
6614
- this._level = this.parseLogLevel(configLevel);
6615
- this._enableMetrics = config.get("logging").enableMetrics;
6617
+ const loggingConfig = config.get("logging");
6618
+ this._level = this.parseLogLevel(loggingConfig.level);
6619
+ this._enableMetrics = loggingConfig.enableMetrics;
6620
+ this._logFilePath = loggingConfig.file;
6616
6621
  } catch {
6617
6622
  this._level = LogLevel.INFO;
6618
6623
  this._enableMetrics = false;
6624
+ this._logFilePath = undefined;
6619
6625
  }
6620
6626
  this._initialized = true;
6621
6627
  }
@@ -6628,6 +6634,10 @@ class Logger {
6628
6634
  this.ensureInitialized();
6629
6635
  return this._enableMetrics;
6630
6636
  }
6637
+ get logFilePath() {
6638
+ this.ensureInitialized();
6639
+ return this._logFilePath;
6640
+ }
6631
6641
  parseLogLevel(level) {
6632
6642
  const levels = {
6633
6643
  debug: LogLevel.DEBUG,
@@ -6647,6 +6657,13 @@ class Logger {
6647
6657
  }
6648
6658
  write(message, _level) {
6649
6659
  console.error(message);
6660
+ const filePath = this.logFilePath;
6661
+ if (filePath) {
6662
+ try {
6663
+ fs3.appendFileSync(filePath, message + `
6664
+ `);
6665
+ } catch {}
6666
+ }
6650
6667
  }
6651
6668
  debug(message, meta) {
6652
6669
  if (this.shouldLog(LogLevel.DEBUG)) {
@@ -7056,7 +7073,7 @@ var init_hosts = __esm(() => {
7056
7073
  });
7057
7074
 
7058
7075
  // ../../packages/shared/dist/profile-switch/state.js
7059
- import fs3 from "fs";
7076
+ import fs4 from "fs";
7060
7077
  import path7 from "path";
7061
7078
  function namedError(name, message) {
7062
7079
  const err = new InstallStateError(message);
@@ -7083,7 +7100,7 @@ function validateShape(raw2, filePath) {
7083
7100
  function readInstallState(filePath) {
7084
7101
  let text;
7085
7102
  try {
7086
- text = fs3.readFileSync(filePath, "utf-8");
7103
+ text = fs4.readFileSync(filePath, "utf-8");
7087
7104
  } catch (err) {
7088
7105
  const code = err.code;
7089
7106
  if (code === "ENOENT")
@@ -7103,8 +7120,8 @@ function writeInstallState(filePath, state) {
7103
7120
  const text = `${JSON.stringify(validated, null, 2)}
7104
7121
  `;
7105
7122
  try {
7106
- fs3.mkdirSync(path7.dirname(filePath), { recursive: true });
7107
- fs3.writeFileSync(filePath, text);
7123
+ fs4.mkdirSync(path7.dirname(filePath), { recursive: true });
7124
+ fs4.writeFileSync(filePath, text);
7108
7125
  } catch (err) {
7109
7126
  throw UnwritableInstallStateError(filePath, err.message);
7110
7127
  }
@@ -7131,7 +7148,7 @@ var init_state = __esm(() => {
7131
7148
  });
7132
7149
 
7133
7150
  // ../../packages/shared/dist/profile-switch/lock.js
7134
- import fs4 from "fs";
7151
+ import fs5 from "fs";
7135
7152
  import path8 from "path";
7136
7153
  import os4 from "os";
7137
7154
  import crypto4 from "crypto";
@@ -7144,7 +7161,7 @@ function namedError2(name, message) {
7144
7161
  function readOwner(ownerPath) {
7145
7162
  let raw2;
7146
7163
  try {
7147
- raw2 = JSON.parse(fs4.readFileSync(ownerPath, "utf-8"));
7164
+ raw2 = JSON.parse(fs5.readFileSync(ownerPath, "utf-8"));
7148
7165
  } catch {
7149
7166
  return null;
7150
7167
  }
@@ -7160,7 +7177,7 @@ function releaseIfOwned(lockDir, ownerPath, token) {
7160
7177
  const owner = readOwner(ownerPath);
7161
7178
  if (owner === null || owner.token !== token)
7162
7179
  return;
7163
- fs4.rmSync(lockDir, { recursive: true, force: true });
7180
+ fs5.rmSync(lockDir, { recursive: true, force: true });
7164
7181
  }
7165
7182
  function acquireLock(stateFilePath, options = {}) {
7166
7183
  const lockDir = `${stateFilePath}.switch.lock`;
@@ -7169,11 +7186,11 @@ function acquireLock(stateFilePath, options = {}) {
7169
7186
  const identity = options.identity ?? DEFAULT_IDENTITY;
7170
7187
  const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
7171
7188
  const createFresh = () => {
7172
- fs4.mkdirSync(lockDir);
7189
+ fs5.mkdirSync(lockDir);
7173
7190
  const pid = identity.pid();
7174
7191
  const startedAt = identity.processStart(pid);
7175
7192
  if (startedAt == null) {
7176
- fs4.rmSync(lockDir, { recursive: true, force: true });
7193
+ fs5.rmSync(lockDir, { recursive: true, force: true });
7177
7194
  throw LockAcquireError(lockDir, "could not determine this process's start-time identity");
7178
7195
  }
7179
7196
  const token = crypto4.randomUUID();
@@ -7184,8 +7201,8 @@ function acquireLock(stateFilePath, options = {}) {
7184
7201
  token,
7185
7202
  timestamp: clock.now()
7186
7203
  };
7187
- fs4.mkdirSync(path8.dirname(ownerPath), { recursive: true });
7188
- fs4.writeFileSync(ownerPath, JSON.stringify(record));
7204
+ fs5.mkdirSync(path8.dirname(ownerPath), { recursive: true });
7205
+ fs5.writeFileSync(ownerPath, JSON.stringify(record));
7189
7206
  return { lockDir, release: () => releaseIfOwned(lockDir, ownerPath, token) };
7190
7207
  };
7191
7208
  try {
@@ -7200,11 +7217,11 @@ function acquireLock(stateFilePath, options = {}) {
7200
7217
  throw LockHeldError(lockDir);
7201
7218
  const reclaimDir = `${lockDir}.reclaim.${owner.token}`;
7202
7219
  try {
7203
- fs4.renameSync(lockDir, reclaimDir);
7220
+ fs5.renameSync(lockDir, reclaimDir);
7204
7221
  } catch {
7205
7222
  throw LockHeldError(lockDir);
7206
7223
  }
7207
- fs4.rmSync(reclaimDir, { recursive: true, force: true });
7224
+ fs5.rmSync(reclaimDir, { recursive: true, force: true });
7208
7225
  try {
7209
7226
  return createFresh();
7210
7227
  } catch {
@@ -7238,7 +7255,7 @@ var init_lock = __esm(() => {
7238
7255
  });
7239
7256
 
7240
7257
  // ../../packages/shared/dist/profile-switch/engine.js
7241
- import fs5 from "fs";
7258
+ import fs6 from "fs";
7242
7259
  import path9 from "path";
7243
7260
  import os5 from "os";
7244
7261
  import crypto5 from "crypto";
@@ -7272,7 +7289,7 @@ function listProfiles(opts = {}) {
7272
7289
  availableProfiles: []
7273
7290
  };
7274
7291
  }
7275
- const installed = fs5.existsSync(layout.activeDir);
7292
+ const installed = fs6.existsSync(layout.activeDir);
7276
7293
  const availableProfiles = listVariantProfiles(layout);
7277
7294
  const platform = state.platforms[host];
7278
7295
  return {
@@ -7288,9 +7305,9 @@ function listProfiles(opts = {}) {
7288
7305
  return { hosts };
7289
7306
  }
7290
7307
  function listVariantProfiles(layout) {
7291
- if (!fs5.existsSync(layout.variantsRoot))
7308
+ if (!fs6.existsSync(layout.variantsRoot))
7292
7309
  return [];
7293
- return fs5.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
7310
+ return fs6.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
7294
7311
  }
7295
7312
  function matchesGlob(filename, glob) {
7296
7313
  const starIdx = glob.indexOf("*");
@@ -7303,32 +7320,32 @@ function matchesGlob(filename, glob) {
7303
7320
  function assertStateWritable(stateFilePath) {
7304
7321
  const dir = path9.dirname(stateFilePath);
7305
7322
  try {
7306
- fs5.mkdirSync(dir, { recursive: true });
7323
+ fs6.mkdirSync(dir, { recursive: true });
7307
7324
  } catch (err) {
7308
7325
  throw UnwritableInstallStateError(stateFilePath, err.message);
7309
7326
  }
7310
- const checkPath = fs5.existsSync(stateFilePath) ? stateFilePath : dir;
7327
+ const checkPath = fs6.existsSync(stateFilePath) ? stateFilePath : dir;
7311
7328
  try {
7312
- fs5.accessSync(checkPath, fs5.constants.W_OK);
7329
+ fs6.accessSync(checkPath, fs6.constants.W_OK);
7313
7330
  } catch (err) {
7314
7331
  throw UnwritableInstallStateError(stateFilePath, err.message);
7315
7332
  }
7316
7333
  }
7317
7334
  function copyFileRouteVariant(layout, variantDir) {
7318
- fs5.mkdirSync(layout.activeDir, { recursive: true });
7335
+ fs6.mkdirSync(layout.activeDir, { recursive: true });
7319
7336
  let changed = 0;
7320
- for (const entry of fs5.readdirSync(variantDir, { withFileTypes: true })) {
7337
+ for (const entry of fs6.readdirSync(variantDir, { withFileTypes: true })) {
7321
7338
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
7322
7339
  continue;
7323
- fs5.copyFileSync(path9.join(variantDir, entry.name), path9.join(layout.activeDir, entry.name));
7340
+ fs6.copyFileSync(path9.join(variantDir, entry.name), path9.join(layout.activeDir, entry.name));
7324
7341
  changed++;
7325
7342
  }
7326
7343
  return changed;
7327
7344
  }
7328
7345
  function repointOpencodeVariant(layout, variantDir) {
7329
- fs5.mkdirSync(layout.activeDir, { recursive: true });
7346
+ fs6.mkdirSync(layout.activeDir, { recursive: true });
7330
7347
  let changed = 0;
7331
- for (const entry of fs5.readdirSync(variantDir, { withFileTypes: true })) {
7348
+ for (const entry of fs6.readdirSync(variantDir, { withFileTypes: true })) {
7332
7349
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
7333
7350
  continue;
7334
7351
  const dest = path9.join(layout.activeDir, entry.name);
@@ -7336,15 +7353,15 @@ function repointOpencodeVariant(layout, variantDir) {
7336
7353
  let destExists = true;
7337
7354
  let destIsSymlink = false;
7338
7355
  try {
7339
- destIsSymlink = fs5.lstatSync(dest).isSymbolicLink();
7356
+ destIsSymlink = fs6.lstatSync(dest).isSymbolicLink();
7340
7357
  } catch {
7341
7358
  destExists = false;
7342
7359
  }
7343
7360
  if (destExists && !destIsSymlink)
7344
7361
  continue;
7345
7362
  const tmp = `${dest}.massa-ai-switch.${crypto5.randomUUID()}`;
7346
- fs5.symlinkSync(target, tmp);
7347
- fs5.renameSync(tmp, dest);
7363
+ fs6.symlinkSync(target, tmp);
7364
+ fs6.renameSync(tmp, dest);
7348
7365
  changed++;
7349
7366
  }
7350
7367
  return changed;
@@ -7366,13 +7383,13 @@ function switchProfile(opts) {
7366
7383
  if (fileHosts.length === 0) {
7367
7384
  return { profile: opts.profile, dryRun, hosts: orderRows(universe, skipRows), restartRequired: false };
7368
7385
  }
7369
- const installedFileHosts = fileHosts.filter((h) => fs5.existsSync(h.layout.activeDir));
7386
+ const installedFileHosts = fileHosts.filter((h) => fs6.existsSync(h.layout.activeDir));
7370
7387
  if (installedFileHosts.length === 0)
7371
7388
  throw NoHostsDetectedError();
7372
7389
  const withAvailability = fileHosts.map((h) => {
7373
- const variantsRootExists = fs5.existsSync(h.layout.variantsRoot);
7390
+ const variantsRootExists = fs6.existsSync(h.layout.variantsRoot);
7374
7391
  const variantDir = h.layout.variantDir(opts.profile);
7375
- const available = variantsRootExists && fs5.existsSync(variantDir) && fs5.statSync(variantDir).isDirectory();
7392
+ const available = variantsRootExists && fs6.existsSync(variantDir) && fs6.statSync(variantDir).isDirectory();
7376
7393
  return { ...h, variantsRootExists, variantDir, available };
7377
7394
  });
7378
7395
  if (!withAvailability.some((h) => h.available)) {
@@ -11580,8 +11597,8 @@ var init_esm4 = __esm(() => {
11580
11597
  #children;
11581
11598
  nocase;
11582
11599
  #fs;
11583
- constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs6 = defaultFS } = {}) {
11584
- this.#fs = fsFromOption(fs6);
11600
+ constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs7 = defaultFS } = {}) {
11601
+ this.#fs = fsFromOption(fs7);
11585
11602
  if (cwd instanceof URL || cwd.startsWith("file://")) {
11586
11603
  cwd = fileURLToPath(cwd);
11587
11604
  }
@@ -12056,8 +12073,8 @@ var init_esm4 = __esm(() => {
12056
12073
  parseRootPath(dir) {
12057
12074
  return win32.parse(dir).root.toUpperCase();
12058
12075
  }
12059
- newRoot(fs6) {
12060
- return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs6 });
12076
+ newRoot(fs7) {
12077
+ return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs7 });
12061
12078
  }
12062
12079
  isAbsolute(p) {
12063
12080
  return p.startsWith("/") || p.startsWith("\\") || /^[a-z]:(\/|\\)/i.test(p);
@@ -12073,8 +12090,8 @@ var init_esm4 = __esm(() => {
12073
12090
  parseRootPath(_dir) {
12074
12091
  return "/";
12075
12092
  }
12076
- newRoot(fs6) {
12077
- return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs6 });
12093
+ newRoot(fs7) {
12094
+ return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs7 });
12078
12095
  }
12079
12096
  isAbsolute(p) {
12080
12097
  return p.startsWith("/");
@@ -13480,7 +13497,7 @@ var init_capture_policy = __esm(() => {
13480
13497
  });
13481
13498
 
13482
13499
  // ../../packages/core/dist/services/search/ignore-patterns.js
13483
- import fs6 from "fs/promises";
13500
+ import fs7 from "fs/promises";
13484
13501
  import path11 from "path";
13485
13502
  function buildExtensionGlob(extensions2) {
13486
13503
  return extensions2.map((ext2) => `**/*${ext2}`);
@@ -13505,7 +13522,7 @@ async function loadProjectIgnore(projectPath) {
13505
13522
  ig.add(DEFAULT_IGNORES);
13506
13523
  try {
13507
13524
  const gitignorePath = path11.join(projectPath, ".gitignore");
13508
- const gitignoreContent = await fs6.readFile(gitignorePath, "utf8");
13525
+ const gitignoreContent = await fs7.readFile(gitignorePath, "utf8");
13509
13526
  const rules = gitignoreContent.split(`
13510
13527
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
13511
13528
  ig.add(rules);
@@ -13587,6 +13604,89 @@ var init_db_connection = __esm(() => {
13587
13604
  init_config();
13588
13605
  });
13589
13606
 
13607
+ // ../../packages/core/dist/kernel/sanitize/credential-scrub.js
13608
+ function markerFor(id) {
13609
+ return `[REDACTED:${id}]`;
13610
+ }
13611
+ function fullMatchRule(id, pattern) {
13612
+ const marker = markerFor(id);
13613
+ return {
13614
+ id,
13615
+ replace(text) {
13616
+ let count = 0;
13617
+ const replaced = text.replace(pattern, () => {
13618
+ count++;
13619
+ return marker;
13620
+ });
13621
+ return { text: replaced, count };
13622
+ }
13623
+ };
13624
+ }
13625
+ function scrubCredentials(payloadJson) {
13626
+ const redactions = {};
13627
+ for (const id of RULE_IDS)
13628
+ redactions[id] = 0;
13629
+ let text = payloadJson;
13630
+ for (const rule of RULES) {
13631
+ const { text: next, count } = rule.replace(text);
13632
+ text = next;
13633
+ redactions[rule.id] += count;
13634
+ }
13635
+ const total = Object.values(redactions).reduce((sum, n2) => sum + n2, 0);
13636
+ return {
13637
+ sanitized: text,
13638
+ redactions,
13639
+ total
13640
+ };
13641
+ }
13642
+ var PEM_PATTERN, JWT_PATTERN, AWS_KEY_PATTERN, SK_KEY_PATTERN, GITHUB_TOKEN_PATTERN, SLACK_TOKEN_PATTERN, BEARER_PATTERN, RULES, RULE_IDS;
13643
+ var init_credential_scrub = __esm(() => {
13644
+ PEM_PATTERN = /-----BEGIN [A-Z ]{0,32}PRIVATE KEY-----[\s\S]{0,8192}?-----END [A-Z ]{0,32}PRIVATE KEY-----/g;
13645
+ JWT_PATTERN = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g;
13646
+ AWS_KEY_PATTERN = /\b(?:AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}\b/g;
13647
+ SK_KEY_PATTERN = /\bsk-[A-Za-z0-9_-]{20,}\b/g;
13648
+ GITHUB_TOKEN_PATTERN = /\bgh[pousr]_[A-Za-z0-9]{36,}\b|\bgithub_pat_[A-Za-z0-9_]{22,}\b/g;
13649
+ SLACK_TOKEN_PATTERN = /\bxox[baprs]-[A-Za-z0-9-]{18,}\b/g;
13650
+ BEARER_PATTERN = /(Bearer\s+)([A-Za-z0-9._~+/=-]{20,})/g;
13651
+ RULES = [
13652
+ fullMatchRule("pem", PEM_PATTERN),
13653
+ fullMatchRule("jwt", JWT_PATTERN),
13654
+ fullMatchRule("aws-key", AWS_KEY_PATTERN),
13655
+ fullMatchRule("sk-key", SK_KEY_PATTERN),
13656
+ fullMatchRule("github-token", GITHUB_TOKEN_PATTERN),
13657
+ fullMatchRule("slack-token", SLACK_TOKEN_PATTERN),
13658
+ {
13659
+ id: "bearer",
13660
+ replace(text) {
13661
+ let count = 0;
13662
+ const replaced = text.replace(BEARER_PATTERN, (_m, prefix) => {
13663
+ count++;
13664
+ return `${prefix}${markerFor("bearer")}`;
13665
+ });
13666
+ return { text: replaced, count };
13667
+ }
13668
+ }
13669
+ ];
13670
+ RULE_IDS = RULES.map((r2) => r2.id);
13671
+ });
13672
+
13673
+ // ../../packages/core/dist/kernel/sanitize/safe-error-summary.js
13674
+ function safeErrorSummary(error) {
13675
+ if (error instanceof Error) {
13676
+ return {
13677
+ name: error.name,
13678
+ message: scrubCredentials(error.message).sanitized
13679
+ };
13680
+ }
13681
+ return {
13682
+ name: "UnknownError",
13683
+ message: scrubCredentials(String(error)).sanitized
13684
+ };
13685
+ }
13686
+ var init_safe_error_summary = __esm(() => {
13687
+ init_credential_scrub();
13688
+ });
13689
+
13590
13690
  // ../../packages/core/dist/kernel/alias-resolver.js
13591
13691
  class ProjectIdentityAliasResolver {
13592
13692
  ttlMs;
@@ -13612,9 +13712,7 @@ class ProjectIdentityAliasResolver {
13612
13712
  this.cache.set(projectId, { canonical, expiresAt: this.now() + this.ttlMs });
13613
13713
  return canonical;
13614
13714
  } catch (error) {
13615
- logger.warn("[project-identity] alias resolution failed; using original id (sanitized)", {
13616
- name: error instanceof Error ? error.name : "unknown"
13617
- });
13715
+ logger.warn("[project-identity] alias resolution failed; using original id", safeErrorSummary(error));
13618
13716
  return projectId;
13619
13717
  }
13620
13718
  }
@@ -13671,10 +13769,11 @@ var DEFAULT_TTL_MS = 30000, DEFAULT_RESOLVE_TIMEOUT_MS = 250, sharedResolver = n
13671
13769
  var init_alias_resolver = __esm(() => {
13672
13770
  init_dist();
13673
13771
  init_db_connection();
13772
+ init_safe_error_summary();
13674
13773
  });
13675
13774
 
13676
13775
  // ../../packages/core/dist/services/search/index-manager.js
13677
- import fs7 from "fs";
13776
+ import fs8 from "fs";
13678
13777
  import path12 from "path";
13679
13778
 
13680
13779
  class IndexManager {
@@ -13770,7 +13869,7 @@ class IndexManager {
13770
13869
  for (const filePath of indexedFiles) {
13771
13870
  const fullPath = path12.join(projectPath, filePath);
13772
13871
  try {
13773
- const stat2 = await fs7.promises.stat(fullPath);
13872
+ const stat2 = await fs8.promises.stat(fullPath);
13774
13873
  fileMetadata[filePath] = {
13775
13874
  path: filePath,
13776
13875
  mtime: stat2.mtimeMs,
@@ -13823,7 +13922,7 @@ class IndexManager {
13823
13922
  }
13824
13923
  const fullPath = path12.join(projectPath, match2);
13825
13924
  try {
13826
- const stat2 = await fs7.promises.stat(fullPath);
13925
+ const stat2 = await fs8.promises.stat(fullPath);
13827
13926
  files.set(match2, {
13828
13927
  path: match2,
13829
13928
  mtime: stat2.mtimeMs,
@@ -35514,7 +35613,7 @@ var require_auth_config = __commonJS((exports, module) => {
35514
35613
  writeAuthConfig: () => writeAuthConfig
35515
35614
  });
35516
35615
  module.exports = __toCommonJS2(auth_config_exports);
35517
- var fs8 = __toESM2(__require("fs"));
35616
+ var fs9 = __toESM2(__require("fs"));
35518
35617
  var path13 = __toESM2(__require("path"));
35519
35618
  var import_token_util = require_token_util();
35520
35619
  function getAuthConfigPath() {
@@ -35527,10 +35626,10 @@ var require_auth_config = __commonJS((exports, module) => {
35527
35626
  function readAuthConfig() {
35528
35627
  try {
35529
35628
  const authPath = getAuthConfigPath();
35530
- if (!fs8.existsSync(authPath)) {
35629
+ if (!fs9.existsSync(authPath)) {
35531
35630
  return null;
35532
35631
  }
35533
- const content = fs8.readFileSync(authPath, "utf8");
35632
+ const content = fs9.readFileSync(authPath, "utf8");
35534
35633
  if (!content) {
35535
35634
  return null;
35536
35635
  }
@@ -35542,10 +35641,10 @@ var require_auth_config = __commonJS((exports, module) => {
35542
35641
  function writeAuthConfig(config3) {
35543
35642
  const authPath = getAuthConfigPath();
35544
35643
  const authDir = path13.dirname(authPath);
35545
- if (!fs8.existsSync(authDir)) {
35546
- fs8.mkdirSync(authDir, { mode: 504, recursive: true });
35644
+ if (!fs9.existsSync(authDir)) {
35645
+ fs9.mkdirSync(authDir, { mode: 504, recursive: true });
35547
35646
  }
35548
- fs8.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
35647
+ fs9.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
35549
35648
  }
35550
35649
  function isValidAccessToken(authConfig, expirationBufferMs = 0) {
35551
35650
  if (!authConfig.token)
@@ -35721,7 +35820,7 @@ var require_token_util = __commonJS((exports, module) => {
35721
35820
  });
35722
35821
  module.exports = __toCommonJS2(token_util_exports);
35723
35822
  var path13 = __toESM2(__require("path"));
35724
- var fs8 = __toESM2(__require("fs"));
35823
+ var fs9 = __toESM2(__require("fs"));
35725
35824
  var import_token_error = require_token_error();
35726
35825
  var import_token_io = require_token_io();
35727
35826
  var import_auth_config = require_auth_config();
@@ -35802,10 +35901,10 @@ var require_token_util = __commonJS((exports, module) => {
35802
35901
  throw new import_token_error.VercelOidcTokenError("Unable to find project root directory. Have you linked your project with `vc link?`");
35803
35902
  }
35804
35903
  const prjPath = path13.join(dir, ".vercel", "project.json");
35805
- if (!fs8.existsSync(prjPath)) {
35904
+ if (!fs9.existsSync(prjPath)) {
35806
35905
  throw new import_token_error.VercelOidcTokenError("project.json not found, have you linked your project with `vc link?`");
35807
35906
  }
35808
- const prj = JSON.parse(fs8.readFileSync(prjPath, "utf8"));
35907
+ const prj = JSON.parse(fs9.readFileSync(prjPath, "utf8"));
35809
35908
  if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
35810
35909
  throw new TypeError("Expected a string-valued projectId property. Try running `vc link` to re-link your project.");
35811
35910
  }
@@ -35818,9 +35917,9 @@ var require_token_util = __commonJS((exports, module) => {
35818
35917
  }
35819
35918
  const tokenPath = path13.join(dir, "com.vercel.token", `${projectId}.json`);
35820
35919
  const tokenJson = JSON.stringify(token);
35821
- fs8.mkdirSync(path13.dirname(tokenPath), { mode: 504, recursive: true });
35822
- fs8.writeFileSync(tokenPath, tokenJson);
35823
- fs8.chmodSync(tokenPath, 432);
35920
+ fs9.mkdirSync(path13.dirname(tokenPath), { mode: 504, recursive: true });
35921
+ fs9.writeFileSync(tokenPath, tokenJson);
35922
+ fs9.chmodSync(tokenPath, 432);
35824
35923
  return;
35825
35924
  }
35826
35925
  function loadToken(projectId) {
@@ -35829,10 +35928,10 @@ var require_token_util = __commonJS((exports, module) => {
35829
35928
  throw new import_token_error.VercelOidcTokenError("Unable to find user data directory. Please reach out to Vercel support.");
35830
35929
  }
35831
35930
  const tokenPath = path13.join(dir, "com.vercel.token", `${projectId}.json`);
35832
- if (!fs8.existsSync(tokenPath)) {
35931
+ if (!fs9.existsSync(tokenPath)) {
35833
35932
  return null;
35834
35933
  }
35835
- const token = JSON.parse(fs8.readFileSync(tokenPath, "utf8"));
35934
+ const token = JSON.parse(fs9.readFileSync(tokenPath, "utf8"));
35836
35935
  assertVercelOidcTokenResponse(token);
35837
35936
  return token;
35838
35937
  }
@@ -63262,26 +63361,26 @@ var require_process = __commonJS((exports, module) => {
63262
63361
 
63263
63362
  // ../../node_modules/detect-libc/lib/filesystem.js
63264
63363
  var require_filesystem = __commonJS((exports, module) => {
63265
- var fs8 = __require("fs");
63364
+ var fs9 = __require("fs");
63266
63365
  var LDD_PATH = "/usr/bin/ldd";
63267
63366
  var SELF_PATH = "/proc/self/exe";
63268
63367
  var MAX_LENGTH = 2048;
63269
63368
  var readFileSync2 = (path13) => {
63270
- const fd = fs8.openSync(path13, "r");
63369
+ const fd = fs9.openSync(path13, "r");
63271
63370
  const buffer = Buffer.alloc(MAX_LENGTH);
63272
- const bytesRead = fs8.readSync(fd, buffer, 0, MAX_LENGTH, 0);
63273
- fs8.close(fd, () => {});
63371
+ const bytesRead = fs9.readSync(fd, buffer, 0, MAX_LENGTH, 0);
63372
+ fs9.close(fd, () => {});
63274
63373
  return buffer.subarray(0, bytesRead);
63275
63374
  };
63276
63375
  var readFile = (path13) => new Promise((resolve4, reject) => {
63277
- fs8.open(path13, "r", (err, fd) => {
63376
+ fs9.open(path13, "r", (err, fd) => {
63278
63377
  if (err) {
63279
63378
  reject(err);
63280
63379
  } else {
63281
63380
  const buffer = Buffer.alloc(MAX_LENGTH);
63282
- fs8.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
63381
+ fs9.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
63283
63382
  resolve4(buffer.subarray(0, bytesRead));
63284
- fs8.close(fd, () => {});
63383
+ fs9.close(fd, () => {});
63285
63384
  });
63286
63385
  }
63287
63386
  });
@@ -99944,10 +100043,10 @@ Note that ${s.bold("include")} statements only accept relation fields.`, a12;
99944
100043
  super(t2, "P2023", r2);
99945
100044
  }
99946
100045
  };
99947
- var fs8 = new WeakMap;
100046
+ var fs9 = new WeakMap;
99948
100047
  function Ep(e) {
99949
- let t2 = fs8.get(e);
99950
- return t2 || (t2 = Object.entries(e), fs8.set(e, t2)), t2;
100048
+ let t2 = fs9.get(e);
100049
+ return t2 || (t2 = Object.entries(e), fs9.set(e, t2)), t2;
99951
100050
  }
99952
100051
  function hs(e, t2, r2) {
99953
100052
  switch (t2.type) {
@@ -113391,6 +113490,89 @@ var init_reranker = __esm(() => {
113391
113490
  });
113392
113491
  });
113393
113492
 
113493
+ // ../../packages/core/dist/kernel/search-diagnostics.js
113494
+ function searchBackendUnavailable(component, cause) {
113495
+ return cause instanceof SearchServiceError ? cause : new SearchServiceError("SEARCH_BACKEND_UNAVAILABLE", component, { cause });
113496
+ }
113497
+ function storeCorruption(component, cause) {
113498
+ return cause instanceof SearchServiceError ? cause : new SearchServiceError("STORE_CORRUPTION", component, {
113499
+ cause,
113500
+ statusCode: 500
113501
+ });
113502
+ }
113503
+ function projectNotIndexed(projectId, message) {
113504
+ return new SearchServiceError("PROJECT_NOT_INDEXED", projectId, {
113505
+ message,
113506
+ statusCode: 404
113507
+ });
113508
+ }
113509
+ function recordSearchDegradation(code, component, projectId) {
113510
+ const degradation = {
113511
+ code,
113512
+ component,
113513
+ message: DEGRADATION_MESSAGES[code]
113514
+ };
113515
+ diagnostics.push({
113516
+ kind: "degradation",
113517
+ ...degradation,
113518
+ projectId,
113519
+ timestamp: new Date().toISOString()
113520
+ });
113521
+ if (diagnostics.length > MAX_DIAGNOSTICS) {
113522
+ diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
113523
+ }
113524
+ return degradation;
113525
+ }
113526
+ function recordSearchFailure(error51, projectId) {
113527
+ if (recordedFailures.has(error51))
113528
+ return;
113529
+ recordedFailures.add(error51);
113530
+ diagnostics.push({
113531
+ kind: "failure",
113532
+ code: error51.code,
113533
+ component: error51.component,
113534
+ message: error51.message,
113535
+ projectId,
113536
+ timestamp: new Date().toISOString()
113537
+ });
113538
+ if (diagnostics.length > MAX_DIAGNOSTICS) {
113539
+ diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
113540
+ }
113541
+ }
113542
+ function getSearchDiagnostics() {
113543
+ return diagnostics.map((diagnostic) => ({ ...diagnostic }));
113544
+ }
113545
+ function resetSearchDiagnosticsForTests() {
113546
+ diagnostics.length = 0;
113547
+ }
113548
+ var MAX_DIAGNOSTICS = 100, diagnostics, recordedFailures, DEGRADATION_MESSAGES, SearchServiceError;
113549
+ var init_search_diagnostics = __esm(() => {
113550
+ diagnostics = [];
113551
+ recordedFailures = new WeakSet;
113552
+ DEGRADATION_MESSAGES = {
113553
+ QUERY_UNDERSTANDING_UNAVAILABLE: "Query understanding was unavailable; original query used",
113554
+ TRIGRAM_UNAVAILABLE: "Trigram enrichment was unavailable",
113555
+ FUZZY_SEARCH_UNAVAILABLE: "Fuzzy enrichment was unavailable",
113556
+ PROXIMITY_RERANK_UNAVAILABLE: "Proximity reranking was unavailable; fused order preserved",
113557
+ GRAPH_AUGMENTATION_UNAVAILABLE: "Graph augmentation was unavailable",
113558
+ SYNAPSE_UNAVAILABLE: "Synapse enrichment was unavailable; stateless results used",
113559
+ SEARCH_AUDIT_UNAVAILABLE: "Search event auditing was unavailable",
113560
+ SEARCH_ANALYTICS_UNAVAILABLE: "Search analytics were unavailable"
113561
+ };
113562
+ SearchServiceError = class SearchServiceError extends Error {
113563
+ code;
113564
+ component;
113565
+ statusCode;
113566
+ constructor(code, component, options) {
113567
+ super(options?.message ?? (code === "STORE_CORRUPTION" ? "Stored data is invalid" : "A required search backend is unavailable"), options?.cause === undefined ? undefined : { cause: options.cause });
113568
+ this.code = code;
113569
+ this.component = component;
113570
+ this.name = "SearchServiceError";
113571
+ this.statusCode = options?.statusCode ?? 503;
113572
+ }
113573
+ };
113574
+ });
113575
+
113394
113576
  // ../../packages/core/dist/kernel/enum-validation.js
113395
113577
  function validateEnum(paramName, value, validValues) {
113396
113578
  if (typeof value !== "string" || !validValues.includes(value)) {
@@ -113499,7 +113681,7 @@ class SearchController {
113499
113681
  });
113500
113682
  const admission = await this.contextualSearch.checkSearchAdmission(projectId, projectPath);
113501
113683
  if (!admission.admitted) {
113502
- throw new Error(admission.error ?? `Project '${projectId}' is not indexed`);
113684
+ throw projectNotIndexed(projectId, admission.error ?? `Project '${projectId}' is not indexed`);
113503
113685
  }
113504
113686
  const staleWarning = admission.stale ?? null;
113505
113687
  let reindexInfo = null;
@@ -113723,6 +113905,7 @@ var init_search_controller = __esm(() => {
113723
113905
  init_contextual_search_rlm();
113724
113906
  init_event_bus();
113725
113907
  init_reranker();
113908
+ init_search_diagnostics();
113726
113909
  init_esm();
113727
113910
  init_filter_validation();
113728
113911
  });
@@ -114208,83 +114391,6 @@ var init_session_bias = __esm(() => {
114208
114391
  init_synapse();
114209
114392
  });
114210
114393
 
114211
- // ../../packages/core/dist/kernel/search-diagnostics.js
114212
- function searchBackendUnavailable(component, cause) {
114213
- return cause instanceof SearchServiceError ? cause : new SearchServiceError("SEARCH_BACKEND_UNAVAILABLE", component, { cause });
114214
- }
114215
- function storeCorruption(component, cause) {
114216
- return cause instanceof SearchServiceError ? cause : new SearchServiceError("STORE_CORRUPTION", component, {
114217
- cause,
114218
- statusCode: 500
114219
- });
114220
- }
114221
- function recordSearchDegradation(code, component, projectId) {
114222
- const degradation = {
114223
- code,
114224
- component,
114225
- message: DEGRADATION_MESSAGES[code]
114226
- };
114227
- diagnostics.push({
114228
- kind: "degradation",
114229
- ...degradation,
114230
- projectId,
114231
- timestamp: new Date().toISOString()
114232
- });
114233
- if (diagnostics.length > MAX_DIAGNOSTICS) {
114234
- diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
114235
- }
114236
- return degradation;
114237
- }
114238
- function recordSearchFailure(error51, projectId) {
114239
- if (recordedFailures.has(error51))
114240
- return;
114241
- recordedFailures.add(error51);
114242
- diagnostics.push({
114243
- kind: "failure",
114244
- code: error51.code,
114245
- component: error51.component,
114246
- message: error51.message,
114247
- projectId,
114248
- timestamp: new Date().toISOString()
114249
- });
114250
- if (diagnostics.length > MAX_DIAGNOSTICS) {
114251
- diagnostics.splice(0, diagnostics.length - MAX_DIAGNOSTICS);
114252
- }
114253
- }
114254
- function getSearchDiagnostics() {
114255
- return diagnostics.map((diagnostic) => ({ ...diagnostic }));
114256
- }
114257
- function resetSearchDiagnosticsForTests() {
114258
- diagnostics.length = 0;
114259
- }
114260
- var MAX_DIAGNOSTICS = 100, diagnostics, recordedFailures, DEGRADATION_MESSAGES, SearchServiceError;
114261
- var init_search_diagnostics = __esm(() => {
114262
- diagnostics = [];
114263
- recordedFailures = new WeakSet;
114264
- DEGRADATION_MESSAGES = {
114265
- QUERY_UNDERSTANDING_UNAVAILABLE: "Query understanding was unavailable; original query used",
114266
- TRIGRAM_UNAVAILABLE: "Trigram enrichment was unavailable",
114267
- FUZZY_SEARCH_UNAVAILABLE: "Fuzzy enrichment was unavailable",
114268
- PROXIMITY_RERANK_UNAVAILABLE: "Proximity reranking was unavailable; fused order preserved",
114269
- GRAPH_AUGMENTATION_UNAVAILABLE: "Graph augmentation was unavailable",
114270
- SYNAPSE_UNAVAILABLE: "Synapse enrichment was unavailable; stateless results used",
114271
- SEARCH_AUDIT_UNAVAILABLE: "Search event auditing was unavailable",
114272
- SEARCH_ANALYTICS_UNAVAILABLE: "Search analytics were unavailable"
114273
- };
114274
- SearchServiceError = class SearchServiceError extends Error {
114275
- code;
114276
- component;
114277
- statusCode;
114278
- constructor(code, component, options) {
114279
- super(code === "STORE_CORRUPTION" ? "Stored data is invalid" : "A required search backend is unavailable", options?.cause === undefined ? undefined : { cause: options.cause });
114280
- this.code = code;
114281
- this.component = component;
114282
- this.name = "SearchServiceError";
114283
- this.statusCode = options?.statusCode ?? 503;
114284
- }
114285
- };
114286
- });
114287
-
114288
114394
  // ../../packages/core/dist/services/search/hybrid-search.js
114289
114395
  async function search(deps, query, projectId, options = {}) {
114290
114396
  const maxResults = options.maxResults ?? 10;
@@ -115641,7 +115747,7 @@ var init_managed_run_repository_pg = __esm(() => {
115641
115747
  });
115642
115748
 
115643
115749
  // ../../packages/core/dist/services/search/project-indexer.js
115644
- import fs8 from "fs/promises";
115750
+ import fs9 from "fs/promises";
115645
115751
  import path14 from "path";
115646
115752
  import { randomUUID as randomUUID3 } from "crypto";
115647
115753
  async function runWithIndexLock(lockMap, projectId, work) {
@@ -115901,7 +116007,7 @@ async function checkSearchAdmission(deps, projectId, projectPath) {
115901
116007
  }
115902
116008
  async function indexFile(deps, filePath, projectId, projectRoot, centralityMap) {
115903
116009
  projectId = await getProjectIdentityAliasResolver().resolve(projectId);
115904
- const content = await fs8.readFile(filePath, "utf-8");
116010
+ const content = await fs9.readFile(filePath, "utf-8");
115905
116011
  const relativePath = path14.relative(projectRoot, filePath);
115906
116012
  const maxFileSize = config.get("security").maxFileSize || 1024 * 1024;
115907
116013
  if (content.length > maxFileSize) {
@@ -116739,6 +116845,7 @@ class IndexJobTracker {
116739
116845
  filesIndexed: r2?.filesIndexed ?? 0,
116740
116846
  chunksIndexed: r2?.chunksIndexed ?? 0,
116741
116847
  symbolsIndexed: 0,
116848
+ errors: r2?.errors ?? 0,
116742
116849
  durationMs: r2?.duration ?? 0,
116743
116850
  activatedGraphGenerationId: r2?.activatedGraphGenerationId ?? ""
116744
116851
  });
@@ -116760,8 +116867,13 @@ var init_index_job_tracker = __esm(() => {
116760
116867
  indexJobTracker = IndexJobTracker.getInstance();
116761
116868
  });
116762
116869
 
116870
+ // ../../packages/core/dist/kernel/sanitize/strip-nul.js
116871
+ function stripNul(content) {
116872
+ return content.includes("\x00") ? content.replaceAll("\x00", "") : content;
116873
+ }
116874
+
116763
116875
  // ../../packages/core/dist/services/etl/stages/discover.js
116764
- import fs9 from "fs/promises";
116876
+ import fs10 from "fs/promises";
116765
116877
  import path15 from "path";
116766
116878
  import { createHash as createHash5 } from "crypto";
116767
116879
 
@@ -116849,8 +116961,8 @@ class DiscoverStage {
116849
116961
  async processFile(ctx, relativePath, forceReindex) {
116850
116962
  const absolutePath = path15.join(ctx.projectPath, relativePath);
116851
116963
  try {
116852
- const stat2 = await fs9.stat(absolutePath);
116853
- const content = await fs9.readFile(absolutePath, "utf-8");
116964
+ const stat2 = await fs10.stat(absolutePath);
116965
+ const content = stripNul(await fs10.readFile(absolutePath, "utf-8"));
116854
116966
  const contentHash = createHash5("sha256").update(content).digest("hex");
116855
116967
  let needsReparse = forceReindex;
116856
116968
  if (!forceReindex) {
@@ -116894,7 +117006,7 @@ class DiscoverStage {
116894
117006
  }
116895
117007
  try {
116896
117008
  const gitignorePath = path15.join(projectPath, ".gitignore");
116897
- const gitignoreContent = await fs9.readFile(gitignorePath, "utf8");
117009
+ const gitignoreContent = await fs10.readFile(gitignorePath, "utf8");
116898
117010
  const rules = gitignoreContent.split(`
116899
117011
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
116900
117012
  ig.add(rules);
@@ -119223,7 +119335,7 @@ var init_structural_runtime = __esm(() => {
119223
119335
 
119224
119336
  // ../../packages/core/dist/services/etl/stages/parse.js
119225
119337
  import path16 from "path";
119226
- import fs10 from "fs/promises";
119338
+ import fs11 from "fs/promises";
119227
119339
  function resolveChunkerMaxChars() {
119228
119340
  const global2 = Number(process.env.EMBEDDING_MAX_CHARS);
119229
119341
  if (Number.isFinite(global2) && global2 > 0)
@@ -119315,7 +119427,7 @@ class ParseStage {
119315
119427
  if (!file3.needsReparse) {
119316
119428
  const extension = path16.extname(file3.relativePath).toLowerCase();
119317
119429
  if ([".c", ".cpp", ".hpp"].includes(extension)) {
119318
- const content = file3.snapshotContent ?? await fs10.readFile(file3.absolutePath, "utf8");
119430
+ const content = file3.snapshotContent ?? await fs11.readFile(file3.absolutePath, "utf8");
119319
119431
  const outcome = await this.runtime.parse({ extension, source: Buffer.from(content) });
119320
119432
  if (outcome.status === "failed")
119321
119433
  throw new StructuralEtlParseError(file3.relativePath, outcome.failureKind, `Structural evidence parse failed (${outcome.failureKind})`, outcome.diagnosticCount, outcome.diagnostics.slice(0, 10));
@@ -119327,7 +119439,7 @@ class ParseStage {
119327
119439
  return { file: file3, chunks: [], symbols: [], rawImports: [], rawEdges: [] };
119328
119440
  }
119329
119441
  try {
119330
- const content = file3.snapshotContent ?? await fs10.readFile(file3.absolutePath, "utf-8");
119442
+ const content = file3.snapshotContent ?? await fs11.readFile(file3.absolutePath, "utf-8");
119331
119443
  const ext2 = path16.extname(file3.relativePath).toLowerCase();
119332
119444
  const chunkerMaxChars = resolveChunkerMaxChars();
119333
119445
  const chunks = smartChunk(content, file3.relativePath, chunkerMaxChars ? { maxChunkChars: chunkerMaxChars } : {});
@@ -120368,7 +120480,7 @@ var init_data_document2 = __esm(() => {
120368
120480
 
120369
120481
  // ../../packages/core/dist/services/etl/stages/resolve.js
120370
120482
  import path19 from "path";
120371
- import fs11 from "fs";
120483
+ import fs12 from "fs";
120372
120484
 
120373
120485
  class ResolveStage {
120374
120486
  symbolRepository;
@@ -120685,7 +120797,7 @@ class ResolveStage {
120685
120797
  const aliases = [];
120686
120798
  const tsconfigPath = path19.join(projectPath, "tsconfig.json");
120687
120799
  try {
120688
- const raw2 = fs11.readFileSync(tsconfigPath, "utf-8");
120800
+ const raw2 = fs12.readFileSync(tsconfigPath, "utf-8");
120689
120801
  const stripped = raw2.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
120690
120802
  const tsconfig = JSON.parse(stripped);
120691
120803
  const paths = tsconfig?.compilerOptions?.paths ?? {};
@@ -120911,6 +121023,7 @@ class LoadStage {
120911
121023
  let chunksLoaded = 0;
120912
121024
  let symbolsLoaded = 0;
120913
121025
  let errors5 = 0;
121026
+ const fileErrors = [];
120914
121027
  let processedSinceStart = 0;
120915
121028
  let lastEtaLogAt = 0;
120916
121029
  const BATCH = 10;
@@ -120981,6 +121094,12 @@ class LoadStage {
120981
121094
  } catch (err) {
120982
121095
  errors5++;
120983
121096
  processedSinceStart++;
121097
+ if (fileErrors.length < MAX_FILE_ERRORS) {
121098
+ fileErrors.push({
121099
+ filePath: file3.file.relativePath,
121100
+ error: err.message
121101
+ });
121102
+ }
120984
121103
  if (emitLifecycle)
120985
121104
  ctx.emit({
120986
121105
  type: "file_error",
@@ -121046,7 +121165,7 @@ class LoadStage {
121046
121165
  duration: formatDuration(durationMs),
121047
121166
  filesPerSec: filesLoaded > 0 && durationMs > 0 ? Number((filesLoaded / durationMs * 1000).toFixed(2)) : 0
121048
121167
  });
121049
- return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors5 };
121168
+ return { filesLoaded, chunksLoaded, symbolsLoaded, errors: errors5, fileErrors };
121050
121169
  }
121051
121170
  async loadToSearchStores(ctx, file3) {
121052
121171
  if (file3.chunks.length === 0)
@@ -121118,6 +121237,7 @@ class LoadStage {
121118
121237
  return batch.definitions.length;
121119
121238
  }
121120
121239
  }
121240
+ var MAX_FILE_ERRORS = 50;
121121
121241
  var init_load = __esm(() => {
121122
121242
  init_dist();
121123
121243
  init_with_deadlock_retry();
@@ -121860,7 +121980,12 @@ var init_pipeline = __esm(() => {
121860
121980
  throw managedRunLeaseLost;
121861
121981
  stageTimings.load = Math.round(performance.now() - st4);
121862
121982
  if (loadResult.errors > 0) {
121863
- throw new Error(`ETL completed with ${loadResult.errors} file error${loadResult.errors === 1 ? "" : "s"}`);
121983
+ logger.warn("EtlPipeline: completed with file errors", {
121984
+ projectId,
121985
+ jobId,
121986
+ errors: loadResult.errors,
121987
+ fileErrors: (loadResult.fileErrors ?? []).slice(0, 10)
121988
+ });
121864
121989
  }
121865
121990
  const activationSnapshot = await abortable(this.discover.run(ctx, { forceReindex, includeTests: include_tests }), graphAbortController.signal);
121866
121991
  if (buildGraphInputSnapshotHash(activationSnapshot) !== graphGenerationLease.inputSnapshotHash) {
@@ -121917,6 +122042,7 @@ var init_pipeline = __esm(() => {
121917
122042
  filesIndexed: result.filesIndexed,
121918
122043
  chunksIndexed: result.chunksIndexed,
121919
122044
  errors: result.errors,
122045
+ fileErrors: loadResult.fileErrors ?? [],
121920
122046
  duration: durationMs,
121921
122047
  activatedGraphGenerationId: result.activatedGraphGenerationId,
121922
122048
  parserDiagnostics: result.parserDiagnostics
@@ -121927,6 +122053,7 @@ var init_pipeline = __esm(() => {
121927
122053
  filesIndexed: result.filesIndexed,
121928
122054
  chunksIndexed: result.chunksIndexed,
121929
122055
  symbolsIndexed: result.symbolsIndexed,
122056
+ errors: result.errors,
121930
122057
  durationMs,
121931
122058
  activatedGraphGenerationId: result.activatedGraphGenerationId
121932
122059
  });
@@ -122966,7 +123093,7 @@ __export(exports_symbol_graph_service, {
122966
123093
  SymbolGraphService: () => SymbolGraphService
122967
123094
  });
122968
123095
  import path23 from "path";
122969
- import fs12 from "fs/promises";
123096
+ import fs13 from "fs/promises";
122970
123097
 
122971
123098
  class SymbolGraphService {
122972
123099
  identityLookup;
@@ -123294,7 +123421,7 @@ class SymbolGraphService {
123294
123421
  async readSnippet(relativePath, lineStart, lineEnd, projectId) {
123295
123422
  try {
123296
123423
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123297
- const content = await fs12.readFile(absolutePath, "utf-8");
123424
+ const content = await fs13.readFile(absolutePath, "utf-8");
123298
123425
  const lines = content.split(`
123299
123426
  `);
123300
123427
  return lines.slice(Math.max(0, lineStart - 1), Math.min(lines.length, lineEnd)).join(`
@@ -123306,7 +123433,7 @@ class SymbolGraphService {
123306
123433
  async readContext(relativePath, lineNumber, contextLines, projectId) {
123307
123434
  try {
123308
123435
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123309
- const content = await fs12.readFile(absolutePath, "utf-8");
123436
+ const content = await fs13.readFile(absolutePath, "utf-8");
123310
123437
  const lines = content.split(`
123311
123438
  `);
123312
123439
  const start = Math.max(0, lineNumber - contextLines - 1);
@@ -130475,7 +130602,7 @@ var init_l1_memory_cache = __esm(() => {
130475
130602
  });
130476
130603
 
130477
130604
  // ../../packages/core/dist/services/health/local-health-checker.js
130478
- import fs15 from "fs/promises";
130605
+ import fs16 from "fs/promises";
130479
130606
  import { existsSync as existsSync3 } from "fs";
130480
130607
  import path28 from "path";
130481
130608
 
@@ -130511,10 +130638,10 @@ class LocalHealthChecker {
130511
130638
  const start = Date.now();
130512
130639
  try {
130513
130640
  if (!existsSync3(this.dataDir))
130514
- await fs15.mkdir(this.dataDir, { recursive: true });
130641
+ await fs16.mkdir(this.dataDir, { recursive: true });
130515
130642
  const probe2 = path28.join(this.dataDir, ".health-check-test");
130516
- await fs15.writeFile(probe2, "ok");
130517
- await fs15.unlink(probe2);
130643
+ await fs16.writeFile(probe2, "ok");
130644
+ await fs16.unlink(probe2);
130518
130645
  return { available: true, latency: Date.now() - start, details: { path: this.dataDir, writable: true } };
130519
130646
  } catch (error51) {
130520
130647
  return { available: false, latency: Date.now() - start, error: `Data directory error: ${error51.message}` };
@@ -132424,7 +132551,7 @@ var init_scheduler2 = __esm(() => {
132424
132551
  });
132425
132552
 
132426
132553
  // ../../packages/core/dist/services/pricing/models-dev-client.js
132427
- import fs16 from "fs/promises";
132554
+ import fs17 from "fs/promises";
132428
132555
  import { existsSync as existsSync4 } from "fs";
132429
132556
  import path29 from "path";
132430
132557
  function getModelsDevClient() {
@@ -132454,7 +132581,7 @@ var init_models_dev_client = __esm(() => {
132454
132581
  if (!existsSync4(cachePath)) {
132455
132582
  return null;
132456
132583
  }
132457
- const content = await fs16.readFile(cachePath, "utf-8");
132584
+ const content = await fs17.readFile(cachePath, "utf-8");
132458
132585
  const data = JSON.parse(content);
132459
132586
  const age = Date.now() - data.timestamp;
132460
132587
  if (age > ModelsDevClient.LOCAL_CACHE_TTL) {
@@ -132482,13 +132609,13 @@ var init_models_dev_client = __esm(() => {
132482
132609
  const cachePath = this.getLocalCachePath();
132483
132610
  try {
132484
132611
  const dir = path29.dirname(cachePath);
132485
- await fs16.mkdir(dir, { recursive: true });
132612
+ await fs17.mkdir(dir, { recursive: true });
132486
132613
  const data = {
132487
132614
  timestamp: Date.now(),
132488
132615
  version: "1.0.0",
132489
132616
  models: Object.fromEntries(models)
132490
132617
  };
132491
- await fs16.writeFile(cachePath, JSON.stringify(data), "utf-8");
132618
+ await fs17.writeFile(cachePath, JSON.stringify(data), "utf-8");
132492
132619
  logger.debug("Saved pricing to local cache", {
132493
132620
  models: models.size,
132494
132621
  path: cachePath
@@ -132817,7 +132944,7 @@ var init_models_dev_client = __esm(() => {
132817
132944
  const cachePath = this.getLocalCachePath();
132818
132945
  try {
132819
132946
  if (existsSync4(cachePath)) {
132820
- await fs16.unlink(cachePath);
132947
+ await fs17.unlink(cachePath);
132821
132948
  logger.debug("Local pricing cache file deleted");
132822
132949
  }
132823
132950
  } catch (error51) {
@@ -150835,6 +150962,7 @@ __export(exports_services, {
150835
150962
  selectCompressionCandidates: () => selectCompressionCandidates,
150836
150963
  searchSessionHook: () => searchSessionHook,
150837
150964
  searchBackendUnavailable: () => searchBackendUnavailable,
150965
+ safeErrorSummary: () => safeErrorSummary,
150838
150966
  runPool: () => runPool,
150839
150967
  resolveStructuralParseLanguage: () => resolveStructuralParseLanguage,
150840
150968
  resetSynapseManager: () => resetSynapseManager,
@@ -150849,6 +150977,7 @@ __export(exports_services, {
150849
150977
  recordSearchFailure: () => recordSearchFailure,
150850
150978
  recordSearchDegradation: () => recordSearchDegradation,
150851
150979
  quoteDiscoveredIdentifier: () => quoteDiscoveredIdentifier,
150980
+ projectNotIndexed: () => projectNotIndexed,
150852
150981
  payloadStorePolicies: () => payloadStorePolicies,
150853
150982
  parseStructuralFqn: () => parseStructuralFqn,
150854
150983
  parseProjectIdentityPreviewRequest: () => parseProjectIdentityPreviewRequest,
@@ -151066,6 +151195,7 @@ var init_services = __esm(() => {
151066
151195
  init_search_analytics_pg();
151067
151196
  init_index_manager();
151068
151197
  init_search_diagnostics();
151198
+ init_safe_error_summary();
151069
151199
  init_memory_controller();
151070
151200
  init_llm_client();
151071
151201
  init_search_controller();
@@ -175513,7 +175643,8 @@ init_compaction_snapshot_service();
175513
175643
  init_dist();
175514
175644
  init_db_connection();
175515
175645
  init_alias_resolver();
175516
- import fs13 from "fs";
175646
+ init_safe_error_summary();
175647
+ import fs14 from "fs";
175517
175648
  import os6 from "os";
175518
175649
  import path25 from "path";
175519
175650
 
@@ -175590,9 +175721,7 @@ class PgWorkspaceRootProvider {
175590
175721
  this.cache = { roots, expiresAt: this.now() + PROVIDER_TTL_MS };
175591
175722
  return roots;
175592
175723
  } catch (error51) {
175593
- logger.warn("[hook-attribution] workspace roots lookup failed; containment disabled (sanitized)", {
175594
- name: error51 instanceof Error ? error51.name : "unknown"
175595
- });
175724
+ logger.warn("[hook-attribution] workspace roots lookup failed; containment disabled", safeErrorSummary(error51));
175596
175725
  return [];
175597
175726
  } finally {
175598
175727
  if (timer)
@@ -175701,7 +175830,7 @@ class AttributionResolver {
175701
175830
  }
175702
175831
  function defaultCanonicalize(cwd) {
175703
175832
  try {
175704
- return fs13.realpathSync(cwd);
175833
+ return fs14.realpathSync(cwd);
175705
175834
  } catch {
175706
175835
  try {
175707
175836
  return path25.resolve(cwd);
@@ -175717,70 +175846,9 @@ function getAttributionResolver() {
175717
175846
  return sharedResolver2;
175718
175847
  }
175719
175848
 
175720
- // ../../packages/core/dist/kernel/sanitize/credential-scrub.js
175721
- function markerFor(id) {
175722
- return `[REDACTED:${id}]`;
175723
- }
175724
- function fullMatchRule(id, pattern) {
175725
- const marker26 = markerFor(id);
175726
- return {
175727
- id,
175728
- replace(text3) {
175729
- let count = 0;
175730
- const replaced = text3.replace(pattern, () => {
175731
- count++;
175732
- return marker26;
175733
- });
175734
- return { text: replaced, count };
175735
- }
175736
- };
175737
- }
175738
- var PEM_PATTERN = /-----BEGIN [A-Z ]{0,32}PRIVATE KEY-----[\s\S]{0,8192}?-----END [A-Z ]{0,32}PRIVATE KEY-----/g;
175739
- var JWT_PATTERN = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g;
175740
- var AWS_KEY_PATTERN = /\b(?:AKIA|ASIA|ABIA|ACCA)[A-Z0-9]{16}\b/g;
175741
- var SK_KEY_PATTERN = /\bsk-[A-Za-z0-9_-]{20,}\b/g;
175742
- var GITHUB_TOKEN_PATTERN = /\bgh[pousr]_[A-Za-z0-9]{36,}\b|\bgithub_pat_[A-Za-z0-9_]{22,}\b/g;
175743
- var SLACK_TOKEN_PATTERN = /\bxox[baprs]-[A-Za-z0-9-]{18,}\b/g;
175744
- var BEARER_PATTERN = /(Bearer\s+)([A-Za-z0-9._~+/=-]{20,})/g;
175745
- var RULES = [
175746
- fullMatchRule("pem", PEM_PATTERN),
175747
- fullMatchRule("jwt", JWT_PATTERN),
175748
- fullMatchRule("aws-key", AWS_KEY_PATTERN),
175749
- fullMatchRule("sk-key", SK_KEY_PATTERN),
175750
- fullMatchRule("github-token", GITHUB_TOKEN_PATTERN),
175751
- fullMatchRule("slack-token", SLACK_TOKEN_PATTERN),
175752
- {
175753
- id: "bearer",
175754
- replace(text3) {
175755
- let count = 0;
175756
- const replaced = text3.replace(BEARER_PATTERN, (_m, prefix) => {
175757
- count++;
175758
- return `${prefix}${markerFor("bearer")}`;
175759
- });
175760
- return { text: replaced, count };
175761
- }
175762
- }
175763
- ];
175764
- var RULE_IDS = RULES.map((r2) => r2.id);
175765
- function scrubCredentials(payloadJson) {
175766
- const redactions = {};
175767
- for (const id of RULE_IDS)
175768
- redactions[id] = 0;
175769
- let text3 = payloadJson;
175770
- for (const rule of RULES) {
175771
- const { text: next, count } = rule.replace(text3);
175772
- text3 = next;
175773
- redactions[rule.id] += count;
175774
- }
175775
- const total = Object.values(redactions).reduce((sum, n2) => sum + n2, 0);
175776
- return {
175777
- sanitized: text3,
175778
- redactions,
175779
- total
175780
- };
175781
- }
175782
-
175783
175849
  // ../../packages/core/dist/tools/compact_snapshot.js
175850
+ init_credential_scrub();
175851
+
175784
175852
  class CompactSnapshotTool {
175785
175853
  name = "compact_snapshot";
175786
175854
  storeOverride;
@@ -176302,7 +176370,7 @@ init_code_compressor();
176302
176370
 
176303
176371
  // ../../packages/core/dist/services/file-read/file-content-cache.js
176304
176372
  init_dist();
176305
- import fs14 from "fs/promises";
176373
+ import fs15 from "fs/promises";
176306
176374
 
176307
176375
  class FileContentCache {
176308
176376
  extractMetadata;
@@ -176335,7 +176403,7 @@ class FileContentCache {
176335
176403
  metadata: cached2.metadata
176336
176404
  };
176337
176405
  }
176338
- const content = await fs14.readFile(filePath, "utf-8");
176406
+ const content = await fs15.readFile(filePath, "utf-8");
176339
176407
  const metadata = await this.extractMetadata(content, filePath, options);
176340
176408
  evictOldest(this.fileCache, this.FILE_CACHE_MAX_ENTRIES - 1);
176341
176409
  this.fileCache.set(cacheKey, {
@@ -177170,6 +177238,8 @@ class WriterQueue {
177170
177238
  // ../../packages/core/dist/services/hooks/hook-service.js
177171
177239
  init_observation_extractor();
177172
177240
  init_observation_consolidation_job();
177241
+ init_credential_scrub();
177242
+
177173
177243
  class NoopBridge {
177174
177244
  maybeRun() {}
177175
177245
  }
@@ -177374,7 +177444,7 @@ init_event_bus();
177374
177444
  init_llm_client();
177375
177445
  init_symbol_graph_service();
177376
177446
  import { randomUUID as randomUUID9 } from "crypto";
177377
- import fs17 from "fs";
177447
+ import fs18 from "fs";
177378
177448
  import path30 from "path";
177379
177449
  import { spawn as spawn2 } from "child_process";
177380
177450
  var FALLBACK_BOOTSTRAP = {
@@ -177560,8 +177630,8 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177560
177630
  try {
177561
177631
  for (const name26 of README_CANDIDATES) {
177562
177632
  const p = path30.join(projectRoot, name26);
177563
- if (fs17.existsSync(p) && fs17.statSync(p).isFile()) {
177564
- const buf = fs17.readFileSync(p);
177633
+ if (fs18.existsSync(p) && fs18.statSync(p).isFile()) {
177634
+ const buf = fs18.readFileSync(p);
177565
177635
  signals.readme = buf.slice(0, MAX_README_BYTES).toString("utf8");
177566
177636
  break;
177567
177637
  }
@@ -177571,11 +177641,11 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177571
177641
  }
177572
177642
  try {
177573
177643
  const docsDir = path30.join(projectRoot, "docs");
177574
- if (fs17.existsSync(docsDir) && fs17.statSync(docsDir).isDirectory()) {
177644
+ if (fs18.existsSync(docsDir) && fs18.statSync(docsDir).isDirectory()) {
177575
177645
  const entries = walkMarkdown(docsDir).slice(0, MAX_DOCS);
177576
177646
  for (const rel of entries) {
177577
177647
  try {
177578
- const buf = fs17.readFileSync(rel);
177648
+ const buf = fs18.readFileSync(rel);
177579
177649
  signals.docs.push({
177580
177650
  path: path30.relative(projectRoot, rel),
177581
177651
  snippet: buf.slice(0, MAX_DOC_BYTES).toString("utf8")
@@ -177589,9 +177659,9 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177589
177659
  try {
177590
177660
  for (const name26 of MANIFEST_FILES) {
177591
177661
  const p = path30.join(projectRoot, name26);
177592
- if (!fs17.existsSync(p) || !fs17.statSync(p).isFile())
177662
+ if (!fs18.existsSync(p) || !fs18.statSync(p).isFile())
177593
177663
  continue;
177594
- const raw2 = fs17.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
177664
+ const raw2 = fs18.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
177595
177665
  const kind = name26;
177596
177666
  if (name26 === "package.json") {
177597
177667
  try {
@@ -177631,7 +177701,7 @@ function walkMarkdown(dir) {
177631
177701
  const cur = stack.pop();
177632
177702
  let entries;
177633
177703
  try {
177634
- entries = fs17.readdirSync(cur, { withFileTypes: true });
177704
+ entries = fs18.readdirSync(cur, { withFileTypes: true });
177635
177705
  } catch {
177636
177706
  continue;
177637
177707
  }
@@ -178669,7 +178739,7 @@ var checkpointRoutes = new Elysia({ prefix: "/api/v1/checkpoints" }).post("/list
178669
178739
 
178670
178740
  // src/routes/project.ts
178671
178741
  init_dist();
178672
- import fs18 from "fs/promises";
178742
+ import fs19 from "fs/promises";
178673
178743
  import path31 from "path";
178674
178744
  var indexProjectTool = null;
178675
178745
  var indexStatusTool = null;
@@ -178881,8 +178951,8 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
178881
178951
  const finalProjectId = rawBase.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 128);
178882
178952
  const uploadRoot = process.env.MASSA_AI_UPLOAD_DIR || path31.join(getGlobalDataDir(), "uploads");
178883
178953
  const stagingDir = path31.resolve(uploadRoot, finalProjectId);
178884
- await fs18.rm(stagingDir, { recursive: true, force: true });
178885
- await fs18.mkdir(stagingDir, { recursive: true });
178954
+ await fs19.rm(stagingDir, { recursive: true, force: true });
178955
+ await fs19.mkdir(stagingDir, { recursive: true });
178886
178956
  const WRITE_BATCH = 20;
178887
178957
  for (let i = 0;i < body.files.length; i += WRITE_BATCH) {
178888
178958
  await Promise.all(body.files.slice(i, i + WRITE_BATCH).map(async (file3) => {
@@ -178893,8 +178963,8 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
178893
178963
  if (!dest.startsWith(stagingDir + path31.sep)) {
178894
178964
  throw new Error(`Path escapes staging directory: ${file3.relativePath}`);
178895
178965
  }
178896
- await fs18.mkdir(path31.dirname(dest), { recursive: true });
178897
- await fs18.writeFile(dest, file3.content, "utf-8");
178966
+ await fs19.mkdir(path31.dirname(dest), { recursive: true });
178967
+ await fs19.writeFile(dest, file3.content, "utf-8");
178898
178968
  }));
178899
178969
  }
178900
178970
  return await getIndexProjectTool().handle({
@@ -179049,7 +179119,7 @@ var analyticsRoutes = new Elysia({ prefix: "/api/v1/analytics" }).post("/", asyn
179049
179119
  // src/routes/system.ts
179050
179120
  init_dist();
179051
179121
  import path32 from "path";
179052
- import fs19 from "fs";
179122
+ import fs20 from "fs";
179053
179123
  import os7 from "os";
179054
179124
  function databaseUrlParts() {
179055
179125
  const url2 = new URL(process.env.DATABASE_URL);
@@ -179125,9 +179195,9 @@ var systemRoutes = new Elysia({ prefix: "/api/v1/system" }).get("/info", async (
179125
179195
  }).get("/metrics", async () => {
179126
179196
  const metricsPath = path32.join(process.cwd(), "data", "metrics.json");
179127
179197
  let metrics2 = {};
179128
- if (fs19.existsSync(metricsPath)) {
179198
+ if (fs20.existsSync(metricsPath)) {
179129
179199
  try {
179130
- metrics2 = JSON.parse(fs19.readFileSync(metricsPath, "utf-8"));
179200
+ metrics2 = JSON.parse(fs20.readFileSync(metricsPath, "utf-8"));
179131
179201
  } catch {}
179132
179202
  }
179133
179203
  const database = await getDatabaseInfo();
@@ -179277,7 +179347,7 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
179277
179347
  });
179278
179348
 
179279
179349
  // src/routes/workspace.ts
179280
- import fs20 from "fs/promises";
179350
+ import fs21 from "fs/promises";
179281
179351
  import path33 from "path";
179282
179352
  import { realpathSync as realpathSync4 } from "fs";
179283
179353
  var indexProjectTool2 = null;
@@ -179803,7 +179873,7 @@ var workspaceRoutes = new Elysia({ prefix: "/api/v1" }).get("/workspace/list", a
179803
179873
  end = start + 20;
179804
179874
  }
179805
179875
  const absolutePath = path33.join(workspace.project_path, file3);
179806
- const content = await fs20.readFile(absolutePath, "utf-8");
179876
+ const content = await fs21.readFile(absolutePath, "utf-8");
179807
179877
  const lines = content.split(/\r?\n/);
179808
179878
  const slice = lines.slice(start - 1, Math.min(lines.length, end));
179809
179879
  const formatted = slice.map((text3, idx) => ({
@@ -179841,8 +179911,18 @@ function getReadFileTool() {
179841
179911
  }
179842
179912
  return readFileTool;
179843
179913
  }
179844
- var fileRoutes = new Elysia({ prefix: "/api/v1/file" }).post("/read", async ({ body }) => {
179845
- return await getReadFileTool().handle(body);
179914
+ function classifyReadFileFailureStatus(message) {
179915
+ if (message && /ENOENT|no such file/i.test(message)) {
179916
+ return 404;
179917
+ }
179918
+ return 400;
179919
+ }
179920
+ var fileRoutes = new Elysia({ prefix: "/api/v1/file" }).post("/read", async ({ body, set: set3 }) => {
179921
+ const result = await getReadFileTool().handle(body);
179922
+ if (result.success === false) {
179923
+ set3.status = classifyReadFileFailureStatus(result.error);
179924
+ }
179925
+ return result;
179846
179926
  }, {
179847
179927
  body: t.Object({
179848
179928
  filePath: t.String({
@@ -180718,7 +180798,7 @@ var webRoutes = new Elysia({ prefix: "/api/v1/web" }).post("/fetch_and_index", a
180718
180798
  });
180719
180799
 
180720
180800
  // src/routes/web-ui.ts
180721
- import fs21 from "fs/promises";
180801
+ import fs22 from "fs/promises";
180722
180802
  import path34 from "path";
180723
180803
  import { fileURLToPath as fileURLToPath3 } from "url";
180724
180804
 
@@ -180777,7 +180857,7 @@ var STATIC_DIR_CANDIDATES = buildStaticDirCandidates(path34.dirname(fileURLToPat
180777
180857
  async function resolveStaticDir() {
180778
180858
  for (const dir of STATIC_DIR_CANDIDATES) {
180779
180859
  try {
180780
- const st = await fs21.stat(dir);
180860
+ const st = await fs22.stat(dir);
180781
180861
  if (st.isDirectory())
180782
180862
  return dir;
180783
180863
  } catch {}
@@ -180815,7 +180895,7 @@ async function resolveSafePath(staticDir, sub) {
180815
180895
  return null;
180816
180896
  }
180817
180897
  try {
180818
- await fs21.stat(abs);
180898
+ await fs22.stat(abs);
180819
180899
  return { abs, exists: true };
180820
180900
  } catch {
180821
180901
  return { abs, exists: false };
@@ -180838,7 +180918,7 @@ function injectAccessMarkup(html, apiKey, trusted) {
180838
180918
  return out;
180839
180919
  }
180840
180920
  async function readShell(indexPath, remoteAddress) {
180841
- const raw2 = await fs21.readFile(indexPath, "utf-8");
180921
+ const raw2 = await fs22.readFile(indexPath, "utf-8");
180842
180922
  const trusted = isTrustedWebUiCaller(remoteAddress);
180843
180923
  return Buffer.from(injectAccessMarkup(raw2, getConfiguredApiKey(), trusted), "utf-8");
180844
180924
  }
@@ -180888,7 +180968,7 @@ var webUiRoutes = new Elysia().get("/ui", async ({ set: set3, request }) => {
180888
180968
  }
180889
180969
  if (resolved.exists) {
180890
180970
  try {
180891
- const body = await fs21.readFile(resolved.abs);
180971
+ const body = await fs22.readFile(resolved.abs);
180892
180972
  set3.headers["content-type"] = contentTypeFor(resolved.abs);
180893
180973
  return body;
180894
180974
  } catch {
@@ -181124,10 +181204,13 @@ var profileRoutes = new Elysia({ prefix: "/api/v1/profiles" }).get("/", ({ query
181124
181204
  });
181125
181205
 
181126
181206
  // src/middleware/error.ts
181127
- var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3 }) => {
181128
- console.error("[massa-ai-api] Request failed", {
181129
- name: error51 instanceof Error ? error51.name : "UnknownError",
181130
- code
181207
+ init_dist();
181208
+ var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path35, request }) => {
181209
+ logger.error("[massa-ai-api] Request failed", undefined, {
181210
+ ...safeErrorSummary(error51),
181211
+ code,
181212
+ path: path35,
181213
+ method: request.method
181131
181214
  });
181132
181215
  if (error51 instanceof SearchServiceError) {
181133
181216
  set3.status = error51.statusCode;
@@ -181150,6 +181233,16 @@ var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error:
181150
181233
  }
181151
181234
  };
181152
181235
  }
181236
+ if (code === "NOT_FOUND") {
181237
+ set3.status = 404;
181238
+ return {
181239
+ success: false,
181240
+ error: {
181241
+ code: "NOT_FOUND",
181242
+ message: "Route not found"
181243
+ }
181244
+ };
181245
+ }
181153
181246
  if (!set3.status || set3.status === 200) {
181154
181247
  set3.status = 500;
181155
181248
  }