@massa-ai/tools-api 1.45.0 → 1.47.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 +1428 -546
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -401,9 +401,16 @@ var init_xdg = () => {};
401
401
 
402
402
  // ../../packages/shared/dist/config/massa-ai-config.js
403
403
  import path2 from "path";
404
- var defaultMassaAiConfig;
404
+ var SCHEDULER_JOB_KINDS, defaultMassaAiConfig;
405
405
  var init_massa_ai_config = __esm(() => {
406
406
  init_xdg();
407
+ SCHEDULER_JOB_KINDS = [
408
+ "memory-consolidation",
409
+ "decay-sweep",
410
+ "auto-improve",
411
+ "observation-bridge",
412
+ "checkpoint-purge"
413
+ ];
407
414
  defaultMassaAiConfig = {
408
415
  database: {
409
416
  url: ""
@@ -759,9 +766,27 @@ function restartNeededSections(config) {
759
766
  return config.llm !== undefined;
760
767
  if (s === "security")
761
768
  return config.security !== undefined;
769
+ if (s === "scheduler")
770
+ return config.scheduler !== undefined;
762
771
  return false;
763
772
  });
764
773
  }
774
+ function deepEqual(a, b) {
775
+ if (a === b)
776
+ return true;
777
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
778
+ return false;
779
+ if (Array.isArray(a) !== Array.isArray(b))
780
+ return false;
781
+ const ka = Object.keys(a);
782
+ const kb = Object.keys(b);
783
+ if (ka.length !== kb.length)
784
+ return false;
785
+ return ka.every((k) => deepEqual(a[k], b[k]));
786
+ }
787
+ function changedRestartSections(before, after) {
788
+ return RESTART_SECTIONS.filter((s) => !deepEqual(before[s], after[s]));
789
+ }
765
790
  function applyMaskedSentinel(partial, current) {
766
791
  const result = JSON.parse(JSON.stringify(partial));
767
792
  if (result.security?.apiKey === MASK_SENTINEL) {
@@ -991,6 +1016,29 @@ function validatePartial(partial) {
991
1016
  details.push("security.allowedExtensions[] must be dot-prefixed extensions");
992
1017
  }
993
1018
  }
1019
+ if (partial.scheduler !== undefined) {
1020
+ const sch = partial.scheduler;
1021
+ if (sch.enabled !== undefined && !checkBoolean(sch.enabled))
1022
+ details.push("scheduler.enabled must be a boolean");
1023
+ if (sch.tickMs !== undefined && !checkNumber(sch.tickMs, 1000))
1024
+ details.push("scheduler.tickMs must be a number >= 1000");
1025
+ if (sch.maxConcurrent !== undefined && !checkNumber(sch.maxConcurrent, 1))
1026
+ details.push("scheduler.maxConcurrent must be a number >= 1");
1027
+ if (sch.jobs !== undefined) {
1028
+ for (const [kind, job] of Object.entries(sch.jobs)) {
1029
+ if (!SCHEDULER_JOB_KINDS.includes(kind)) {
1030
+ details.push(`scheduler.jobs.${kind} is not a registered job kind (expected one of: ${SCHEDULER_JOB_KINDS.join(", ")})`);
1031
+ continue;
1032
+ }
1033
+ if (job === undefined || job === null)
1034
+ continue;
1035
+ if (job.enabled !== undefined && !checkBoolean(job.enabled))
1036
+ details.push(`scheduler.jobs.${kind}.enabled must be a boolean`);
1037
+ if (job.intervalMs !== undefined && !checkNumber(job.intervalMs, 60000))
1038
+ details.push(`scheduler.jobs.${kind}.intervalMs must be a number >= 60000`);
1039
+ }
1040
+ }
1041
+ }
994
1042
  return details;
995
1043
  }
996
1044
  function repairAndPruneBackups(configPath) {
@@ -1044,13 +1092,15 @@ function savePartialConfig(partial) {
1044
1092
  return {
1045
1093
  success: true,
1046
1094
  config: merged,
1047
- restartNeededSections: restartNeededSections(merged)
1095
+ restartNeededSections: restartNeededSections(merged),
1096
+ changedRestartSections: changedRestartSections(current, merged)
1048
1097
  };
1049
1098
  }
1050
1099
  var MASK_SENTINEL = "***", RESTART_SECTIONS, VALID_EMBEDDING_PROVIDERS, VALID_LOG_LEVELS, BACKUP_RETENTION_LIMIT = 10;
1051
1100
  var init_config_writer = __esm(() => {
1052
1101
  init_config_loader();
1053
- RESTART_SECTIONS = ["database", "embedding", "llm", "security"];
1102
+ init_massa_ai_config();
1103
+ RESTART_SECTIONS = ["database", "embedding", "llm", "security", "scheduler"];
1054
1104
  VALID_EMBEDDING_PROVIDERS = ["ollama", "mistral", "openai", "google", "cohere"];
1055
1105
  VALID_LOG_LEVELS = ["debug", "info", "warn", "error"];
1056
1106
  });
@@ -1224,6 +1274,22 @@ function envList(key, fallback) {
1224
1274
  const parsed = s.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
1225
1275
  return parsed.length > 0 ? parsed : fallback;
1226
1276
  }
1277
+ function readSchedulerConfig(rawFileConfig) {
1278
+ try {
1279
+ const cfg = rawFileConfig;
1280
+ return cfg?.scheduler ?? {};
1281
+ } catch {
1282
+ return {};
1283
+ }
1284
+ }
1285
+ function resolveSchedulerJob(kind, fileJobs) {
1286
+ const meta = SCHEDULER_JOB_ENV[kind];
1287
+ const fileJob = fileJobs?.[kind];
1288
+ return {
1289
+ enabled: envBool(meta.enabledVar, fileJob?.enabled ?? false),
1290
+ intervalMs: envNum(meta.intervalVar, fileJob?.intervalMs ?? meta.defaultIntervalMs)
1291
+ };
1292
+ }
1227
1293
  function validateCapturePolicyConfig(raw2) {
1228
1294
  if (!raw2 || typeof raw2 !== "object")
1229
1295
  throw new TypeError("capturePolicy must be an object");
@@ -1351,6 +1417,11 @@ class Config {
1351
1417
  rateLimit: { ...defaults.rateLimit, ...overrides.rateLimit },
1352
1418
  security: { ...defaults.security, ...overrides.security },
1353
1419
  logging: { ...defaults.logging, ...overrides.logging },
1420
+ scheduler: {
1421
+ ...defaults.scheduler,
1422
+ ...overrides.scheduler,
1423
+ jobs: { ...defaults.scheduler.jobs, ...overrides.scheduler?.jobs }
1424
+ },
1354
1425
  synapse: {
1355
1426
  ...defaults.synapse,
1356
1427
  ...overrides.synapse,
@@ -1419,15 +1490,43 @@ class Config {
1419
1490
  this.config[key] = value;
1420
1491
  }
1421
1492
  }
1422
- var DEFAULT_LLM_MODEL = "qwen2.5:7b-instruct", DEFAULT_LLM_CODE_MODEL = "qwen2.5-coder:7b", MAX_IGNORE_PATTERNS = 1024, DEFAULT_ALLOWED_EXTENSIONS, fileConfig, fileCacheL1Bytes, fileCacheL2Bytes, defaultConfig, config;
1493
+ var DEFAULT_LLM_MODEL = "qwen2.5:7b-instruct", DEFAULT_LLM_CODE_MODEL = "qwen2.5-coder:7b", SCHEDULER_JOB_ENV, MAX_IGNORE_PATTERNS = 1024, DEFAULT_ALLOWED_EXTENSIONS, fileConfig, fileCacheL1Bytes, fileCacheL2Bytes, resolvedDataDir, defaultConfig, config;
1423
1494
  var init_config = __esm(() => {
1424
1495
  init_env();
1425
1496
  init_config_loader();
1426
1497
  init_massa_ai_config();
1498
+ init_massa_ai_config();
1427
1499
  init_config_loader();
1428
1500
  init_config_writer();
1429
1501
  init_xdg();
1430
1502
  init_api_key();
1503
+ SCHEDULER_JOB_ENV = {
1504
+ "memory-consolidation": {
1505
+ enabledVar: "MASSA_AI_SCHEDULER_CONSOLIDATION_ENABLED",
1506
+ intervalVar: "MASSA_AI_SCHEDULER_CONSOLIDATION_INTERVAL_MS",
1507
+ defaultIntervalMs: 30 * 60 * 1000
1508
+ },
1509
+ "decay-sweep": {
1510
+ enabledVar: "MASSA_AI_SCHEDULER_DECAY_ENABLED",
1511
+ intervalVar: "MASSA_AI_SCHEDULER_DECAY_INTERVAL_MS",
1512
+ defaultIntervalMs: 60 * 60 * 1000
1513
+ },
1514
+ "auto-improve": {
1515
+ enabledVar: "MASSA_AI_SCHEDULER_AUTO_IMPROVE_ENABLED",
1516
+ intervalVar: "MASSA_AI_SCHEDULER_AUTO_IMPROVE_INTERVAL_MS",
1517
+ defaultIntervalMs: 30 * 60 * 1000
1518
+ },
1519
+ "observation-bridge": {
1520
+ enabledVar: "MASSA_AI_SCHEDULER_OBSERVATION_BRIDGE_ENABLED",
1521
+ intervalVar: "MASSA_AI_SCHEDULER_OBSERVATION_BRIDGE_INTERVAL_MS",
1522
+ defaultIntervalMs: 30 * 60 * 1000
1523
+ },
1524
+ "checkpoint-purge": {
1525
+ enabledVar: "MASSA_AI_SCHEDULER_CHECKPOINT_PURGE_ENABLED",
1526
+ intervalVar: "MASSA_AI_SCHEDULER_CHECKPOINT_PURGE_INTERVAL_MS",
1527
+ defaultIntervalMs: 60 * 60 * 1000
1528
+ }
1529
+ };
1431
1530
  DEFAULT_ALLOWED_EXTENSIONS = [
1432
1531
  ".ts",
1433
1532
  ".js",
@@ -1466,10 +1565,11 @@ var init_config = __esm(() => {
1466
1565
  fileConfig = loadConfigSafe();
1467
1566
  fileCacheL1Bytes = fileConfig.cache?.l1MaxSizeMB ? fileConfig.cache.l1MaxSizeMB * 1024 * 1024 : undefined;
1468
1567
  fileCacheL2Bytes = fileConfig.cache?.l2MaxSizeMB ? fileConfig.cache.l2MaxSizeMB * 1024 * 1024 : undefined;
1568
+ resolvedDataDir = getGlobalDataDir();
1469
1569
  defaultConfig = {
1470
1570
  name: "massa-ai-server",
1471
1571
  version: "1.0.0",
1472
- dataDir: getGlobalDataDir(),
1572
+ dataDir: resolvedDataDir,
1473
1573
  cache: {
1474
1574
  l1: {
1475
1575
  maxSize: envNum("L1_CACHE_MAX_SIZE", fileCacheL1Bytes ?? 100 * 1024 * 1024),
@@ -1593,8 +1693,24 @@ var init_config = __esm(() => {
1593
1693
  logging: {
1594
1694
  level: process.env.LOG_LEVEL || fileConfig.logging?.level || "info",
1595
1695
  enableMetrics: process.env.ENABLE_METRICS === "true" || process.env.ENABLE_METRICS === undefined && !!fileConfig.logging?.enableMetrics,
1596
- file: process.env.MASSA_AI_LOG_FILE || fileConfig.logging?.file || undefined
1597
- },
1696
+ file: process.env.MASSA_AI_LOG_FILE || fileConfig.logging?.file || path6.join(resolvedDataDir, "logs", "massa-ai.log"),
1697
+ enableFileSink: envBool("MASSA_AI_LOG_ENABLE_FILE_SINK", fileConfig.logging?.enableFileSink ?? true),
1698
+ bufferSize: envNum("MASSA_AI_LOG_BUFFER_SIZE", fileConfig.logging?.bufferSize ?? 2000),
1699
+ maxFileSizeMb: envNum("MASSA_AI_LOG_MAX_FILE_SIZE_MB", fileConfig.logging?.maxFileSizeMb ?? 32),
1700
+ maxFiles: envNum("MASSA_AI_LOG_MAX_FILES", fileConfig.logging?.maxFiles ?? 5)
1701
+ },
1702
+ scheduler: (() => {
1703
+ const fileScheduler = readSchedulerConfig(fileConfig);
1704
+ return {
1705
+ enabled: envBool("MASSA_AI_SCHEDULER_ENABLED", fileScheduler.enabled ?? false),
1706
+ tickMs: envNum("MASSA_AI_SCHEDULER_TICK_MS", fileScheduler.tickMs ?? 60000),
1707
+ maxConcurrent: envNum("MASSA_AI_SCHEDULER_MAX_CONCURRENT", fileScheduler.maxConcurrent ?? 2),
1708
+ jobs: Object.fromEntries(SCHEDULER_JOB_KINDS.map((kind) => [
1709
+ kind,
1710
+ resolveSchedulerJob(kind, fileScheduler.jobs)
1711
+ ]))
1712
+ };
1713
+ })(),
1598
1714
  synapse: {
1599
1715
  enabled: process.env.SYNAPSE_ENABLED !== "false",
1600
1716
  inhibition: {
@@ -6931,13 +7047,190 @@ var init_types = __esm(() => {
6931
7047
  // ../../packages/shared/dist/types/interfaces.js
6932
7048
  var init_interfaces = () => {};
6933
7049
 
6934
- // ../../packages/shared/dist/utils/logger.js
7050
+ // ../../packages/shared/dist/utils/log-sink.js
6935
7051
  import fs4 from "fs";
7052
+ import path7 from "path";
7053
+ function getState(filePath) {
7054
+ let state = pathState.get(filePath);
7055
+ if (!state) {
7056
+ state = { trackedSize: 0, deltaSinceStat: 0, primed: false };
7057
+ pathState.set(filePath, state);
7058
+ }
7059
+ return state;
7060
+ }
7061
+ function ensureDir(filePath) {
7062
+ const dir = path7.dirname(filePath);
7063
+ if (ensuredDirs.has(dir))
7064
+ return;
7065
+ fs4.mkdirSync(dir, { recursive: true });
7066
+ ensuredDirs.add(dir);
7067
+ }
7068
+ function restat(filePath, state) {
7069
+ try {
7070
+ state.trackedSize = fs4.statSync(filePath).size;
7071
+ } catch {
7072
+ state.trackedSize = 0;
7073
+ }
7074
+ state.deltaSinceStat = 0;
7075
+ state.primed = true;
7076
+ }
7077
+ function rotate(filePath, maxFiles) {
7078
+ if (maxFiles <= 0) {
7079
+ if (fs4.existsSync(filePath))
7080
+ fs4.unlinkSync(filePath);
7081
+ return;
7082
+ }
7083
+ const oldest = `${filePath}.${maxFiles}`;
7084
+ if (fs4.existsSync(oldest))
7085
+ fs4.unlinkSync(oldest);
7086
+ for (let n2 = maxFiles - 1;n2 >= 1; n2--) {
7087
+ const src = `${filePath}.${n2}`;
7088
+ const dest = `${filePath}.${n2 + 1}`;
7089
+ if (fs4.existsSync(src))
7090
+ fs4.renameSync(src, dest);
7091
+ }
7092
+ if (fs4.existsSync(filePath))
7093
+ fs4.renameSync(filePath, `${filePath}.1`);
7094
+ }
7095
+ function appendLine(opts, line) {
7096
+ const { filePath, maxFileSizeBytes, maxFiles } = opts;
7097
+ try {
7098
+ ensureDir(filePath);
7099
+ const state = getState(filePath);
7100
+ const lineBytes = Buffer.byteLength(line + `
7101
+ `, "utf8");
7102
+ if (!state.primed || state.deltaSinceStat >= STAT_DELTA_THRESHOLD_BYTES || state.trackedSize + state.deltaSinceStat >= maxFileSizeBytes) {
7103
+ restat(filePath, state);
7104
+ }
7105
+ if (maxFileSizeBytes > 0 && state.trackedSize >= maxFileSizeBytes) {
7106
+ rotate(filePath, maxFiles);
7107
+ state.trackedSize = 0;
7108
+ state.deltaSinceStat = 0;
7109
+ state.primed = true;
7110
+ }
7111
+ fs4.appendFileSync(filePath, line + `
7112
+ `);
7113
+ state.trackedSize += lineBytes;
7114
+ state.deltaSinceStat += lineBytes;
7115
+ } catch (err) {
7116
+ lastError = err;
7117
+ }
7118
+ }
7119
+ function sinkFiles(filePath, maxFiles) {
7120
+ const files = [];
7121
+ try {
7122
+ if (fs4.existsSync(filePath))
7123
+ files.push(filePath);
7124
+ for (let n2 = 1;n2 <= maxFiles; n2++) {
7125
+ const rotated = `${filePath}.${n2}`;
7126
+ if (fs4.existsSync(rotated))
7127
+ files.push(rotated);
7128
+ }
7129
+ } catch (err) {
7130
+ lastError = err;
7131
+ }
7132
+ return files;
7133
+ }
7134
+ var STAT_DELTA_THRESHOLD_BYTES, ensuredDirs, pathState, lastError;
7135
+ var init_log_sink = __esm(() => {
7136
+ STAT_DELTA_THRESHOLD_BYTES = 1024 * 1024;
7137
+ ensuredDirs = new Set;
7138
+ pathState = new Map;
7139
+ });
7140
+
7141
+ // ../../packages/shared/dist/utils/log-buffer.js
7142
+ class LogBufferImpl {
7143
+ capacity = DEFAULT_CAPACITY;
7144
+ entries = [];
7145
+ subscribers = new Set;
7146
+ nextSeq = 0;
7147
+ dispatching = false;
7148
+ pending = [];
7149
+ push(entry) {
7150
+ if (this.dispatching) {
7151
+ this.pending.push(entry);
7152
+ return;
7153
+ }
7154
+ this.dispatching = true;
7155
+ try {
7156
+ this.pushOne(entry);
7157
+ while (this.pending.length > 0) {
7158
+ const next = this.pending.shift();
7159
+ this.pushOne(next);
7160
+ }
7161
+ } finally {
7162
+ this.dispatching = false;
7163
+ }
7164
+ }
7165
+ pushOne(entry) {
7166
+ const full = { ...entry, seq: this.nextSeq++ };
7167
+ this.entries.push(full);
7168
+ while (this.entries.length > this.capacity) {
7169
+ this.entries.shift();
7170
+ }
7171
+ for (const fn of this.subscribers) {
7172
+ try {
7173
+ fn(full);
7174
+ } catch {}
7175
+ }
7176
+ }
7177
+ snapshot(opts) {
7178
+ const from = opts?.from;
7179
+ const to = opts?.to;
7180
+ const level = opts?.level;
7181
+ const q = opts?.q?.toLowerCase();
7182
+ const result = [];
7183
+ for (let i = this.entries.length - 1;i >= 0; i--) {
7184
+ const e = this.entries[i];
7185
+ if (from !== undefined && e.seq < from)
7186
+ continue;
7187
+ if (to !== undefined && e.seq > to)
7188
+ continue;
7189
+ if (level !== undefined && e.level !== level)
7190
+ continue;
7191
+ if (q !== undefined && !e.message.toLowerCase().includes(q))
7192
+ continue;
7193
+ result.push(e);
7194
+ }
7195
+ return result;
7196
+ }
7197
+ subscribe(fn) {
7198
+ this.subscribers.add(fn);
7199
+ return () => {
7200
+ this.subscribers.delete(fn);
7201
+ };
7202
+ }
7203
+ setCapacity(n2) {
7204
+ this.capacity = n2 > 0 ? n2 : 0;
7205
+ while (this.entries.length > this.capacity) {
7206
+ this.entries.shift();
7207
+ }
7208
+ }
7209
+ size() {
7210
+ return this.entries.length;
7211
+ }
7212
+ _resetForTesting() {
7213
+ this.entries = [];
7214
+ this.subscribers.clear();
7215
+ this.nextSeq = 0;
7216
+ this.dispatching = false;
7217
+ this.pending = [];
7218
+ this.capacity = DEFAULT_CAPACITY;
7219
+ }
7220
+ }
7221
+ var DEFAULT_CAPACITY = 2000, logBuffer;
7222
+ var init_log_buffer = __esm(() => {
7223
+ logBuffer = new LogBufferImpl;
7224
+ });
6936
7225
 
7226
+ // ../../packages/shared/dist/utils/logger.js
6937
7227
  class Logger {
6938
7228
  _level;
6939
7229
  _enableMetrics;
6940
7230
  _logFilePath;
7231
+ _enableFileSink;
7232
+ _maxFileSizeBytes;
7233
+ _maxFiles;
6941
7234
  _initialized = false;
6942
7235
  constructor() {}
6943
7236
  ensureInitialized() {
@@ -6947,10 +7240,18 @@ class Logger {
6947
7240
  this._level = this.parseLogLevel(loggingConfig.level);
6948
7241
  this._enableMetrics = loggingConfig.enableMetrics;
6949
7242
  this._logFilePath = loggingConfig.file;
7243
+ this._enableFileSink = loggingConfig.enableFileSink;
7244
+ this._maxFileSizeBytes = loggingConfig.maxFileSizeMb * 1024 * 1024;
7245
+ this._maxFiles = loggingConfig.maxFiles;
7246
+ logBuffer.setCapacity(loggingConfig.bufferSize);
6950
7247
  } catch {
6951
7248
  this._level = LogLevel.INFO;
6952
7249
  this._enableMetrics = false;
6953
7250
  this._logFilePath = undefined;
7251
+ this._enableFileSink = false;
7252
+ this._maxFileSizeBytes = 32 * 1024 * 1024;
7253
+ this._maxFiles = 5;
7254
+ logBuffer.setCapacity(2000);
6954
7255
  }
6955
7256
  this._initialized = true;
6956
7257
  }
@@ -6967,6 +7268,18 @@ class Logger {
6967
7268
  this.ensureInitialized();
6968
7269
  return this._logFilePath;
6969
7270
  }
7271
+ get enableFileSink() {
7272
+ this.ensureInitialized();
7273
+ return this._enableFileSink;
7274
+ }
7275
+ get maxFileSizeBytes() {
7276
+ this.ensureInitialized();
7277
+ return this._maxFileSizeBytes;
7278
+ }
7279
+ get maxFiles() {
7280
+ this.ensureInitialized();
7281
+ return this._maxFiles;
7282
+ }
6970
7283
  parseLogLevel(level) {
6971
7284
  const levels = {
6972
7285
  debug: LogLevel.DEBUG,
@@ -6979,34 +7292,40 @@ class Logger {
6979
7292
  shouldLog(level) {
6980
7293
  return level >= this.level;
6981
7294
  }
6982
- formatMessage(level, message, meta) {
6983
- const timestamp = new Date().toISOString();
7295
+ formatMessage(level, message, meta, timestamp = new Date().toISOString()) {
6984
7296
  const metaStr = meta ? ` ${JSON.stringify(meta)}` : "";
6985
7297
  return `[${timestamp}] [${level}] ${message}${metaStr}`;
6986
7298
  }
6987
- write(message, _level) {
6988
- console.error(message);
6989
- const filePath = this.logFilePath;
6990
- if (filePath) {
6991
- try {
6992
- fs4.appendFileSync(filePath, message + `
6993
- `);
6994
- } catch {}
7299
+ emit(level, message, meta) {
7300
+ const ts = new Date().toISOString();
7301
+ const line = this.formatMessage(LOG_LEVEL_LABELS[level], message, meta, ts);
7302
+ console.error(line);
7303
+ if (this.enableFileSink) {
7304
+ const filePath = this.logFilePath;
7305
+ if (filePath) {
7306
+ appendLine({ filePath, maxFileSizeBytes: this.maxFileSizeBytes, maxFiles: this.maxFiles }, line);
7307
+ }
6995
7308
  }
7309
+ logBuffer.push({
7310
+ ts,
7311
+ level: LOG_LEVEL_BUFFER_TAGS[level],
7312
+ message,
7313
+ ...meta ? { meta } : {}
7314
+ });
6996
7315
  }
6997
7316
  debug(message, meta) {
6998
7317
  if (this.shouldLog(LogLevel.DEBUG)) {
6999
- this.write(this.formatMessage("DEBUG", message, meta), LogLevel.DEBUG);
7318
+ this.emit(LogLevel.DEBUG, message, meta);
7000
7319
  }
7001
7320
  }
7002
7321
  info(message, meta) {
7003
7322
  if (this.shouldLog(LogLevel.INFO)) {
7004
- this.write(this.formatMessage("INFO", message, meta), LogLevel.INFO);
7323
+ this.emit(LogLevel.INFO, message, meta);
7005
7324
  }
7006
7325
  }
7007
7326
  warn(message, meta) {
7008
7327
  if (this.shouldLog(LogLevel.WARN)) {
7009
- this.write(this.formatMessage("WARN", message, meta), LogLevel.WARN);
7328
+ this.emit(LogLevel.WARN, message, meta);
7010
7329
  }
7011
7330
  }
7012
7331
  error(message, error, meta) {
@@ -7019,7 +7338,7 @@ class Logger {
7019
7338
  stack: error.stack
7020
7339
  }
7021
7340
  } : meta;
7022
- this.write(this.formatMessage("ERROR", message, errorMeta), LogLevel.ERROR);
7341
+ this.emit(LogLevel.ERROR, message, errorMeta);
7023
7342
  }
7024
7343
  }
7025
7344
  metric(name, value, unit) {
@@ -7048,15 +7367,29 @@ class Logger {
7048
7367
  return childLogger;
7049
7368
  }
7050
7369
  }
7051
- var LogLevel, logger;
7370
+ var LogLevel, LOG_LEVEL_LABELS, LOG_LEVEL_BUFFER_TAGS, logger;
7052
7371
  var init_logger = __esm(() => {
7053
7372
  init_config();
7373
+ init_log_sink();
7374
+ init_log_buffer();
7054
7375
  (function(LogLevel2) {
7055
7376
  LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
7056
7377
  LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
7057
7378
  LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
7058
7379
  LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
7059
7380
  })(LogLevel || (LogLevel = {}));
7381
+ LOG_LEVEL_LABELS = {
7382
+ [LogLevel.DEBUG]: "DEBUG",
7383
+ [LogLevel.INFO]: "INFO",
7384
+ [LogLevel.WARN]: "WARN",
7385
+ [LogLevel.ERROR]: "ERROR"
7386
+ };
7387
+ LOG_LEVEL_BUFFER_TAGS = {
7388
+ [LogLevel.DEBUG]: "debug",
7389
+ [LogLevel.INFO]: "info",
7390
+ [LogLevel.WARN]: "warn",
7391
+ [LogLevel.ERROR]: "error"
7392
+ };
7060
7393
  logger = new Logger;
7061
7394
  });
7062
7395
 
@@ -7339,6 +7672,8 @@ var init_rate_limiter = __esm(() => {
7339
7672
  // ../../packages/shared/dist/utils/index.js
7340
7673
  var init_utils = __esm(() => {
7341
7674
  init_logger();
7675
+ init_log_buffer();
7676
+ init_log_sink();
7342
7677
  init_sanitizer();
7343
7678
  init_metrics();
7344
7679
  init_rate_limiter();
@@ -7346,7 +7681,7 @@ var init_utils = __esm(() => {
7346
7681
 
7347
7682
  // ../../packages/shared/dist/profile-switch/hosts.js
7348
7683
  import os3 from "os";
7349
- import path7 from "path";
7684
+ import path8 from "path";
7350
7685
  function isHost(v) {
7351
7686
  return typeof v === "string" && HOSTS.includes(v);
7352
7687
  }
@@ -7357,7 +7692,7 @@ function fileLayout(host, activeDir, activeGlob, variantsRoot) {
7357
7692
  activeDir,
7358
7693
  activeGlob,
7359
7694
  variantsRoot,
7360
- variantDir: (profile) => path7.join(variantsRoot, profile)
7695
+ variantDir: (profile) => path8.join(variantsRoot, profile)
7361
7696
  };
7362
7697
  }
7363
7698
  function resolveHostLayout(host, opts = {}) {
@@ -7367,25 +7702,37 @@ function resolveHostLayout(host, opts = {}) {
7367
7702
  case "cursor":
7368
7703
  return { host, route: "skip", reason: CURSOR_SKIP_REASON };
7369
7704
  case "claude": {
7370
- const root = override ?? path7.join(targetHome, ".claude");
7371
- return fileLayout(host, path7.join(root, "agents"), "massa-ai-*.md", path7.join(root, "massa-ai", "agent-profiles"));
7705
+ const marketplaceRoot = opts.marketplaceRoot?.claude;
7706
+ if (override === undefined && marketplaceRoot !== undefined) {
7707
+ return fileLayout(host, path8.join(marketplaceRoot, "agents"), "massa-ai-*.md", path8.join(marketplaceRoot, "agent-profiles"));
7708
+ }
7709
+ const root = override ?? path8.join(targetHome, ".claude");
7710
+ return fileLayout(host, path8.join(root, "agents"), "massa-ai-*.md", path8.join(root, "massa-ai", "agent-profiles"));
7372
7711
  }
7373
7712
  case "codex": {
7374
- const root = override ?? path7.join(targetHome, ".codex");
7375
- return fileLayout(host, path7.join(root, "agents"), "massa-ai-*.toml", path7.join(root, "massa-ai", "agent-profiles"));
7713
+ const root = override ?? path8.join(targetHome, ".codex");
7714
+ return fileLayout(host, path8.join(root, "agents"), "massa-ai-*.toml", path8.join(root, "massa-ai", "agent-profiles"));
7376
7715
  }
7377
7716
  case "opencode": {
7378
- const root = override ?? path7.join(targetHome, ".config", "opencode");
7379
- const pluginsDir = path7.join(root, "plugins", "massa-ai");
7380
- return fileLayout(host, path7.join(root, "agents"), "massa-ai-*.md", path7.join(pluginsDir, "agent-profiles"));
7717
+ const root = override ?? path8.join(targetHome, ".config", "opencode");
7718
+ const pluginsDir = path8.join(root, "plugins", "massa-ai");
7719
+ return fileLayout(host, path8.join(root, "agents"), "massa-ai-*.md", path8.join(pluginsDir, "agent-profiles"));
7381
7720
  }
7382
7721
  }
7383
7722
  }
7384
- function detectRoute(platform) {
7723
+ function detectRoute(platform, host) {
7385
7724
  const route = platform?.installRoute;
7386
7725
  if (route === "file")
7387
7726
  return { kind: "proceed" };
7388
7727
  if (route === "marketplace") {
7728
+ if (host === "claude")
7729
+ return { kind: "proceed" };
7730
+ if (host === "codex") {
7731
+ return {
7732
+ kind: "refuse",
7733
+ reason: "codex marketplace-route installs are refused (in-place bundle rewrite would dirty a checkout " + "and break the drift gate) \u2014 use the dev path: MASSA_AI_MODEL_PROFILE + regenerate."
7734
+ };
7735
+ }
7389
7736
  return {
7390
7737
  kind: "refuse",
7391
7738
  reason: "claude/codex marketplace-route installs are refused (in-place bundle rewrite would dirty a checkout " + "and break the drift gate) \u2014 use the dev path: MASSA_AI_MODEL_PROFILE + regenerate."
@@ -7403,7 +7750,7 @@ var init_hosts = __esm(() => {
7403
7750
 
7404
7751
  // ../../packages/shared/dist/profile-switch/state.js
7405
7752
  import fs5 from "fs";
7406
- import path8 from "path";
7753
+ import path9 from "path";
7407
7754
  function namedError(name, message) {
7408
7755
  const err = new InstallStateError(message);
7409
7756
  err.name = name;
@@ -7449,7 +7796,7 @@ function writeInstallState(filePath, state) {
7449
7796
  const text = `${JSON.stringify(validated, null, 2)}
7450
7797
  `;
7451
7798
  try {
7452
- fs5.mkdirSync(path8.dirname(filePath), { recursive: true });
7799
+ fs5.mkdirSync(path9.dirname(filePath), { recursive: true });
7453
7800
  fs5.writeFileSync(filePath, text);
7454
7801
  } catch (err) {
7455
7802
  throw UnwritableInstallStateError(filePath, err.message);
@@ -7478,7 +7825,7 @@ var init_state = __esm(() => {
7478
7825
 
7479
7826
  // ../../packages/shared/dist/profile-switch/lock.js
7480
7827
  import fs6 from "fs";
7481
- import path9 from "path";
7828
+ import path10 from "path";
7482
7829
  import os4 from "os";
7483
7830
  import crypto4 from "crypto";
7484
7831
  import { execFileSync } from "child_process";
@@ -7510,7 +7857,7 @@ function releaseIfOwned(lockDir, ownerPath, token) {
7510
7857
  }
7511
7858
  function acquireLock(stateFilePath, options = {}) {
7512
7859
  const lockDir = `${stateFilePath}.switch.lock`;
7513
- const ownerPath = path9.join(lockDir, "owner.json");
7860
+ const ownerPath = path10.join(lockDir, "owner.json");
7514
7861
  const clock = options.clock ?? DEFAULT_CLOCK;
7515
7862
  const identity = options.identity ?? DEFAULT_IDENTITY;
7516
7863
  const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
@@ -7530,7 +7877,7 @@ function acquireLock(stateFilePath, options = {}) {
7530
7877
  token,
7531
7878
  timestamp: clock.now()
7532
7879
  };
7533
- fs6.mkdirSync(path9.dirname(ownerPath), { recursive: true });
7880
+ fs6.mkdirSync(path10.dirname(ownerPath), { recursive: true });
7534
7881
  fs6.writeFileSync(ownerPath, JSON.stringify(record));
7535
7882
  return { lockDir, release: () => releaseIfOwned(lockDir, ownerPath, token) };
7536
7883
  };
@@ -7583,10 +7930,59 @@ var init_lock = __esm(() => {
7583
7930
  };
7584
7931
  });
7585
7932
 
7586
- // ../../packages/shared/dist/profile-switch/engine.js
7933
+ // ../../packages/shared/dist/profile-switch/claude-marketplace.js
7587
7934
  import fs7 from "fs";
7588
- import path10 from "path";
7589
7935
  import os5 from "os";
7936
+ import path11 from "path";
7937
+ function selectRecord(records) {
7938
+ if (records.length === 0)
7939
+ return;
7940
+ const userScoped = records.filter((r2) => r2.scope === "user");
7941
+ const pool = userScoped.length > 0 ? userScoped : records;
7942
+ let best;
7943
+ let bestTime = -Infinity;
7944
+ for (const record of pool) {
7945
+ const parsed = record.lastUpdated ? Date.parse(record.lastUpdated) : NaN;
7946
+ if (Number.isFinite(parsed) && parsed >= bestTime) {
7947
+ best = record;
7948
+ bestTime = parsed;
7949
+ }
7950
+ }
7951
+ return best ?? pool[pool.length - 1];
7952
+ }
7953
+ function resolveClaudeMarketplaceRoot(opts = {}) {
7954
+ const targetHome = opts.targetHome ?? os5.homedir();
7955
+ const pluginKey = opts.pluginKey ?? DEFAULT_PLUGIN_KEY;
7956
+ const registryPath = path11.join(targetHome, ".claude", "plugins", "installed_plugins.json");
7957
+ let records;
7958
+ try {
7959
+ const raw2 = fs7.readFileSync(registryPath, "utf8");
7960
+ const parsed = JSON.parse(raw2);
7961
+ records = parsed?.plugins?.[pluginKey];
7962
+ } catch {
7963
+ return null;
7964
+ }
7965
+ if (!Array.isArray(records) || records.length === 0)
7966
+ return null;
7967
+ const selected = selectRecord(records);
7968
+ const installPath = selected?.installPath;
7969
+ if (!installPath)
7970
+ return null;
7971
+ try {
7972
+ if (!fs7.existsSync(installPath))
7973
+ return null;
7974
+ } catch {
7975
+ return null;
7976
+ }
7977
+ return installPath;
7978
+ }
7979
+ var DEFAULT_PLUGIN_KEY = "massa-ai@massa-ai";
7980
+ var init_claude_marketplace = () => {};
7981
+
7982
+ // ../../packages/shared/dist/profile-switch/engine.js
7983
+ import fs8 from "fs";
7984
+ import path12 from "path";
7985
+ import os6 from "os";
7590
7986
  import crypto5 from "crypto";
7591
7987
  function namedError3(name, message) {
7592
7988
  const err = new SwitchEngineError(message);
@@ -7594,19 +7990,39 @@ function namedError3(name, message) {
7594
7990
  return err;
7595
7991
  }
7596
7992
  function defaultStatePath(targetHome) {
7597
- return path10.join(targetHome, ".config", "massa-ai", "install-state.json");
7993
+ return path12.join(targetHome, ".config", "massa-ai", "install-state.json");
7598
7994
  }
7599
7995
  function resolveCommon(opts) {
7600
- const targetHome = opts.targetHome ?? os5.homedir();
7996
+ const targetHome = opts.targetHome ?? os6.homedir();
7601
7997
  const stateFilePath = opts.stateFilePath ?? defaultStatePath(targetHome);
7602
7998
  return { targetHome, stateFilePath };
7603
7999
  }
8000
+ function marketplaceRoots(targetHome, state) {
8001
+ return state.platforms.claude?.installRoute === "marketplace" ? { claude: resolveClaudeMarketplaceRoot({ targetHome }) ?? undefined } : {};
8002
+ }
8003
+ function claudeMarketplaceUnresolvedReason(targetHome) {
8004
+ const registryPath = path12.join(targetHome, ".claude", "plugins", "installed_plugins.json");
8005
+ return `claude installRoute is "marketplace" but no install root could be resolved from ${registryPath} ` + "\u2014 re-run the Claude plugin installer, or verify the plugin registry file";
8006
+ }
7604
8007
  function listProfiles(opts = {}) {
7605
8008
  const { targetHome, stateFilePath } = resolveCommon(opts);
7606
8009
  const state = readInstallState(stateFilePath);
8010
+ const roots = marketplaceRoots(targetHome, state);
7607
8011
  const universe = opts.hosts ?? HOSTS;
7608
8012
  const hosts = universe.map((host) => {
7609
- const layout = resolveHostLayout(host, { targetHome, projectRoot: opts.projectRoot });
8013
+ if (host === "claude" && state.platforms.claude?.installRoute === "marketplace" && roots.claude === undefined) {
8014
+ const platform2 = state.platforms.claude;
8015
+ return {
8016
+ host,
8017
+ installed: false,
8018
+ skipped: false,
8019
+ skipReason: null,
8020
+ activeProfile: platform2.modelProfile?.profile ?? opts.hostDefaults?.[host] ?? "balanced",
8021
+ bundleVersion: platform2.plugin?.version ?? null,
8022
+ availableProfiles: []
8023
+ };
8024
+ }
8025
+ const layout = resolveHostLayout(host, { targetHome, projectRoot: opts.projectRoot, marketplaceRoot: roots });
7610
8026
  if (layout.route === "skip") {
7611
8027
  return {
7612
8028
  host,
@@ -7618,7 +8034,7 @@ function listProfiles(opts = {}) {
7618
8034
  availableProfiles: []
7619
8035
  };
7620
8036
  }
7621
- const installed = fs7.existsSync(layout.activeDir);
8037
+ const installed = fs8.existsSync(layout.activeDir);
7622
8038
  const availableProfiles = listVariantProfiles(layout);
7623
8039
  const platform = state.platforms[host];
7624
8040
  return {
@@ -7634,9 +8050,9 @@ function listProfiles(opts = {}) {
7634
8050
  return { hosts };
7635
8051
  }
7636
8052
  function listVariantProfiles(layout) {
7637
- if (!fs7.existsSync(layout.variantsRoot))
8053
+ if (!fs8.existsSync(layout.variantsRoot))
7638
8054
  return [];
7639
- return fs7.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
8055
+ return fs8.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
7640
8056
  }
7641
8057
  function matchesGlob(filename, glob) {
7642
8058
  const starIdx = glob.indexOf("*");
@@ -7647,50 +8063,50 @@ function matchesGlob(filename, glob) {
7647
8063
  return filename.length >= prefix.length + suffix.length && filename.startsWith(prefix) && filename.endsWith(suffix);
7648
8064
  }
7649
8065
  function assertStateWritable(stateFilePath) {
7650
- const dir = path10.dirname(stateFilePath);
8066
+ const dir = path12.dirname(stateFilePath);
7651
8067
  try {
7652
- fs7.mkdirSync(dir, { recursive: true });
8068
+ fs8.mkdirSync(dir, { recursive: true });
7653
8069
  } catch (err) {
7654
8070
  throw UnwritableInstallStateError(stateFilePath, err.message);
7655
8071
  }
7656
- const checkPath = fs7.existsSync(stateFilePath) ? stateFilePath : dir;
8072
+ const checkPath = fs8.existsSync(stateFilePath) ? stateFilePath : dir;
7657
8073
  try {
7658
- fs7.accessSync(checkPath, fs7.constants.W_OK);
8074
+ fs8.accessSync(checkPath, fs8.constants.W_OK);
7659
8075
  } catch (err) {
7660
8076
  throw UnwritableInstallStateError(stateFilePath, err.message);
7661
8077
  }
7662
8078
  }
7663
8079
  function copyFileRouteVariant(layout, variantDir) {
7664
- fs7.mkdirSync(layout.activeDir, { recursive: true });
8080
+ fs8.mkdirSync(layout.activeDir, { recursive: true });
7665
8081
  let changed = 0;
7666
- for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
8082
+ for (const entry of fs8.readdirSync(variantDir, { withFileTypes: true })) {
7667
8083
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
7668
8084
  continue;
7669
- fs7.copyFileSync(path10.join(variantDir, entry.name), path10.join(layout.activeDir, entry.name));
8085
+ fs8.copyFileSync(path12.join(variantDir, entry.name), path12.join(layout.activeDir, entry.name));
7670
8086
  changed++;
7671
8087
  }
7672
8088
  return changed;
7673
8089
  }
7674
8090
  function repointOpencodeVariant(layout, variantDir) {
7675
- fs7.mkdirSync(layout.activeDir, { recursive: true });
8091
+ fs8.mkdirSync(layout.activeDir, { recursive: true });
7676
8092
  let changed = 0;
7677
- for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
8093
+ for (const entry of fs8.readdirSync(variantDir, { withFileTypes: true })) {
7678
8094
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
7679
8095
  continue;
7680
- const dest = path10.join(layout.activeDir, entry.name);
7681
- const target = path10.resolve(path10.join(variantDir, entry.name));
8096
+ const dest = path12.join(layout.activeDir, entry.name);
8097
+ const target = path12.resolve(path12.join(variantDir, entry.name));
7682
8098
  let destExists = true;
7683
8099
  let destIsSymlink = false;
7684
8100
  try {
7685
- destIsSymlink = fs7.lstatSync(dest).isSymbolicLink();
8101
+ destIsSymlink = fs8.lstatSync(dest).isSymbolicLink();
7686
8102
  } catch {
7687
8103
  destExists = false;
7688
8104
  }
7689
8105
  if (destExists && !destIsSymlink)
7690
8106
  continue;
7691
8107
  const tmp = `${dest}.massa-ai-switch.${crypto5.randomUUID()}`;
7692
- fs7.symlinkSync(target, tmp);
7693
- fs7.renameSync(tmp, dest);
8108
+ fs8.symlinkSync(target, tmp);
8109
+ fs8.renameSync(tmp, dest);
7694
8110
  changed++;
7695
8111
  }
7696
8112
  return changed;
@@ -7706,19 +8122,37 @@ function switchProfile(opts) {
7706
8122
  const state = readInstallState(stateFilePath);
7707
8123
  if (!dryRun)
7708
8124
  assertStateWritable(stateFilePath);
7709
- const layouts = universe.map((host) => ({ host, layout: resolveHostLayout(host, { targetHome, projectRoot: opts.projectRoot }) }));
7710
- const skipRows = layouts.filter((l2) => l2.layout.route === "skip").map((l2) => ({ host: l2.host, status: "skipped", reason: l2.layout.reason }));
8125
+ const roots = marketplaceRoots(targetHome, state);
8126
+ const unresolvedRows = [];
8127
+ const resolvableUniverse = universe.filter((host) => {
8128
+ if (host !== "claude")
8129
+ return true;
8130
+ if (state.platforms.claude?.installRoute !== "marketplace")
8131
+ return true;
8132
+ if (roots.claude !== undefined)
8133
+ return true;
8134
+ unresolvedRows.push({ host, status: "failed", reason: claudeMarketplaceUnresolvedReason(targetHome) });
8135
+ return false;
8136
+ });
8137
+ const layouts = resolvableUniverse.map((host) => ({
8138
+ host,
8139
+ layout: resolveHostLayout(host, { targetHome, projectRoot: opts.projectRoot, marketplaceRoot: roots })
8140
+ }));
8141
+ const skipRows = [
8142
+ ...unresolvedRows,
8143
+ ...layouts.filter((l2) => l2.layout.route === "skip").map((l2) => ({ host: l2.host, status: "skipped", reason: l2.layout.reason }))
8144
+ ];
7711
8145
  const fileHosts = layouts.filter((l2) => l2.layout.route === "files");
7712
8146
  if (fileHosts.length === 0) {
7713
8147
  return { profile: opts.profile, dryRun, hosts: orderRows(universe, skipRows), restartRequired: false };
7714
8148
  }
7715
- const installedFileHosts = fileHosts.filter((h) => fs7.existsSync(h.layout.activeDir));
8149
+ const installedFileHosts = fileHosts.filter((h) => fs8.existsSync(h.layout.activeDir));
7716
8150
  if (installedFileHosts.length === 0)
7717
8151
  throw NoHostsDetectedError();
7718
8152
  const withAvailability = fileHosts.map((h) => {
7719
- const variantsRootExists = fs7.existsSync(h.layout.variantsRoot);
8153
+ const variantsRootExists = fs8.existsSync(h.layout.variantsRoot);
7720
8154
  const variantDir = h.layout.variantDir(opts.profile);
7721
- const available = variantsRootExists && fs7.existsSync(variantDir) && fs7.statSync(variantDir).isDirectory();
8155
+ const available = variantsRootExists && fs8.existsSync(variantDir) && fs8.statSync(variantDir).isDirectory();
7722
8156
  return { ...h, variantsRootExists, variantDir, available };
7723
8157
  });
7724
8158
  if (!withAvailability.some((h) => h.available)) {
@@ -7748,7 +8182,7 @@ function switchProfile(opts) {
7748
8182
  });
7749
8183
  continue;
7750
8184
  }
7751
- const route = detectRoute(state.platforms[h.host]);
8185
+ const route = detectRoute(state.platforms[h.host], h.host);
7752
8186
  if (route.kind === "refuse") {
7753
8187
  rows.push({ host: h.host, status: "failed", reason: route.reason });
7754
8188
  continue;
@@ -7783,6 +8217,7 @@ var init_engine = __esm(() => {
7783
8217
  init_hosts();
7784
8218
  init_state();
7785
8219
  init_lock();
8220
+ init_claude_marketplace();
7786
8221
  SwitchEngineError = class SwitchEngineError extends Error {
7787
8222
  constructor(message) {
7788
8223
  super(message);
@@ -7797,18 +8232,25 @@ function reportSucceeded(report) {
7797
8232
  }
7798
8233
 
7799
8234
  // ../../packages/shared/dist/profile-switch/variant-sync.js
7800
- import fs8 from "fs";
7801
- import path11 from "path";
8235
+ import fs9 from "fs";
8236
+ import path13 from "path";
8237
+ import os7 from "os";
7802
8238
  import crypto6 from "crypto";
8239
+ function defaultStatePath2(targetHome) {
8240
+ return path13.join(targetHome, ".config", "massa-ai", "install-state.json");
8241
+ }
8242
+ function marketplaceRoots2(targetHome, state) {
8243
+ return state.platforms.claude?.installRoute === "marketplace" ? { claude: resolveClaudeMarketplaceRoot({ targetHome }) ?? undefined } : {};
8244
+ }
7803
8245
  function writeFileIntoDirAtomically(destDir, destName, content) {
7804
8246
  const unique = `${process.pid}.${++tempFileCounter2}.${crypto6.randomBytes(6).toString("hex")}`;
7805
- const tempFile = path11.join(destDir, `.${destName}.${unique}.tmp`);
8247
+ const tempFile = path13.join(destDir, `.${destName}.${unique}.tmp`);
7806
8248
  try {
7807
- fs8.writeFileSync(tempFile, content);
7808
- fs8.renameSync(tempFile, path11.join(destDir, destName));
8249
+ fs9.writeFileSync(tempFile, content);
8250
+ fs9.renameSync(tempFile, path13.join(destDir, destName));
7809
8251
  } catch (error) {
7810
8252
  try {
7811
- fs8.unlinkSync(tempFile);
8253
+ fs9.unlinkSync(tempFile);
7812
8254
  } catch {}
7813
8255
  throw error;
7814
8256
  }
@@ -7816,20 +8258,20 @@ function writeFileIntoDirAtomically(destDir, destName, content) {
7816
8258
  function isSafeDirName(name) {
7817
8259
  if (name === "." || name === "..")
7818
8260
  return false;
7819
- if (name.includes("/") || name.includes("\\") || name.includes(path11.sep))
8261
+ if (name.includes("/") || name.includes("\\") || name.includes(path13.sep))
7820
8262
  return false;
7821
- return path11.basename(name) === name;
8263
+ return path13.basename(name) === name;
7822
8264
  }
7823
- function syncHost(host, sourceRoot, targetHome) {
7824
- const layout = resolveHostLayout(host, { targetHome });
8265
+ function syncHost(host, sourceRoot, targetHome, marketplaceRoot) {
8266
+ const layout = resolveHostLayout(host, { targetHome, marketplaceRoot });
7825
8267
  if (layout.route === "skip") {
7826
8268
  return { host, status: "skipped", profiles: [], retained: [], files: 0, reason: layout.reason };
7827
8269
  }
7828
- const srcDir = path11.join(sourceRoot, "apps", `${host}-plugin`, "agent-profiles");
7829
- if (!fs8.existsSync(srcDir) || !fs8.statSync(srcDir).isDirectory()) {
8270
+ const srcDir = path13.join(sourceRoot, "apps", `${host}-plugin`, "agent-profiles");
8271
+ if (!fs9.existsSync(srcDir) || !fs9.statSync(srcDir).isDirectory()) {
7830
8272
  return { host, status: "skipped", profiles: [], retained: [], files: 0, reason: "no generated variants for this host" };
7831
8273
  }
7832
- if (!fs8.existsSync(layout.variantsRoot)) {
8274
+ if (!fs9.existsSync(layout.variantsRoot)) {
7833
8275
  return {
7834
8276
  host,
7835
8277
  status: "skipped",
@@ -7841,24 +8283,24 @@ function syncHost(host, sourceRoot, targetHome) {
7841
8283
  }
7842
8284
  const profiles = [];
7843
8285
  let files = 0;
7844
- for (const entry of fs8.readdirSync(srcDir, { withFileTypes: true })) {
8286
+ for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
7845
8287
  if (!entry.isDirectory())
7846
8288
  continue;
7847
8289
  if (!isSafeDirName(entry.name))
7848
8290
  continue;
7849
- const srcProfileDir = path11.join(srcDir, entry.name);
7850
- const destProfileDir = path11.join(layout.variantsRoot, entry.name);
7851
- fs8.mkdirSync(destProfileDir, { recursive: true });
7852
- for (const fileEntry of fs8.readdirSync(srcProfileDir, { withFileTypes: true })) {
8291
+ const srcProfileDir = path13.join(srcDir, entry.name);
8292
+ const destProfileDir = path13.join(layout.variantsRoot, entry.name);
8293
+ fs9.mkdirSync(destProfileDir, { recursive: true });
8294
+ for (const fileEntry of fs9.readdirSync(srcProfileDir, { withFileTypes: true })) {
7853
8295
  if (!fileEntry.isFile())
7854
8296
  continue;
7855
- const content = fs8.readFileSync(path11.join(srcProfileDir, fileEntry.name));
8297
+ const content = fs9.readFileSync(path13.join(srcProfileDir, fileEntry.name));
7856
8298
  writeFileIntoDirAtomically(destProfileDir, fileEntry.name, content);
7857
8299
  files++;
7858
8300
  }
7859
8301
  profiles.push(entry.name);
7860
8302
  }
7861
- const retained = fs8.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && !profiles.includes(e.name)).map((e) => e.name).sort();
8303
+ const retained = fs9.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && !profiles.includes(e.name)).map((e) => e.name).sort();
7862
8304
  return { host, status: "synced", profiles: profiles.sort(), retained, files };
7863
8305
  }
7864
8306
  function syncGeneratedVariants(opts) {
@@ -7874,9 +8316,12 @@ function syncGeneratedVariants(opts) {
7874
8316
  }));
7875
8317
  }
7876
8318
  const sourceRoot = opts.sourceRoot;
8319
+ const targetHome = opts.targetHome ?? os7.homedir();
8320
+ const state = readInstallState(defaultStatePath2(targetHome));
8321
+ const roots = marketplaceRoots2(targetHome, state);
7877
8322
  return hosts.map((host) => {
7878
8323
  try {
7879
- return syncHost(host, sourceRoot, opts.targetHome);
8324
+ return syncHost(host, sourceRoot, opts.targetHome, roots);
7880
8325
  } catch (err) {
7881
8326
  return { host, status: "failed", profiles: [], retained: [], files: 0, error: err.message };
7882
8327
  }
@@ -7885,17 +8330,19 @@ function syncGeneratedVariants(opts) {
7885
8330
  var tempFileCounter2 = 0;
7886
8331
  var init_variant_sync = __esm(() => {
7887
8332
  init_hosts();
8333
+ init_state();
8334
+ init_claude_marketplace();
7888
8335
  });
7889
8336
 
7890
8337
  // ../../packages/shared/dist/profile-switch/repo-root.js
7891
- import fs9 from "fs";
7892
- import path12 from "path";
8338
+ import fs10 from "fs";
8339
+ import path14 from "path";
7893
8340
  function findRepoRootWithMarker(startDir, marker, maxLevels) {
7894
8341
  let dir = startDir;
7895
8342
  for (let i = 0;i <= maxLevels; i++) {
7896
- if (fs9.existsSync(path12.join(dir, marker)))
8343
+ if (fs10.existsSync(path14.join(dir, marker)))
7897
8344
  return dir;
7898
- const parent = path12.dirname(dir);
8345
+ const parent = path14.dirname(dir);
7899
8346
  if (parent === dir)
7900
8347
  break;
7901
8348
  dir = parent;
@@ -9435,7 +9882,7 @@ var import_brace_expansion, minimatch = (p, pattern, options = {}) => {
9435
9882
  }, qmarksTestNoExtDot = ([$0]) => {
9436
9883
  const len = $0.length;
9437
9884
  return (f) => f.length === len && f !== "." && f !== "..";
9438
- }, defaultPlatform, path13, sep, GLOBSTAR, qmark2 = "[^/]", star2, twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?", twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?", filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options), ext = (a12, b = {}) => Object.assign({}, a12, b), defaults = (def) => {
9885
+ }, defaultPlatform, path15, sep, GLOBSTAR, qmark2 = "[^/]", star2, twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?", twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?", filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options), ext = (a12, b = {}) => Object.assign({}, a12, b), defaults = (def) => {
9439
9886
  if (!def || typeof def !== "object" || !Object.keys(def).length) {
9440
9887
  return minimatch;
9441
9888
  }
@@ -9493,11 +9940,11 @@ var init_esm = __esm(() => {
9493
9940
  starRE = /^\*+$/;
9494
9941
  qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
9495
9942
  defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
9496
- path13 = {
9943
+ path15 = {
9497
9944
  win32: { sep: "\\" },
9498
9945
  posix: { sep: "/" }
9499
9946
  };
9500
- sep = defaultPlatform === "win32" ? path13.win32.sep : path13.posix.sep;
9947
+ sep = defaultPlatform === "win32" ? path15.win32.sep : path15.posix.sep;
9501
9948
  minimatch.sep = sep;
9502
9949
  GLOBSTAR = Symbol("globstar **");
9503
9950
  minimatch.GLOBSTAR = GLOBSTAR;
@@ -11463,12 +11910,12 @@ var init_esm4 = __esm(() => {
11463
11910
  childrenCache() {
11464
11911
  return this.#children;
11465
11912
  }
11466
- resolve(path14) {
11467
- if (!path14) {
11913
+ resolve(path16) {
11914
+ if (!path16) {
11468
11915
  return this;
11469
11916
  }
11470
- const rootPath = this.getRootString(path14);
11471
- const dir = path14.substring(rootPath.length);
11917
+ const rootPath = this.getRootString(path16);
11918
+ const dir = path16.substring(rootPath.length);
11472
11919
  const dirParts = dir.split(this.splitSep);
11473
11920
  const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
11474
11921
  return result;
@@ -11996,8 +12443,8 @@ var init_esm4 = __esm(() => {
11996
12443
  newChild(name, type = UNKNOWN, opts = {}) {
11997
12444
  return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
11998
12445
  }
11999
- getRootString(path14) {
12000
- return win32.parse(path14).root;
12446
+ getRootString(path16) {
12447
+ return win32.parse(path16).root;
12001
12448
  }
12002
12449
  getRoot(rootPath) {
12003
12450
  rootPath = uncToDrive(rootPath.toUpperCase());
@@ -12022,8 +12469,8 @@ var init_esm4 = __esm(() => {
12022
12469
  constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
12023
12470
  super(name, type, root, roots, nocase, children, opts);
12024
12471
  }
12025
- getRootString(path14) {
12026
- return path14.startsWith("/") ? "/" : "";
12472
+ getRootString(path16) {
12473
+ return path16.startsWith("/") ? "/" : "";
12027
12474
  }
12028
12475
  getRoot(_rootPath) {
12029
12476
  return this.root;
@@ -12042,8 +12489,8 @@ var init_esm4 = __esm(() => {
12042
12489
  #children;
12043
12490
  nocase;
12044
12491
  #fs;
12045
- constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs10 = defaultFS } = {}) {
12046
- this.#fs = fsFromOption(fs10);
12492
+ constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs11 = defaultFS } = {}) {
12493
+ this.#fs = fsFromOption(fs11);
12047
12494
  if (cwd instanceof URL || cwd.startsWith("file://")) {
12048
12495
  cwd = fileURLToPath(cwd);
12049
12496
  }
@@ -12079,11 +12526,11 @@ var init_esm4 = __esm(() => {
12079
12526
  }
12080
12527
  this.cwd = prev;
12081
12528
  }
12082
- depth(path14 = this.cwd) {
12083
- if (typeof path14 === "string") {
12084
- path14 = this.cwd.resolve(path14);
12529
+ depth(path16 = this.cwd) {
12530
+ if (typeof path16 === "string") {
12531
+ path16 = this.cwd.resolve(path16);
12085
12532
  }
12086
- return path14.depth();
12533
+ return path16.depth();
12087
12534
  }
12088
12535
  childrenCache() {
12089
12536
  return this.#children;
@@ -12499,9 +12946,9 @@ var init_esm4 = __esm(() => {
12499
12946
  process2();
12500
12947
  return results;
12501
12948
  }
12502
- chdir(path14 = this.cwd) {
12949
+ chdir(path16 = this.cwd) {
12503
12950
  const oldCwd = this.cwd;
12504
- this.cwd = typeof path14 === "string" ? this.cwd.resolve(path14) : path14;
12951
+ this.cwd = typeof path16 === "string" ? this.cwd.resolve(path16) : path16;
12505
12952
  this.cwd[setAsCwd](oldCwd);
12506
12953
  }
12507
12954
  };
@@ -12518,8 +12965,8 @@ var init_esm4 = __esm(() => {
12518
12965
  parseRootPath(dir) {
12519
12966
  return win32.parse(dir).root.toUpperCase();
12520
12967
  }
12521
- newRoot(fs10) {
12522
- return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs10 });
12968
+ newRoot(fs11) {
12969
+ return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs11 });
12523
12970
  }
12524
12971
  isAbsolute(p) {
12525
12972
  return p.startsWith("/") || p.startsWith("\\") || /^[a-z]:(\/|\\)/i.test(p);
@@ -12535,8 +12982,8 @@ var init_esm4 = __esm(() => {
12535
12982
  parseRootPath(_dir) {
12536
12983
  return "/";
12537
12984
  }
12538
- newRoot(fs10) {
12539
- return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs10 });
12985
+ newRoot(fs11) {
12986
+ return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs11 });
12540
12987
  }
12541
12988
  isAbsolute(p) {
12542
12989
  return p.startsWith("/");
@@ -12793,8 +13240,8 @@ class MatchRecord {
12793
13240
  this.store.set(target, current === undefined ? n2 : n2 & current);
12794
13241
  }
12795
13242
  entries() {
12796
- return [...this.store.entries()].map(([path14, n2]) => [
12797
- path14,
13243
+ return [...this.store.entries()].map(([path16, n2]) => [
13244
+ path16,
12798
13245
  !!(n2 & 2),
12799
13246
  !!(n2 & 1)
12800
13247
  ]);
@@ -12998,9 +13445,9 @@ class GlobUtil {
12998
13445
  signal;
12999
13446
  maxDepth;
13000
13447
  includeChildMatches;
13001
- constructor(patterns, path14, opts) {
13448
+ constructor(patterns, path16, opts) {
13002
13449
  this.patterns = patterns;
13003
- this.path = path14;
13450
+ this.path = path16;
13004
13451
  this.opts = opts;
13005
13452
  this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
13006
13453
  this.includeChildMatches = opts.includeChildMatches !== false;
@@ -13019,11 +13466,11 @@ class GlobUtil {
13019
13466
  });
13020
13467
  }
13021
13468
  }
13022
- #ignored(path14) {
13023
- return this.seen.has(path14) || !!this.#ignore?.ignored?.(path14);
13469
+ #ignored(path16) {
13470
+ return this.seen.has(path16) || !!this.#ignore?.ignored?.(path16);
13024
13471
  }
13025
- #childrenIgnored(path14) {
13026
- return !!this.#ignore?.childrenIgnored?.(path14);
13472
+ #childrenIgnored(path16) {
13473
+ return !!this.#ignore?.childrenIgnored?.(path16);
13027
13474
  }
13028
13475
  pause() {
13029
13476
  this.paused = true;
@@ -13240,8 +13687,8 @@ var init_walker = __esm(() => {
13240
13687
  init_processor();
13241
13688
  GlobWalker = class GlobWalker extends GlobUtil {
13242
13689
  matches = new Set;
13243
- constructor(patterns, path14, opts) {
13244
- super(patterns, path14, opts);
13690
+ constructor(patterns, path16, opts) {
13691
+ super(patterns, path16, opts);
13245
13692
  }
13246
13693
  matchEmit(e) {
13247
13694
  this.matches.add(e);
@@ -13278,8 +13725,8 @@ var init_walker = __esm(() => {
13278
13725
  };
13279
13726
  GlobStream = class GlobStream extends GlobUtil {
13280
13727
  results;
13281
- constructor(patterns, path14, opts) {
13282
- super(patterns, path14, opts);
13728
+ constructor(patterns, path16, opts) {
13729
+ super(patterns, path16, opts);
13283
13730
  this.results = new Minipass({
13284
13731
  signal: this.signal,
13285
13732
  objectMode: true
@@ -13707,20 +14154,20 @@ var require_ignore = __commonJS((exports, module) => {
13707
14154
  var throwError = (message, Ctor) => {
13708
14155
  throw new Ctor(message);
13709
14156
  };
13710
- var checkPath = (path14, originalPath, doThrow) => {
13711
- if (!isString(path14)) {
14157
+ var checkPath = (path16, originalPath, doThrow) => {
14158
+ if (!isString(path16)) {
13712
14159
  return doThrow(`path must be a string, but got \`${originalPath}\``, TypeError);
13713
14160
  }
13714
- if (!path14) {
14161
+ if (!path16) {
13715
14162
  return doThrow(`path must not be empty`, TypeError);
13716
14163
  }
13717
- if (checkPath.isNotRelative(path14)) {
14164
+ if (checkPath.isNotRelative(path16)) {
13718
14165
  const r2 = "`path.relative()`d";
13719
14166
  return doThrow(`path should be a ${r2} string, but got "${originalPath}"`, RangeError);
13720
14167
  }
13721
14168
  return true;
13722
14169
  };
13723
- var isNotRelative = (path14) => REGEX_TEST_INVALID_PATH.test(path14);
14170
+ var isNotRelative = (path16) => REGEX_TEST_INVALID_PATH.test(path16);
13724
14171
  checkPath.isNotRelative = isNotRelative;
13725
14172
  checkPath.convert = (p) => p;
13726
14173
 
@@ -13763,7 +14210,7 @@ var require_ignore = __commonJS((exports, module) => {
13763
14210
  addPattern(pattern) {
13764
14211
  return this.add(pattern);
13765
14212
  }
13766
- _testOne(path14, checkUnignored) {
14213
+ _testOne(path16, checkUnignored) {
13767
14214
  let ignored = false;
13768
14215
  let unignored = false;
13769
14216
  this._rules.forEach((rule) => {
@@ -13771,7 +14218,7 @@ var require_ignore = __commonJS((exports, module) => {
13771
14218
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
13772
14219
  return;
13773
14220
  }
13774
- const matched = rule.regex.test(path14);
14221
+ const matched = rule.regex.test(path16);
13775
14222
  if (matched) {
13776
14223
  ignored = !negative;
13777
14224
  unignored = negative;
@@ -13783,39 +14230,39 @@ var require_ignore = __commonJS((exports, module) => {
13783
14230
  };
13784
14231
  }
13785
14232
  _test(originalPath, cache, checkUnignored, slices) {
13786
- const path14 = originalPath && checkPath.convert(originalPath);
13787
- checkPath(path14, originalPath, this._allowRelativePaths ? RETURN_FALSE : throwError);
13788
- return this._t(path14, cache, checkUnignored, slices);
14233
+ const path16 = originalPath && checkPath.convert(originalPath);
14234
+ checkPath(path16, originalPath, this._allowRelativePaths ? RETURN_FALSE : throwError);
14235
+ return this._t(path16, cache, checkUnignored, slices);
13789
14236
  }
13790
- _t(path14, cache, checkUnignored, slices) {
13791
- if (path14 in cache) {
13792
- return cache[path14];
14237
+ _t(path16, cache, checkUnignored, slices) {
14238
+ if (path16 in cache) {
14239
+ return cache[path16];
13793
14240
  }
13794
14241
  if (!slices) {
13795
- slices = path14.split(SLASH);
14242
+ slices = path16.split(SLASH);
13796
14243
  }
13797
14244
  slices.pop();
13798
14245
  if (!slices.length) {
13799
- return cache[path14] = this._testOne(path14, checkUnignored);
14246
+ return cache[path16] = this._testOne(path16, checkUnignored);
13800
14247
  }
13801
14248
  const parent = this._t(slices.join(SLASH) + SLASH, cache, checkUnignored, slices);
13802
- return cache[path14] = parent.ignored ? parent : this._testOne(path14, checkUnignored);
14249
+ return cache[path16] = parent.ignored ? parent : this._testOne(path16, checkUnignored);
13803
14250
  }
13804
- ignores(path14) {
13805
- return this._test(path14, this._ignoreCache, false).ignored;
14251
+ ignores(path16) {
14252
+ return this._test(path16, this._ignoreCache, false).ignored;
13806
14253
  }
13807
14254
  createFilter() {
13808
- return (path14) => !this.ignores(path14);
14255
+ return (path16) => !this.ignores(path16);
13809
14256
  }
13810
14257
  filter(paths) {
13811
14258
  return makeArray(paths).filter(this.createFilter());
13812
14259
  }
13813
- test(path14) {
13814
- return this._test(path14, this._testCache, true);
14260
+ test(path16) {
14261
+ return this._test(path16, this._testCache, true);
13815
14262
  }
13816
14263
  }
13817
14264
  var factory = (options) => new Ignore2(options);
13818
- var isPathValid = (path14) => checkPath(path14 && checkPath.convert(path14), path14, RETURN_FALSE);
14265
+ var isPathValid = (path16) => checkPath(path16 && checkPath.convert(path16), path16, RETURN_FALSE);
13819
14266
  factory.isPathValid = isPathValid;
13820
14267
  factory.default = factory;
13821
14268
  module.exports = factory;
@@ -13823,7 +14270,7 @@ var require_ignore = __commonJS((exports, module) => {
13823
14270
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
13824
14271
  checkPath.convert = makePosix;
13825
14272
  const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
13826
- checkPath.isNotRelative = (path14) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path14) || isNotRelative(path14);
14273
+ checkPath.isNotRelative = (path16) => REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path16) || isNotRelative(path16);
13827
14274
  }
13828
14275
  });
13829
14276
 
@@ -13885,13 +14332,13 @@ function validatePolicy(policy, opts = {}) {
13885
14332
  }
13886
14333
  }
13887
14334
  }
13888
- function matchesGlob2(path14, pattern) {
14335
+ function matchesGlob2(path16, pattern) {
13889
14336
  let re = regexCache.get(pattern);
13890
14337
  if (!re) {
13891
14338
  re = globToRegex(pattern);
13892
14339
  regexCache.set(pattern, re);
13893
14340
  }
13894
- return re.test(path14);
14341
+ return re.test(path16);
13895
14342
  }
13896
14343
  var MAX_MATCH_WORK = 1e5, MAX_IGNORE_PATTERNS2 = 1024, DEFAULT_POLICY, applyPolicy = (filePath, policy) => {
13897
14344
  const normalized = filePath.trim();
@@ -13942,8 +14389,8 @@ var init_capture_policy = __esm(() => {
13942
14389
  });
13943
14390
 
13944
14391
  // ../../packages/core/dist/services/search/ignore-patterns.js
13945
- import fs10 from "fs/promises";
13946
- import path14 from "path";
14392
+ import fs11 from "fs/promises";
14393
+ import path16 from "path";
13947
14394
  function buildExtensionGlob(extensions2) {
13948
14395
  return extensions2.map((ext2) => `**/*${ext2}`);
13949
14396
  }
@@ -13966,8 +14413,8 @@ async function loadProjectIgnore(projectPath) {
13966
14413
  const ig = ignore();
13967
14414
  ig.add(DEFAULT_IGNORES);
13968
14415
  try {
13969
- const gitignorePath = path14.join(projectPath, ".gitignore");
13970
- const gitignoreContent = await fs10.readFile(gitignorePath, "utf8");
14416
+ const gitignorePath = path16.join(projectPath, ".gitignore");
14417
+ const gitignoreContent = await fs11.readFile(gitignorePath, "utf8");
13971
14418
  const rules = gitignoreContent.split(`
13972
14419
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
13973
14420
  ig.add(rules);
@@ -14218,8 +14665,8 @@ var init_alias_resolver = __esm(() => {
14218
14665
  });
14219
14666
 
14220
14667
  // ../../packages/core/dist/services/search/index-manager.js
14221
- import fs11 from "fs";
14222
- import path15 from "path";
14668
+ import fs12 from "fs";
14669
+ import path17 from "path";
14223
14670
 
14224
14671
  class IndexManager {
14225
14672
  metadataCache = new Map;
@@ -14312,9 +14759,9 @@ class IndexManager {
14312
14759
  const fileMetadata = {};
14313
14760
  let totalSize = 0;
14314
14761
  for (const filePath of indexedFiles) {
14315
- const fullPath = path15.join(projectPath, filePath);
14762
+ const fullPath = path17.join(projectPath, filePath);
14316
14763
  try {
14317
- const stat2 = await fs11.promises.stat(fullPath);
14764
+ const stat2 = await fs12.promises.stat(fullPath);
14318
14765
  fileMetadata[filePath] = {
14319
14766
  path: filePath,
14320
14767
  mtime: stat2.mtimeMs,
@@ -14365,9 +14812,9 @@ class IndexManager {
14365
14812
  if (ig.ignores(match2)) {
14366
14813
  continue;
14367
14814
  }
14368
- const fullPath = path15.join(projectPath, match2);
14815
+ const fullPath = path17.join(projectPath, match2);
14369
14816
  try {
14370
- const stat2 = await fs11.promises.stat(fullPath);
14817
+ const stat2 = await fs12.promises.stat(fullPath);
14371
14818
  files.set(match2, {
14372
14819
  path: match2,
14373
14820
  mtime: stat2.mtimeMs,
@@ -14818,10 +15265,10 @@ function mergeDefs(...defs) {
14818
15265
  function cloneDef(schema) {
14819
15266
  return mergeDefs(schema._zod.def);
14820
15267
  }
14821
- function getElementAtPath(obj, path16) {
14822
- if (!path16)
15268
+ function getElementAtPath(obj, path18) {
15269
+ if (!path18)
14823
15270
  return obj;
14824
- return path16.reduce((acc, key) => acc?.[key], obj);
15271
+ return path18.reduce((acc, key) => acc?.[key], obj);
14825
15272
  }
14826
15273
  function promiseAllObject(promisesObj) {
14827
15274
  const keys = Object.keys(promisesObj);
@@ -15149,11 +15596,11 @@ function explicitlyAborted(x, startIndex = 0) {
15149
15596
  }
15150
15597
  return false;
15151
15598
  }
15152
- function prefixIssues(path16, issues) {
15599
+ function prefixIssues(path18, issues) {
15153
15600
  return issues.map((iss) => {
15154
15601
  var _a4;
15155
15602
  (_a4 = iss).path ?? (_a4.path = []);
15156
- iss.path.unshift(path16);
15603
+ iss.path.unshift(path18);
15157
15604
  return iss;
15158
15605
  });
15159
15606
  }
@@ -15366,16 +15813,16 @@ function flattenError(error, mapper = (issue2) => issue2.message) {
15366
15813
  }
15367
15814
  function formatError(error, mapper = (issue2) => issue2.message) {
15368
15815
  const fieldErrors = { _errors: [] };
15369
- const processError = (error2, path16 = []) => {
15816
+ const processError = (error2, path18 = []) => {
15370
15817
  for (const issue2 of error2.issues) {
15371
15818
  if (issue2.code === "invalid_union" && issue2.errors.length) {
15372
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
15819
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
15373
15820
  } else if (issue2.code === "invalid_key") {
15374
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
15821
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
15375
15822
  } else if (issue2.code === "invalid_element") {
15376
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
15823
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
15377
15824
  } else {
15378
- const fullpath = [...path16, ...issue2.path];
15825
+ const fullpath = [...path18, ...issue2.path];
15379
15826
  if (fullpath.length === 0) {
15380
15827
  fieldErrors._errors.push(mapper(issue2));
15381
15828
  } else {
@@ -15402,17 +15849,17 @@ function formatError(error, mapper = (issue2) => issue2.message) {
15402
15849
  }
15403
15850
  function treeifyError(error, mapper = (issue2) => issue2.message) {
15404
15851
  const result = { errors: [] };
15405
- const processError = (error2, path16 = []) => {
15852
+ const processError = (error2, path18 = []) => {
15406
15853
  var _a4, _b;
15407
15854
  for (const issue2 of error2.issues) {
15408
15855
  if (issue2.code === "invalid_union" && issue2.errors.length) {
15409
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
15856
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
15410
15857
  } else if (issue2.code === "invalid_key") {
15411
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
15858
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
15412
15859
  } else if (issue2.code === "invalid_element") {
15413
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
15860
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
15414
15861
  } else {
15415
- const fullpath = [...path16, ...issue2.path];
15862
+ const fullpath = [...path18, ...issue2.path];
15416
15863
  if (fullpath.length === 0) {
15417
15864
  result.errors.push(mapper(issue2));
15418
15865
  continue;
@@ -15444,8 +15891,8 @@ function treeifyError(error, mapper = (issue2) => issue2.message) {
15444
15891
  }
15445
15892
  function toDotPath(_path) {
15446
15893
  const segs = [];
15447
- const path16 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
15448
- for (const seg of path16) {
15894
+ const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
15895
+ for (const seg of path18) {
15449
15896
  if (typeof seg === "number")
15450
15897
  segs.push(`[${seg}]`);
15451
15898
  else if (typeof seg === "symbol")
@@ -28448,13 +28895,13 @@ function resolveRef(ref, ctx) {
28448
28895
  if (!ref.startsWith("#")) {
28449
28896
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
28450
28897
  }
28451
- const path16 = ref.slice(1).split("/").filter(Boolean);
28452
- if (path16.length === 0) {
28898
+ const path18 = ref.slice(1).split("/").filter(Boolean);
28899
+ if (path18.length === 0) {
28453
28900
  return ctx.rootSchema;
28454
28901
  }
28455
28902
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
28456
- if (path16[0] === defsKey) {
28457
- const key = path16[1];
28903
+ if (path18[0] === defsKey) {
28904
+ const key = path18[1];
28458
28905
  if (!key || !ctx.defs[key]) {
28459
28906
  throw new Error(`Reference not found: ${ref}`);
28460
28907
  }
@@ -29943,8 +30390,8 @@ class ParseStatus2 {
29943
30390
  }
29944
30391
  }
29945
30392
  var makeIssue2 = (params) => {
29946
- const { data, path: path16, errorMaps, issueData } = params;
29947
- const fullPath = [...path16, ...issueData.path || []];
30393
+ const { data, path: path18, errorMaps, issueData } = params;
30394
+ const fullPath = [...path18, ...issueData.path || []];
29948
30395
  const fullIssue = {
29949
30396
  ...issueData,
29950
30397
  path: fullPath
@@ -29989,11 +30436,11 @@ var init_errorUtil = __esm(() => {
29989
30436
 
29990
30437
  // ../../node_modules/zod/v3/types.js
29991
30438
  class ParseInputLazyPath2 {
29992
- constructor(parent, value, path16, key) {
30439
+ constructor(parent, value, path18, key) {
29993
30440
  this._cachedPath = [];
29994
30441
  this.parent = parent;
29995
30442
  this.data = value;
29996
- this._path = path16;
30443
+ this._path = path18;
29997
30444
  this._key = key;
29998
30445
  }
29999
30446
  get path() {
@@ -35990,19 +36437,19 @@ var require_token_io = __commonJS((exports, module) => {
35990
36437
  getUserDataDir: () => getUserDataDir
35991
36438
  });
35992
36439
  module.exports = __toCommonJS2(token_io_exports);
35993
- var import_path10 = __toESM2(__require("path"));
35994
- var import_fs7 = __toESM2(__require("fs"));
36440
+ var import_path11 = __toESM2(__require("path"));
36441
+ var import_fs8 = __toESM2(__require("fs"));
35995
36442
  var import_os3 = __toESM2(__require("os"));
35996
36443
  var import_token_error = require_token_error();
35997
36444
  function findRootDir() {
35998
36445
  try {
35999
36446
  let dir = process.cwd();
36000
- while (dir !== import_path10.default.dirname(dir)) {
36001
- const pkgPath = import_path10.default.join(dir, ".vercel");
36002
- if (import_fs7.default.existsSync(pkgPath)) {
36447
+ while (dir !== import_path11.default.dirname(dir)) {
36448
+ const pkgPath = import_path11.default.join(dir, ".vercel");
36449
+ if (import_fs8.default.existsSync(pkgPath)) {
36003
36450
  return dir;
36004
36451
  }
36005
- dir = import_path10.default.dirname(dir);
36452
+ dir = import_path11.default.dirname(dir);
36006
36453
  }
36007
36454
  } catch (e) {
36008
36455
  throw new import_token_error.VercelOidcTokenError("Token refresh only supported in node server environments");
@@ -36015,9 +36462,9 @@ var require_token_io = __commonJS((exports, module) => {
36015
36462
  }
36016
36463
  switch (import_os3.default.platform()) {
36017
36464
  case "darwin":
36018
- return import_path10.default.join(import_os3.default.homedir(), "Library/Application Support");
36465
+ return import_path11.default.join(import_os3.default.homedir(), "Library/Application Support");
36019
36466
  case "linux":
36020
- return import_path10.default.join(import_os3.default.homedir(), ".local/share");
36467
+ return import_path11.default.join(import_os3.default.homedir(), ".local/share");
36021
36468
  case "win32":
36022
36469
  if (process.env.LOCALAPPDATA) {
36023
36470
  return process.env.LOCALAPPDATA;
@@ -36058,23 +36505,23 @@ var require_auth_config = __commonJS((exports, module) => {
36058
36505
  writeAuthConfig: () => writeAuthConfig
36059
36506
  });
36060
36507
  module.exports = __toCommonJS2(auth_config_exports);
36061
- var fs12 = __toESM2(__require("fs"));
36062
- var path16 = __toESM2(__require("path"));
36508
+ var fs13 = __toESM2(__require("fs"));
36509
+ var path18 = __toESM2(__require("path"));
36063
36510
  var import_token_util = require_token_util();
36064
36511
  function getAuthConfigPath() {
36065
36512
  const dataDir = (0, import_token_util.getVercelDataDir)();
36066
36513
  if (!dataDir) {
36067
36514
  throw new Error(`Unable to find Vercel CLI data directory. Your platform: ${process.platform}. Supported: darwin, linux, win32.`);
36068
36515
  }
36069
- return path16.join(dataDir, "auth.json");
36516
+ return path18.join(dataDir, "auth.json");
36070
36517
  }
36071
36518
  function readAuthConfig() {
36072
36519
  try {
36073
36520
  const authPath = getAuthConfigPath();
36074
- if (!fs12.existsSync(authPath)) {
36521
+ if (!fs13.existsSync(authPath)) {
36075
36522
  return null;
36076
36523
  }
36077
- const content = fs12.readFileSync(authPath, "utf8");
36524
+ const content = fs13.readFileSync(authPath, "utf8");
36078
36525
  if (!content) {
36079
36526
  return null;
36080
36527
  }
@@ -36085,11 +36532,11 @@ var require_auth_config = __commonJS((exports, module) => {
36085
36532
  }
36086
36533
  function writeAuthConfig(config3) {
36087
36534
  const authPath = getAuthConfigPath();
36088
- const authDir = path16.dirname(authPath);
36089
- if (!fs12.existsSync(authDir)) {
36090
- fs12.mkdirSync(authDir, { mode: 504, recursive: true });
36535
+ const authDir = path18.dirname(authPath);
36536
+ if (!fs13.existsSync(authDir)) {
36537
+ fs13.mkdirSync(authDir, { mode: 504, recursive: true });
36091
36538
  }
36092
- fs12.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
36539
+ fs13.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
36093
36540
  }
36094
36541
  function isValidAccessToken(authConfig, expirationBufferMs = 0) {
36095
36542
  if (!authConfig.token)
@@ -36264,8 +36711,8 @@ var require_token_util = __commonJS((exports, module) => {
36264
36711
  saveToken: () => saveToken
36265
36712
  });
36266
36713
  module.exports = __toCommonJS2(token_util_exports);
36267
- var path16 = __toESM2(__require("path"));
36268
- var fs12 = __toESM2(__require("fs"));
36714
+ var path18 = __toESM2(__require("path"));
36715
+ var fs13 = __toESM2(__require("fs"));
36269
36716
  var import_token_error = require_token_error();
36270
36717
  var import_token_io = require_token_io();
36271
36718
  var import_auth_config = require_auth_config();
@@ -36277,7 +36724,7 @@ var require_token_util = __commonJS((exports, module) => {
36277
36724
  if (!dataDir) {
36278
36725
  return null;
36279
36726
  }
36280
- return path16.join(dataDir, vercelFolder);
36727
+ return path18.join(dataDir, vercelFolder);
36281
36728
  }
36282
36729
  async function getVercelToken2(options) {
36283
36730
  const authConfig = (0, import_auth_config.readAuthConfig)();
@@ -36345,11 +36792,11 @@ var require_token_util = __commonJS((exports, module) => {
36345
36792
  if (!dir) {
36346
36793
  throw new import_token_error.VercelOidcTokenError("Unable to find project root directory. Have you linked your project with `vc link?`");
36347
36794
  }
36348
- const prjPath = path16.join(dir, ".vercel", "project.json");
36349
- if (!fs12.existsSync(prjPath)) {
36795
+ const prjPath = path18.join(dir, ".vercel", "project.json");
36796
+ if (!fs13.existsSync(prjPath)) {
36350
36797
  throw new import_token_error.VercelOidcTokenError("project.json not found, have you linked your project with `vc link?`");
36351
36798
  }
36352
- const prj = JSON.parse(fs12.readFileSync(prjPath, "utf8"));
36799
+ const prj = JSON.parse(fs13.readFileSync(prjPath, "utf8"));
36353
36800
  if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
36354
36801
  throw new TypeError("Expected a string-valued projectId property. Try running `vc link` to re-link your project.");
36355
36802
  }
@@ -36360,11 +36807,11 @@ var require_token_util = __commonJS((exports, module) => {
36360
36807
  if (!dir) {
36361
36808
  throw new import_token_error.VercelOidcTokenError("Unable to find user data directory. Please reach out to Vercel support.");
36362
36809
  }
36363
- const tokenPath = path16.join(dir, "com.vercel.token", `${projectId}.json`);
36810
+ const tokenPath = path18.join(dir, "com.vercel.token", `${projectId}.json`);
36364
36811
  const tokenJson = JSON.stringify(token);
36365
- fs12.mkdirSync(path16.dirname(tokenPath), { mode: 504, recursive: true });
36366
- fs12.writeFileSync(tokenPath, tokenJson);
36367
- fs12.chmodSync(tokenPath, 432);
36812
+ fs13.mkdirSync(path18.dirname(tokenPath), { mode: 504, recursive: true });
36813
+ fs13.writeFileSync(tokenPath, tokenJson);
36814
+ fs13.chmodSync(tokenPath, 432);
36368
36815
  return;
36369
36816
  }
36370
36817
  function loadToken(projectId) {
@@ -36372,11 +36819,11 @@ var require_token_util = __commonJS((exports, module) => {
36372
36819
  if (!dir) {
36373
36820
  throw new import_token_error.VercelOidcTokenError("Unable to find user data directory. Please reach out to Vercel support.");
36374
36821
  }
36375
- const tokenPath = path16.join(dir, "com.vercel.token", `${projectId}.json`);
36376
- if (!fs12.existsSync(tokenPath)) {
36822
+ const tokenPath = path18.join(dir, "com.vercel.token", `${projectId}.json`);
36823
+ if (!fs13.existsSync(tokenPath)) {
36377
36824
  return null;
36378
36825
  }
36379
- const token = JSON.parse(fs12.readFileSync(tokenPath, "utf8"));
36826
+ const token = JSON.parse(fs13.readFileSync(tokenPath, "utf8"));
36380
36827
  assertVercelOidcTokenResponse(token);
36381
36828
  return token;
36382
36829
  }
@@ -47218,37 +47665,37 @@ function createOpenAI(options = {}) {
47218
47665
  }, `ai-sdk/openai/${VERSION4}`);
47219
47666
  const createChatModel = (modelId) => new OpenAIChatLanguageModel(modelId, {
47220
47667
  provider: `${providerName}.chat`,
47221
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47668
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47222
47669
  headers: getHeaders,
47223
47670
  fetch: options.fetch
47224
47671
  });
47225
47672
  const createCompletionModel = (modelId) => new OpenAICompletionLanguageModel(modelId, {
47226
47673
  provider: `${providerName}.completion`,
47227
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47674
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47228
47675
  headers: getHeaders,
47229
47676
  fetch: options.fetch
47230
47677
  });
47231
47678
  const createEmbeddingModel = (modelId) => new OpenAIEmbeddingModel(modelId, {
47232
47679
  provider: `${providerName}.embedding`,
47233
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47680
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47234
47681
  headers: getHeaders,
47235
47682
  fetch: options.fetch
47236
47683
  });
47237
47684
  const createImageModel = (modelId) => new OpenAIImageModel(modelId, {
47238
47685
  provider: `${providerName}.image`,
47239
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47686
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47240
47687
  headers: getHeaders,
47241
47688
  fetch: options.fetch
47242
47689
  });
47243
47690
  const createTranscriptionModel = (modelId) => new OpenAITranscriptionModel(modelId, {
47244
47691
  provider: `${providerName}.transcription`,
47245
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47692
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47246
47693
  headers: getHeaders,
47247
47694
  fetch: options.fetch
47248
47695
  });
47249
47696
  const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
47250
47697
  provider: `${providerName}.speech`,
47251
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47698
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47252
47699
  headers: getHeaders,
47253
47700
  fetch: options.fetch
47254
47701
  });
@@ -47261,7 +47708,7 @@ function createOpenAI(options = {}) {
47261
47708
  const createResponsesModel = (modelId) => {
47262
47709
  return new OpenAIResponsesLanguageModel(modelId, {
47263
47710
  provider: `${providerName}.responses`,
47264
- url: ({ path: path16 }) => `${baseURL}${path16}`,
47711
+ url: ({ path: path18 }) => `${baseURL}${path18}`,
47265
47712
  headers: getHeaders,
47266
47713
  fetch: options.fetch,
47267
47714
  fileIdPrefixes: ["file-"]
@@ -63806,26 +64253,26 @@ var require_process = __commonJS((exports, module) => {
63806
64253
 
63807
64254
  // ../../node_modules/detect-libc/lib/filesystem.js
63808
64255
  var require_filesystem = __commonJS((exports, module) => {
63809
- var fs12 = __require("fs");
64256
+ var fs13 = __require("fs");
63810
64257
  var LDD_PATH = "/usr/bin/ldd";
63811
64258
  var SELF_PATH = "/proc/self/exe";
63812
64259
  var MAX_LENGTH = 2048;
63813
- var readFileSync2 = (path16) => {
63814
- const fd = fs12.openSync(path16, "r");
64260
+ var readFileSync2 = (path18) => {
64261
+ const fd = fs13.openSync(path18, "r");
63815
64262
  const buffer = Buffer.alloc(MAX_LENGTH);
63816
- const bytesRead = fs12.readSync(fd, buffer, 0, MAX_LENGTH, 0);
63817
- fs12.close(fd, () => {});
64263
+ const bytesRead = fs13.readSync(fd, buffer, 0, MAX_LENGTH, 0);
64264
+ fs13.close(fd, () => {});
63818
64265
  return buffer.subarray(0, bytesRead);
63819
64266
  };
63820
- var readFile = (path16) => new Promise((resolve4, reject) => {
63821
- fs12.open(path16, "r", (err, fd) => {
64267
+ var readFile = (path18) => new Promise((resolve4, reject) => {
64268
+ fs13.open(path18, "r", (err, fd) => {
63822
64269
  if (err) {
63823
64270
  reject(err);
63824
64271
  } else {
63825
64272
  const buffer = Buffer.alloc(MAX_LENGTH);
63826
- fs12.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
64273
+ fs13.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
63827
64274
  resolve4(buffer.subarray(0, bytesRead));
63828
- fs12.close(fd, () => {});
64275
+ fs13.close(fd, () => {});
63829
64276
  });
63830
64277
  }
63831
64278
  });
@@ -63930,11 +64377,11 @@ var require_detect_libc = __commonJS((exports, module) => {
63930
64377
  }
63931
64378
  return null;
63932
64379
  };
63933
- var familyFromInterpreterPath = (path16) => {
63934
- if (path16) {
63935
- if (path16.includes("/ld-musl-")) {
64380
+ var familyFromInterpreterPath = (path18) => {
64381
+ if (path18) {
64382
+ if (path18.includes("/ld-musl-")) {
63936
64383
  return MUSL;
63937
- } else if (path16.includes("/ld-linux-")) {
64384
+ } else if (path18.includes("/ld-linux-")) {
63938
64385
  return GLIBC;
63939
64386
  }
63940
64387
  }
@@ -63979,8 +64426,8 @@ var require_detect_libc = __commonJS((exports, module) => {
63979
64426
  cachedFamilyInterpreter = null;
63980
64427
  try {
63981
64428
  const selfContent = await readFile(SELF_PATH);
63982
- const path16 = interpreterPath(selfContent);
63983
- cachedFamilyInterpreter = familyFromInterpreterPath(path16);
64429
+ const path18 = interpreterPath(selfContent);
64430
+ cachedFamilyInterpreter = familyFromInterpreterPath(path18);
63984
64431
  } catch (e) {}
63985
64432
  return cachedFamilyInterpreter;
63986
64433
  };
@@ -63991,8 +64438,8 @@ var require_detect_libc = __commonJS((exports, module) => {
63991
64438
  cachedFamilyInterpreter = null;
63992
64439
  try {
63993
64440
  const selfContent = readFileSync2(SELF_PATH);
63994
- const path16 = interpreterPath(selfContent);
63995
- cachedFamilyInterpreter = familyFromInterpreterPath(path16);
64441
+ const path18 = interpreterPath(selfContent);
64442
+ cachedFamilyInterpreter = familyFromInterpreterPath(path18);
63996
64443
  } catch (e) {}
63997
64444
  return cachedFamilyInterpreter;
63998
64445
  };
@@ -65654,18 +66101,18 @@ var require_sharp = __commonJS((exports, module) => {
65654
66101
  `@img/sharp-${runtimePlatform}/sharp.node`,
65655
66102
  "@img/sharp-wasm32/sharp.node"
65656
66103
  ];
65657
- var path16;
66104
+ var path18;
65658
66105
  var sharp;
65659
66106
  var errors5 = [];
65660
- for (path16 of paths) {
66107
+ for (path18 of paths) {
65661
66108
  try {
65662
- sharp = __require(path16);
66109
+ sharp = __require(path18);
65663
66110
  break;
65664
66111
  } catch (err) {
65665
66112
  errors5.push(err);
65666
66113
  }
65667
66114
  }
65668
- if (sharp && path16.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
66115
+ if (sharp && path18.startsWith("@img/sharp-linux-x64") && !sharp._isUsingX64V2()) {
65669
66116
  const err = new Error("Prebuilt binaries for linux-x64 require v2 microarchitecture");
65670
66117
  err.code = "Unsupported CPU";
65671
66118
  errors5.push(err);
@@ -65674,7 +66121,7 @@ var require_sharp = __commonJS((exports, module) => {
65674
66121
  if (sharp) {
65675
66122
  module.exports = sharp;
65676
66123
  } else {
65677
- const [isLinux, isMacOs, isWindows] = ["linux", "darwin", "win32"].map((os6) => runtimePlatform.startsWith(os6));
66124
+ const [isLinux, isMacOs, isWindows] = ["linux", "darwin", "win32"].map((os8) => runtimePlatform.startsWith(os8));
65678
66125
  const help = [`Could not load the "sharp" module using the ${runtimePlatform} runtime`];
65679
66126
  errors5.forEach((err) => {
65680
66127
  if (err.code !== "MODULE_NOT_FOUND") {
@@ -65687,9 +66134,9 @@ var require_sharp = __commonJS((exports, module) => {
65687
66134
  const { found, expected } = isUnsupportedNodeRuntime();
65688
66135
  help.push("- Please upgrade Node.js:", ` Found ${found}`, ` Requires ${expected}`);
65689
66136
  } else if (prebuiltPlatforms.includes(runtimePlatform)) {
65690
- const [os6, cpu] = runtimePlatform.split("-");
65691
- const libc = os6.endsWith("musl") ? " --libc=musl" : "";
65692
- help.push("- Ensure optional dependencies can be installed:", " npm install --include=optional sharp", "- Ensure your package manager supports multi-platform installation:", " See https://sharp.pixelplumbing.com/install#cross-platform", "- Add platform-specific dependencies:", ` npm install --os=${os6.replace("musl", "")}${libc} --cpu=${cpu} sharp`);
66137
+ const [os8, cpu] = runtimePlatform.split("-");
66138
+ const libc = os8.endsWith("musl") ? " --libc=musl" : "";
66139
+ help.push("- Ensure optional dependencies can be installed:", " npm install --include=optional sharp", "- Ensure your package manager supports multi-platform installation:", " See https://sharp.pixelplumbing.com/install#cross-platform", "- Add platform-specific dependencies:", ` npm install --os=${os8.replace("musl", "")}${libc} --cpu=${cpu} sharp`);
65693
66140
  } else {
65694
66141
  help.push(`- Manually install libvips >= ${minimumLibvipsVersion}`, "- Add experimental WebAssembly-based dependencies:", " npm install --cpu=wasm32 sharp", " npm install @img/sharp-wasm32");
65695
66142
  }
@@ -66949,7 +67396,7 @@ var require_operation = __commonJS((exports, module) => {
66949
67396
  float: "float",
66950
67397
  approximate: "approximate"
66951
67398
  };
66952
- function rotate(angle, options) {
67399
+ function rotate2(angle, options) {
66953
67400
  if (!is.defined(angle)) {
66954
67401
  return this.autoOrient();
66955
67402
  }
@@ -67376,7 +67823,7 @@ var require_operation = __commonJS((exports, module) => {
67376
67823
  module.exports = (Sharp) => {
67377
67824
  Object.assign(Sharp.prototype, {
67378
67825
  autoOrient,
67379
- rotate,
67826
+ rotate: rotate2,
67380
67827
  flip,
67381
67828
  flop,
67382
67829
  affine,
@@ -68527,15 +68974,15 @@ var require_color = __commonJS((exports, module) => {
68527
68974
  };
68528
68975
  }
68529
68976
  function wrapConversion(toModel, graph) {
68530
- const path16 = [graph[toModel].parent, toModel];
68977
+ const path18 = [graph[toModel].parent, toModel];
68531
68978
  let fn = conversions_default[graph[toModel].parent][toModel];
68532
68979
  let cur = graph[toModel].parent;
68533
68980
  while (graph[cur].parent) {
68534
- path16.unshift(graph[cur].parent);
68981
+ path18.unshift(graph[cur].parent);
68535
68982
  fn = link(conversions_default[graph[cur].parent][cur], fn);
68536
68983
  cur = graph[cur].parent;
68537
68984
  }
68538
- fn.conversion = path16;
68985
+ fn.conversion = path18;
68539
68986
  return fn;
68540
68987
  }
68541
68988
  function route(fromModel) {
@@ -69140,7 +69587,7 @@ var require_output = __commonJS((exports, module) => {
69140
69587
  Copyright 2013 Lovell Fuller and others.
69141
69588
  SPDX-License-Identifier: Apache-2.0
69142
69589
  */
69143
- var path16 = __require("path");
69590
+ var path18 = __require("path");
69144
69591
  var is = require_is();
69145
69592
  var sharp = require_sharp();
69146
69593
  var formats = new Map([
@@ -69171,9 +69618,9 @@ var require_output = __commonJS((exports, module) => {
69171
69618
  let err;
69172
69619
  if (!is.string(fileOut)) {
69173
69620
  err = new Error("Missing output file path");
69174
- } else if (is.string(this.options.input.file) && path16.resolve(this.options.input.file) === path16.resolve(fileOut)) {
69621
+ } else if (is.string(this.options.input.file) && path18.resolve(this.options.input.file) === path18.resolve(fileOut)) {
69175
69622
  err = new Error("Cannot use same file for input and output");
69176
- } else if (jp2Regex.test(path16.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
69623
+ } else if (jp2Regex.test(path18.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
69177
69624
  err = errJp2Save();
69178
69625
  }
69179
69626
  if (err) {
@@ -76420,11 +76867,11 @@ var init_transformers_node = __esm(() => {
76420
76867
  throw new Error(`The number of external data chunks (${num_chunks}) exceeds the maximum allowed value (${_utils_hub_js__WEBPACK_IMPORTED_MODULE_5__.MAX_EXTERNAL_DATA_CHUNKS}).`);
76421
76868
  }
76422
76869
  for (let i = 0;i < num_chunks; ++i) {
76423
- const path16 = `${baseName}_data${i === 0 ? "" : "_" + i}`;
76424
- const fullPath = `${options.subfolder ?? ""}/${path16}`;
76870
+ const path18 = `${baseName}_data${i === 0 ? "" : "_" + i}`;
76871
+ const fullPath = `${options.subfolder ?? ""}/${path18}`;
76425
76872
  externalDataPromises.push(new Promise(async (resolve4, reject) => {
76426
76873
  const data = await (0, _utils_hub_js__WEBPACK_IMPORTED_MODULE_5__.getModelFile)(pretrained_model_name_or_path, fullPath, true, options, return_path);
76427
- resolve4(data instanceof Uint8Array ? { path: path16, data } : path16);
76874
+ resolve4(data instanceof Uint8Array ? { path: path18, data } : path18);
76428
76875
  }));
76429
76876
  }
76430
76877
  } else if (session_options.externalData !== undefined) {
@@ -89488,7 +89935,7 @@ ${fake_token_around_image}` + `${global_img_token}` + image_token.repeat(image_s
89488
89935
  const blob = new Blob([wav], { type: "audio/wav" });
89489
89936
  return blob;
89490
89937
  }
89491
- async save(path16) {
89938
+ async save(path18) {
89492
89939
  let fn;
89493
89940
  if (_env_js__WEBPACK_IMPORTED_MODULE_3__.apis.IS_BROWSER_ENV) {
89494
89941
  if (_env_js__WEBPACK_IMPORTED_MODULE_3__.apis.IS_WEBWORKER_ENV) {
@@ -89496,14 +89943,14 @@ ${fake_token_around_image}` + `${global_img_token}` + image_token.repeat(image_s
89496
89943
  }
89497
89944
  fn = _core_js__WEBPACK_IMPORTED_MODULE_2__.saveBlob;
89498
89945
  } else if (_env_js__WEBPACK_IMPORTED_MODULE_3__.apis.IS_FS_AVAILABLE) {
89499
- fn = async (path17, blob) => {
89946
+ fn = async (path19, blob) => {
89500
89947
  let buffer = await blob.arrayBuffer();
89501
- node_fs__WEBPACK_IMPORTED_MODULE_5__["default"].writeFileSync(path17, Buffer.from(buffer));
89948
+ node_fs__WEBPACK_IMPORTED_MODULE_5__["default"].writeFileSync(path19, Buffer.from(buffer));
89502
89949
  };
89503
89950
  } else {
89504
89951
  throw new Error("Unable to save because filesystem is disabled in this environment.");
89505
89952
  }
89506
- await fn(path16, this.toBlob());
89953
+ await fn(path18, this.toBlob());
89507
89954
  }
89508
89955
  }
89509
89956
  },
@@ -89599,11 +90046,11 @@ ${fake_token_around_image}` + `${global_img_token}` + image_token.repeat(image_s
89599
90046
  function calculateReflectOffset(i, w) {
89600
90047
  return Math.abs((i + w) % (2 * w) - w);
89601
90048
  }
89602
- function saveBlob(path16, blob) {
90049
+ function saveBlob(path18, blob) {
89603
90050
  const dataURL = URL.createObjectURL(blob);
89604
90051
  const downloadLink = document.createElement("a");
89605
90052
  downloadLink.href = dataURL;
89606
- downloadLink.download = path16;
90053
+ downloadLink.download = path18;
89607
90054
  downloadLink.click();
89608
90055
  downloadLink.remove();
89609
90056
  URL.revokeObjectURL(dataURL);
@@ -90204,8 +90651,8 @@ ${fake_token_around_image}` + `${global_img_token}` + image_token.repeat(image_s
90204
90651
  }
90205
90652
 
90206
90653
  class FileCache {
90207
- constructor(path16) {
90208
- this.path = path16;
90654
+ constructor(path18) {
90655
+ this.path = path18;
90209
90656
  }
90210
90657
  async match(request) {
90211
90658
  let filePath = node_path__WEBPACK_IMPORTED_MODULE_1__["default"].join(this.path, request);
@@ -90961,20 +91408,20 @@ ${fake_token_around_image}` + `${global_img_token}` + image_token.repeat(image_s
90961
91408
  }
90962
91409
  return this;
90963
91410
  }
90964
- async save(path16) {
91411
+ async save(path18) {
90965
91412
  if (IS_BROWSER_OR_WEBWORKER) {
90966
91413
  if (_env_js__WEBPACK_IMPORTED_MODULE_2__.apis.IS_WEBWORKER_ENV) {
90967
91414
  throw new Error("Unable to save an image from a Web Worker.");
90968
91415
  }
90969
- const extension = path16.split(".").pop().toLowerCase();
91416
+ const extension = path18.split(".").pop().toLowerCase();
90970
91417
  const mime2 = CONTENT_TYPE_MAP.get(extension) ?? "image/png";
90971
91418
  const blob = await this.toBlob(mime2);
90972
- (0, _core_js__WEBPACK_IMPORTED_MODULE_0__.saveBlob)(path16, blob);
91419
+ (0, _core_js__WEBPACK_IMPORTED_MODULE_0__.saveBlob)(path18, blob);
90973
91420
  } else if (!_env_js__WEBPACK_IMPORTED_MODULE_2__.apis.IS_FS_AVAILABLE) {
90974
91421
  throw new Error("Unable to save the image because filesystem is disabled in this environment.");
90975
91422
  } else {
90976
91423
  const img = this.toSharp();
90977
- return await img.toFile(path16);
91424
+ return await img.toFile(path18);
90978
91425
  }
90979
91426
  }
90980
91427
  toSharp() {
@@ -94501,20 +94948,20 @@ function getRetryDelay(attempt, config3) {
94501
94948
  return Math.min(delay2, config3.maxDelay);
94502
94949
  }
94503
94950
  async function withRetry(fn, config3, context2) {
94504
- let lastError;
94951
+ let lastError2;
94505
94952
  for (let attempt = 0;attempt <= config3.maxRetries; attempt++) {
94506
94953
  try {
94507
94954
  return await fn();
94508
94955
  } catch (error51) {
94509
- lastError = error51;
94956
+ lastError2 = error51;
94510
94957
  if (attempt < config3.maxRetries) {
94511
94958
  const delay2 = getRetryDelay(attempt, config3);
94512
- logger.warn(`[EmbeddingProvider] ${context2} failed (attempt ${attempt + 1}/${config3.maxRetries + 1}), retrying in ${delay2}ms`, { error: lastError.message });
94959
+ logger.warn(`[EmbeddingProvider] ${context2} failed (attempt ${attempt + 1}/${config3.maxRetries + 1}), retrying in ${delay2}ms`, { error: lastError2.message });
94513
94960
  await sleep(delay2);
94514
94961
  }
94515
94962
  }
94516
94963
  }
94517
- throw new Error(`${context2} failed after ${config3.maxRetries + 1} attempts: ${lastError?.message}`);
94964
+ throw new Error(`${context2} failed after ${config3.maxRetries + 1} attempts: ${lastError2?.message}`);
94518
94965
  }
94519
94966
  async function withTimeout(fn, timeoutMs, context2) {
94520
94967
  let timeoutId;
@@ -100200,7 +100647,7 @@ Note that ${s.bold("include")} statements only accept relation fields.`, a12;
100200
100647
  function ns(e = Yo, t2 = Yo) {
100201
100648
  return (r2) => e(t2(r2));
100202
100649
  }
100203
- function os6({ dataPath: e, modelName: t2, args: r2, runtimeDataModel: n2 }) {
100650
+ function os8({ dataPath: e, modelName: t2, args: r2, runtimeDataModel: n2 }) {
100204
100651
  let i = { modelName: t2, args: r2 ?? {} }, o = dp(e);
100205
100652
  if (!o || o.length === 0)
100206
100653
  return i;
@@ -100505,10 +100952,10 @@ Note that ${s.bold("include")} statements only accept relation fields.`, a12;
100505
100952
  super(t2, "P2023", r2);
100506
100953
  }
100507
100954
  };
100508
- var fs12 = new WeakMap;
100955
+ var fs13 = new WeakMap;
100509
100956
  function Ep(e) {
100510
- let t2 = fs12.get(e);
100511
- return t2 || (t2 = Object.entries(e), fs12.set(e, t2)), t2;
100957
+ let t2 = fs13.get(e);
100958
+ return t2 || (t2 = Object.entries(e), fs13.set(e, t2)), t2;
100512
100959
  }
100513
100960
  function hs(e, t2, r2) {
100514
100961
  switch (t2.type) {
@@ -104073,7 +104520,7 @@ new PrismaClient({
104073
104520
  let m2 = await es(this, d);
104074
104521
  if (!d.model)
104075
104522
  return m2;
104076
- let g = os6({ dataPath: d.dataPath, modelName: d.model, args: d.args, runtimeDataModel: this._runtimeDataModel });
104523
+ let g = os8({ dataPath: d.dataPath, modelName: d.model, args: d.args, runtimeDataModel: this._runtimeDataModel });
104077
104524
  return Wo({ result: m2, modelName: g.modelName, args: g.args, extensions: this._extensions, runtimeDataModel: this._runtimeDataModel, globalOmit: this._globalOmit });
104078
104525
  };
104079
104526
  return this._tracingHelper.runInChildSpan(s.operation, () => new zl.AsyncResource("prisma-client-request").runInAsyncScope(() => a12(o)));
@@ -104476,7 +104923,7 @@ var require_prisma = __commonJS((exports) => {
104476
104923
  Prisma.JsonNull = JsonNull2;
104477
104924
  Prisma.AnyNull = AnyNull2;
104478
104925
  Prisma.NullTypes = NullTypes2;
104479
- var path16 = __require("path");
104926
+ var path18 = __require("path");
104480
104927
  exports.Prisma.TransactionIsolationLevel = makeStrictEnum2({
104481
104928
  ReadUncommitted: "ReadUncommitted",
104482
104929
  ReadCommitted: "ReadCommitted",
@@ -110624,7 +111071,7 @@ async function upsertWorkspace(ws) {
110624
111071
  }, { timeout: 60000, maxWait: 1e4 });
110625
111072
  }
110626
111073
  async function updateWorkspaceStatus(projectId, status2, opts) {
110627
- const lastError = typeof opts === "string" ? opts : opts?.lastError ?? null;
111074
+ const lastError2 = typeof opts === "string" ? opts : opts?.lastError ?? null;
110628
111075
  const filesCount = typeof opts === "object" ? opts?.filesCount : undefined;
110629
111076
  const chunksCount = typeof opts === "object" ? opts?.chunksCount : undefined;
110630
111077
  const symbolsCount = typeof opts === "object" ? opts?.symbolsCount : undefined;
@@ -110634,7 +111081,7 @@ async function updateWorkspaceStatus(projectId, status2, opts) {
110634
111081
  await tx.$executeRaw`
110635
111082
  UPDATE workspaces SET
110636
111083
  status = ${status2},
110637
- last_error = ${lastError},
111084
+ last_error = ${lastError2},
110638
111085
  last_indexed_at = ${lastIndexedAt ?? null},
110639
111086
  files_count = COALESCE(${filesCount ?? null}, files_count),
110640
111087
  chunks_count = COALESCE(${chunksCount ?? null}, chunks_count),
@@ -115978,10 +116425,10 @@ var init_chunker_code = __esm(() => {
115978
116425
  });
115979
116426
 
115980
116427
  // ../../packages/core/dist/services/search/smart-chunker.js
115981
- import path16 from "path";
116428
+ import path18 from "path";
115982
116429
  function smartChunk(content, filePath, config3 = {}) {
115983
116430
  const cfg = { ...DEFAULT_CONFIG, ...config3 };
115984
- const ext2 = path16.extname(filePath).toLowerCase();
116431
+ const ext2 = path18.extname(filePath).toLowerCase();
115985
116432
  const relativePath = filePath;
115986
116433
  const fileImports = isCodeFile(ext2) ? extractFileImports(content, ext2) : undefined;
115987
116434
  let chunks;
@@ -116288,8 +116735,8 @@ var init_managed_run_repository_pg = __esm(() => {
116288
116735
  });
116289
116736
 
116290
116737
  // ../../packages/core/dist/services/search/project-indexer.js
116291
- import fs12 from "fs/promises";
116292
- import path17 from "path";
116738
+ import fs13 from "fs/promises";
116739
+ import path19 from "path";
116293
116740
  import { randomUUID as randomUUID3 } from "crypto";
116294
116741
  async function runWithIndexLock(lockMap, projectId, work) {
116295
116742
  const prevLock = lockMap.get(projectId);
@@ -116332,7 +116779,7 @@ async function indexProjectInternal(deps, projectPath, projectId, options = {})
116332
116779
  dot: false
116333
116780
  });
116334
116781
  const filteredFiles = files.filter((file3) => {
116335
- const relativePath = path17.relative(projectPath, file3);
116782
+ const relativePath = path19.relative(projectPath, file3);
116336
116783
  const shouldIgnore = ig.ignores(relativePath);
116337
116784
  if (shouldIgnore) {
116338
116785
  logger.debug("Ignoring file per .gitignore during indexing", {
@@ -116372,7 +116819,7 @@ async function indexProjectInternal(deps, projectPath, projectId, options = {})
116372
116819
  });
116373
116820
  }
116374
116821
  }
116375
- const indexedFilesList = filteredFiles.map((f) => path17.relative(projectPath, f));
116822
+ const indexedFilesList = filteredFiles.map((f) => path19.relative(projectPath, f));
116376
116823
  await deps.indexManager.updateIndexMetadata(projectId, projectPath, indexedFilesList);
116377
116824
  logger.info("Project indexing completed", {
116378
116825
  projectId,
@@ -116497,7 +116944,7 @@ async function ensureFreshIndex(deps, projectId, projectPath, options = {}) {
116497
116944
  let errors5 = 0;
116498
116945
  for (const relativeFilePath of filesToReindex) {
116499
116946
  try {
116500
- const fullPath = path17.join(projectPath, relativeFilePath);
116947
+ const fullPath = path19.join(projectPath, relativeFilePath);
116501
116948
  const result = await deps.indexFile(fullPath, projectId, projectPath, centralityMap);
116502
116949
  filesIndexed++;
116503
116950
  chunksIndexed += result.chunks;
@@ -116548,8 +116995,8 @@ async function checkSearchAdmission(deps, projectId, projectPath) {
116548
116995
  }
116549
116996
  async function indexFile(deps, filePath, projectId, projectRoot, centralityMap) {
116550
116997
  projectId = await getProjectIdentityAliasResolver().resolve(projectId);
116551
- const content = await fs12.readFile(filePath, "utf-8");
116552
- const relativePath = path17.relative(projectRoot, filePath);
116998
+ const content = await fs13.readFile(filePath, "utf-8");
116999
+ const relativePath = path19.relative(projectRoot, filePath);
116553
117000
  const maxFileSize = config.get("security").maxFileSize || 1024 * 1024;
116554
117001
  if (content.length > maxFileSize) {
116555
117002
  logger.warn("File too large, skipping", {
@@ -116569,7 +117016,7 @@ async function indexFile(deps, filePath, projectId, projectRoot, centralityMap)
116569
117016
  chunkIndex: i,
116570
117017
  totalChunks: chunks.length,
116571
117018
  type: chunk.type,
116572
- language: path17.extname(filePath).slice(1),
117019
+ language: path19.extname(filePath).slice(1),
116573
117020
  lineStart: chunk.lineStart,
116574
117021
  lineEnd: chunk.lineEnd,
116575
117022
  label: chunk.label,
@@ -117414,8 +117861,8 @@ function stripNul(content) {
117414
117861
  }
117415
117862
 
117416
117863
  // ../../packages/core/dist/services/etl/stages/discover.js
117417
- import fs13 from "fs/promises";
117418
- import path18 from "path";
117864
+ import fs14 from "fs/promises";
117865
+ import path20 from "path";
117419
117866
  import { createHash as createHash5 } from "crypto";
117420
117867
 
117421
117868
  class DiscoverStage {
@@ -117441,7 +117888,7 @@ class DiscoverStage {
117441
117888
  dot: false,
117442
117889
  absolute: false
117443
117890
  });
117444
- relPaths = found.map((p) => path18.isAbsolute(p) ? path18.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p) && applyPolicy(p, policy) !== "Drop");
117891
+ relPaths = found.map((p) => path20.isAbsolute(p) ? path20.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p) && applyPolicy(p, policy) !== "Drop");
117445
117892
  }
117446
117893
  if (ctx.resumeCursor?.path) {
117447
117894
  const cursorPath = ctx.resumeCursor.path;
@@ -117500,10 +117947,10 @@ class DiscoverStage {
117500
117947
  return discovered;
117501
117948
  }
117502
117949
  async processFile(ctx, relativePath, forceReindex) {
117503
- const absolutePath = path18.join(ctx.projectPath, relativePath);
117950
+ const absolutePath = path20.join(ctx.projectPath, relativePath);
117504
117951
  try {
117505
- const stat2 = await fs13.stat(absolutePath);
117506
- const content = stripNul(await fs13.readFile(absolutePath, "utf-8"));
117952
+ const stat2 = await fs14.stat(absolutePath);
117953
+ const content = stripNul(await fs14.readFile(absolutePath, "utf-8"));
117507
117954
  const contentHash = createHash5("sha256").update(content).digest("hex");
117508
117955
  let needsReparse = forceReindex;
117509
117956
  if (!forceReindex) {
@@ -117546,8 +117993,8 @@ class DiscoverStage {
117546
117993
  ig.add(pattern);
117547
117994
  }
117548
117995
  try {
117549
- const gitignorePath = path18.join(projectPath, ".gitignore");
117550
- const gitignoreContent = await fs13.readFile(gitignorePath, "utf8");
117996
+ const gitignorePath = path20.join(projectPath, ".gitignore");
117997
+ const gitignoreContent = await fs14.readFile(gitignorePath, "utf8");
117551
117998
  const rules = gitignoreContent.split(`
117552
117999
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
117553
118000
  ig.add(rules);
@@ -118902,8 +119349,8 @@ function rustUseLeaves(node2, source, prefix = []) {
118902
119349
  }
118903
119350
  if (node2.type === "use_wildcard")
118904
119351
  return [{ path: [...prefix, "*"], glob: true }];
118905
- const path19 = rustPathSegments(node2, source);
118906
- return path19.length ? [{ path: [...prefix, ...path19] }] : [];
119352
+ const path21 = rustPathSegments(node2, source);
119353
+ return path21.length ? [{ path: [...prefix, ...path21] }] : [];
118907
119354
  }
118908
119355
  function functionalCaptures(captures, source, family) {
118909
119356
  if (family !== "clojure")
@@ -119875,8 +120322,8 @@ var init_structural_runtime = __esm(() => {
119875
120322
  });
119876
120323
 
119877
120324
  // ../../packages/core/dist/services/etl/stages/parse.js
119878
- import path19 from "path";
119879
- import fs14 from "fs/promises";
120325
+ import path21 from "path";
120326
+ import fs15 from "fs/promises";
119880
120327
  function resolveChunkerMaxChars() {
119881
120328
  const global2 = Number(process.env.EMBEDDING_MAX_CHARS);
119882
120329
  if (Number.isFinite(global2) && global2 > 0)
@@ -119904,8 +120351,8 @@ class ParseStage {
119904
120351
  const results = new Map;
119905
120352
  let processed = 0;
119906
120353
  const phases = [
119907
- files.filter((file3) => path19.extname(file3.relativePath).toLowerCase() !== ".h"),
119908
- files.filter((file3) => path19.extname(file3.relativePath).toLowerCase() === ".h")
120354
+ files.filter((file3) => path21.extname(file3.relativePath).toLowerCase() !== ".h"),
120355
+ files.filter((file3) => path21.extname(file3.relativePath).toLowerCase() === ".h")
119909
120356
  ];
119910
120357
  const batches = phases.flatMap((phase) => Array.from({ length: Math.ceil(phase.length / BATCH_SIZE) }, (_2, index) => phase.slice(index * BATCH_SIZE, (index + 1) * BATCH_SIZE)));
119911
120358
  for (const batch of batches) {
@@ -119943,19 +120390,19 @@ class ParseStage {
119943
120390
  return files.map((file3) => results.get(file3.relativePath));
119944
120391
  }
119945
120392
  recordHeaderImporterEvidence(ctx, files, parsedFiles) {
119946
- const knownHeaders = new Set(files.filter((file3) => path19.extname(file3.relativePath).toLowerCase() === ".h").map((file3) => path19.posix.normalize(file3.relativePath)));
120393
+ const knownHeaders = new Set(files.filter((file3) => path21.extname(file3.relativePath).toLowerCase() === ".h").map((file3) => path21.posix.normalize(file3.relativePath)));
119947
120394
  const mutable = {
119948
120395
  ...ctx.structuralHeaderEvidenceByFile
119949
120396
  };
119950
120397
  for (const parsed of parsedFiles) {
119951
- const extension = path19.extname(parsed.file.relativePath).toLowerCase();
120398
+ const extension = path21.extname(parsed.file.relativePath).toLowerCase();
119952
120399
  const key = extension === ".c" ? "cImporters" : [".cpp", ".hpp"].includes(extension) ? "cppImporters" : undefined;
119953
120400
  if (!key)
119954
120401
  continue;
119955
120402
  for (const imported of parsed.rawImports) {
119956
120403
  if (!["c_include", "cpp_include"].includes(imported.form) || imported.specifier.startsWith("<"))
119957
120404
  continue;
119958
- const header = path19.posix.normalize(path19.posix.join(path19.posix.dirname(parsed.file.relativePath), imported.specifier));
120405
+ const header = path21.posix.normalize(path21.posix.join(path21.posix.dirname(parsed.file.relativePath), imported.specifier));
119959
120406
  if (!knownHeaders.has(header))
119960
120407
  continue;
119961
120408
  const existing = mutable[header] ?? {};
@@ -119966,9 +120413,9 @@ class ParseStage {
119966
120413
  }
119967
120414
  async parseFile(ctx, file3) {
119968
120415
  if (!file3.needsReparse) {
119969
- const extension = path19.extname(file3.relativePath).toLowerCase();
120416
+ const extension = path21.extname(file3.relativePath).toLowerCase();
119970
120417
  if ([".c", ".cpp", ".hpp"].includes(extension)) {
119971
- const content = file3.snapshotContent ?? await fs14.readFile(file3.absolutePath, "utf8");
120418
+ const content = file3.snapshotContent ?? await fs15.readFile(file3.absolutePath, "utf8");
119972
120419
  const outcome = await this.runtime.parse({ extension, source: Buffer.from(content) });
119973
120420
  if (outcome.status === "failed")
119974
120421
  throw new StructuralEtlParseError(file3.relativePath, outcome.failureKind, `Structural evidence parse failed (${outcome.failureKind})`, outcome.diagnosticCount, outcome.diagnostics.slice(0, 10));
@@ -119980,8 +120427,8 @@ class ParseStage {
119980
120427
  return { file: file3, chunks: [], symbols: [], rawImports: [], rawEdges: [] };
119981
120428
  }
119982
120429
  try {
119983
- const content = file3.snapshotContent ?? await fs14.readFile(file3.absolutePath, "utf-8");
119984
- const ext2 = path19.extname(file3.relativePath).toLowerCase();
120430
+ const content = file3.snapshotContent ?? await fs15.readFile(file3.absolutePath, "utf-8");
120431
+ const ext2 = path21.extname(file3.relativePath).toLowerCase();
119985
120432
  const chunkerMaxChars = resolveChunkerMaxChars();
119986
120433
  const chunks = smartChunk(content, file3.relativePath, chunkerMaxChars ? { maxChunkChars: chunkerMaxChars } : {});
119987
120434
  let symbols;
@@ -120535,7 +120982,7 @@ var init_resolver = __esm(() => {
120535
120982
  });
120536
120983
 
120537
120984
  // ../../packages/core/dist/services/structural/resolvers/typescript.js
120538
- import path20 from "path";
120985
+ import path22 from "path";
120539
120986
  function candidates(identities) {
120540
120987
  return Object.freeze(identities.map((identity) => Object.freeze({
120541
120988
  fqn: identity.fqn,
@@ -120630,7 +121077,7 @@ function probe(base, known, dialect = "typescript") {
120630
121077
  const bases = /\.[cm]?jsx?$/u.test(base) ? [base.replace(/\.[cm]?jsx?$/u, ".ts"), base.replace(/\.[cm]?jsx?$/u, ".tsx"), base] : [base];
120631
121078
  for (const candidateBase of bases)
120632
121079
  for (const suffix of DIALECT_PROBES[dialect] ?? [""]) {
120633
- const value = path20.posix.normalize(`${candidateBase}${suffix}`);
121080
+ const value = path22.posix.normalize(`${candidateBase}${suffix}`);
120634
121081
  if (!value.startsWith("../") && value !== ".." && known.has(value))
120635
121082
  return value;
120636
121083
  }
@@ -120639,7 +121086,7 @@ function probe(base, known, dialect = "typescript") {
120639
121086
  function resolveStructuralSpecifier(specifier, fromFile, build, dialect = "typescript") {
120640
121087
  const known = new Set(build.knownFiles.map(normalizeStructuralFile));
120641
121088
  if (specifier.startsWith("./") || specifier.startsWith("../")) {
120642
- return probe(path20.posix.join(path20.posix.dirname(fromFile), specifier), known, dialect);
121089
+ return probe(path22.posix.join(path22.posix.dirname(fromFile), specifier), known, dialect);
120643
121090
  }
120644
121091
  const aliases = build.pathAliasesByFile?.[normalizeStructuralFile(fromFile)] ?? build.pathAliases ?? [];
120645
121092
  for (const alias of aliases) {
@@ -120903,7 +121350,7 @@ var init_scripting2 = __esm(() => {
120903
121350
  });
120904
121351
 
120905
121352
  // ../../packages/core/dist/services/structural/resolvers/systems.js
120906
- import path21 from "path";
121353
+ import path23 from "path";
120907
121354
  var DIALECTS, SYSTEMS_LANGUAGE_RESOLVER;
120908
121355
  var init_systems2 = __esm(() => {
120909
121356
  init_typescript2();
@@ -120922,7 +121369,7 @@ var init_systems2 = __esm(() => {
120922
121369
  const bindings = item.bindings.map((binding) => binding.imported === "*" && binding.local === "*" && unresolvedTarget && !unresolvedTarget.qualifier ? { ...binding, imported: unresolvedTarget.name, local: unresolvedTarget.name } : binding);
120923
121370
  if (item.specifier === "crate" || item.specifier.startsWith("crate/")) {
120924
121371
  const crateRoot = file3.file.startsWith("src/") ? "src" : "";
120925
- return { ...item, bindings, specifier: `./${path21.posix.relative(path21.posix.dirname(file3.file), path21.posix.join(crateRoot, item.specifier.replace(/^crate\/?/u, "")))}` };
121372
+ return { ...item, bindings, specifier: `./${path23.posix.relative(path23.posix.dirname(file3.file), path23.posix.join(crateRoot, item.specifier.replace(/^crate\/?/u, "")))}` };
120926
121373
  }
120927
121374
  if (item.specifier === "self" || item.specifier.startsWith("self/"))
120928
121375
  return { ...item, bindings, specifier: `./${item.specifier.replace(/^self\/?/u, "")}` };
@@ -121020,8 +121467,8 @@ var init_data_document2 = __esm(() => {
121020
121467
  });
121021
121468
 
121022
121469
  // ../../packages/core/dist/services/etl/stages/resolve.js
121023
- import path22 from "path";
121024
- import fs15 from "fs";
121470
+ import path24 from "path";
121471
+ import fs16 from "fs";
121025
121472
 
121026
121473
  class ResolveStage {
121027
121474
  symbolRepository;
@@ -121045,7 +121492,7 @@ class ResolveStage {
121045
121492
  const structuralDocuments = files.flatMap((file3) => {
121046
121493
  if (!file3.structure)
121047
121494
  return [];
121048
- const language = resolveStructuralLanguage(path22.extname(file3.file.relativePath));
121495
+ const language = resolveStructuralLanguage(path24.extname(file3.file.relativePath));
121049
121496
  if (language.status !== "supported")
121050
121497
  throw new Error(`structural_manifest_missing:${file3.file.relativePath}`);
121051
121498
  return [{
@@ -121057,13 +121504,13 @@ class ResolveStage {
121057
121504
  }];
121058
121505
  });
121059
121506
  const currentStructuralFiles = new Set(structuralDocuments.map((document2) => document2.file));
121060
- const skippedStructuralFiles = new Set(files.filter((item) => !item.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path22.extname(item.file.relativePath).toLowerCase())).map((item) => item.file.relativePath));
121507
+ const skippedStructuralFiles = new Set(files.filter((item) => !item.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path24.extname(item.file.relativePath).toLowerCase())).map((item) => item.file.relativePath));
121061
121508
  const pathAliasesByFile = Object.fromEntries([...knownRelPaths].map((file3) => [
121062
121509
  file3,
121063
121510
  this.structuralAliasesFor(file3, rootAliases, monorepoPackages)
121064
121511
  ]));
121065
121512
  const buildMetadata = { knownFiles: [...knownRelPaths], pathAliasesByFile };
121066
- const seedRows = repositoryDefinitions.filter((definition) => STRUCTURAL_SEED_EXTENSIONS.has(path22.extname(definition.file_path).toLowerCase())).filter((definition) => knownRelPaths.has(definition.file_path) && skippedStructuralFiles.has(definition.file_path)).filter((definition) => !currentStructuralFiles.has(definition.file_path));
121513
+ const seedRows = repositoryDefinitions.filter((definition) => STRUCTURAL_SEED_EXTENSIONS.has(path24.extname(definition.file_path).toLowerCase())).filter((definition) => knownRelPaths.has(definition.file_path) && skippedStructuralFiles.has(definition.file_path)).filter((definition) => !currentStructuralFiles.has(definition.file_path));
121067
121514
  const seedIds = new Set;
121068
121515
  for (const definition of seedRows) {
121069
121516
  if (seedIds.has(definition.id))
@@ -121156,7 +121603,7 @@ class ResolveStage {
121156
121603
  if (parsed.file !== definition.file_path) {
121157
121604
  throw new Error(`structural_repository_seed_file_mismatch:${definition.id}`);
121158
121605
  }
121159
- const language = resolveStructuralLanguage(path22.extname(definition.file_path));
121606
+ const language = resolveStructuralLanguage(path24.extname(definition.file_path));
121160
121607
  if (language.status !== "supported")
121161
121608
  throw new Error(`structural_repository_seed_language:${definition.id}`);
121162
121609
  let identity;
@@ -121208,7 +121655,7 @@ class ResolveStage {
121208
121655
  });
121209
121656
  }
121210
121657
  resolveFile(parsed, projectPath, knownRelPaths, rootAliases, monorepoPackages, symbolIndex, knownFqns) {
121211
- const fromDir = path22.dirname(path22.join(projectPath, parsed.file.relativePath));
121658
+ const fromDir = path24.dirname(path24.join(projectPath, parsed.file.relativePath));
121212
121659
  const packageAliases = this.getPackageAliases(parsed.file.relativePath, monorepoPackages);
121213
121660
  const allAliases = [...packageAliases, ...rootAliases];
121214
121661
  const resolvedImports = parsed.rawImports.map((raw2) => {
@@ -121279,7 +121726,7 @@ class ResolveStage {
121279
121726
  index.set(def.name, `${def.file_path}#${def.name}`);
121280
121727
  }
121281
121728
  } catch (err) {
121282
- const skippedStructural = files.some((file3) => !file3.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path22.extname(file3.file.relativePath).toLowerCase()));
121729
+ const skippedStructural = files.some((file3) => !file3.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path24.extname(file3.file.relativePath).toLowerCase()));
121283
121730
  if (skippedStructural)
121284
121731
  throw new Error("structural_repository_seed_failed", { cause: err });
121285
121732
  logger.warn("buildSymbolIndex: repo seed failed, in-batch only", {
@@ -121303,7 +121750,7 @@ class ResolveStage {
121303
121750
  }
121304
121751
  resolveSpecifier(specifier, fromDir, projectPath, knownRelPaths, aliases) {
121305
121752
  if (specifier.startsWith("./") || specifier.startsWith("../")) {
121306
- const resolved = this.probeExtensions(path22.resolve(fromDir, specifier), projectPath, knownRelPaths);
121753
+ const resolved = this.probeExtensions(path24.resolve(fromDir, specifier), projectPath, knownRelPaths);
121307
121754
  return { resolvedPath: resolved, external: false };
121308
121755
  }
121309
121756
  for (const alias of aliases) {
@@ -121311,8 +121758,8 @@ class ResolveStage {
121311
121758
  const suffix = specifier.slice(alias.prefix.length);
121312
121759
  for (const target of alias.targets) {
121313
121760
  const cleanTarget = target.replace(/\/\*$/, "");
121314
- const basePath = alias.packagePath ? path22.join(projectPath, alias.packagePath) : projectPath;
121315
- const absPath = path22.join(basePath, cleanTarget + suffix);
121761
+ const basePath = alias.packagePath ? path24.join(projectPath, alias.packagePath) : projectPath;
121762
+ const absPath = path24.join(basePath, cleanTarget + suffix);
121316
121763
  const resolved = this.probeExtensions(absPath, projectPath, knownRelPaths);
121317
121764
  if (resolved)
121318
121765
  return { resolvedPath: resolved, external: false };
@@ -121328,7 +121775,7 @@ class ResolveStage {
121328
121775
  ...TS_EXTENSIONS.map((ext2) => absPath.replace(/\.[^.]+$/, ext2))
121329
121776
  ];
121330
121777
  for (const candidate2 of candidates2) {
121331
- const rel = path22.relative(projectPath, candidate2).replace(/\\/g, "/");
121778
+ const rel = path24.relative(projectPath, candidate2).replace(/\\/g, "/");
121332
121779
  if (knownRelPaths.has(rel))
121333
121780
  return rel;
121334
121781
  }
@@ -121336,9 +121783,9 @@ class ResolveStage {
121336
121783
  }
121337
121784
  loadTsConfigPaths(projectPath, packageBase) {
121338
121785
  const aliases = [];
121339
- const tsconfigPath = path22.join(projectPath, "tsconfig.json");
121786
+ const tsconfigPath = path24.join(projectPath, "tsconfig.json");
121340
121787
  try {
121341
- const raw2 = fs15.readFileSync(tsconfigPath, "utf-8");
121788
+ const raw2 = fs16.readFileSync(tsconfigPath, "utf-8");
121342
121789
  const stripped = raw2.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
121343
121790
  const tsconfig = JSON.parse(stripped);
121344
121791
  const paths = tsconfig?.compilerOptions?.paths ?? {};
@@ -121367,7 +121814,7 @@ class ResolveStage {
121367
121814
  }
121368
121815
  }
121369
121816
  for (const packageRelPath of packagePaths) {
121370
- const absPackagePath = path22.join(projectPath, packageRelPath);
121817
+ const absPackagePath = path24.join(projectPath, packageRelPath);
121371
121818
  const aliases = this.loadTsConfigPaths(absPackagePath, packageRelPath);
121372
121819
  if (aliases.length > 0) {
121373
121820
  packages.push({
@@ -121397,7 +121844,7 @@ class ResolveStage {
121397
121844
  structuralAliasesFor(filePath, rootAliases, packages) {
121398
121845
  return [...this.getPackageAliases(filePath, packages), ...rootAliases].map((alias) => ({
121399
121846
  pattern: alias.prefix + (alias.targets.some((target) => target.includes("*")) ? "/*" : ""),
121400
- targets: alias.targets.map((target) => alias.packagePath ? path22.posix.join(alias.packagePath, target) : target)
121847
+ targets: alias.targets.map((target) => alias.packagePath ? path24.posix.join(alias.packagePath, target) : target)
121401
121848
  }));
121402
121849
  }
121403
121850
  }
@@ -121461,7 +121908,7 @@ var init_with_deadlock_retry = __esm(() => {
121461
121908
  });
121462
121909
 
121463
121910
  // ../../packages/core/dist/services/etl/stages/load.js
121464
- import path23 from "path";
121911
+ import path25 from "path";
121465
121912
  function formatDuration(ms) {
121466
121913
  const totalSec = Math.max(0, Math.round(ms / 1000));
121467
121914
  if (totalSec < 60)
@@ -121738,7 +122185,7 @@ class LoadStage {
121738
122185
  const filePath = file3.file.relativePath;
121739
122186
  const batch = buildSymbolPersistenceBatch(ctx.projectId, file3);
121740
122187
  if (ctx.graphGenerationLease) {
121741
- const manifest = getLanguageManifestEntry(path23.extname(filePath));
122188
+ const manifest = getLanguageManifestEntry(path25.extname(filePath));
121742
122189
  const diagnostics2 = (file3.structuralDiagnostics ?? []).slice(0, 10).map((diagnostic2) => ({
121743
122190
  code: diagnostic2.code,
121744
122191
  severity: diagnostic2.severity,
@@ -122195,9 +122642,9 @@ var init_graph_generation_coordinator = __esm(() => {
122195
122642
  // ../../packages/core/dist/services/etl/pipeline.js
122196
122643
  import { createHash as createHash7 } from "crypto";
122197
122644
  import { setTimeout as delay2 } from "timers/promises";
122198
- import path24 from "path";
122645
+ import path26 from "path";
122199
122646
  function buildHeaderLanguageEvidence(files) {
122200
- const headers = new Set(files.filter((file3) => path24.posix.extname(file3.relativePath).toLowerCase() === ".h").map((file3) => path24.posix.normalize(file3.relativePath)));
122647
+ const headers = new Set(files.filter((file3) => path26.posix.extname(file3.relativePath).toLowerCase() === ".h").map((file3) => path26.posix.normalize(file3.relativePath)));
122201
122648
  const mutable = new Map;
122202
122649
  const entry2 = (header) => {
122203
122650
  let value = mutable.get(header);
@@ -122208,7 +122655,7 @@ function buildHeaderLanguageEvidence(files) {
122208
122655
  return value;
122209
122656
  };
122210
122657
  for (const file3 of files) {
122211
- if (path24.posix.basename(file3.relativePath) !== "compile_commands.json" || file3.snapshotContent === undefined)
122658
+ if (path26.posix.basename(file3.relativePath) !== "compile_commands.json" || file3.snapshotContent === undefined)
122212
122659
  continue;
122213
122660
  let commands;
122214
122661
  try {
@@ -122224,11 +122671,11 @@ function buildHeaderLanguageEvidence(files) {
122224
122671
  const record2 = command;
122225
122672
  if (typeof record2.file !== "string")
122226
122673
  continue;
122227
- const projectRoot = path24.resolve(file3.absolutePath, ...file3.relativePath.split("/").map(() => ".."));
122228
- const commandDirectory = typeof record2.directory === "string" ? path24.resolve(projectRoot, record2.directory) : projectRoot;
122229
- const absoluteInput = path24.resolve(commandDirectory, record2.file);
122230
- const relative2 = path24.relative(projectRoot, absoluteInput);
122231
- const header = path24.posix.normalize(relative2.replaceAll(path24.sep, "/"));
122674
+ const projectRoot = path26.resolve(file3.absolutePath, ...file3.relativePath.split("/").map(() => ".."));
122675
+ const commandDirectory = typeof record2.directory === "string" ? path26.resolve(projectRoot, record2.directory) : projectRoot;
122676
+ const absoluteInput = path26.resolve(commandDirectory, record2.file);
122677
+ const relative2 = path26.relative(projectRoot, absoluteInput);
122678
+ const header = path26.posix.normalize(relative2.replaceAll(path26.sep, "/"));
122232
122679
  if (!headers.has(header))
122233
122680
  continue;
122234
122681
  const invocation = typeof record2.command === "string" ? record2.command : Array.isArray(record2.arguments) ? record2.arguments.join(" ") : "";
@@ -123387,16 +123834,16 @@ function detectRoutes(httpEdges, defs, opts = {}) {
123387
123834
  const seen = new Set;
123388
123835
  const out = [];
123389
123836
  for (const e of httpEdges) {
123390
- const path26 = e.route;
123391
- if (!path26)
123837
+ const path28 = e.route;
123838
+ if (!path28)
123392
123839
  continue;
123393
123840
  const method = (e.method ?? "ANY").toUpperCase();
123394
- const key = method + " " + path26;
123841
+ const key = method + " " + path28;
123395
123842
  if (seen.has(key))
123396
123843
  continue;
123397
123844
  seen.add(key);
123398
123845
  out.push({
123399
- path: path26,
123846
+ path: path28,
123400
123847
  method: e.method,
123401
123848
  file: e.fromFile,
123402
123849
  handler: e.targetFqn ?? e.symbolName
@@ -123407,12 +123854,12 @@ function detectRoutes(httpEdges, defs, opts = {}) {
123407
123854
  continue;
123408
123855
  const parsed = parseRouteName(d.name);
123409
123856
  const method = parsed?.method ?? "ANY";
123410
- const path26 = parsed?.path ?? d.name;
123411
- const key = method + " " + path26;
123857
+ const path28 = parsed?.path ?? d.name;
123858
+ const key = method + " " + path28;
123412
123859
  if (seen.has(key))
123413
123860
  continue;
123414
123861
  seen.add(key);
123415
- out.push({ path: path26, method: parsed?.method, file: d.filePath, handler: d.name });
123862
+ out.push({ path: path28, method: parsed?.method, file: d.filePath, handler: d.name });
123416
123863
  }
123417
123864
  for (const d of defs) {
123418
123865
  const parsed = parseRouteName(d.name);
@@ -123633,8 +124080,8 @@ __export(exports_symbol_graph_service, {
123633
124080
  symbolGraphService: () => symbolGraphService,
123634
124081
  SymbolGraphService: () => SymbolGraphService
123635
124082
  });
123636
- import path26 from "path";
123637
- import fs16 from "fs/promises";
124083
+ import path28 from "path";
124084
+ import fs17 from "fs/promises";
123638
124085
 
123639
124086
  class SymbolGraphService {
123640
124087
  identityLookup;
@@ -123962,7 +124409,7 @@ class SymbolGraphService {
123962
124409
  async readSnippet(relativePath, lineStart, lineEnd, projectId) {
123963
124410
  try {
123964
124411
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123965
- const content = await fs16.readFile(absolutePath, "utf-8");
124412
+ const content = await fs17.readFile(absolutePath, "utf-8");
123966
124413
  const lines = content.split(`
123967
124414
  `);
123968
124415
  return lines.slice(Math.max(0, lineStart - 1), Math.min(lines.length, lineEnd)).join(`
@@ -123974,7 +124421,7 @@ class SymbolGraphService {
123974
124421
  async readContext(relativePath, lineNumber, contextLines, projectId) {
123975
124422
  try {
123976
124423
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123977
- const content = await fs16.readFile(absolutePath, "utf-8");
124424
+ const content = await fs17.readFile(absolutePath, "utf-8");
123978
124425
  const lines = content.split(`
123979
124426
  `);
123980
124427
  const start = Math.max(0, lineNumber - contextLines - 1);
@@ -123987,7 +124434,7 @@ class SymbolGraphService {
123987
124434
  }
123988
124435
  async resolveToAbsolute(relativePath, projectId) {
123989
124436
  const root = await this.getProjectRoot(projectId);
123990
- return root ? path26.resolve(root, relativePath) : relativePath;
124437
+ return root ? path28.resolve(root, relativePath) : relativePath;
123991
124438
  }
123992
124439
  async getProjectRoot(projectId) {
123993
124440
  const cached2 = this.projectRootCache.get(projectId);
@@ -127981,31 +128428,31 @@ class TracePathService {
127981
128428
  const chains = [];
127982
128429
  const seen = new Set;
127983
128430
  let walks = 0;
127984
- const walk = (fqn, path29) => {
128431
+ const walk = (fqn, path31) => {
127985
128432
  if (chains.length >= CHAIN_CAP)
127986
128433
  return;
127987
128434
  if (walks >= MAX_WALKS)
127988
128435
  return;
127989
128436
  walks++;
127990
- const key = path29.join("\u2192");
128437
+ const key = path31.join("\u2192");
127991
128438
  if (seen.has(key))
127992
128439
  return;
127993
128440
  seen.add(key);
127994
128441
  const next = adj.get(fqn);
127995
128442
  if (!next || next.length === 0 || !whoHasChild.has(fqn)) {
127996
- if (path29.length > 1)
127997
- chains.push(path29.map((n2) => this.fqnToName(n2)).join(" \u2192 "));
128443
+ if (path31.length > 1)
128444
+ chains.push(path31.map((n2) => this.fqnToName(n2)).join(" \u2192 "));
127998
128445
  return;
127999
128446
  }
128000
128447
  for (const child of next) {
128001
128448
  if (chains.length >= CHAIN_CAP || walks >= MAX_WALKS)
128002
128449
  return;
128003
- if (path29.includes(child)) {
128004
- const cycled = [...path29, `${this.fqnToName(child)}\u21BA`];
128450
+ if (path31.includes(child)) {
128451
+ const cycled = [...path31, `${this.fqnToName(child)}\u21BA`];
128005
128452
  chains.push(cycled.map((n2) => n2).join(" \u2192 "));
128006
128453
  continue;
128007
128454
  }
128008
- walk(child, [...path29, child]);
128455
+ walk(child, [...path31, child]);
128009
128456
  }
128010
128457
  };
128011
128458
  for (const seed of seeds) {
@@ -131147,9 +131594,9 @@ var init_l1_memory_cache = __esm(() => {
131147
131594
  });
131148
131595
 
131149
131596
  // ../../packages/core/dist/services/health/local-health-checker.js
131150
- import fs19 from "fs/promises";
131597
+ import fs20 from "fs/promises";
131151
131598
  import { existsSync as existsSync3 } from "fs";
131152
- import path31 from "path";
131599
+ import path33 from "path";
131153
131600
 
131154
131601
  class LocalHealthChecker {
131155
131602
  ollamaBaseUrl = process.env.OLLAMA_BASE_URL || "http://localhost:11434";
@@ -131183,10 +131630,10 @@ class LocalHealthChecker {
131183
131630
  const start = Date.now();
131184
131631
  try {
131185
131632
  if (!existsSync3(this.dataDir))
131186
- await fs19.mkdir(this.dataDir, { recursive: true });
131187
- const probe2 = path31.join(this.dataDir, ".health-check-test");
131188
- await fs19.writeFile(probe2, "ok");
131189
- await fs19.unlink(probe2);
131633
+ await fs20.mkdir(this.dataDir, { recursive: true });
131634
+ const probe2 = path33.join(this.dataDir, ".health-check-test");
131635
+ await fs20.writeFile(probe2, "ok");
131636
+ await fs20.unlink(probe2);
131190
131637
  return { available: true, latency: Date.now() - start, details: { path: this.dataDir, writable: true } };
131191
131638
  } catch (error51) {
131192
131639
  return { available: false, latency: Date.now() - start, error: `Data directory error: ${error51.message}` };
@@ -131582,10 +132029,18 @@ var init_scheduler_store_factory = __esm(() => {
131582
132029
  });
131583
132030
 
131584
132031
  // ../../packages/core/dist/services/scheduler/scheduler.js
131585
- function readEnabled() {
132032
+ function readEnabledEnv() {
131586
132033
  const raw2 = process.env.MASSA_AI_SCHEDULER_ENABLED;
132034
+ if (raw2 === undefined)
132035
+ return;
131587
132036
  return raw2 === "true" || raw2 === "1";
131588
132037
  }
132038
+ function envPositiveInt(raw2) {
132039
+ if (raw2 === undefined || raw2 === "")
132040
+ return;
132041
+ const parsed = parsePositiveIntEnv(raw2, NaN);
132042
+ return Number.isNaN(parsed) ? undefined : parsed;
132043
+ }
131589
132044
 
131590
132045
  class Scheduler {
131591
132046
  store;
@@ -131599,9 +132054,10 @@ class Scheduler {
131599
132054
  started = false;
131600
132055
  constructor(opts = {}) {
131601
132056
  this.store = opts.store ?? getScheduledJobStore();
131602
- this.tickIntervalMs = opts.tickIntervalMs ?? parsePositiveIntEnv(process.env.MASSA_AI_SCHEDULER_TICK_MS, DEFAULTS.tickMs);
131603
- this.maxConcurrent = opts.maxConcurrent ?? parsePositiveIntEnv(process.env.MASSA_AI_SCHEDULER_MAX_CONCURRENT, DEFAULTS.maxConcurrent);
131604
- this.enabled = opts.enabled ?? readEnabled();
132057
+ const schedulerConfig = config.get("scheduler");
132058
+ this.tickIntervalMs = opts.tickIntervalMs ?? envPositiveInt(process.env.MASSA_AI_SCHEDULER_TICK_MS) ?? schedulerConfig?.tickMs ?? DEFAULTS.tickMs;
132059
+ this.maxConcurrent = opts.maxConcurrent ?? envPositiveInt(process.env.MASSA_AI_SCHEDULER_MAX_CONCURRENT) ?? schedulerConfig?.maxConcurrent ?? DEFAULTS.maxConcurrent;
132060
+ this.enabled = opts.enabled ?? readEnabledEnv() ?? schedulerConfig?.enabled ?? false;
131605
132061
  }
131606
132062
  registerHandler(jobKind, handler) {
131607
132063
  this.handlers.set(jobKind, handler);
@@ -132965,21 +133421,31 @@ var init_observation_consolidation_job = __esm(() => {
132965
133421
  });
132966
133422
 
132967
133423
  // ../../packages/core/dist/services/scheduler/scheduler-defaults.js
132968
- function envBool2(key, fallback) {
133424
+ function envBool2(key, fileValue, fallback) {
132969
133425
  const raw2 = process.env[key];
132970
133426
  if (raw2 === undefined)
132971
- return fallback;
133427
+ return fileValue ?? fallback;
132972
133428
  return raw2 === "true" || raw2 === "1";
132973
133429
  }
132974
- function envNum2(key, fallback) {
133430
+ function envNum2(key, fileValue, fallback) {
132975
133431
  const raw2 = process.env[key];
132976
- if (raw2 === undefined || raw2 === "")
132977
- return fallback;
132978
- const n2 = Number(raw2);
132979
- return Number.isFinite(n2) && n2 > 0 ? n2 : fallback;
133432
+ if (raw2 !== undefined && raw2 !== "") {
133433
+ const n2 = Number(raw2);
133434
+ if (Number.isFinite(n2) && n2 > 0)
133435
+ return n2;
133436
+ }
133437
+ return fileValue ?? fallback;
133438
+ }
133439
+ function readFileSchedulerJobs() {
133440
+ try {
133441
+ const raw2 = loadConfigSafe().scheduler?.jobs;
133442
+ return raw2;
133443
+ } catch {
133444
+ return;
133445
+ }
132980
133446
  }
132981
133447
  function applySafeDefaults(job) {
132982
- if (!envBool2("MASSA_AI_SCHEDULER_SAFE_DEFAULTS", false)) {
133448
+ if (!envBool2("MASSA_AI_SCHEDULER_SAFE_DEFAULTS", undefined, false)) {
132983
133449
  return job;
132984
133450
  }
132985
133451
  if (job.jobKind === "memory-consolidation") {
@@ -133026,10 +133492,12 @@ function registerDefaultJobs(scheduler) {
133026
133492
  const count = CheckpointManager2.getInstance().purgeExpired();
133027
133493
  logger.info("Scheduled checkpoint purge completed", { count });
133028
133494
  });
133495
+ const fileJobs = readFileSchedulerJobs();
133029
133496
  for (const rawDef of DEFAULT_SCHEDULED_JOBS) {
133030
133497
  const def = applySafeDefaults(rawDef);
133031
- const enabled2 = envBool2(def.enableEnvVar, def.defaultEnabled);
133032
- const intervalMs = envNum2(def.intervalEnvVar, def.schedule.intervalMs ?? THIRTY_MIN);
133498
+ const fileJob = fileJobs?.[def.jobKind];
133499
+ const enabled2 = envBool2(def.enableEnvVar, fileJob?.enabled, def.defaultEnabled);
133500
+ const intervalMs = envNum2(def.intervalEnvVar, fileJob?.intervalMs, def.schedule.intervalMs ?? THIRTY_MIN);
133033
133501
  const schedule = { type: "interval", intervalMs };
133034
133502
  scheduler.registerOrResumeJob({
133035
133503
  id: def.id,
@@ -133110,9 +133578,9 @@ var init_scheduler2 = __esm(() => {
133110
133578
  });
133111
133579
 
133112
133580
  // ../../packages/core/dist/services/pricing/models-dev-client.js
133113
- import fs20 from "fs/promises";
133581
+ import fs21 from "fs/promises";
133114
133582
  import { existsSync as existsSync4 } from "fs";
133115
- import path32 from "path";
133583
+ import path34 from "path";
133116
133584
  function getModelsDevClient() {
133117
133585
  if (!clientInstance) {
133118
133586
  clientInstance = new ModelsDevClient;
@@ -133132,7 +133600,7 @@ var init_models_dev_client = __esm(() => {
133132
133600
  memoryCacheTimestamp = 0;
133133
133601
  getLocalCachePath() {
133134
133602
  const dataDir = config.get("dataDir");
133135
- return path32.join(dataDir, ModelsDevClient.LOCAL_CACHE_FILE);
133603
+ return path34.join(dataDir, ModelsDevClient.LOCAL_CACHE_FILE);
133136
133604
  }
133137
133605
  async loadLocalCache() {
133138
133606
  const cachePath = this.getLocalCachePath();
@@ -133140,7 +133608,7 @@ var init_models_dev_client = __esm(() => {
133140
133608
  if (!existsSync4(cachePath)) {
133141
133609
  return null;
133142
133610
  }
133143
- const content = await fs20.readFile(cachePath, "utf-8");
133611
+ const content = await fs21.readFile(cachePath, "utf-8");
133144
133612
  const data = JSON.parse(content);
133145
133613
  const age = Date.now() - data.timestamp;
133146
133614
  if (age > ModelsDevClient.LOCAL_CACHE_TTL) {
@@ -133167,14 +133635,14 @@ var init_models_dev_client = __esm(() => {
133167
133635
  async saveLocalCache(models) {
133168
133636
  const cachePath = this.getLocalCachePath();
133169
133637
  try {
133170
- const dir = path32.dirname(cachePath);
133171
- await fs20.mkdir(dir, { recursive: true });
133638
+ const dir = path34.dirname(cachePath);
133639
+ await fs21.mkdir(dir, { recursive: true });
133172
133640
  const data = {
133173
133641
  timestamp: Date.now(),
133174
133642
  version: "1.0.0",
133175
133643
  models: Object.fromEntries(models)
133176
133644
  };
133177
- await fs20.writeFile(cachePath, JSON.stringify(data), "utf-8");
133645
+ await fs21.writeFile(cachePath, JSON.stringify(data), "utf-8");
133178
133646
  logger.debug("Saved pricing to local cache", {
133179
133647
  models: models.size,
133180
133648
  path: cachePath
@@ -133503,7 +133971,7 @@ var init_models_dev_client = __esm(() => {
133503
133971
  const cachePath = this.getLocalCachePath();
133504
133972
  try {
133505
133973
  if (existsSync4(cachePath)) {
133506
- await fs20.unlink(cachePath);
133974
+ await fs21.unlink(cachePath);
133507
133975
  logger.debug("Local pricing cache file deleted");
133508
133976
  }
133509
133977
  } catch (error51) {
@@ -139058,33 +139526,33 @@ var require_URL = __commonJS((exports, module) => {
139058
139526
  else
139059
139527
  return basepath.substring(0, lastslash + 1) + refpath;
139060
139528
  }
139061
- function remove_dot_segments(path33) {
139062
- if (!path33)
139063
- return path33;
139529
+ function remove_dot_segments(path35) {
139530
+ if (!path35)
139531
+ return path35;
139064
139532
  var output = "";
139065
- while (path33.length > 0) {
139066
- if (path33 === "." || path33 === "..") {
139067
- path33 = "";
139533
+ while (path35.length > 0) {
139534
+ if (path35 === "." || path35 === "..") {
139535
+ path35 = "";
139068
139536
  break;
139069
139537
  }
139070
- var twochars = path33.substring(0, 2);
139071
- var threechars = path33.substring(0, 3);
139072
- var fourchars = path33.substring(0, 4);
139538
+ var twochars = path35.substring(0, 2);
139539
+ var threechars = path35.substring(0, 3);
139540
+ var fourchars = path35.substring(0, 4);
139073
139541
  if (threechars === "../") {
139074
- path33 = path33.substring(3);
139542
+ path35 = path35.substring(3);
139075
139543
  } else if (twochars === "./") {
139076
- path33 = path33.substring(2);
139544
+ path35 = path35.substring(2);
139077
139545
  } else if (threechars === "/./") {
139078
- path33 = "/" + path33.substring(3);
139079
- } else if (twochars === "/." && path33.length === 2) {
139080
- path33 = "/";
139081
- } else if (fourchars === "/../" || threechars === "/.." && path33.length === 3) {
139082
- path33 = "/" + path33.substring(4);
139546
+ path35 = "/" + path35.substring(3);
139547
+ } else if (twochars === "/." && path35.length === 2) {
139548
+ path35 = "/";
139549
+ } else if (fourchars === "/../" || threechars === "/.." && path35.length === 3) {
139550
+ path35 = "/" + path35.substring(4);
139083
139551
  output = output.replace(/\/?[^\/]*$/, "");
139084
139552
  } else {
139085
- var segment = path33.match(/(\/?([^\/]*))/)[0];
139553
+ var segment = path35.match(/(\/?([^\/]*))/)[0];
139086
139554
  output += segment;
139087
- path33 = path33.substring(segment.length);
139555
+ path35 = path35.substring(segment.length);
139088
139556
  }
139089
139557
  }
139090
139558
  return output;
@@ -151154,21 +151622,21 @@ function jsonToKeyPathChunks(value, label = "$") {
151154
151622
  walk(value, label, out);
151155
151623
  return out;
151156
151624
  }
151157
- function walk(val, path33, out) {
151625
+ function walk(val, path35, out) {
151158
151626
  if (val === null || val === undefined)
151159
151627
  return;
151160
151628
  if (Array.isArray(val)) {
151161
151629
  if (val.length === 0) {
151162
- out.push({ path: path33, content: `**${path33}** = _[]_` });
151630
+ out.push({ path: path35, content: `**${path35}** = _[]_` });
151163
151631
  return;
151164
151632
  }
151165
151633
  if (val.every((v) => v !== null && typeof v === "object")) {
151166
- val.forEach((v, i) => walk(v, `${path33}[${i}]`, out));
151634
+ val.forEach((v, i) => walk(v, `${path35}[${i}]`, out));
151167
151635
  return;
151168
151636
  }
151169
151637
  const items = val.map((v) => `- \`${String(v)}\``).join(`
151170
151638
  `);
151171
- out.push({ path: path33, content: `**${path33}**
151639
+ out.push({ path: path35, content: `**${path35}**
151172
151640
 
151173
151641
  ${items}` });
151174
151642
  return;
@@ -151176,16 +151644,16 @@ ${items}` });
151176
151644
  if (typeof val === "object") {
151177
151645
  const entries = Object.entries(val);
151178
151646
  if (entries.length === 0) {
151179
- out.push({ path: path33, content: `**${path33}** = _{}_` });
151647
+ out.push({ path: path35, content: `**${path35}** = _{}_` });
151180
151648
  return;
151181
151649
  }
151182
151650
  for (const [k2, v] of entries) {
151183
151651
  const safeKey = /^[A-Za-z_$][\w$]*$/.test(k2) ? k2 : JSON.stringify(k2);
151184
- walk(v, `${path33}.${safeKey}`, out);
151652
+ walk(v, `${path35}.${safeKey}`, out);
151185
151653
  }
151186
151654
  return;
151187
151655
  }
151188
- out.push({ path: path33, content: `**${path33}** = \`${String(val)}\`` });
151656
+ out.push({ path: path35, content: `**${path35}** = \`${String(val)}\`` });
151189
151657
  }
151190
151658
  var gfm, STRIP_SELECTORS, tdCache = null;
151191
151659
  var init_html_to_md = __esm(() => {
@@ -174176,9 +174644,9 @@ async function acquireIndexingLease(request) {
174176
174644
 
174177
174645
  // ../../packages/core/dist/services/project-identity/project-root-identity.js
174178
174646
  import { realpath as realpath2 } from "fs/promises";
174179
- import path25 from "path";
174647
+ import path27 from "path";
174180
174648
  async function canonicalizeProjectRoot(projectPath, canonicalize = realpath2) {
174181
- return canonicalize(path25.resolve(projectPath));
174649
+ return canonicalize(path27.resolve(projectPath));
174182
174650
  }
174183
174651
  async function assertProjectRootReuse(options) {
174184
174652
  if (!options.storedProjectPath || options.forceReindex)
@@ -174186,9 +174654,9 @@ async function assertProjectRootReuse(options) {
174186
174654
  const canonicalize = options.canonicalize ?? realpath2;
174187
174655
  let storedCanonical;
174188
174656
  try {
174189
- storedCanonical = await canonicalize(path25.resolve(options.storedProjectPath));
174657
+ storedCanonical = await canonicalize(path27.resolve(options.storedProjectPath));
174190
174658
  } catch {
174191
- storedCanonical = path25.resolve(options.storedProjectPath);
174659
+ storedCanonical = path27.resolve(options.storedProjectPath);
174192
174660
  }
174193
174661
  if (storedCanonical !== options.canonicalProjectPath) {
174194
174662
  throw new Error(`Project ID "${options.projectId}" already indexes canonical root ` + `"${storedCanonical}", not "${options.canonicalProjectPath}"; ` + "use forceReindex only after verifying ownership of the existing project");
@@ -174198,7 +174666,7 @@ async function assertProjectRootReuse(options) {
174198
174666
  // ../../packages/core/dist/tools/index_project.js
174199
174667
  init_workspace_manager();
174200
174668
  init_parser_readiness();
174201
- import path27 from "path";
174669
+ import path29 from "path";
174202
174670
 
174203
174671
  class IndexProjectTool {
174204
174672
  name = "index_project";
@@ -174246,7 +174714,7 @@ class IndexProjectTool {
174246
174714
  try {
174247
174715
  await assertParserReadyForIndexing();
174248
174716
  const canonicalProjectPath = await canonicalizeProjectRoot(projectPath);
174249
- const finalProjectId = projectId || path27.basename(canonicalProjectPath) || "default";
174717
+ const finalProjectId = projectId || path29.basename(canonicalProjectPath) || "default";
174250
174718
  const existing = await workspaceManager.getWorkspace(finalProjectId);
174251
174719
  await assertProjectRootReuse({
174252
174720
  projectId: finalProjectId,
@@ -174800,17 +175268,17 @@ function applyReplacer(root, replacer) {
174800
175268
  return transformChildren(root, replacer, []);
174801
175269
  return transformChildren(normalizeValue(replacedRoot), replacer, []);
174802
175270
  }
174803
- function transformChildren(value, replacer, path28) {
175271
+ function transformChildren(value, replacer, path30) {
174804
175272
  if (isJsonObject(value))
174805
- return transformObject(value, replacer, path28);
175273
+ return transformObject(value, replacer, path30);
174806
175274
  if (isJsonArray(value))
174807
- return transformArray(value, replacer, path28);
175275
+ return transformArray(value, replacer, path30);
174808
175276
  return value;
174809
175277
  }
174810
- function transformObject(obj, replacer, path28) {
175278
+ function transformObject(obj, replacer, path30) {
174811
175279
  const result = {};
174812
175280
  for (const [key, value] of Object.entries(obj)) {
174813
- const childPath = [...path28, key];
175281
+ const childPath = [...path30, key];
174814
175282
  const replacedValue = replacer(key, value, childPath);
174815
175283
  if (replacedValue === undefined)
174816
175284
  continue;
@@ -174818,11 +175286,11 @@ function transformObject(obj, replacer, path28) {
174818
175286
  }
174819
175287
  return result;
174820
175288
  }
174821
- function transformArray(arr, replacer, path28) {
175289
+ function transformArray(arr, replacer, path30) {
174822
175290
  const result = [];
174823
175291
  for (let i = 0;i < arr.length; i++) {
174824
175292
  const value = arr[i];
174825
- const childPath = [...path28, i];
175293
+ const childPath = [...path30, i];
174826
175294
  const replacedValue = replacer(String(i), value, childPath);
174827
175295
  if (replacedValue === undefined)
174828
175296
  continue;
@@ -176203,9 +176671,9 @@ init_dist();
176203
176671
  init_db_connection();
176204
176672
  init_alias_resolver();
176205
176673
  init_safe_error_summary();
176206
- import fs17 from "fs";
176207
- import os6 from "os";
176208
- import path28 from "path";
176674
+ import fs18 from "fs";
176675
+ import os8 from "os";
176676
+ import path30 from "path";
176209
176677
 
176210
176678
  // ../../packages/core/dist/services/hooks/session-pin-store.js
176211
176679
  var DEFAULT_MAX_SIZE = 1000;
@@ -176304,8 +176772,8 @@ class AttributionResolver {
176304
176772
  this.aliasResolver = options.aliasResolver ?? getProjectIdentityAliasResolver();
176305
176773
  this.pins = options.pins ?? new SessionPinStore;
176306
176774
  this.canonicalize = options.canonicalize ?? defaultCanonicalize;
176307
- this.homedir = options.homedir ?? os6.homedir;
176308
- this.fsRoot = options.fsRoot ?? (() => path28.parse(path28.sep).root);
176775
+ this.homedir = options.homedir ?? os8.homedir;
176776
+ this.fsRoot = options.fsRoot ?? (() => path30.parse(path30.sep).root);
176309
176777
  }
176310
176778
  async resolve(input) {
176311
176779
  const caller = input.callerProjectId;
@@ -176356,7 +176824,7 @@ class AttributionResolver {
176356
176824
  }
176357
176825
  let bestPath = null;
176358
176826
  for (const candidate2 of byPath.keys()) {
176359
- if (canonicalCwd === candidate2 || canonicalCwd.startsWith(candidate2.endsWith(path28.sep) ? candidate2 : candidate2 + path28.sep)) {
176827
+ if (canonicalCwd === candidate2 || canonicalCwd.startsWith(candidate2.endsWith(path30.sep) ? candidate2 : candidate2 + path30.sep)) {
176360
176828
  if (bestPath === null || candidate2.length > bestPath.length) {
176361
176829
  bestPath = candidate2;
176362
176830
  }
@@ -176379,7 +176847,7 @@ class AttributionResolver {
176379
176847
  return projectPath2;
176380
176848
  const fsRoot = this.fsRoot();
176381
176849
  let normalized = projectPath2;
176382
- while (normalized.length > fsRoot.length && normalized.endsWith(path28.sep)) {
176850
+ while (normalized.length > fsRoot.length && normalized.endsWith(path30.sep)) {
176383
176851
  normalized = normalized.slice(0, -1);
176384
176852
  }
176385
176853
  return normalized;
@@ -176387,10 +176855,10 @@ class AttributionResolver {
176387
176855
  }
176388
176856
  function defaultCanonicalize(cwd) {
176389
176857
  try {
176390
- return fs17.realpathSync(cwd);
176858
+ return fs18.realpathSync(cwd);
176391
176859
  } catch {
176392
176860
  try {
176393
- return path28.resolve(cwd);
176861
+ return path30.resolve(cwd);
176394
176862
  } catch {
176395
176863
  return;
176396
176864
  }
@@ -176927,7 +177395,7 @@ init_code_compressor();
176927
177395
 
176928
177396
  // ../../packages/core/dist/services/file-read/file-content-cache.js
176929
177397
  init_dist();
176930
- import fs18 from "fs/promises";
177398
+ import fs19 from "fs/promises";
176931
177399
 
176932
177400
  class FileContentCache {
176933
177401
  extractMetadata;
@@ -176960,7 +177428,7 @@ class FileContentCache {
176960
177428
  metadata: cached2.metadata
176961
177429
  };
176962
177430
  }
176963
- const content = await fs18.readFile(filePath, "utf-8");
177431
+ const content = await fs19.readFile(filePath, "utf-8");
176964
177432
  const metadata = await this.extractMetadata(content, filePath, options);
176965
177433
  evictOldest(this.fileCache, this.FILE_CACHE_MAX_ENTRIES - 1);
176966
177434
  this.fileCache.set(cacheKey, {
@@ -176975,7 +177443,7 @@ class FileContentCache {
176975
177443
 
176976
177444
  // ../../packages/core/dist/services/file-read/file-metadata.js
176977
177445
  init_dist();
176978
- import path29 from "path";
177446
+ import path31 from "path";
176979
177447
 
176980
177448
  class FileMetadataExtractor {
176981
177449
  symbolGraph;
@@ -177011,7 +177479,7 @@ class FileMetadataExtractor {
177011
177479
  return metadata;
177012
177480
  }
177013
177481
  detectLanguage(filePath) {
177014
- const ext2 = path29.extname(filePath).toLowerCase();
177482
+ const ext2 = path31.extname(filePath).toLowerCase();
177015
177483
  const languageMap2 = {
177016
177484
  ".ts": "TypeScript",
177017
177485
  ".tsx": "TypeScript",
@@ -177128,7 +177596,7 @@ function selectLines(lines, range) {
177128
177596
 
177129
177597
  // ../../packages/core/dist/services/file-read/path-containment.js
177130
177598
  init_dist();
177131
- import path30 from "path";
177599
+ import path32 from "path";
177132
177600
 
177133
177601
  class PathContainment {
177134
177602
  projectRoots;
@@ -177136,14 +177604,14 @@ class PathContainment {
177136
177604
  this.projectRoots = projectRoots;
177137
177605
  }
177138
177606
  async resolveFilePath(filePath, projectId) {
177139
- if (path30.isAbsolute(filePath)) {
177140
- return path30.resolve(filePath);
177607
+ if (path32.isAbsolute(filePath)) {
177608
+ return path32.resolve(filePath);
177141
177609
  }
177142
177610
  if (projectId) {
177143
177611
  const root = await this.projectRoots.getProjectRoot(projectId);
177144
177612
  if (root) {
177145
177613
  const cleaned = sanitizeFilePath(filePath);
177146
- return path30.resolve(root, cleaned);
177614
+ return path32.resolve(root, cleaned);
177147
177615
  }
177148
177616
  return null;
177149
177617
  }
@@ -177154,17 +177622,17 @@ class PathContainment {
177154
177622
  if (projectId) {
177155
177623
  const root = await this.projectRoots.getProjectRoot(projectId);
177156
177624
  if (root)
177157
- roots.push(path30.resolve(root));
177625
+ roots.push(path32.resolve(root));
177158
177626
  }
177159
- roots.push(path30.resolve(process.cwd()));
177627
+ roots.push(path32.resolve(process.cwd()));
177160
177628
  const envRoots = (process.env.MASSA_AI_READ_FILE_ROOTS ?? "").split(":").map((s) => s.trim()).filter((s) => s.length > 0);
177161
177629
  for (const extra of envRoots) {
177162
- roots.push(path30.resolve(extra));
177630
+ roots.push(path32.resolve(extra));
177163
177631
  }
177164
- const target = path30.resolve(absoluteFilePath);
177632
+ const target = path32.resolve(absoluteFilePath);
177165
177633
  for (const root of roots) {
177166
- const rel = path30.relative(root, target);
177167
- if (rel !== "" && !rel.startsWith("..") && !path30.isAbsolute(rel)) {
177634
+ const rel = path32.relative(root, target);
177635
+ if (rel !== "" && !rel.startsWith("..") && !path32.isAbsolute(rel)) {
177168
177636
  return { allowed: true };
177169
177637
  }
177170
177638
  if (rel === "")
@@ -178001,8 +178469,8 @@ init_event_bus();
178001
178469
  init_llm_client();
178002
178470
  init_symbol_graph_service();
178003
178471
  import { randomUUID as randomUUID9 } from "crypto";
178004
- import fs21 from "fs";
178005
- import path33 from "path";
178472
+ import fs22 from "fs";
178473
+ import path35 from "path";
178006
178474
  import { spawn as spawn2 } from "child_process";
178007
178475
  var FALLBACK_BOOTSTRAP = {
178008
178476
  enabled: true,
@@ -178186,9 +178654,9 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
178186
178654
  }
178187
178655
  try {
178188
178656
  for (const name26 of README_CANDIDATES) {
178189
- const p = path33.join(projectRoot, name26);
178190
- if (fs21.existsSync(p) && fs21.statSync(p).isFile()) {
178191
- const buf = fs21.readFileSync(p);
178657
+ const p = path35.join(projectRoot, name26);
178658
+ if (fs22.existsSync(p) && fs22.statSync(p).isFile()) {
178659
+ const buf = fs22.readFileSync(p);
178192
178660
  signals.readme = buf.slice(0, MAX_README_BYTES).toString("utf8");
178193
178661
  break;
178194
178662
  }
@@ -178197,14 +178665,14 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
178197
178665
  logger.debug("bootstrap scan: README read failed", { error: e.message });
178198
178666
  }
178199
178667
  try {
178200
- const docsDir = path33.join(projectRoot, "docs");
178201
- if (fs21.existsSync(docsDir) && fs21.statSync(docsDir).isDirectory()) {
178668
+ const docsDir = path35.join(projectRoot, "docs");
178669
+ if (fs22.existsSync(docsDir) && fs22.statSync(docsDir).isDirectory()) {
178202
178670
  const entries = walkMarkdown(docsDir).slice(0, MAX_DOCS);
178203
178671
  for (const rel of entries) {
178204
178672
  try {
178205
- const buf = fs21.readFileSync(rel);
178673
+ const buf = fs22.readFileSync(rel);
178206
178674
  signals.docs.push({
178207
- path: path33.relative(projectRoot, rel),
178675
+ path: path35.relative(projectRoot, rel),
178208
178676
  snippet: buf.slice(0, MAX_DOC_BYTES).toString("utf8")
178209
178677
  });
178210
178678
  } catch {}
@@ -178215,10 +178683,10 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
178215
178683
  }
178216
178684
  try {
178217
178685
  for (const name26 of MANIFEST_FILES) {
178218
- const p = path33.join(projectRoot, name26);
178219
- if (!fs21.existsSync(p) || !fs21.statSync(p).isFile())
178686
+ const p = path35.join(projectRoot, name26);
178687
+ if (!fs22.existsSync(p) || !fs22.statSync(p).isFile())
178220
178688
  continue;
178221
- const raw2 = fs21.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
178689
+ const raw2 = fs22.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
178222
178690
  const kind = name26;
178223
178691
  if (name26 === "package.json") {
178224
178692
  try {
@@ -178258,12 +178726,12 @@ function walkMarkdown(dir) {
178258
178726
  const cur = stack.pop();
178259
178727
  let entries;
178260
178728
  try {
178261
- entries = fs21.readdirSync(cur, { withFileTypes: true });
178729
+ entries = fs22.readdirSync(cur, { withFileTypes: true });
178262
178730
  } catch {
178263
178731
  continue;
178264
178732
  }
178265
178733
  for (const e of entries) {
178266
- const full = path33.join(cur, e.name);
178734
+ const full = path35.join(cur, e.name);
178267
178735
  if (e.isDirectory()) {
178268
178736
  if (e.name === "node_modules" || e.name.startsWith("."))
178269
178737
  continue;
@@ -179332,8 +179800,8 @@ var checkpointRoutes = new Elysia({ prefix: "/api/v1/checkpoints" }).post("/list
179332
179800
 
179333
179801
  // src/routes/project.ts
179334
179802
  init_dist();
179335
- import fs22 from "fs/promises";
179336
- import path34 from "path";
179803
+ import fs23 from "fs/promises";
179804
+ import path36 from "path";
179337
179805
  function isDimensionMismatchError(error51) {
179338
179806
  const message = error51 instanceof Error ? error51.message : String(error51);
179339
179807
  return /dimension mismatch/i.test(message);
@@ -179553,22 +180021,22 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
179553
180021
  }).post("/upload-and-index", async ({ body }) => {
179554
180022
  const rawBase = body.projectId || body.projectPath.replace(/\\/g, "/").split("/").filter(Boolean).pop() || "default";
179555
180023
  const finalProjectId = rawBase.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 128);
179556
- const uploadRoot = process.env.MASSA_AI_UPLOAD_DIR || path34.join(getGlobalDataDir(), "uploads");
179557
- const stagingDir = path34.resolve(uploadRoot, finalProjectId);
179558
- await fs22.rm(stagingDir, { recursive: true, force: true });
179559
- await fs22.mkdir(stagingDir, { recursive: true });
180024
+ const uploadRoot = process.env.MASSA_AI_UPLOAD_DIR || path36.join(getGlobalDataDir(), "uploads");
180025
+ const stagingDir = path36.resolve(uploadRoot, finalProjectId);
180026
+ await fs23.rm(stagingDir, { recursive: true, force: true });
180027
+ await fs23.mkdir(stagingDir, { recursive: true });
179560
180028
  const WRITE_BATCH = 20;
179561
180029
  for (let i = 0;i < body.files.length; i += WRITE_BATCH) {
179562
180030
  await Promise.all(body.files.slice(i, i + WRITE_BATCH).map(async (file3) => {
179563
- if (path34.isAbsolute(file3.relativePath) || file3.relativePath.includes("..")) {
180031
+ if (path36.isAbsolute(file3.relativePath) || file3.relativePath.includes("..")) {
179564
180032
  throw new Error(`Invalid file path: ${file3.relativePath}`);
179565
180033
  }
179566
- const dest = path34.resolve(stagingDir, file3.relativePath.replace(/\//g, path34.sep));
179567
- if (!dest.startsWith(stagingDir + path34.sep)) {
180034
+ const dest = path36.resolve(stagingDir, file3.relativePath.replace(/\//g, path36.sep));
180035
+ if (!dest.startsWith(stagingDir + path36.sep)) {
179568
180036
  throw new Error(`Path escapes staging directory: ${file3.relativePath}`);
179569
180037
  }
179570
- await fs22.mkdir(path34.dirname(dest), { recursive: true });
179571
- await fs22.writeFile(dest, file3.content, "utf-8");
180038
+ await fs23.mkdir(path36.dirname(dest), { recursive: true });
180039
+ await fs23.writeFile(dest, file3.content, "utf-8");
179572
180040
  }));
179573
180041
  }
179574
180042
  return await getIndexProjectTool().handle({
@@ -179722,9 +180190,9 @@ var analyticsRoutes = new Elysia({ prefix: "/api/v1/analytics" }).post("/", asyn
179722
180190
 
179723
180191
  // src/routes/system.ts
179724
180192
  init_dist();
179725
- import path35 from "path";
179726
- import fs23 from "fs";
179727
- import os7 from "os";
180193
+ import path37 from "path";
180194
+ import fs24 from "fs";
180195
+ import os9 from "os";
179728
180196
  function databaseUrlParts() {
179729
180197
  const url2 = new URL(process.env.DATABASE_URL);
179730
180198
  return {
@@ -179755,13 +180223,13 @@ var systemRoutes = new Elysia({ prefix: "/api/v1/system" }).get("/info", async (
179755
180223
  version: "1.0.0",
179756
180224
  service: "massa-ai-tools-api",
179757
180225
  node: process.version,
179758
- platform: os7.platform(),
179759
- arch: os7.arch(),
180226
+ platform: os9.platform(),
180227
+ arch: os9.arch(),
179760
180228
  uptime: process.uptime(),
179761
180229
  memory: {
179762
- total: os7.totalmem(),
179763
- free: os7.freemem(),
179764
- used: os7.totalmem() - os7.freemem(),
180230
+ total: os9.totalmem(),
180231
+ free: os9.freemem(),
180232
+ used: os9.totalmem() - os9.freemem(),
179765
180233
  process: process.memoryUsage()
179766
180234
  },
179767
180235
  dataDir: config.get("dataDir"),
@@ -179797,11 +180265,11 @@ var systemRoutes = new Elysia({ prefix: "/api/v1/system" }).get("/info", async (
179797
180265
  description: "Check PostgreSQL, pgvector, Ollama, and local artifact directory health"
179798
180266
  }
179799
180267
  }).get("/metrics", async () => {
179800
- const metricsPath = path35.join(process.cwd(), "data", "metrics.json");
180268
+ const metricsPath = path37.join(process.cwd(), "data", "metrics.json");
179801
180269
  let metrics2 = {};
179802
- if (fs23.existsSync(metricsPath)) {
180270
+ if (fs24.existsSync(metricsPath)) {
179803
180271
  try {
179804
- metrics2 = JSON.parse(fs23.readFileSync(metricsPath, "utf-8"));
180272
+ metrics2 = JSON.parse(fs24.readFileSync(metricsPath, "utf-8"));
179805
180273
  } catch {}
179806
180274
  }
179807
180275
  const database = await getDatabaseInfo();
@@ -179951,8 +180419,8 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
179951
180419
  });
179952
180420
 
179953
180421
  // src/routes/workspace.ts
179954
- import fs24 from "fs/promises";
179955
- import path36 from "path";
180422
+ import fs25 from "fs/promises";
180423
+ import path38 from "path";
179956
180424
  import { realpathSync as realpathSync4 } from "fs";
179957
180425
  var indexProjectTool2 = null;
179958
180426
  function getIndexProjectTool2() {
@@ -179994,7 +180462,7 @@ function realpathSafe(p) {
179994
180462
  try {
179995
180463
  return realpathSync4(p);
179996
180464
  } catch {
179997
- return path36.resolve(p);
180465
+ return path38.resolve(p);
179998
180466
  }
179999
180467
  }
180000
180468
  var graphController = null;
@@ -180345,8 +180813,8 @@ var workspaceRoutes = new Elysia({ prefix: "/api/v1" }).get("/workspace/list", a
180345
180813
  }
180346
180814
  const registeredRoot = realpathSafe(workspace.project_path);
180347
180815
  const callerRoot = realpathSafe(projectPath2);
180348
- const rel = path36.relative(registeredRoot, callerRoot);
180349
- const escapes = rel.startsWith("..") || path36.isAbsolute(rel);
180816
+ const rel = path38.relative(registeredRoot, callerRoot);
180817
+ const escapes = rel.startsWith("..") || path38.isAbsolute(rel);
180350
180818
  if (registeredRoot !== callerRoot && escapes) {
180351
180819
  return {
180352
180820
  success: false,
@@ -180476,8 +180944,8 @@ var workspaceRoutes = new Elysia({ prefix: "/api/v1" }).get("/workspace/list", a
180476
180944
  } else {
180477
180945
  end = start + 20;
180478
180946
  }
180479
- const absolutePath = path36.join(workspace.project_path, file3);
180480
- const content = await fs24.readFile(absolutePath, "utf-8");
180947
+ const absolutePath = path38.join(workspace.project_path, file3);
180948
+ const content = await fs25.readFile(absolutePath, "utf-8");
180481
180949
  const lines = content.split(/\r?\n/);
180482
180950
  const slice = lines.slice(start - 1, Math.min(lines.length, end));
180483
180951
  const formatted = slice.map((text3, idx) => ({
@@ -181402,8 +181870,8 @@ var webRoutes = new Elysia({ prefix: "/api/v1/web" }).post("/fetch_and_index", a
181402
181870
  });
181403
181871
 
181404
181872
  // src/routes/web-ui.ts
181405
- import fs25 from "fs/promises";
181406
- import path37 from "path";
181873
+ import fs26 from "fs/promises";
181874
+ import path39 from "path";
181407
181875
  import { fileURLToPath as fileURLToPath3 } from "url";
181408
181876
 
181409
181877
  // src/web-ui-trust.ts
@@ -181447,9 +181915,9 @@ function buildStaticDirCandidates(moduleDir, cwd) {
181447
181915
  for (const root2 of [moduleDir, cwd]) {
181448
181916
  let dir = root2;
181449
181917
  for (let i = 0;i < 10; i++) {
181450
- candidates2.push(path37.resolve(dir, "apps/web-ui/src/static"));
181451
- candidates2.push(path37.resolve(dir, "web-ui/src/static"));
181452
- const parent = path37.dirname(dir);
181918
+ candidates2.push(path39.resolve(dir, "apps/web-ui/src/static"));
181919
+ candidates2.push(path39.resolve(dir, "web-ui/src/static"));
181920
+ const parent = path39.dirname(dir);
181453
181921
  if (parent === dir)
181454
181922
  break;
181455
181923
  dir = parent;
@@ -181457,11 +181925,11 @@ function buildStaticDirCandidates(moduleDir, cwd) {
181457
181925
  }
181458
181926
  return [...new Set(candidates2)];
181459
181927
  }
181460
- var STATIC_DIR_CANDIDATES = buildStaticDirCandidates(path37.dirname(fileURLToPath3(import.meta.url)), process.cwd());
181928
+ var STATIC_DIR_CANDIDATES = buildStaticDirCandidates(path39.dirname(fileURLToPath3(import.meta.url)), process.cwd());
181461
181929
  async function resolveStaticDir() {
181462
181930
  for (const dir of STATIC_DIR_CANDIDATES) {
181463
181931
  try {
181464
- const st = await fs25.stat(dir);
181932
+ const st = await fs26.stat(dir);
181465
181933
  if (st.isDirectory())
181466
181934
  return dir;
181467
181935
  } catch {}
@@ -181482,7 +181950,7 @@ var CONTENT_TYPES = {
181482
181950
  ".woff2": "font/woff2"
181483
181951
  };
181484
181952
  function contentTypeFor(filePath) {
181485
- const ext2 = path37.extname(filePath).toLowerCase();
181953
+ const ext2 = path39.extname(filePath).toLowerCase();
181486
181954
  return CONTENT_TYPES[ext2] ?? "application/octet-stream";
181487
181955
  }
181488
181956
  function webUiDisabled() {
@@ -181493,13 +181961,13 @@ function webUiDisabled() {
181493
181961
  }
181494
181962
  async function resolveSafePath(staticDir, sub) {
181495
181963
  const cleaned = sub.replace(/^\/+/, "");
181496
- const abs = path37.resolve(staticDir, cleaned);
181497
- const rel = path37.relative(staticDir, abs);
181498
- if (rel.startsWith("..") || path37.isAbsolute(rel)) {
181964
+ const abs = path39.resolve(staticDir, cleaned);
181965
+ const rel = path39.relative(staticDir, abs);
181966
+ if (rel.startsWith("..") || path39.isAbsolute(rel)) {
181499
181967
  return null;
181500
181968
  }
181501
181969
  try {
181502
- await fs25.stat(abs);
181970
+ await fs26.stat(abs);
181503
181971
  return { abs, exists: true };
181504
181972
  } catch {
181505
181973
  return { abs, exists: false };
@@ -181522,7 +181990,7 @@ function injectAccessMarkup(html, apiKey, trusted) {
181522
181990
  return out;
181523
181991
  }
181524
181992
  async function readShell(indexPath, remoteAddress) {
181525
- const raw2 = await fs25.readFile(indexPath, "utf-8");
181993
+ const raw2 = await fs26.readFile(indexPath, "utf-8");
181526
181994
  const trusted = isTrustedWebUiCaller(remoteAddress);
181527
181995
  return Buffer.from(injectAccessMarkup(raw2, getConfiguredApiKey(), trusted), "utf-8");
181528
181996
  }
@@ -181539,7 +182007,7 @@ var webUiRoutes = new Elysia().get("/ui", async ({ set: set3, request }) => {
181539
182007
  set3.status = 500;
181540
182008
  return { status: 500, error: "web ui static dir not found" };
181541
182009
  }
181542
- const indexPath = path37.join(dir, "index.html");
182010
+ const indexPath = path39.join(dir, "index.html");
181543
182011
  try {
181544
182012
  const body = await readShell(indexPath, remoteAddressOf(request));
181545
182013
  set3.headers["content-type"] = contentTypeFor(indexPath);
@@ -181572,7 +182040,7 @@ var webUiRoutes = new Elysia().get("/ui", async ({ set: set3, request }) => {
181572
182040
  }
181573
182041
  if (resolved.exists) {
181574
182042
  try {
181575
- const body = await fs25.readFile(resolved.abs);
182043
+ const body = await fs26.readFile(resolved.abs);
181576
182044
  set3.headers["content-type"] = contentTypeFor(resolved.abs);
181577
182045
  return body;
181578
182046
  } catch {
@@ -181581,7 +182049,7 @@ var webUiRoutes = new Elysia().get("/ui", async ({ set: set3, request }) => {
181581
182049
  }
181582
182050
  }
181583
182051
  try {
181584
- const body = await readShell(path37.join(dir, "index.html"), remoteAddressOf(request));
182052
+ const body = await readShell(path39.join(dir, "index.html"), remoteAddressOf(request));
181585
182053
  set3.headers["content-type"] = "text/html; charset=utf-8";
181586
182054
  return body;
181587
182055
  } catch {
@@ -181729,8 +182197,8 @@ init_dist();
181729
182197
 
181730
182198
  // src/routes/model-registry-deployment.ts
181731
182199
  init_dist();
181732
- import path38 from "path";
181733
- var MARKER = path38.join("scripts", "generate-subagent-artifacts.ts");
182200
+ import path40 from "path";
182201
+ var MARKER = path40.join("scripts", "generate-subagent-artifacts.ts");
181734
182202
  var MAX_LEVELS2 = 6;
181735
182203
  var cachedRoot;
181736
182204
  function findDeploymentRoot(startDir) {
@@ -181748,8 +182216,8 @@ function deploymentUnavailableMessage(what) {
181748
182216
 
181749
182217
  // src/routes/model-registry.ts
181750
182218
  init_config();
181751
- import fs26 from "fs";
181752
- import path39 from "path";
182219
+ import fs27 from "fs";
182220
+ import path41 from "path";
181753
182221
  import { spawnSync } from "child_process";
181754
182222
  var _profilesLib = null;
181755
182223
  function profilesLib() {
@@ -181758,7 +182226,7 @@ function profilesLib() {
181758
182226
  if (!root2) {
181759
182227
  throw new Error(deploymentUnavailableMessage("scripts/lib/model-profiles.ts"));
181760
182228
  }
181761
- const libPath = path39.join(root2, "scripts", "lib", "model-profiles.ts");
182229
+ const libPath = path41.join(root2, "scripts", "lib", "model-profiles.ts");
181762
182230
  _profilesLib = __require(libPath);
181763
182231
  }
181764
182232
  return _profilesLib;
@@ -181783,7 +182251,7 @@ function generatorLib() {
181783
182251
  if (!root2) {
181784
182252
  throw new Error(deploymentUnavailableMessage("scripts/generate-subagent-artifacts.ts"));
181785
182253
  }
181786
- const libPath = path39.join(root2, "scripts", "generate-subagent-artifacts.ts");
182254
+ const libPath = path41.join(root2, "scripts", "generate-subagent-artifacts.ts");
181787
182255
  _generatorLib = __require(libPath);
181788
182256
  }
181789
182257
  return _generatorLib;
@@ -181800,7 +182268,7 @@ async function loadAgentsInventory() {
181800
182268
  var REGISTRY_DETAIL = {
181801
182269
  tags: ["model-registry"]
181802
182270
  };
181803
- var OVERLAY_PATH = path39.join(configDir("massa-ai"), "model-profiles.json");
182271
+ var OVERLAY_PATH = path41.join(configDir("massa-ai"), "model-profiles.json");
181804
182272
  var modelRegistryRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).get("/", async ({ set: set3 }) => {
181805
182273
  const root2 = getDeploymentRoot();
181806
182274
  if (!root2) {
@@ -181883,7 +182351,7 @@ var modelRegistryRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).get("
181883
182351
  set3.status = 501;
181884
182352
  return { success: false, error: deploymentUnavailableMessage("scripts/generate-subagent-artifacts.ts") };
181885
182353
  }
181886
- const generateScript = path39.join(root2, "scripts", "generate-subagent-artifacts.ts");
182354
+ const generateScript = path41.join(root2, "scripts", "generate-subagent-artifacts.ts");
181887
182355
  try {
181888
182356
  const child = spawnSync("bun", [generateScript], {
181889
182357
  env: { ...process.env },
@@ -181922,8 +182390,8 @@ var modelRegistryRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).get("
181922
182390
  }
181923
182391
  const lib = profilesLib();
181924
182392
  try {
181925
- if (fs26.existsSync(OVERLAY_PATH)) {
181926
- fs26.unlinkSync(OVERLAY_PATH);
182393
+ if (fs27.existsSync(OVERLAY_PATH)) {
182394
+ fs27.unlinkSync(OVERLAY_PATH);
181927
182395
  }
181928
182396
  const builtin = lib.loadRegistry(lib.DEFAULT_REGISTRY_PATH);
181929
182397
  set3.status = 200;
@@ -181949,17 +182417,17 @@ var modelRegistryRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).get("
181949
182417
  }
181950
182418
  });
181951
182419
  function writeOverlayAtomically(overlayPath, data) {
181952
- const dir = path39.dirname(overlayPath);
181953
- if (!fs26.existsSync(dir)) {
181954
- fs26.mkdirSync(dir, { recursive: true });
182420
+ const dir = path41.dirname(overlayPath);
182421
+ if (!fs27.existsSync(dir)) {
182422
+ fs27.mkdirSync(dir, { recursive: true });
181955
182423
  }
181956
182424
  const tmp = `${overlayPath}.${process.pid}.${Date.now()}.tmp`;
181957
182425
  try {
181958
- fs26.writeFileSync(tmp, JSON.stringify(data, null, 2));
181959
- fs26.renameSync(tmp, overlayPath);
182426
+ fs27.writeFileSync(tmp, JSON.stringify(data, null, 2));
182427
+ fs27.renameSync(tmp, overlayPath);
181960
182428
  } catch (e) {
181961
182429
  try {
181962
- fs26.unlinkSync(tmp);
182430
+ fs27.unlinkSync(tmp);
181963
182431
  } catch {}
181964
182432
  throw e;
181965
182433
  }
@@ -182131,7 +182599,11 @@ var configRoutes = new Elysia({ prefix: "/api/v1/config" }).get("/", ({ set: set
182131
182599
  set3.status = 200;
182132
182600
  return {
182133
182601
  success: true,
182134
- data: { config: masked, restartNeededSections: result.restartNeededSections }
182602
+ data: {
182603
+ config: masked,
182604
+ restartNeededSections: result.restartNeededSections,
182605
+ changedRestartSections: result.changedRestartSections
182606
+ }
182135
182607
  };
182136
182608
  }, {
182137
182609
  body: t.Object({}, { additionalProperties: true }),
@@ -182145,7 +182617,7 @@ var configRoutes = new Elysia({ prefix: "/api/v1/config" }).get("/", ({ set: set
182145
182617
  // src/routes/model-registry-stream.ts
182146
182618
  init_config();
182147
182619
  init_dist();
182148
- import path40 from "path";
182620
+ import path42 from "path";
182149
182621
  import { spawn as spawn3 } from "child_process";
182150
182622
  var encoder3 = new TextEncoder;
182151
182623
  function sseFrame(data) {
@@ -182227,7 +182699,7 @@ function createRegenerateStreamHandler() {
182227
182699
  closedRef.closed = true;
182228
182700
  return;
182229
182701
  }
182230
- const generateScript = path40.join(root2, "scripts", "generate-subagent-artifacts.ts");
182702
+ const generateScript = path42.join(root2, "scripts", "generate-subagent-artifacts.ts");
182231
182703
  try {
182232
182704
  child = spawn3("bun", [generateScript], {
182233
182705
  env: { ...process.env },
@@ -182321,13 +182793,422 @@ var modelRegistryStreamRoutes = new Elysia({ prefix: "/api/v1/model-registry" })
182321
182793
  }
182322
182794
  });
182323
182795
 
182796
+ // src/lifecycle.ts
182797
+ import { existsSync as existsSync5 } from "fs";
182798
+ var serverStopper = () => {};
182799
+ var jobsStopper = () => {};
182800
+ function setServerStopper(fn) {
182801
+ serverStopper = fn;
182802
+ }
182803
+ function setJobsStopper(fn) {
182804
+ jobsStopper = fn;
182805
+ }
182806
+ function defaultSeams() {
182807
+ return {
182808
+ stopServer: () => serverStopper(),
182809
+ stopJobs: () => jobsStopper(),
182810
+ disconnect: async () => {
182811
+ const { disconnectPrisma: disconnectPrisma2 } = await Promise.resolve().then(() => (init_services(), exports_services));
182812
+ await disconnectPrisma2();
182813
+ },
182814
+ spawn: (argv, opts) => {
182815
+ Bun.spawn({
182816
+ cmd: argv,
182817
+ cwd: opts.cwd,
182818
+ env: opts.env,
182819
+ stdio: ["ignore", "inherit", "inherit"]
182820
+ }).unref();
182821
+ },
182822
+ exit: (code) => process.exit(code)
182823
+ };
182824
+ }
182825
+ var testSeams = null;
182826
+ var testMode = null;
182827
+ function detectRestartMode(env6 = process.env, dockerProbe = () => existsSync5("/.dockerenv")) {
182828
+ if (testMode)
182829
+ return testMode;
182830
+ if (env6.MASSA_AI_DEV_WATCH === "1")
182831
+ return "dev-watch";
182832
+ if (env6.MASSA_AI_SUPERVISED === "1" || dockerProbe())
182833
+ return "supervised";
182834
+ return "respawn";
182835
+ }
182836
+ var armedMode = null;
182837
+ function armRestart(mode) {
182838
+ armedMode = mode;
182839
+ }
182840
+ function consumeArmedRestart() {
182841
+ const mode = armedMode;
182842
+ armedMode = null;
182843
+ return mode;
182844
+ }
182845
+ async function shutdownAndRestart(mode, seams = testSeams ?? defaultSeams()) {
182846
+ await seams.stopServer();
182847
+ seams.stopJobs();
182848
+ try {
182849
+ await seams.disconnect();
182850
+ } catch {}
182851
+ if (mode === "respawn") {
182852
+ seams.spawn([process.execPath, ...process.argv.slice(1)], {
182853
+ cwd: process.cwd(),
182854
+ env: process.env
182855
+ });
182856
+ }
182857
+ seams.exit(0);
182858
+ }
182859
+ async function gracefulShutdown(seams = testSeams ?? defaultSeams()) {
182860
+ await seams.stopServer();
182861
+ seams.stopJobs();
182862
+ try {
182863
+ await seams.disconnect();
182864
+ } catch {}
182865
+ seams.exit(0);
182866
+ }
182867
+
182868
+ // src/routes/restart.ts
182869
+ var restartRoutes = new Elysia({ prefix: "/api/v1/system" }).onAfterResponse(() => {
182870
+ const mode = consumeArmedRestart();
182871
+ if (mode)
182872
+ shutdownAndRestart(mode);
182873
+ }).post("/restart", ({ set: set3 }) => {
182874
+ const mode = detectRestartMode();
182875
+ if (mode === "dev-watch") {
182876
+ set3.status = 409;
182877
+ return {
182878
+ success: false,
182879
+ error: "restart refused",
182880
+ reason: "dev watcher active (bun --watch owns this process's lifecycle) \u2014 save a file to restart, or run without the dev script"
182881
+ };
182882
+ }
182883
+ armRestart(mode);
182884
+ set3.status = 200;
182885
+ return { success: true, restarting: true, mode };
182886
+ }, {
182887
+ detail: {
182888
+ tags: ["system"],
182889
+ summary: "Gracefully restart the API server",
182890
+ description: "Responds first, then drains (listener, job reaper, scheduler, Prisma) and exits. " + "Mode 'supervised' (MASSA_AI_SUPERVISED=1 or /.dockerenv): exit 0 and let the supervisor respawn. " + "Mode 'respawn' (no supervisor): a detached replacement with the same argv is spawned after the listener stops. " + "409 when the dev watcher owns the process (MASSA_AI_DEV_WATCH=1). " + "Poll GET /health to observe recovery."
182891
+ }
182892
+ });
182893
+
182894
+ // src/routes/logs.ts
182895
+ init_dist();
182896
+ import fs28 from "fs";
182897
+ var LOGS_DETAIL = { tags: ["logs"] };
182898
+ var MAX_SCAN_BYTES = 64 * 1024 * 1024;
182899
+ var MAX_LIMIT = 1000;
182900
+ var DEFAULT_LIMIT = 200;
182901
+ function isQueryValidationError(v) {
182902
+ return "param" in v;
182903
+ }
182904
+ function parseRangeQuery(query) {
182905
+ const fromRaw = query.from;
182906
+ const toRaw = query.to;
182907
+ const fromMs = fromRaw !== undefined ? Date.parse(fromRaw) : -Infinity;
182908
+ if (fromRaw !== undefined && Number.isNaN(fromMs)) {
182909
+ return { param: "from", message: `"from" is not a parseable ISO-8601 timestamp: "${fromRaw}"` };
182910
+ }
182911
+ const toMs = toRaw !== undefined ? Date.parse(toRaw) : Infinity;
182912
+ if (toRaw !== undefined && Number.isNaN(toMs)) {
182913
+ return { param: "to", message: `"to" is not a parseable ISO-8601 timestamp: "${toRaw}"` };
182914
+ }
182915
+ if (fromMs > toMs) {
182916
+ return { param: "from", message: `"from" (${fromRaw}) is after "to" (${toRaw})` };
182917
+ }
182918
+ let limit = DEFAULT_LIMIT;
182919
+ if (query.limit !== undefined) {
182920
+ const n2 = Number(query.limit);
182921
+ if (!Number.isFinite(n2) || n2 < 0) {
182922
+ return { param: "limit", message: `"limit" must be a non-negative number: "${query.limit}"` };
182923
+ }
182924
+ if (n2 > MAX_LIMIT) {
182925
+ return { param: "limit", message: `"limit" exceeds the maximum of ${MAX_LIMIT}: "${query.limit}"` };
182926
+ }
182927
+ limit = Math.floor(n2);
182928
+ }
182929
+ let offset = 0;
182930
+ if (query.offset !== undefined) {
182931
+ const n2 = Number(query.offset);
182932
+ if (!Number.isFinite(n2) || n2 < 0) {
182933
+ return { param: "offset", message: `"offset" must be a non-negative number: "${query.offset}"` };
182934
+ }
182935
+ offset = Math.floor(n2);
182936
+ }
182937
+ return { fromMs, toMs, fromRaw, toRaw, level: query.level, q: query.q, limit, offset };
182938
+ }
182939
+ var LINE_RE = /^\[(?<ts>[^\]]+)\] \[(?<level>[A-Z]+)\] (?<rest>[\s\S]*)$/;
182940
+ function normalizeLevel(raw2) {
182941
+ const lower2 = raw2.toLowerCase();
182942
+ return lower2 === "debug" || lower2 === "info" || lower2 === "warn" || lower2 === "error" ? lower2 : "raw";
182943
+ }
182944
+ function splitMessageAndMeta(rest) {
182945
+ if (!rest.endsWith("}"))
182946
+ return { message: rest };
182947
+ let searchFrom = rest.length;
182948
+ for (;; ) {
182949
+ const idx = rest.lastIndexOf(" {", searchFrom - 1);
182950
+ if (idx === -1)
182951
+ break;
182952
+ const candidate2 = rest.slice(idx + 1);
182953
+ try {
182954
+ const parsed = JSON.parse(candidate2);
182955
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
182956
+ return { message: rest.slice(0, idx), meta: parsed };
182957
+ }
182958
+ } catch {}
182959
+ searchFrom = idx;
182960
+ }
182961
+ return { message: rest };
182962
+ }
182963
+ function parseLine(line, prevTs) {
182964
+ const match2 = LINE_RE.exec(line);
182965
+ if (!match2 || !match2.groups) {
182966
+ return { entry: { seq: 0, ts: prevTs, level: "raw", message: line }, ts: prevTs };
182967
+ }
182968
+ const { ts, level, rest } = match2.groups;
182969
+ const { message, meta: meta3 } = splitMessageAndMeta(rest);
182970
+ const entry2 = { seq: 0, ts, level: normalizeLevel(level), message, ...meta3 ? { meta: meta3 } : {} };
182971
+ return { entry: entry2, ts };
182972
+ }
182973
+ function realReadTail(filePath, maxBytes) {
182974
+ let size;
182975
+ try {
182976
+ size = fs28.statSync(filePath).size;
182977
+ } catch {
182978
+ return { content: "", truncated: false };
182979
+ }
182980
+ if (size === 0)
182981
+ return { content: "", truncated: false };
182982
+ if (size <= maxBytes) {
182983
+ try {
182984
+ return { content: fs28.readFileSync(filePath, "utf8"), truncated: false };
182985
+ } catch {
182986
+ return { content: "", truncated: false };
182987
+ }
182988
+ }
182989
+ try {
182990
+ const fd = fs28.openSync(filePath, "r");
182991
+ try {
182992
+ const start = size - maxBytes;
182993
+ const buf = Buffer.alloc(maxBytes);
182994
+ fs28.readSync(fd, buf, 0, maxBytes, start);
182995
+ let text3 = buf.toString("utf8");
182996
+ const firstNewline = text3.indexOf(`
182997
+ `);
182998
+ text3 = firstNewline !== -1 ? text3.slice(firstNewline + 1) : "";
182999
+ return { content: text3, truncated: true };
183000
+ } finally {
183001
+ fs28.closeSync(fd);
183002
+ }
183003
+ } catch {
183004
+ return { content: "", truncated: true };
183005
+ }
183006
+ }
183007
+ var realReader = {
183008
+ listFiles(filePath, maxFiles) {
183009
+ return sinkFiles(filePath, maxFiles).filter((f) => {
183010
+ try {
183011
+ fs28.accessSync(f, fs28.constants.R_OK);
183012
+ return true;
183013
+ } catch {
183014
+ return false;
183015
+ }
183016
+ });
183017
+ },
183018
+ readTail: realReadTail
183019
+ };
183020
+ var activeReader = realReader;
183021
+ function scanEntries() {
183022
+ const loggingConfig = config.get("logging");
183023
+ const filePath = loggingConfig.file;
183024
+ const files = filePath ? activeReader.listFiles(filePath, loggingConfig.maxFiles) : [];
183025
+ if (files.length === 0) {
183026
+ return { entries: logBuffer.snapshot(), source: "buffer", truncated: false };
183027
+ }
183028
+ const readFiles = [];
183029
+ let budgetLeft = MAX_SCAN_BYTES;
183030
+ let truncated = false;
183031
+ for (const file3 of files) {
183032
+ if (budgetLeft <= 0) {
183033
+ truncated = true;
183034
+ break;
183035
+ }
183036
+ const { content, truncated: fileTruncated } = activeReader.readTail(file3, budgetLeft);
183037
+ if (fileTruncated)
183038
+ truncated = true;
183039
+ readFiles.push(content);
183040
+ budgetLeft -= Buffer.byteLength(content, "utf8");
183041
+ if (fileTruncated)
183042
+ break;
183043
+ }
183044
+ let prevTs = new Date().toISOString();
183045
+ const chronoEntries = [];
183046
+ for (let i = readFiles.length - 1;i >= 0; i--) {
183047
+ const lines = readFiles[i].split(`
183048
+ `).filter((l2) => l2.length > 0);
183049
+ for (const line of lines) {
183050
+ const { entry: entry2, ts } = parseLine(line, prevTs);
183051
+ prevTs = ts;
183052
+ chronoEntries.push(entry2);
183053
+ }
183054
+ }
183055
+ const entries = chronoEntries.reverse();
183056
+ for (let i = 0;i < entries.length; i++) {
183057
+ entries[i].seq = entries.length - 1 - i;
183058
+ }
183059
+ return { entries, source: "file", truncated };
183060
+ }
183061
+ function matchesFilter(entry2, parsed) {
183062
+ const tsMs = Date.parse(entry2.ts);
183063
+ if (Number.isNaN(tsMs) || tsMs < parsed.fromMs || tsMs > parsed.toMs)
183064
+ return false;
183065
+ if (parsed.level !== undefined && entry2.level !== parsed.level)
183066
+ return false;
183067
+ if (parsed.q !== undefined && !entry2.message.toLowerCase().includes(parsed.q.toLowerCase()))
183068
+ return false;
183069
+ return true;
183070
+ }
183071
+ function filteredEntries(parsed) {
183072
+ const scan = scanEntries();
183073
+ return { ...scan, entries: scan.entries.filter((e) => matchesFilter(e, parsed)) };
183074
+ }
183075
+ function sanitizeForFilename(s) {
183076
+ return s.replace(/[^A-Za-z0-9._-]/g, "-");
183077
+ }
183078
+ function exportFilename(parsed, ext2) {
183079
+ const fromPart = sanitizeForFilename(parsed.fromRaw ?? "all");
183080
+ const toPart = sanitizeForFilename(parsed.toRaw ?? "all");
183081
+ return `massa-ai-logs-${fromPart}_${toPart}.${ext2}`;
183082
+ }
183083
+ function renderTxtLine(entry2) {
183084
+ const metaStr = entry2.meta ? ` ${JSON.stringify(entry2.meta)}` : "";
183085
+ return `[${entry2.ts}] [${entry2.level.toUpperCase()}] ${entry2.message}${metaStr}`;
183086
+ }
183087
+ var SSE_HEARTBEAT_MS_DEFAULT = 15000;
183088
+ var SSE_MAX_DURATION_MS_DEFAULT = 10 * 60 * 1000;
183089
+ var logsRoutes = new Elysia({ prefix: "/api/v1/logs" }).get("/", ({ query, set: set3 }) => {
183090
+ const parsed = parseRangeQuery(query);
183091
+ if (isQueryValidationError(parsed)) {
183092
+ set3.status = 400;
183093
+ return { success: false, error: `invalid "${parsed.param}": ${parsed.message}` };
183094
+ }
183095
+ const { entries, source, truncated } = filteredEntries(parsed);
183096
+ const total = entries.length;
183097
+ const page = entries.slice(parsed.offset, parsed.offset + parsed.limit);
183098
+ set3.status = 200;
183099
+ return { success: true, data: { entries: page, total, source, truncated } };
183100
+ }, {
183101
+ detail: {
183102
+ ...LOGS_DETAIL,
183103
+ summary: "Range/level/substring query over the log sink (or the ring buffer)",
183104
+ description: 'Query params: from, to (ISO-8601, closed interval), level, q (substring), limit (<=1000), offset. Reads the file sink newest-first within a 64 MB scan bound (truncated:true if the bound was hit); falls back to the in-process ring buffer (source:"buffer") when no sink file is present or readable. Validates from/to/limit before any read.'
183105
+ }
183106
+ }).get("/export", ({ query, set: set3 }) => {
183107
+ const parsed = parseRangeQuery(query);
183108
+ if (isQueryValidationError(parsed)) {
183109
+ set3.status = 400;
183110
+ return { success: false, error: `invalid "${parsed.param}": ${parsed.message}` };
183111
+ }
183112
+ const { entries } = filteredEntries(parsed);
183113
+ const format = query.format === "txt" ? "txt" : "jsonl";
183114
+ const ext2 = format === "txt" ? "txt" : "jsonl";
183115
+ const contentType = format === "txt" ? "text/plain" : "application/x-ndjson";
183116
+ const body = format === "txt" ? entries.map(renderTxtLine).join(`
183117
+ `) : entries.map((e) => JSON.stringify(e)).join(`
183118
+ `);
183119
+ const filename = exportFilename(parsed, ext2);
183120
+ return new Response(body, {
183121
+ status: 200,
183122
+ headers: {
183123
+ "Content-Type": contentType,
183124
+ "Content-Disposition": `attachment; filename="${filename}"`
183125
+ }
183126
+ });
183127
+ }, {
183128
+ detail: {
183129
+ ...LOGS_DETAIL,
183130
+ summary: "Download the queried log range as jsonl or txt",
183131
+ description: "Same query surface as GET /api/v1/logs (minus limit/offset \u2014 the full matching range is returned) plus format=jsonl|txt. Responds with Content-Disposition: attachment and a filename carrying the range. A range matching zero entries still returns an empty (200) download."
183132
+ }
183133
+ }).get("/stream", () => {
183134
+ const HEARTBEAT_MS = Number(process.env.MASSA_AI_SSE_HEARTBEAT_MS) || SSE_HEARTBEAT_MS_DEFAULT;
183135
+ const MAX_DURATION_MS = Number(process.env.MASSA_AI_SSE_MAX_DURATION_MS) || SSE_MAX_DURATION_MS_DEFAULT;
183136
+ const encoder4 = new TextEncoder;
183137
+ let closed = false;
183138
+ let unsubscribe;
183139
+ let heartbeatTimer;
183140
+ let closeTimer;
183141
+ const stream2 = new ReadableStream({
183142
+ start(controller2) {
183143
+ const enqueue = (data) => {
183144
+ if (closed)
183145
+ return;
183146
+ try {
183147
+ controller2.enqueue(encoder4.encode(`data: ${JSON.stringify(data)}
183148
+
183149
+ `));
183150
+ } catch {
183151
+ closed = true;
183152
+ }
183153
+ };
183154
+ unsubscribe = logBuffer.subscribe((entry2) => {
183155
+ enqueue(entry2);
183156
+ });
183157
+ heartbeatTimer = setInterval(() => {
183158
+ if (closed) {
183159
+ clearInterval(heartbeatTimer);
183160
+ return;
183161
+ }
183162
+ try {
183163
+ controller2.enqueue(encoder4.encode(`: heartbeat
183164
+
183165
+ `));
183166
+ } catch {
183167
+ closed = true;
183168
+ clearInterval(heartbeatTimer);
183169
+ }
183170
+ }, HEARTBEAT_MS);
183171
+ closeTimer = setTimeout(() => {
183172
+ closed = true;
183173
+ unsubscribe?.();
183174
+ clearInterval(heartbeatTimer);
183175
+ try {
183176
+ controller2.close();
183177
+ } catch {}
183178
+ }, MAX_DURATION_MS);
183179
+ },
183180
+ cancel() {
183181
+ closed = true;
183182
+ unsubscribe?.();
183183
+ if (heartbeatTimer)
183184
+ clearInterval(heartbeatTimer);
183185
+ if (closeTimer)
183186
+ clearTimeout(closeTimer);
183187
+ }
183188
+ });
183189
+ return new Response(stream2, {
183190
+ headers: {
183191
+ "Content-Type": "text/event-stream",
183192
+ "Cache-Control": "no-cache",
183193
+ Connection: "keep-alive",
183194
+ "X-Accel-Buffering": "no"
183195
+ }
183196
+ });
183197
+ }, {
183198
+ detail: {
183199
+ ...LOGS_DETAIL,
183200
+ summary: "SSE tail of newly buffered log entries",
183201
+ description: "Server-Sent Events stream emitting `data: <LogEntry JSON>` for every entry subsequently pushed into the in-process ring buffer, plus `: heartbeat` comments. Same heartbeat and max-duration auto-close behavior as GET /api/v1/events. Scoped to this server process \u2014 a separate range query over the file sink may contain entries this stream never showed (e.g. from the stdio MCP server)."
183202
+ }
183203
+ });
183204
+
182324
183205
  // src/middleware/error.ts
182325
183206
  init_dist();
182326
- var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path41, request }) => {
183207
+ var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path43, request }) => {
182327
183208
  logger.error("[massa-ai-api] Request failed", undefined, {
182328
183209
  ...safeErrorSummary(error51),
182329
183210
  code,
182330
- path: path41,
183211
+ path: path43,
182331
183212
  method: request.method
182332
183213
  });
182333
183214
  if (error51 instanceof SearchServiceError) {
@@ -182429,7 +183310,8 @@ var app = new Elysia({ adapter: node() }).use(cors(buildCorsOptions(config.get("
182429
183310
  { name: "executor", description: "Polyglot sandbox: execute code, run code over files, batch shell commands" },
182430
183311
  { name: "web", description: "SSRF-guarded web fetch + HTML\u2192md + index (fetch_and_index)" },
182431
183312
  { name: "webUi", description: "Read-only memory/search web browser (Phase 8)" },
182432
- { name: "profiles", description: "Model-profile switch: list shipped profiles, switch installed agents" }
183313
+ { name: "profiles", description: "Model-profile switch: list shipped profiles, switch installed agents" },
183314
+ { name: "logs", description: "Log read: range/level/substring query, export, live SSE tail" }
182433
183315
  ],
182434
183316
  components: {
182435
183317
  securitySchemes: {
@@ -182443,13 +183325,15 @@ var app = new Elysia({ adapter: node() }).use(cors(buildCorsOptions(config.get("
182443
183325
  },
182444
183326
  security: [{ ApiKeyAuth: [] }]
182445
183327
  }
182446
- })).use(errorHandler).use(authMiddleware).use(searchRoutes).use(memoryRoutes).use(checkpointRoutes).use(projectRoutes).use(contextRoutes).use(analyticsRoutes).use(systemRoutes).use(eventsRoutes).use(workspaceRoutes).use(fileRoutes).use(synapseRoutes).use(hookRoutes).use(bootstrapRoutes).use(handoffRoutes).use(proposalRoutes).use(executorRoutes).use(webRoutes).use(webUiRoutes).use(architectureRoutes).use(dashboardRoutes).use(profileRoutes).use(configRoutes).use(modelRegistryRoutes).use(modelRegistryStreamRoutes).get("/health", () => buildHealthResponse(getParserReadiness()));
183328
+ })).use(errorHandler).use(authMiddleware).use(searchRoutes).use(memoryRoutes).use(checkpointRoutes).use(projectRoutes).use(contextRoutes).use(analyticsRoutes).use(systemRoutes).use(eventsRoutes).use(workspaceRoutes).use(fileRoutes).use(synapseRoutes).use(hookRoutes).use(bootstrapRoutes).use(handoffRoutes).use(proposalRoutes).use(executorRoutes).use(webRoutes).use(webUiRoutes).use(architectureRoutes).use(dashboardRoutes).use(profileRoutes).use(configRoutes).use(modelRegistryRoutes).use(modelRegistryStreamRoutes).use(restartRoutes).use(logsRoutes).get("/health", () => buildHealthResponse(getParserReadiness()));
182447
183329
  initAuthOrExit();
182448
183330
  warnIfTrustOverrideEnabled();
182449
183331
  await listenAfterParserValidation({
182450
183332
  validate: validateAllGrammars,
182451
183333
  listen: () => {
182452
- app.listen(PORT);
183334
+ app.listen(PORT, (server) => {
183335
+ setServerStopper(() => void server.stop());
183336
+ });
182453
183337
  },
182454
183338
  onValidationFailure: (error51) => {
182455
183339
  console.error("Structural parser readiness failed; indexing is unavailable:", error51 instanceof Error ? error51.message : error51);
@@ -182490,18 +183374,16 @@ try {
182490
183374
  } catch (err) {
182491
183375
  console.error(`[scheduler] init error:`, err instanceof Error ? err.message : err);
182492
183376
  }
183377
+ setJobsStopper(() => {
183378
+ clearInterval(jobReaperTimer);
183379
+ try {
183380
+ scheduler.stop();
183381
+ } catch {}
183382
+ });
182493
183383
  for (const signal of ["SIGTERM", "SIGINT"]) {
182494
- process.on(signal, async () => {
183384
+ process.on(signal, () => {
182495
183385
  console.log(`${signal} received, shutting down gracefully...`);
182496
- clearInterval(jobReaperTimer);
182497
- try {
182498
- scheduler.stop();
182499
- } catch {}
182500
- try {
182501
- const { disconnectPrisma: disconnectPrisma2 } = await Promise.resolve().then(() => (init_services(), exports_services));
182502
- await disconnectPrisma2();
182503
- } catch {}
182504
- process.exit(0);
183386
+ gracefulShutdown();
182505
183387
  });
182506
183388
  }
182507
183389
  (async () => {