@massa-ai/tools-api 1.40.1 → 1.41.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 +687 -134
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -728,9 +728,296 @@ var init_env = __esm(() => {
728
728
  } catch {}
729
729
  });
730
730
 
731
+ // ../../packages/shared/dist/config/config-writer.js
732
+ import fs2 from "fs";
733
+ function maskSensitive(config) {
734
+ const masked = JSON.parse(JSON.stringify(config));
735
+ if (masked.security?.apiKey)
736
+ masked.security.apiKey = MASK_SENTINEL;
737
+ if (masked.llm?.apiKey)
738
+ masked.llm.apiKey = MASK_SENTINEL;
739
+ if (masked.embedding?.apiKey)
740
+ masked.embedding.apiKey = MASK_SENTINEL;
741
+ if (masked.database?.url)
742
+ masked.database.url = MASK_SENTINEL;
743
+ return masked;
744
+ }
745
+ function restartNeededSections(config) {
746
+ return RESTART_SECTIONS.filter((s) => {
747
+ if (s === "database")
748
+ return config.database !== undefined;
749
+ if (s === "embedding")
750
+ return config.embedding !== undefined;
751
+ if (s === "llm")
752
+ return config.llm !== undefined;
753
+ if (s === "security")
754
+ return config.security !== undefined;
755
+ return false;
756
+ });
757
+ }
758
+ function applyMaskedSentinel(partial, current) {
759
+ const result = JSON.parse(JSON.stringify(partial));
760
+ if (result.security?.apiKey === MASK_SENTINEL && current.security?.apiKey) {
761
+ result.security.apiKey = current.security.apiKey;
762
+ }
763
+ if (result.llm?.apiKey === MASK_SENTINEL && current.llm?.apiKey) {
764
+ result.llm.apiKey = current.llm.apiKey;
765
+ }
766
+ if (result.embedding?.apiKey === MASK_SENTINEL && current.embedding?.apiKey) {
767
+ result.embedding.apiKey = current.embedding.apiKey;
768
+ }
769
+ if (result.database?.url === MASK_SENTINEL && current.database?.url) {
770
+ result.database.url = current.database.url;
771
+ }
772
+ return result;
773
+ }
774
+ function checkNumber(val, min, max) {
775
+ if (typeof val !== "number" || !Number.isFinite(val))
776
+ return false;
777
+ if (min !== undefined && val < min)
778
+ return false;
779
+ if (max !== undefined && val > max)
780
+ return false;
781
+ return true;
782
+ }
783
+ function checkBoolean(val) {
784
+ return typeof val === "boolean";
785
+ }
786
+ function checkString(val) {
787
+ return typeof val === "string";
788
+ }
789
+ function validatePartial(partial) {
790
+ const details = [];
791
+ if (partial.database !== undefined) {
792
+ if (!checkString(partial.database.url))
793
+ details.push("database.url must be a string");
794
+ }
795
+ if (partial.embedding !== undefined) {
796
+ const e = partial.embedding;
797
+ if (!VALID_EMBEDDING_PROVIDERS.includes(e.provider))
798
+ details.push(`embedding.provider must be one of: ${VALID_EMBEDDING_PROVIDERS.join(", ")}`);
799
+ if (!checkString(e.model))
800
+ details.push("embedding.model must be a string");
801
+ if (e.baseURL !== undefined && !checkString(e.baseURL))
802
+ details.push("embedding.baseURL must be a string");
803
+ if (e.apiKey !== undefined && !checkString(e.apiKey))
804
+ details.push("embedding.apiKey must be a string");
805
+ if (e.dimensions !== undefined && !checkNumber(e.dimensions, 1))
806
+ details.push("embedding.dimensions must be a positive number");
807
+ }
808
+ if (partial.compression !== undefined) {
809
+ const c = partial.compression;
810
+ if (!checkString(c.defaultStrategy))
811
+ details.push("compression.defaultStrategy must be a string");
812
+ if (!checkNumber(c.minTokensForCompression, 0))
813
+ details.push("compression.minTokensForCompression must be a non-negative number");
814
+ if (!checkNumber(c.targetCompressionRatio, 0, 1))
815
+ details.push("compression.targetCompressionRatio must be a number between 0 and 1");
816
+ if (c.prompt !== undefined && !checkString(c.prompt))
817
+ details.push("compression.prompt must be a string");
818
+ }
819
+ if (partial.impact !== undefined) {
820
+ if (!checkBoolean(partial.impact.bfsCteEnabled))
821
+ details.push("impact.bfsCteEnabled must be a boolean");
822
+ }
823
+ if (partial.cache !== undefined) {
824
+ const c = partial.cache;
825
+ if (!checkBoolean(c.enabled))
826
+ details.push("cache.enabled must be a boolean");
827
+ if (!checkNumber(c.l1MaxSizeMB, 0))
828
+ details.push("cache.l1MaxSizeMB must be a non-negative number");
829
+ if (!checkNumber(c.l2MaxSizeMB, 0))
830
+ details.push("cache.l2MaxSizeMB must be a non-negative number");
831
+ if (!checkNumber(c.defaultTTLSeconds, 0))
832
+ details.push("cache.defaultTTLSeconds must be a non-negative number");
833
+ }
834
+ if (partial.dataDir !== undefined) {
835
+ if (!checkString(partial.dataDir))
836
+ details.push("dataDir must be a string");
837
+ }
838
+ if (partial.logging !== undefined) {
839
+ const l = partial.logging;
840
+ if (!VALID_LOG_LEVELS.includes(l.level))
841
+ details.push(`logging.level must be one of: ${VALID_LOG_LEVELS.join(", ")}`);
842
+ if (!checkBoolean(l.enableMetrics))
843
+ details.push("logging.enableMetrics must be a boolean");
844
+ if (l.file !== undefined && !checkString(l.file))
845
+ details.push("logging.file must be a string");
846
+ }
847
+ if (partial.search !== undefined) {
848
+ const s = partial.search;
849
+ if (!checkNumber(s.autoReindexMaxFiles, 0))
850
+ details.push("search.autoReindexMaxFiles must be a non-negative number");
851
+ const qu = s.queryUnderstanding;
852
+ if (qu !== undefined) {
853
+ if (!checkBoolean(qu.enabled))
854
+ details.push("search.queryUnderstanding.enabled must be a boolean");
855
+ if (!checkBoolean(qu.hydeEnabled))
856
+ details.push("search.queryUnderstanding.hydeEnabled must be a boolean");
857
+ if (!checkNumber(qu.cacheTtlMs, 0))
858
+ details.push("search.queryUnderstanding.cacheTtlMs must be a non-negative number");
859
+ if (!checkNumber(qu.cacheMaxSize, 0))
860
+ details.push("search.queryUnderstanding.cacheMaxSize must be a non-negative number");
861
+ }
862
+ const rr = s.rerank;
863
+ if (rr !== undefined) {
864
+ if (!checkBoolean(rr.enabled))
865
+ details.push("search.rerank.enabled must be a boolean");
866
+ if (!checkNumber(rr.rerankWindow, 0))
867
+ details.push("search.rerank.rerankWindow must be a non-negative number");
868
+ }
869
+ }
870
+ if (partial.llm !== undefined) {
871
+ const l = partial.llm;
872
+ if (!checkBoolean(l.enabled))
873
+ details.push("llm.enabled must be a boolean");
874
+ if (!checkString(l.baseUrl))
875
+ details.push("llm.baseUrl must be a string");
876
+ if (!checkString(l.apiKey))
877
+ details.push("llm.apiKey must be a string");
878
+ if (!checkString(l.model))
879
+ details.push("llm.model must be a string");
880
+ if (!checkString(l.codeModel))
881
+ details.push("llm.codeModel must be a string");
882
+ if (!checkNumber(l.temperature))
883
+ details.push("llm.temperature must be a number");
884
+ if (!checkNumber(l.maxOutputTokens, 1))
885
+ details.push("llm.maxOutputTokens must be a positive number");
886
+ if (!checkNumber(l.timeoutMs, 1))
887
+ details.push("llm.timeoutMs must be a positive number");
888
+ if (!checkBoolean(l.disableThink))
889
+ details.push("llm.disableThink must be a boolean");
890
+ }
891
+ if (partial.memory !== undefined) {
892
+ const m = partial.memory;
893
+ if (m.decay !== undefined) {
894
+ const d = m.decay;
895
+ if (!checkNumber(d.lambda))
896
+ details.push("memory.decay.lambda must be a number");
897
+ if (!checkNumber(d.sigma))
898
+ details.push("memory.decay.sigma must be a number");
899
+ if (!checkNumber(d.mu))
900
+ details.push("memory.decay.mu must be a number");
901
+ if (!checkNumber(d.coldThreshold))
902
+ details.push("memory.decay.coldThreshold must be a number");
903
+ }
904
+ if (m.bootstrap !== undefined) {
905
+ const b = m.bootstrap;
906
+ if (!checkBoolean(b.enabled))
907
+ details.push("memory.bootstrap.enabled must be a boolean");
908
+ if (!checkNumber(b.maxSeedMemories, 0))
909
+ details.push("memory.bootstrap.maxSeedMemories must be a non-negative number");
910
+ if (!checkNumber(b.centralityLimit, 0))
911
+ details.push("memory.bootstrap.centralityLimit must be a non-negative number");
912
+ if (!checkNumber(b.gitLogLimit, 0))
913
+ details.push("memory.bootstrap.gitLogLimit must be a non-negative number");
914
+ if (!checkBoolean(b.refreshEnabled))
915
+ details.push("memory.bootstrap.refreshEnabled must be a boolean");
916
+ }
917
+ if (m.autoImprove !== undefined) {
918
+ const a = m.autoImprove;
919
+ if (!checkBoolean(a.enabled))
920
+ details.push("memory.autoImprove.enabled must be a boolean");
921
+ if (!checkBoolean(a.reviewGate))
922
+ details.push("memory.autoImprove.reviewGate must be a boolean");
923
+ if (!checkNumber(a.minObservations, 0))
924
+ details.push("memory.autoImprove.minObservations must be a non-negative number");
925
+ if (!checkNumber(a.minIntervalMs, 0))
926
+ details.push("memory.autoImprove.minIntervalMs must be a non-negative number");
927
+ if (!checkNumber(a.maxWindow, 0))
928
+ details.push("memory.autoImprove.maxWindow must be a non-negative number");
929
+ if (!checkNumber(a.minQueryHits, 0))
930
+ details.push("memory.autoImprove.minQueryHits must be a non-negative number");
931
+ if (!checkNumber(a.minFileHits, 0))
932
+ details.push("memory.autoImprove.minFileHits must be a non-negative number");
933
+ if (!checkNumber(a.minFixHits, 0))
934
+ details.push("memory.autoImprove.minFixHits must be a non-negative number");
935
+ }
936
+ if (m.autoImportance !== undefined) {
937
+ if (!checkBoolean(m.autoImportance.enabled))
938
+ details.push("memory.autoImportance.enabled must be a boolean");
939
+ }
940
+ }
941
+ if (partial.hooks !== undefined) {
942
+ const h = partial.hooks;
943
+ if (!checkBoolean(h.enabled))
944
+ details.push("hooks.enabled must be a boolean");
945
+ if (!checkNumber(h.maxPayloadBytes, 0))
946
+ details.push("hooks.maxPayloadBytes must be a non-negative number");
947
+ if (h.queue !== undefined) {
948
+ if (!checkNumber(h.queue.maxPending, 0))
949
+ details.push("hooks.queue.maxPending must be a non-negative number");
950
+ }
951
+ if (h.bridge !== undefined) {
952
+ const b = h.bridge;
953
+ if (!checkBoolean(b.enabled))
954
+ details.push("hooks.bridge.enabled must be a boolean");
955
+ if (!checkNumber(b.minObservations, 0))
956
+ details.push("hooks.bridge.minObservations must be a non-negative number");
957
+ if (!checkNumber(b.minIntervalMs, 0))
958
+ details.push("hooks.bridge.minIntervalMs must be a non-negative number");
959
+ if (!checkNumber(b.maxWindow, 0))
960
+ details.push("hooks.bridge.maxWindow must be a non-negative number");
961
+ }
962
+ }
963
+ if (partial.synapse !== undefined) {
964
+ const syn = partial.synapse;
965
+ if (!checkBoolean(syn.enabled))
966
+ details.push("synapse.enabled must be a boolean");
967
+ }
968
+ if (partial.handoffs !== undefined) {
969
+ if (!checkBoolean(partial.handoffs.enabled))
970
+ details.push("handoffs.enabled must be a boolean");
971
+ }
972
+ if (partial.security !== undefined) {
973
+ const sec = partial.security;
974
+ if (sec.apiKey !== undefined && !checkString(sec.apiKey))
975
+ details.push("security.apiKey must be a string");
976
+ if (sec.corsOrigins !== undefined) {
977
+ if (!Array.isArray(sec.corsOrigins) || !sec.corsOrigins.every(checkString))
978
+ details.push("security.corsOrigins must be an array of strings");
979
+ }
980
+ if (sec.allowedExtensions !== undefined) {
981
+ if (!Array.isArray(sec.allowedExtensions) || sec.allowedExtensions.length === 0)
982
+ details.push("security.allowedExtensions must be a non-empty array");
983
+ else if (!sec.allowedExtensions.every((e) => typeof e === "string" && e.startsWith(".") && e.length >= 2))
984
+ details.push("security.allowedExtensions[] must be dot-prefixed extensions");
985
+ }
986
+ }
987
+ return details;
988
+ }
989
+ function savePartialConfig(partial) {
990
+ const current = loadConfig();
991
+ const mergedPartial = applyMaskedSentinel(partial, current);
992
+ const details = validatePartial(mergedPartial);
993
+ if (details.length > 0) {
994
+ return { success: false, details };
995
+ }
996
+ const merged = { ...current, ...mergedPartial };
997
+ const configPath = getConfigPath();
998
+ if (fs2.existsSync(configPath)) {
999
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
1000
+ const backupPath = `${configPath}.bak.${timestamp}`;
1001
+ fs2.copyFileSync(configPath, backupPath);
1002
+ }
1003
+ saveConfig(merged);
1004
+ return {
1005
+ success: true,
1006
+ config: merged,
1007
+ restartNeededSections: restartNeededSections(merged)
1008
+ };
1009
+ }
1010
+ var MASK_SENTINEL = "***", RESTART_SECTIONS, VALID_EMBEDDING_PROVIDERS, VALID_LOG_LEVELS;
1011
+ var init_config_writer = __esm(() => {
1012
+ init_config_loader();
1013
+ RESTART_SECTIONS = ["database", "embedding", "llm", "security"];
1014
+ VALID_EMBEDDING_PROVIDERS = ["ollama", "mistral", "openai", "google", "cohere"];
1015
+ VALID_LOG_LEVELS = ["debug", "info", "warn", "error"];
1016
+ });
1017
+
731
1018
  // ../../packages/shared/dist/config/api-key.js
732
1019
  import crypto3 from "crypto";
733
- import fs2 from "fs";
1020
+ import fs3 from "fs";
734
1021
  import path4 from "path";
735
1022
  function usable(value) {
736
1023
  const trimmed = value?.trim();
@@ -756,15 +1043,15 @@ function provisionApiKey() {
756
1043
  return { key: existing, provisioned: false, source: "config" };
757
1044
  let fd;
758
1045
  try {
759
- fs2.mkdirSync(configDir2, { recursive: true });
760
- fd = fs2.openSync(lockPath, "wx");
1046
+ fs3.mkdirSync(configDir2, { recursive: true });
1047
+ fd = fs3.openSync(lockPath, "wx");
761
1048
  } catch (error) {
762
1049
  if (error.code !== "EEXIST") {
763
1050
  throw new ApiKeyProvisioningError(configPath, error);
764
1051
  }
765
1052
  if (Date.now() > deadline) {
766
1053
  try {
767
- fs2.unlinkSync(lockPath);
1054
+ fs3.unlinkSync(lockPath);
768
1055
  } catch {}
769
1056
  }
770
1057
  sleepSync(LOCK_POLL_MS);
@@ -779,9 +1066,9 @@ function provisionApiKey() {
779
1066
  } catch (error) {
780
1067
  throw new ApiKeyProvisioningError(configPath, error);
781
1068
  } finally {
782
- fs2.closeSync(fd);
1069
+ fs3.closeSync(fd);
783
1070
  try {
784
- fs2.unlinkSync(lockPath);
1071
+ fs3.unlinkSync(lockPath);
785
1072
  } catch {}
786
1073
  }
787
1074
  }
@@ -1098,6 +1385,8 @@ var init_config = __esm(() => {
1098
1385
  init_config_loader();
1099
1386
  init_massa_ai_config();
1100
1387
  init_config_loader();
1388
+ init_config_writer();
1389
+ init_xdg();
1101
1390
  init_api_key();
1102
1391
  DEFAULT_ALLOWED_EXTENSIONS = [
1103
1392
  ".ts",
@@ -6603,7 +6892,7 @@ var init_types = __esm(() => {
6603
6892
  var init_interfaces = () => {};
6604
6893
 
6605
6894
  // ../../packages/shared/dist/utils/logger.js
6606
- import fs3 from "fs";
6895
+ import fs4 from "fs";
6607
6896
 
6608
6897
  class Logger {
6609
6898
  _level;
@@ -6660,7 +6949,7 @@ class Logger {
6660
6949
  const filePath = this.logFilePath;
6661
6950
  if (filePath) {
6662
6951
  try {
6663
- fs3.appendFileSync(filePath, message + `
6952
+ fs4.appendFileSync(filePath, message + `
6664
6953
  `);
6665
6954
  } catch {}
6666
6955
  }
@@ -7073,7 +7362,7 @@ var init_hosts = __esm(() => {
7073
7362
  });
7074
7363
 
7075
7364
  // ../../packages/shared/dist/profile-switch/state.js
7076
- import fs4 from "fs";
7365
+ import fs5 from "fs";
7077
7366
  import path7 from "path";
7078
7367
  function namedError(name, message) {
7079
7368
  const err = new InstallStateError(message);
@@ -7100,7 +7389,7 @@ function validateShape(raw2, filePath) {
7100
7389
  function readInstallState(filePath) {
7101
7390
  let text;
7102
7391
  try {
7103
- text = fs4.readFileSync(filePath, "utf-8");
7392
+ text = fs5.readFileSync(filePath, "utf-8");
7104
7393
  } catch (err) {
7105
7394
  const code = err.code;
7106
7395
  if (code === "ENOENT")
@@ -7120,8 +7409,8 @@ function writeInstallState(filePath, state) {
7120
7409
  const text = `${JSON.stringify(validated, null, 2)}
7121
7410
  `;
7122
7411
  try {
7123
- fs4.mkdirSync(path7.dirname(filePath), { recursive: true });
7124
- fs4.writeFileSync(filePath, text);
7412
+ fs5.mkdirSync(path7.dirname(filePath), { recursive: true });
7413
+ fs5.writeFileSync(filePath, text);
7125
7414
  } catch (err) {
7126
7415
  throw UnwritableInstallStateError(filePath, err.message);
7127
7416
  }
@@ -7148,7 +7437,7 @@ var init_state = __esm(() => {
7148
7437
  });
7149
7438
 
7150
7439
  // ../../packages/shared/dist/profile-switch/lock.js
7151
- import fs5 from "fs";
7440
+ import fs6 from "fs";
7152
7441
  import path8 from "path";
7153
7442
  import os4 from "os";
7154
7443
  import crypto4 from "crypto";
@@ -7161,7 +7450,7 @@ function namedError2(name, message) {
7161
7450
  function readOwner(ownerPath) {
7162
7451
  let raw2;
7163
7452
  try {
7164
- raw2 = JSON.parse(fs5.readFileSync(ownerPath, "utf-8"));
7453
+ raw2 = JSON.parse(fs6.readFileSync(ownerPath, "utf-8"));
7165
7454
  } catch {
7166
7455
  return null;
7167
7456
  }
@@ -7177,7 +7466,7 @@ function releaseIfOwned(lockDir, ownerPath, token) {
7177
7466
  const owner = readOwner(ownerPath);
7178
7467
  if (owner === null || owner.token !== token)
7179
7468
  return;
7180
- fs5.rmSync(lockDir, { recursive: true, force: true });
7469
+ fs6.rmSync(lockDir, { recursive: true, force: true });
7181
7470
  }
7182
7471
  function acquireLock(stateFilePath, options = {}) {
7183
7472
  const lockDir = `${stateFilePath}.switch.lock`;
@@ -7186,11 +7475,11 @@ function acquireLock(stateFilePath, options = {}) {
7186
7475
  const identity = options.identity ?? DEFAULT_IDENTITY;
7187
7476
  const staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
7188
7477
  const createFresh = () => {
7189
- fs5.mkdirSync(lockDir);
7478
+ fs6.mkdirSync(lockDir);
7190
7479
  const pid = identity.pid();
7191
7480
  const startedAt = identity.processStart(pid);
7192
7481
  if (startedAt == null) {
7193
- fs5.rmSync(lockDir, { recursive: true, force: true });
7482
+ fs6.rmSync(lockDir, { recursive: true, force: true });
7194
7483
  throw LockAcquireError(lockDir, "could not determine this process's start-time identity");
7195
7484
  }
7196
7485
  const token = crypto4.randomUUID();
@@ -7201,8 +7490,8 @@ function acquireLock(stateFilePath, options = {}) {
7201
7490
  token,
7202
7491
  timestamp: clock.now()
7203
7492
  };
7204
- fs5.mkdirSync(path8.dirname(ownerPath), { recursive: true });
7205
- fs5.writeFileSync(ownerPath, JSON.stringify(record));
7493
+ fs6.mkdirSync(path8.dirname(ownerPath), { recursive: true });
7494
+ fs6.writeFileSync(ownerPath, JSON.stringify(record));
7206
7495
  return { lockDir, release: () => releaseIfOwned(lockDir, ownerPath, token) };
7207
7496
  };
7208
7497
  try {
@@ -7217,11 +7506,11 @@ function acquireLock(stateFilePath, options = {}) {
7217
7506
  throw LockHeldError(lockDir);
7218
7507
  const reclaimDir = `${lockDir}.reclaim.${owner.token}`;
7219
7508
  try {
7220
- fs5.renameSync(lockDir, reclaimDir);
7509
+ fs6.renameSync(lockDir, reclaimDir);
7221
7510
  } catch {
7222
7511
  throw LockHeldError(lockDir);
7223
7512
  }
7224
- fs5.rmSync(reclaimDir, { recursive: true, force: true });
7513
+ fs6.rmSync(reclaimDir, { recursive: true, force: true });
7225
7514
  try {
7226
7515
  return createFresh();
7227
7516
  } catch {
@@ -7255,7 +7544,7 @@ var init_lock = __esm(() => {
7255
7544
  });
7256
7545
 
7257
7546
  // ../../packages/shared/dist/profile-switch/engine.js
7258
- import fs6 from "fs";
7547
+ import fs7 from "fs";
7259
7548
  import path9 from "path";
7260
7549
  import os5 from "os";
7261
7550
  import crypto5 from "crypto";
@@ -7289,7 +7578,7 @@ function listProfiles(opts = {}) {
7289
7578
  availableProfiles: []
7290
7579
  };
7291
7580
  }
7292
- const installed = fs6.existsSync(layout.activeDir);
7581
+ const installed = fs7.existsSync(layout.activeDir);
7293
7582
  const availableProfiles = listVariantProfiles(layout);
7294
7583
  const platform = state.platforms[host];
7295
7584
  return {
@@ -7305,9 +7594,9 @@ function listProfiles(opts = {}) {
7305
7594
  return { hosts };
7306
7595
  }
7307
7596
  function listVariantProfiles(layout) {
7308
- if (!fs6.existsSync(layout.variantsRoot))
7597
+ if (!fs7.existsSync(layout.variantsRoot))
7309
7598
  return [];
7310
- return fs6.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
7599
+ return fs7.readdirSync(layout.variantsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
7311
7600
  }
7312
7601
  function matchesGlob(filename, glob) {
7313
7602
  const starIdx = glob.indexOf("*");
@@ -7320,32 +7609,32 @@ function matchesGlob(filename, glob) {
7320
7609
  function assertStateWritable(stateFilePath) {
7321
7610
  const dir = path9.dirname(stateFilePath);
7322
7611
  try {
7323
- fs6.mkdirSync(dir, { recursive: true });
7612
+ fs7.mkdirSync(dir, { recursive: true });
7324
7613
  } catch (err) {
7325
7614
  throw UnwritableInstallStateError(stateFilePath, err.message);
7326
7615
  }
7327
- const checkPath = fs6.existsSync(stateFilePath) ? stateFilePath : dir;
7616
+ const checkPath = fs7.existsSync(stateFilePath) ? stateFilePath : dir;
7328
7617
  try {
7329
- fs6.accessSync(checkPath, fs6.constants.W_OK);
7618
+ fs7.accessSync(checkPath, fs7.constants.W_OK);
7330
7619
  } catch (err) {
7331
7620
  throw UnwritableInstallStateError(stateFilePath, err.message);
7332
7621
  }
7333
7622
  }
7334
7623
  function copyFileRouteVariant(layout, variantDir) {
7335
- fs6.mkdirSync(layout.activeDir, { recursive: true });
7624
+ fs7.mkdirSync(layout.activeDir, { recursive: true });
7336
7625
  let changed = 0;
7337
- for (const entry of fs6.readdirSync(variantDir, { withFileTypes: true })) {
7626
+ for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
7338
7627
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
7339
7628
  continue;
7340
- fs6.copyFileSync(path9.join(variantDir, entry.name), path9.join(layout.activeDir, entry.name));
7629
+ fs7.copyFileSync(path9.join(variantDir, entry.name), path9.join(layout.activeDir, entry.name));
7341
7630
  changed++;
7342
7631
  }
7343
7632
  return changed;
7344
7633
  }
7345
7634
  function repointOpencodeVariant(layout, variantDir) {
7346
- fs6.mkdirSync(layout.activeDir, { recursive: true });
7635
+ fs7.mkdirSync(layout.activeDir, { recursive: true });
7347
7636
  let changed = 0;
7348
- for (const entry of fs6.readdirSync(variantDir, { withFileTypes: true })) {
7637
+ for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
7349
7638
  if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
7350
7639
  continue;
7351
7640
  const dest = path9.join(layout.activeDir, entry.name);
@@ -7353,15 +7642,15 @@ function repointOpencodeVariant(layout, variantDir) {
7353
7642
  let destExists = true;
7354
7643
  let destIsSymlink = false;
7355
7644
  try {
7356
- destIsSymlink = fs6.lstatSync(dest).isSymbolicLink();
7645
+ destIsSymlink = fs7.lstatSync(dest).isSymbolicLink();
7357
7646
  } catch {
7358
7647
  destExists = false;
7359
7648
  }
7360
7649
  if (destExists && !destIsSymlink)
7361
7650
  continue;
7362
7651
  const tmp = `${dest}.massa-ai-switch.${crypto5.randomUUID()}`;
7363
- fs6.symlinkSync(target, tmp);
7364
- fs6.renameSync(tmp, dest);
7652
+ fs7.symlinkSync(target, tmp);
7653
+ fs7.renameSync(tmp, dest);
7365
7654
  changed++;
7366
7655
  }
7367
7656
  return changed;
@@ -7383,13 +7672,13 @@ function switchProfile(opts) {
7383
7672
  if (fileHosts.length === 0) {
7384
7673
  return { profile: opts.profile, dryRun, hosts: orderRows(universe, skipRows), restartRequired: false };
7385
7674
  }
7386
- const installedFileHosts = fileHosts.filter((h) => fs6.existsSync(h.layout.activeDir));
7675
+ const installedFileHosts = fileHosts.filter((h) => fs7.existsSync(h.layout.activeDir));
7387
7676
  if (installedFileHosts.length === 0)
7388
7677
  throw NoHostsDetectedError();
7389
7678
  const withAvailability = fileHosts.map((h) => {
7390
- const variantsRootExists = fs6.existsSync(h.layout.variantsRoot);
7679
+ const variantsRootExists = fs7.existsSync(h.layout.variantsRoot);
7391
7680
  const variantDir = h.layout.variantDir(opts.profile);
7392
- const available = variantsRootExists && fs6.existsSync(variantDir) && fs6.statSync(variantDir).isDirectory();
7681
+ const available = variantsRootExists && fs7.existsSync(variantDir) && fs7.statSync(variantDir).isDirectory();
7393
7682
  return { ...h, variantsRootExists, variantDir, available };
7394
7683
  });
7395
7684
  if (!withAvailability.some((h) => h.available)) {
@@ -11597,8 +11886,8 @@ var init_esm4 = __esm(() => {
11597
11886
  #children;
11598
11887
  nocase;
11599
11888
  #fs;
11600
- constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs7 = defaultFS } = {}) {
11601
- this.#fs = fsFromOption(fs7);
11889
+ constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs8 = defaultFS } = {}) {
11890
+ this.#fs = fsFromOption(fs8);
11602
11891
  if (cwd instanceof URL || cwd.startsWith("file://")) {
11603
11892
  cwd = fileURLToPath(cwd);
11604
11893
  }
@@ -12073,8 +12362,8 @@ var init_esm4 = __esm(() => {
12073
12362
  parseRootPath(dir) {
12074
12363
  return win32.parse(dir).root.toUpperCase();
12075
12364
  }
12076
- newRoot(fs7) {
12077
- return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs7 });
12365
+ newRoot(fs8) {
12366
+ return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs8 });
12078
12367
  }
12079
12368
  isAbsolute(p) {
12080
12369
  return p.startsWith("/") || p.startsWith("\\") || /^[a-z]:(\/|\\)/i.test(p);
@@ -12090,8 +12379,8 @@ var init_esm4 = __esm(() => {
12090
12379
  parseRootPath(_dir) {
12091
12380
  return "/";
12092
12381
  }
12093
- newRoot(fs7) {
12094
- return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs7 });
12382
+ newRoot(fs8) {
12383
+ return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs: fs8 });
12095
12384
  }
12096
12385
  isAbsolute(p) {
12097
12386
  return p.startsWith("/");
@@ -13497,7 +13786,7 @@ var init_capture_policy = __esm(() => {
13497
13786
  });
13498
13787
 
13499
13788
  // ../../packages/core/dist/services/search/ignore-patterns.js
13500
- import fs7 from "fs/promises";
13789
+ import fs8 from "fs/promises";
13501
13790
  import path11 from "path";
13502
13791
  function buildExtensionGlob(extensions2) {
13503
13792
  return extensions2.map((ext2) => `**/*${ext2}`);
@@ -13522,7 +13811,7 @@ async function loadProjectIgnore(projectPath) {
13522
13811
  ig.add(DEFAULT_IGNORES);
13523
13812
  try {
13524
13813
  const gitignorePath = path11.join(projectPath, ".gitignore");
13525
- const gitignoreContent = await fs7.readFile(gitignorePath, "utf8");
13814
+ const gitignoreContent = await fs8.readFile(gitignorePath, "utf8");
13526
13815
  const rules = gitignoreContent.split(`
13527
13816
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
13528
13817
  ig.add(rules);
@@ -13773,7 +14062,7 @@ var init_alias_resolver = __esm(() => {
13773
14062
  });
13774
14063
 
13775
14064
  // ../../packages/core/dist/services/search/index-manager.js
13776
- import fs8 from "fs";
14065
+ import fs9 from "fs";
13777
14066
  import path12 from "path";
13778
14067
 
13779
14068
  class IndexManager {
@@ -13869,7 +14158,7 @@ class IndexManager {
13869
14158
  for (const filePath of indexedFiles) {
13870
14159
  const fullPath = path12.join(projectPath, filePath);
13871
14160
  try {
13872
- const stat2 = await fs8.promises.stat(fullPath);
14161
+ const stat2 = await fs9.promises.stat(fullPath);
13873
14162
  fileMetadata[filePath] = {
13874
14163
  path: filePath,
13875
14164
  mtime: stat2.mtimeMs,
@@ -13922,7 +14211,7 @@ class IndexManager {
13922
14211
  }
13923
14212
  const fullPath = path12.join(projectPath, match2);
13924
14213
  try {
13925
- const stat2 = await fs8.promises.stat(fullPath);
14214
+ const stat2 = await fs9.promises.stat(fullPath);
13926
14215
  files.set(match2, {
13927
14216
  path: match2,
13928
14217
  mtime: stat2.mtimeMs,
@@ -35546,7 +35835,7 @@ var require_token_io = __commonJS((exports, module) => {
35546
35835
  });
35547
35836
  module.exports = __toCommonJS2(token_io_exports);
35548
35837
  var import_path9 = __toESM2(__require("path"));
35549
- var import_fs6 = __toESM2(__require("fs"));
35838
+ var import_fs7 = __toESM2(__require("fs"));
35550
35839
  var import_os3 = __toESM2(__require("os"));
35551
35840
  var import_token_error = require_token_error();
35552
35841
  function findRootDir() {
@@ -35554,7 +35843,7 @@ var require_token_io = __commonJS((exports, module) => {
35554
35843
  let dir = process.cwd();
35555
35844
  while (dir !== import_path9.default.dirname(dir)) {
35556
35845
  const pkgPath = import_path9.default.join(dir, ".vercel");
35557
- if (import_fs6.default.existsSync(pkgPath)) {
35846
+ if (import_fs7.default.existsSync(pkgPath)) {
35558
35847
  return dir;
35559
35848
  }
35560
35849
  dir = import_path9.default.dirname(dir);
@@ -35613,7 +35902,7 @@ var require_auth_config = __commonJS((exports, module) => {
35613
35902
  writeAuthConfig: () => writeAuthConfig
35614
35903
  });
35615
35904
  module.exports = __toCommonJS2(auth_config_exports);
35616
- var fs9 = __toESM2(__require("fs"));
35905
+ var fs10 = __toESM2(__require("fs"));
35617
35906
  var path13 = __toESM2(__require("path"));
35618
35907
  var import_token_util = require_token_util();
35619
35908
  function getAuthConfigPath() {
@@ -35626,10 +35915,10 @@ var require_auth_config = __commonJS((exports, module) => {
35626
35915
  function readAuthConfig() {
35627
35916
  try {
35628
35917
  const authPath = getAuthConfigPath();
35629
- if (!fs9.existsSync(authPath)) {
35918
+ if (!fs10.existsSync(authPath)) {
35630
35919
  return null;
35631
35920
  }
35632
- const content = fs9.readFileSync(authPath, "utf8");
35921
+ const content = fs10.readFileSync(authPath, "utf8");
35633
35922
  if (!content) {
35634
35923
  return null;
35635
35924
  }
@@ -35641,10 +35930,10 @@ var require_auth_config = __commonJS((exports, module) => {
35641
35930
  function writeAuthConfig(config3) {
35642
35931
  const authPath = getAuthConfigPath();
35643
35932
  const authDir = path13.dirname(authPath);
35644
- if (!fs9.existsSync(authDir)) {
35645
- fs9.mkdirSync(authDir, { mode: 504, recursive: true });
35933
+ if (!fs10.existsSync(authDir)) {
35934
+ fs10.mkdirSync(authDir, { mode: 504, recursive: true });
35646
35935
  }
35647
- fs9.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
35936
+ fs10.writeFileSync(authPath, JSON.stringify(config3, null, 2), { mode: 384 });
35648
35937
  }
35649
35938
  function isValidAccessToken(authConfig, expirationBufferMs = 0) {
35650
35939
  if (!authConfig.token)
@@ -35820,7 +36109,7 @@ var require_token_util = __commonJS((exports, module) => {
35820
36109
  });
35821
36110
  module.exports = __toCommonJS2(token_util_exports);
35822
36111
  var path13 = __toESM2(__require("path"));
35823
- var fs9 = __toESM2(__require("fs"));
36112
+ var fs10 = __toESM2(__require("fs"));
35824
36113
  var import_token_error = require_token_error();
35825
36114
  var import_token_io = require_token_io();
35826
36115
  var import_auth_config = require_auth_config();
@@ -35901,10 +36190,10 @@ var require_token_util = __commonJS((exports, module) => {
35901
36190
  throw new import_token_error.VercelOidcTokenError("Unable to find project root directory. Have you linked your project with `vc link?`");
35902
36191
  }
35903
36192
  const prjPath = path13.join(dir, ".vercel", "project.json");
35904
- if (!fs9.existsSync(prjPath)) {
36193
+ if (!fs10.existsSync(prjPath)) {
35905
36194
  throw new import_token_error.VercelOidcTokenError("project.json not found, have you linked your project with `vc link?`");
35906
36195
  }
35907
- const prj = JSON.parse(fs9.readFileSync(prjPath, "utf8"));
36196
+ const prj = JSON.parse(fs10.readFileSync(prjPath, "utf8"));
35908
36197
  if (typeof prj.projectId !== "string" && typeof prj.orgId !== "string") {
35909
36198
  throw new TypeError("Expected a string-valued projectId property. Try running `vc link` to re-link your project.");
35910
36199
  }
@@ -35917,9 +36206,9 @@ var require_token_util = __commonJS((exports, module) => {
35917
36206
  }
35918
36207
  const tokenPath = path13.join(dir, "com.vercel.token", `${projectId}.json`);
35919
36208
  const tokenJson = JSON.stringify(token);
35920
- fs9.mkdirSync(path13.dirname(tokenPath), { mode: 504, recursive: true });
35921
- fs9.writeFileSync(tokenPath, tokenJson);
35922
- fs9.chmodSync(tokenPath, 432);
36209
+ fs10.mkdirSync(path13.dirname(tokenPath), { mode: 504, recursive: true });
36210
+ fs10.writeFileSync(tokenPath, tokenJson);
36211
+ fs10.chmodSync(tokenPath, 432);
35923
36212
  return;
35924
36213
  }
35925
36214
  function loadToken(projectId) {
@@ -35928,10 +36217,10 @@ var require_token_util = __commonJS((exports, module) => {
35928
36217
  throw new import_token_error.VercelOidcTokenError("Unable to find user data directory. Please reach out to Vercel support.");
35929
36218
  }
35930
36219
  const tokenPath = path13.join(dir, "com.vercel.token", `${projectId}.json`);
35931
- if (!fs9.existsSync(tokenPath)) {
36220
+ if (!fs10.existsSync(tokenPath)) {
35932
36221
  return null;
35933
36222
  }
35934
- const token = JSON.parse(fs9.readFileSync(tokenPath, "utf8"));
36223
+ const token = JSON.parse(fs10.readFileSync(tokenPath, "utf8"));
35935
36224
  assertVercelOidcTokenResponse(token);
35936
36225
  return token;
35937
36226
  }
@@ -63361,26 +63650,26 @@ var require_process = __commonJS((exports, module) => {
63361
63650
 
63362
63651
  // ../../node_modules/detect-libc/lib/filesystem.js
63363
63652
  var require_filesystem = __commonJS((exports, module) => {
63364
- var fs9 = __require("fs");
63653
+ var fs10 = __require("fs");
63365
63654
  var LDD_PATH = "/usr/bin/ldd";
63366
63655
  var SELF_PATH = "/proc/self/exe";
63367
63656
  var MAX_LENGTH = 2048;
63368
63657
  var readFileSync2 = (path13) => {
63369
- const fd = fs9.openSync(path13, "r");
63658
+ const fd = fs10.openSync(path13, "r");
63370
63659
  const buffer = Buffer.alloc(MAX_LENGTH);
63371
- const bytesRead = fs9.readSync(fd, buffer, 0, MAX_LENGTH, 0);
63372
- fs9.close(fd, () => {});
63660
+ const bytesRead = fs10.readSync(fd, buffer, 0, MAX_LENGTH, 0);
63661
+ fs10.close(fd, () => {});
63373
63662
  return buffer.subarray(0, bytesRead);
63374
63663
  };
63375
63664
  var readFile = (path13) => new Promise((resolve4, reject) => {
63376
- fs9.open(path13, "r", (err, fd) => {
63665
+ fs10.open(path13, "r", (err, fd) => {
63377
63666
  if (err) {
63378
63667
  reject(err);
63379
63668
  } else {
63380
63669
  const buffer = Buffer.alloc(MAX_LENGTH);
63381
- fs9.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
63670
+ fs10.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
63382
63671
  resolve4(buffer.subarray(0, bytesRead));
63383
- fs9.close(fd, () => {});
63672
+ fs10.close(fd, () => {});
63384
63673
  });
63385
63674
  }
63386
63675
  });
@@ -100060,10 +100349,10 @@ Note that ${s.bold("include")} statements only accept relation fields.`, a12;
100060
100349
  super(t2, "P2023", r2);
100061
100350
  }
100062
100351
  };
100063
- var fs9 = new WeakMap;
100352
+ var fs10 = new WeakMap;
100064
100353
  function Ep(e) {
100065
- let t2 = fs9.get(e);
100066
- return t2 || (t2 = Object.entries(e), fs9.set(e, t2)), t2;
100354
+ let t2 = fs10.get(e);
100355
+ return t2 || (t2 = Object.entries(e), fs10.set(e, t2)), t2;
100067
100356
  }
100068
100357
  function hs(e, t2, r2) {
100069
100358
  switch (t2.type) {
@@ -115803,7 +116092,7 @@ var init_managed_run_repository_pg = __esm(() => {
115803
116092
  });
115804
116093
 
115805
116094
  // ../../packages/core/dist/services/search/project-indexer.js
115806
- import fs9 from "fs/promises";
116095
+ import fs10 from "fs/promises";
115807
116096
  import path14 from "path";
115808
116097
  import { randomUUID as randomUUID3 } from "crypto";
115809
116098
  async function runWithIndexLock(lockMap, projectId, work) {
@@ -116063,7 +116352,7 @@ async function checkSearchAdmission(deps, projectId, projectPath) {
116063
116352
  }
116064
116353
  async function indexFile(deps, filePath, projectId, projectRoot, centralityMap) {
116065
116354
  projectId = await getProjectIdentityAliasResolver().resolve(projectId);
116066
- const content = await fs9.readFile(filePath, "utf-8");
116355
+ const content = await fs10.readFile(filePath, "utf-8");
116067
116356
  const relativePath = path14.relative(projectRoot, filePath);
116068
116357
  const maxFileSize = config.get("security").maxFileSize || 1024 * 1024;
116069
116358
  if (content.length > maxFileSize) {
@@ -116929,7 +117218,7 @@ function stripNul(content) {
116929
117218
  }
116930
117219
 
116931
117220
  // ../../packages/core/dist/services/etl/stages/discover.js
116932
- import fs10 from "fs/promises";
117221
+ import fs11 from "fs/promises";
116933
117222
  import path15 from "path";
116934
117223
  import { createHash as createHash5 } from "crypto";
116935
117224
 
@@ -117017,8 +117306,8 @@ class DiscoverStage {
117017
117306
  async processFile(ctx, relativePath, forceReindex) {
117018
117307
  const absolutePath = path15.join(ctx.projectPath, relativePath);
117019
117308
  try {
117020
- const stat2 = await fs10.stat(absolutePath);
117021
- const content = stripNul(await fs10.readFile(absolutePath, "utf-8"));
117309
+ const stat2 = await fs11.stat(absolutePath);
117310
+ const content = stripNul(await fs11.readFile(absolutePath, "utf-8"));
117022
117311
  const contentHash = createHash5("sha256").update(content).digest("hex");
117023
117312
  let needsReparse = forceReindex;
117024
117313
  if (!forceReindex) {
@@ -117062,7 +117351,7 @@ class DiscoverStage {
117062
117351
  }
117063
117352
  try {
117064
117353
  const gitignorePath = path15.join(projectPath, ".gitignore");
117065
- const gitignoreContent = await fs10.readFile(gitignorePath, "utf8");
117354
+ const gitignoreContent = await fs11.readFile(gitignorePath, "utf8");
117066
117355
  const rules = gitignoreContent.split(`
117067
117356
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
117068
117357
  ig.add(rules);
@@ -119391,7 +119680,7 @@ var init_structural_runtime = __esm(() => {
119391
119680
 
119392
119681
  // ../../packages/core/dist/services/etl/stages/parse.js
119393
119682
  import path16 from "path";
119394
- import fs11 from "fs/promises";
119683
+ import fs12 from "fs/promises";
119395
119684
  function resolveChunkerMaxChars() {
119396
119685
  const global2 = Number(process.env.EMBEDDING_MAX_CHARS);
119397
119686
  if (Number.isFinite(global2) && global2 > 0)
@@ -119483,7 +119772,7 @@ class ParseStage {
119483
119772
  if (!file3.needsReparse) {
119484
119773
  const extension = path16.extname(file3.relativePath).toLowerCase();
119485
119774
  if ([".c", ".cpp", ".hpp"].includes(extension)) {
119486
- const content = file3.snapshotContent ?? await fs11.readFile(file3.absolutePath, "utf8");
119775
+ const content = file3.snapshotContent ?? await fs12.readFile(file3.absolutePath, "utf8");
119487
119776
  const outcome = await this.runtime.parse({ extension, source: Buffer.from(content) });
119488
119777
  if (outcome.status === "failed")
119489
119778
  throw new StructuralEtlParseError(file3.relativePath, outcome.failureKind, `Structural evidence parse failed (${outcome.failureKind})`, outcome.diagnosticCount, outcome.diagnostics.slice(0, 10));
@@ -119495,7 +119784,7 @@ class ParseStage {
119495
119784
  return { file: file3, chunks: [], symbols: [], rawImports: [], rawEdges: [] };
119496
119785
  }
119497
119786
  try {
119498
- const content = file3.snapshotContent ?? await fs11.readFile(file3.absolutePath, "utf-8");
119787
+ const content = file3.snapshotContent ?? await fs12.readFile(file3.absolutePath, "utf-8");
119499
119788
  const ext2 = path16.extname(file3.relativePath).toLowerCase();
119500
119789
  const chunkerMaxChars = resolveChunkerMaxChars();
119501
119790
  const chunks = smartChunk(content, file3.relativePath, chunkerMaxChars ? { maxChunkChars: chunkerMaxChars } : {});
@@ -120536,7 +120825,7 @@ var init_data_document2 = __esm(() => {
120536
120825
 
120537
120826
  // ../../packages/core/dist/services/etl/stages/resolve.js
120538
120827
  import path19 from "path";
120539
- import fs12 from "fs";
120828
+ import fs13 from "fs";
120540
120829
 
120541
120830
  class ResolveStage {
120542
120831
  symbolRepository;
@@ -120853,7 +121142,7 @@ class ResolveStage {
120853
121142
  const aliases = [];
120854
121143
  const tsconfigPath = path19.join(projectPath, "tsconfig.json");
120855
121144
  try {
120856
- const raw2 = fs12.readFileSync(tsconfigPath, "utf-8");
121145
+ const raw2 = fs13.readFileSync(tsconfigPath, "utf-8");
120857
121146
  const stripped = raw2.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
120858
121147
  const tsconfig = JSON.parse(stripped);
120859
121148
  const paths = tsconfig?.compilerOptions?.paths ?? {};
@@ -123149,7 +123438,7 @@ __export(exports_symbol_graph_service, {
123149
123438
  SymbolGraphService: () => SymbolGraphService
123150
123439
  });
123151
123440
  import path23 from "path";
123152
- import fs13 from "fs/promises";
123441
+ import fs14 from "fs/promises";
123153
123442
 
123154
123443
  class SymbolGraphService {
123155
123444
  identityLookup;
@@ -123477,7 +123766,7 @@ class SymbolGraphService {
123477
123766
  async readSnippet(relativePath, lineStart, lineEnd, projectId) {
123478
123767
  try {
123479
123768
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123480
- const content = await fs13.readFile(absolutePath, "utf-8");
123769
+ const content = await fs14.readFile(absolutePath, "utf-8");
123481
123770
  const lines = content.split(`
123482
123771
  `);
123483
123772
  return lines.slice(Math.max(0, lineStart - 1), Math.min(lines.length, lineEnd)).join(`
@@ -123489,7 +123778,7 @@ class SymbolGraphService {
123489
123778
  async readContext(relativePath, lineNumber, contextLines, projectId) {
123490
123779
  try {
123491
123780
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123492
- const content = await fs13.readFile(absolutePath, "utf-8");
123781
+ const content = await fs14.readFile(absolutePath, "utf-8");
123493
123782
  const lines = content.split(`
123494
123783
  `);
123495
123784
  const start = Math.max(0, lineNumber - contextLines - 1);
@@ -130662,7 +130951,7 @@ var init_l1_memory_cache = __esm(() => {
130662
130951
  });
130663
130952
 
130664
130953
  // ../../packages/core/dist/services/health/local-health-checker.js
130665
- import fs16 from "fs/promises";
130954
+ import fs17 from "fs/promises";
130666
130955
  import { existsSync as existsSync3 } from "fs";
130667
130956
  import path28 from "path";
130668
130957
 
@@ -130698,10 +130987,10 @@ class LocalHealthChecker {
130698
130987
  const start = Date.now();
130699
130988
  try {
130700
130989
  if (!existsSync3(this.dataDir))
130701
- await fs16.mkdir(this.dataDir, { recursive: true });
130990
+ await fs17.mkdir(this.dataDir, { recursive: true });
130702
130991
  const probe2 = path28.join(this.dataDir, ".health-check-test");
130703
- await fs16.writeFile(probe2, "ok");
130704
- await fs16.unlink(probe2);
130992
+ await fs17.writeFile(probe2, "ok");
130993
+ await fs17.unlink(probe2);
130705
130994
  return { available: true, latency: Date.now() - start, details: { path: this.dataDir, writable: true } };
130706
130995
  } catch (error51) {
130707
130996
  return { available: false, latency: Date.now() - start, error: `Data directory error: ${error51.message}` };
@@ -132625,7 +132914,7 @@ var init_scheduler2 = __esm(() => {
132625
132914
  });
132626
132915
 
132627
132916
  // ../../packages/core/dist/services/pricing/models-dev-client.js
132628
- import fs17 from "fs/promises";
132917
+ import fs18 from "fs/promises";
132629
132918
  import { existsSync as existsSync4 } from "fs";
132630
132919
  import path29 from "path";
132631
132920
  function getModelsDevClient() {
@@ -132655,7 +132944,7 @@ var init_models_dev_client = __esm(() => {
132655
132944
  if (!existsSync4(cachePath)) {
132656
132945
  return null;
132657
132946
  }
132658
- const content = await fs17.readFile(cachePath, "utf-8");
132947
+ const content = await fs18.readFile(cachePath, "utf-8");
132659
132948
  const data = JSON.parse(content);
132660
132949
  const age = Date.now() - data.timestamp;
132661
132950
  if (age > ModelsDevClient.LOCAL_CACHE_TTL) {
@@ -132683,13 +132972,13 @@ var init_models_dev_client = __esm(() => {
132683
132972
  const cachePath = this.getLocalCachePath();
132684
132973
  try {
132685
132974
  const dir = path29.dirname(cachePath);
132686
- await fs17.mkdir(dir, { recursive: true });
132975
+ await fs18.mkdir(dir, { recursive: true });
132687
132976
  const data = {
132688
132977
  timestamp: Date.now(),
132689
132978
  version: "1.0.0",
132690
132979
  models: Object.fromEntries(models)
132691
132980
  };
132692
- await fs17.writeFile(cachePath, JSON.stringify(data), "utf-8");
132981
+ await fs18.writeFile(cachePath, JSON.stringify(data), "utf-8");
132693
132982
  logger.debug("Saved pricing to local cache", {
132694
132983
  models: models.size,
132695
132984
  path: cachePath
@@ -133018,7 +133307,7 @@ var init_models_dev_client = __esm(() => {
133018
133307
  const cachePath = this.getLocalCachePath();
133019
133308
  try {
133020
133309
  if (existsSync4(cachePath)) {
133021
- await fs17.unlink(cachePath);
133310
+ await fs18.unlink(cachePath);
133022
133311
  logger.debug("Local pricing cache file deleted");
133023
133312
  }
133024
133313
  } catch (error51) {
@@ -158254,20 +158543,20 @@ class ElysiaFile {
158254
158543
  warnMissing();
158255
158544
  return;
158256
158545
  }
158257
- const fs3 = process.getBuiltinModule("fs");
158258
- if (!fs3) {
158546
+ const fs4 = process.getBuiltinModule("fs");
158547
+ if (!fs4) {
158259
158548
  warnMissing();
158260
158549
  return;
158261
158550
  }
158262
- if (typeof fs3.createReadStream != "function") {
158551
+ if (typeof fs4.createReadStream != "function") {
158263
158552
  warnMissing();
158264
158553
  return;
158265
158554
  }
158266
- if (typeof fs3.promises?.stat != "function") {
158555
+ if (typeof fs4.promises?.stat != "function") {
158267
158556
  warnMissing();
158268
158557
  return;
158269
158558
  }
158270
- createReadStream = fs3.createReadStream, stat = fs3.promises.stat;
158559
+ createReadStream = fs4.createReadStream, stat = fs4.promises.stat;
158271
158560
  }
158272
158561
  this.value = createReadStream(path6), this.stats = stat(path6);
158273
158562
  }
@@ -175718,7 +176007,7 @@ init_dist();
175718
176007
  init_db_connection();
175719
176008
  init_alias_resolver();
175720
176009
  init_safe_error_summary();
175721
- import fs14 from "fs";
176010
+ import fs15 from "fs";
175722
176011
  import os6 from "os";
175723
176012
  import path25 from "path";
175724
176013
 
@@ -175902,7 +176191,7 @@ class AttributionResolver {
175902
176191
  }
175903
176192
  function defaultCanonicalize(cwd) {
175904
176193
  try {
175905
- return fs14.realpathSync(cwd);
176194
+ return fs15.realpathSync(cwd);
175906
176195
  } catch {
175907
176196
  try {
175908
176197
  return path25.resolve(cwd);
@@ -176442,7 +176731,7 @@ init_code_compressor();
176442
176731
 
176443
176732
  // ../../packages/core/dist/services/file-read/file-content-cache.js
176444
176733
  init_dist();
176445
- import fs15 from "fs/promises";
176734
+ import fs16 from "fs/promises";
176446
176735
 
176447
176736
  class FileContentCache {
176448
176737
  extractMetadata;
@@ -176475,7 +176764,7 @@ class FileContentCache {
176475
176764
  metadata: cached2.metadata
176476
176765
  };
176477
176766
  }
176478
- const content = await fs15.readFile(filePath, "utf-8");
176767
+ const content = await fs16.readFile(filePath, "utf-8");
176479
176768
  const metadata = await this.extractMetadata(content, filePath, options);
176480
176769
  evictOldest(this.fileCache, this.FILE_CACHE_MAX_ENTRIES - 1);
176481
176770
  this.fileCache.set(cacheKey, {
@@ -177516,7 +177805,7 @@ init_event_bus();
177516
177805
  init_llm_client();
177517
177806
  init_symbol_graph_service();
177518
177807
  import { randomUUID as randomUUID9 } from "crypto";
177519
- import fs18 from "fs";
177808
+ import fs19 from "fs";
177520
177809
  import path30 from "path";
177521
177810
  import { spawn as spawn2 } from "child_process";
177522
177811
  var FALLBACK_BOOTSTRAP = {
@@ -177702,8 +177991,8 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177702
177991
  try {
177703
177992
  for (const name26 of README_CANDIDATES) {
177704
177993
  const p = path30.join(projectRoot, name26);
177705
- if (fs18.existsSync(p) && fs18.statSync(p).isFile()) {
177706
- const buf = fs18.readFileSync(p);
177994
+ if (fs19.existsSync(p) && fs19.statSync(p).isFile()) {
177995
+ const buf = fs19.readFileSync(p);
177707
177996
  signals.readme = buf.slice(0, MAX_README_BYTES).toString("utf8");
177708
177997
  break;
177709
177998
  }
@@ -177713,11 +178002,11 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177713
178002
  }
177714
178003
  try {
177715
178004
  const docsDir = path30.join(projectRoot, "docs");
177716
- if (fs18.existsSync(docsDir) && fs18.statSync(docsDir).isDirectory()) {
178005
+ if (fs19.existsSync(docsDir) && fs19.statSync(docsDir).isDirectory()) {
177717
178006
  const entries = walkMarkdown(docsDir).slice(0, MAX_DOCS);
177718
178007
  for (const rel of entries) {
177719
178008
  try {
177720
- const buf = fs18.readFileSync(rel);
178009
+ const buf = fs19.readFileSync(rel);
177721
178010
  signals.docs.push({
177722
178011
  path: path30.relative(projectRoot, rel),
177723
178012
  snippet: buf.slice(0, MAX_DOC_BYTES).toString("utf8")
@@ -177731,9 +178020,9 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177731
178020
  try {
177732
178021
  for (const name26 of MANIFEST_FILES) {
177733
178022
  const p = path30.join(projectRoot, name26);
177734
- if (!fs18.existsSync(p) || !fs18.statSync(p).isFile())
178023
+ if (!fs19.existsSync(p) || !fs19.statSync(p).isFile())
177735
178024
  continue;
177736
- const raw2 = fs18.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
178025
+ const raw2 = fs19.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
177737
178026
  const kind = name26;
177738
178027
  if (name26 === "package.json") {
177739
178028
  try {
@@ -177773,7 +178062,7 @@ function walkMarkdown(dir) {
177773
178062
  const cur = stack.pop();
177774
178063
  let entries;
177775
178064
  try {
177776
- entries = fs18.readdirSync(cur, { withFileTypes: true });
178065
+ entries = fs19.readdirSync(cur, { withFileTypes: true });
177777
178066
  } catch {
177778
178067
  continue;
177779
178068
  }
@@ -178697,6 +178986,7 @@ var memoryRoutes = new Elysia({ prefix: "/api/v1/memory" }).post("/store", async
178697
178986
  });
178698
178987
 
178699
178988
  // src/routes/checkpoints.ts
178989
+ init_services();
178700
178990
  init_dist();
178701
178991
  var listCheckpointsTool = null;
178702
178992
  var createCheckpointTool = null;
@@ -178719,6 +179009,13 @@ function getRestoreCheckpointTool() {
178719
179009
  }
178720
179010
  return restoreCheckpointTool;
178721
179011
  }
179012
+ var checkpointManager = null;
179013
+ function getCheckpointManager() {
179014
+ if (!checkpointManager) {
179015
+ checkpointManager = CheckpointManager.getInstance();
179016
+ }
179017
+ return checkpointManager;
179018
+ }
178722
179019
  var checkpointRoutes = new Elysia({ prefix: "/api/v1/checkpoints" }).post("/list", async ({ body }) => {
178723
179020
  try {
178724
179021
  return await getListCheckpointsTool().handle(body);
@@ -178807,11 +179104,39 @@ var checkpointRoutes = new Elysia({ prefix: "/api/v1/checkpoints" }).post("/list
178807
179104
  summary: "Restore checkpoint",
178808
179105
  description: "Restore a saved checkpoint and return its state plus integrity checks."
178809
179106
  }
179107
+ }).post("/delete", ({ body, set: set3 }) => {
179108
+ try {
179109
+ const { id } = body;
179110
+ const existed = getCheckpointManager().deleteCheckpoint(id);
179111
+ if (!existed) {
179112
+ set3.status = 404;
179113
+ return { success: false, error: "not found" };
179114
+ }
179115
+ set3.status = 200;
179116
+ return { success: true, data: { ok: true } };
179117
+ } catch (error51) {
179118
+ logger.error("Failed to delete checkpoint", error51);
179119
+ set3.status = 500;
179120
+ return {
179121
+ success: false,
179122
+ error: `Checkpoint service error: ${error51.message}`
179123
+ };
179124
+ }
179125
+ }, {
179126
+ body: t.Object({
179127
+ id: t.String({ description: "Checkpoint ID to delete" }),
179128
+ projectId: t.Optional(t.String({ description: "Project ID (unused, for API parity)" }))
179129
+ }),
179130
+ detail: {
179131
+ tags: ["checkpoint"],
179132
+ summary: "Delete checkpoint by ID",
179133
+ description: "Deletes a checkpoint. Returns 200 {ok:true} on mirror-hit, 404 on non-existent ID, 500 on store error. Mirror-sync: the in-memory mirror is updated immediately; the durable PG delete is async (Plan Challenge F4 \u2014 a restart before the durable delete completes could re-show the row)."
179134
+ }
178810
179135
  });
178811
179136
 
178812
179137
  // src/routes/project.ts
178813
179138
  init_dist();
178814
- import fs19 from "fs/promises";
179139
+ import fs20 from "fs/promises";
178815
179140
  import path31 from "path";
178816
179141
  var indexProjectTool = null;
178817
179142
  var indexStatusTool = null;
@@ -179023,8 +179348,8 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
179023
179348
  const finalProjectId = rawBase.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 128);
179024
179349
  const uploadRoot = process.env.MASSA_AI_UPLOAD_DIR || path31.join(getGlobalDataDir(), "uploads");
179025
179350
  const stagingDir = path31.resolve(uploadRoot, finalProjectId);
179026
- await fs19.rm(stagingDir, { recursive: true, force: true });
179027
- await fs19.mkdir(stagingDir, { recursive: true });
179351
+ await fs20.rm(stagingDir, { recursive: true, force: true });
179352
+ await fs20.mkdir(stagingDir, { recursive: true });
179028
179353
  const WRITE_BATCH = 20;
179029
179354
  for (let i = 0;i < body.files.length; i += WRITE_BATCH) {
179030
179355
  await Promise.all(body.files.slice(i, i + WRITE_BATCH).map(async (file3) => {
@@ -179035,8 +179360,8 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
179035
179360
  if (!dest.startsWith(stagingDir + path31.sep)) {
179036
179361
  throw new Error(`Path escapes staging directory: ${file3.relativePath}`);
179037
179362
  }
179038
- await fs19.mkdir(path31.dirname(dest), { recursive: true });
179039
- await fs19.writeFile(dest, file3.content, "utf-8");
179363
+ await fs20.mkdir(path31.dirname(dest), { recursive: true });
179364
+ await fs20.writeFile(dest, file3.content, "utf-8");
179040
179365
  }));
179041
179366
  }
179042
179367
  return await getIndexProjectTool().handle({
@@ -179191,7 +179516,7 @@ var analyticsRoutes = new Elysia({ prefix: "/api/v1/analytics" }).post("/", asyn
179191
179516
  // src/routes/system.ts
179192
179517
  init_dist();
179193
179518
  import path32 from "path";
179194
- import fs20 from "fs";
179519
+ import fs21 from "fs";
179195
179520
  import os7 from "os";
179196
179521
  function databaseUrlParts() {
179197
179522
  const url2 = new URL(process.env.DATABASE_URL);
@@ -179267,9 +179592,9 @@ var systemRoutes = new Elysia({ prefix: "/api/v1/system" }).get("/info", async (
179267
179592
  }).get("/metrics", async () => {
179268
179593
  const metricsPath = path32.join(process.cwd(), "data", "metrics.json");
179269
179594
  let metrics2 = {};
179270
- if (fs20.existsSync(metricsPath)) {
179595
+ if (fs21.existsSync(metricsPath)) {
179271
179596
  try {
179272
- metrics2 = JSON.parse(fs20.readFileSync(metricsPath, "utf-8"));
179597
+ metrics2 = JSON.parse(fs21.readFileSync(metricsPath, "utf-8"));
179273
179598
  } catch {}
179274
179599
  }
179275
179600
  const database = await getDatabaseInfo();
@@ -179419,7 +179744,7 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
179419
179744
  });
179420
179745
 
179421
179746
  // src/routes/workspace.ts
179422
- import fs21 from "fs/promises";
179747
+ import fs22 from "fs/promises";
179423
179748
  import path33 from "path";
179424
179749
  import { realpathSync as realpathSync4 } from "fs";
179425
179750
  var indexProjectTool2 = null;
@@ -179945,7 +180270,7 @@ var workspaceRoutes = new Elysia({ prefix: "/api/v1" }).get("/workspace/list", a
179945
180270
  end = start + 20;
179946
180271
  }
179947
180272
  const absolutePath = path33.join(workspace.project_path, file3);
179948
- const content = await fs21.readFile(absolutePath, "utf-8");
180273
+ const content = await fs22.readFile(absolutePath, "utf-8");
179949
180274
  const lines = content.split(/\r?\n/);
179950
180275
  const slice = lines.slice(start - 1, Math.min(lines.length, end));
179951
180276
  const formatted = slice.map((text3, idx) => ({
@@ -180870,7 +181195,7 @@ var webRoutes = new Elysia({ prefix: "/api/v1/web" }).post("/fetch_and_index", a
180870
181195
  });
180871
181196
 
180872
181197
  // src/routes/web-ui.ts
180873
- import fs22 from "fs/promises";
181198
+ import fs23 from "fs/promises";
180874
181199
  import path34 from "path";
180875
181200
  import { fileURLToPath as fileURLToPath3 } from "url";
180876
181201
 
@@ -180929,7 +181254,7 @@ var STATIC_DIR_CANDIDATES = buildStaticDirCandidates(path34.dirname(fileURLToPat
180929
181254
  async function resolveStaticDir() {
180930
181255
  for (const dir of STATIC_DIR_CANDIDATES) {
180931
181256
  try {
180932
- const st = await fs22.stat(dir);
181257
+ const st = await fs23.stat(dir);
180933
181258
  if (st.isDirectory())
180934
181259
  return dir;
180935
181260
  } catch {}
@@ -180967,7 +181292,7 @@ async function resolveSafePath(staticDir, sub) {
180967
181292
  return null;
180968
181293
  }
180969
181294
  try {
180970
- await fs22.stat(abs);
181295
+ await fs23.stat(abs);
180971
181296
  return { abs, exists: true };
180972
181297
  } catch {
180973
181298
  return { abs, exists: false };
@@ -180990,7 +181315,7 @@ function injectAccessMarkup(html, apiKey, trusted) {
180990
181315
  return out;
180991
181316
  }
180992
181317
  async function readShell(indexPath, remoteAddress) {
180993
- const raw2 = await fs22.readFile(indexPath, "utf-8");
181318
+ const raw2 = await fs23.readFile(indexPath, "utf-8");
180994
181319
  const trusted = isTrustedWebUiCaller(remoteAddress);
180995
181320
  return Buffer.from(injectAccessMarkup(raw2, getConfiguredApiKey(), trusted), "utf-8");
180996
181321
  }
@@ -181040,7 +181365,7 @@ var webUiRoutes = new Elysia().get("/ui", async ({ set: set3, request }) => {
181040
181365
  }
181041
181366
  if (resolved.exists) {
181042
181367
  try {
181043
- const body = await fs22.readFile(resolved.abs);
181368
+ const body = await fs23.readFile(resolved.abs);
181044
181369
  set3.headers["content-type"] = contentTypeFor(resolved.abs);
181045
181370
  return body;
181046
181371
  } catch {
@@ -181275,13 +181600,241 @@ var profileRoutes = new Elysia({ prefix: "/api/v1/profiles" }).get("/", ({ query
181275
181600
  }
181276
181601
  });
181277
181602
 
181603
+ // src/routes/config.ts
181604
+ init_dist();
181605
+ var CONFIG_DETAIL = {
181606
+ tags: ["config"]
181607
+ };
181608
+ var configRoutes = new Elysia({ prefix: "/api/v1/config" }).get("/", ({ set: set3 }) => {
181609
+ const config3 = loadConfig();
181610
+ const masked = maskSensitive(config3);
181611
+ const restart = restartNeededSections(config3);
181612
+ set3.status = 200;
181613
+ return {
181614
+ success: true,
181615
+ data: { config: masked, restartNeededSections: restart }
181616
+ };
181617
+ }, {
181618
+ detail: {
181619
+ ...CONFIG_DETAIL,
181620
+ summary: "Get current config with sensitive fields masked",
181621
+ description: "Returns the current config.json with security.apiKey, llm.apiKey, embedding.apiKey, and database.url masked to '***'. Includes restartNeededSections \u2014 the subset of [database, embedding, llm, security] present in the config."
181622
+ }
181623
+ }).put("/", ({ body, set: set3 }) => {
181624
+ const result = savePartialConfig(body);
181625
+ if (!result.success) {
181626
+ set3.status = 400;
181627
+ return {
181628
+ success: false,
181629
+ error: "validation failed",
181630
+ details: result.details
181631
+ };
181632
+ }
181633
+ const masked = maskSensitive(result.config);
181634
+ set3.status = 200;
181635
+ return {
181636
+ success: true,
181637
+ data: { config: masked, restartNeededSections: result.restartNeededSections }
181638
+ };
181639
+ }, {
181640
+ body: t.Object({}, { additionalProperties: true }),
181641
+ detail: {
181642
+ ...CONFIG_DETAIL,
181643
+ summary: "Update config sections (partial, validated, atomic)",
181644
+ description: "Accepts one or more top-level config sections. Validates each provided section, backs up to config.json.bak.<timestamp>, merges shallowly per top-level key, writes atomically. Returns the updated masked config + restartNeededSections. A sensitive field equal to '***' preserves the existing value."
181645
+ }
181646
+ });
181647
+
181648
+ // src/routes/model-registry.ts
181649
+ init_config();
181650
+ import fs24 from "fs";
181651
+ import path35 from "path";
181652
+ import { spawnSync } from "child_process";
181653
+ var _profilesLib = null;
181654
+ function profilesLib() {
181655
+ if (!_profilesLib) {
181656
+ const libPath = ["..", "..", "..", "..", "scripts", "lib", "model-profiles.ts"].join("/");
181657
+ _profilesLib = __require(libPath);
181658
+ }
181659
+ return _profilesLib;
181660
+ }
181661
+ var REGISTRY_DETAIL = {
181662
+ tags: ["model-registry"]
181663
+ };
181664
+ var OVERLAY_PATH = path35.join(configDir("massa-ai"), "model-profiles.json");
181665
+ var GENERATE_SCRIPT = path35.resolve(import.meta.dirname, "../../../../scripts/generate-subagent-artifacts.ts");
181666
+ var modelRegistryRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).get("/", ({ set: set3 }) => {
181667
+ const lib = profilesLib();
181668
+ const result = lib.loadEffectiveRegistry({ overlayPath: OVERLAY_PATH });
181669
+ set3.status = 200;
181670
+ return {
181671
+ success: true,
181672
+ data: {
181673
+ registry: result.registry,
181674
+ source: result.source,
181675
+ ...result.overlayError ? { overlayError: result.overlayError } : {}
181676
+ }
181677
+ };
181678
+ }, {
181679
+ detail: {
181680
+ ...REGISTRY_DETAIL,
181681
+ summary: "Get effective registry (builtin + overlay) with source attribution",
181682
+ description: "Returns the merged registry (builtin + overlay), source attribution (builtin, overlay, tombstoned), and overlayError if the overlay is corrupted (200 status, never fails)."
181683
+ }
181684
+ }).put("/", ({ body, set: set3 }) => {
181685
+ const lib = profilesLib();
181686
+ const overlay = body;
181687
+ const builtin = lib.loadRegistry(lib.DEFAULT_REGISTRY_PATH);
181688
+ const merged = mergeOverlayForValidation(builtin, overlay);
181689
+ try {
181690
+ lib.validateRegistry(merged);
181691
+ } catch (e) {
181692
+ if (e instanceof lib.RegistryValidationError) {
181693
+ set3.status = 400;
181694
+ return {
181695
+ success: false,
181696
+ error: "validation failed",
181697
+ details: e.violations
181698
+ };
181699
+ }
181700
+ throw e;
181701
+ }
181702
+ try {
181703
+ writeOverlayAtomically(OVERLAY_PATH, overlay);
181704
+ } catch (e) {
181705
+ set3.status = 500;
181706
+ return {
181707
+ success: false,
181708
+ error: `overlay write failed: ${e.message}`
181709
+ };
181710
+ }
181711
+ const result = lib.loadEffectiveRegistry({ overlayPath: OVERLAY_PATH });
181712
+ set3.status = 200;
181713
+ return {
181714
+ success: true,
181715
+ data: {
181716
+ registry: result.registry,
181717
+ source: result.source
181718
+ }
181719
+ };
181720
+ }, {
181721
+ body: t.Object({}, { additionalProperties: true }),
181722
+ detail: {
181723
+ ...REGISTRY_DETAIL,
181724
+ summary: "Write overlay (full-replace, validated, atomic)",
181725
+ description: "Accepts the full overlay object. Validates the merged result (builtin + overlay) via validateRegistry(). On success, writes atomically to ~/.config/massa-ai/model-profiles.json and returns the updated effective registry. On failure, returns 400 with all violations."
181726
+ }
181727
+ }).post("/regenerate", ({ set: set3 }) => {
181728
+ try {
181729
+ const child = spawnSync("bun", [GENERATE_SCRIPT], {
181730
+ env: { ...process.env },
181731
+ stdio: ["pipe", "pipe", "pipe"]
181732
+ });
181733
+ if (child.exitCode !== 0) {
181734
+ set3.status = 500;
181735
+ return {
181736
+ success: false,
181737
+ error: `regeneration failed (exit ${child.exitCode}): ${child.stderr?.toString().trim()}`
181738
+ };
181739
+ }
181740
+ set3.status = 200;
181741
+ return {
181742
+ success: true,
181743
+ data: { regenerated: true }
181744
+ };
181745
+ } catch (e) {
181746
+ set3.status = 500;
181747
+ return {
181748
+ success: false,
181749
+ error: `regeneration error: ${e.message}`
181750
+ };
181751
+ }
181752
+ }, {
181753
+ detail: {
181754
+ ...REGISTRY_DETAIL,
181755
+ summary: "Regenerate subagent artifacts (spawn child process)",
181756
+ description: "Spawns `bun scripts/generate-subagent-artifacts.ts` as a child process with inherited env. Returns {regenerated:true} on success or 500 on non-zero exit. Does not switch profiles."
181757
+ }
181758
+ }).delete("/overlay", ({ set: set3 }) => {
181759
+ const lib = profilesLib();
181760
+ try {
181761
+ if (fs24.existsSync(OVERLAY_PATH)) {
181762
+ fs24.unlinkSync(OVERLAY_PATH);
181763
+ }
181764
+ const builtin = lib.loadRegistry(lib.DEFAULT_REGISTRY_PATH);
181765
+ set3.status = 200;
181766
+ return {
181767
+ success: true,
181768
+ data: {
181769
+ registry: builtin,
181770
+ source: { builtin, overlay: null, tombstoned: [] }
181771
+ }
181772
+ };
181773
+ } catch (e) {
181774
+ set3.status = 500;
181775
+ return {
181776
+ success: false,
181777
+ error: `failed to delete overlay: ${e.message}`
181778
+ };
181779
+ }
181780
+ }, {
181781
+ detail: {
181782
+ ...REGISTRY_DETAIL,
181783
+ summary: "Delete overlay (reset to built-in)",
181784
+ description: "Deletes the overlay file at ~/.config/massa-ai/model-profiles.json and returns the builtin registry."
181785
+ }
181786
+ });
181787
+ function mergeOverlayForValidation(builtin, overlay) {
181788
+ const result = JSON.parse(JSON.stringify(builtin));
181789
+ if (overlay.tiers && Array.isArray(overlay.tiers)) {
181790
+ result.tiers = [...overlay.tiers];
181791
+ }
181792
+ if (overlay.hostDefaults) {
181793
+ result.hostDefaults = { ...overlay.hostDefaults };
181794
+ }
181795
+ if (overlay.workflowTiers) {
181796
+ result.workflowTiers = { ...overlay.workflowTiers };
181797
+ }
181798
+ if (overlay.profiles) {
181799
+ const profiles = result.profiles;
181800
+ for (const [key, val] of Object.entries(overlay.profiles)) {
181801
+ if (val && typeof val === "object" && !Array.isArray(val)) {
181802
+ if (val._delete === true) {
181803
+ delete profiles[key];
181804
+ continue;
181805
+ }
181806
+ const { _delete: _unused, ...profileData } = val;
181807
+ profiles[key] = profileData;
181808
+ }
181809
+ }
181810
+ result.profiles = profiles;
181811
+ }
181812
+ return result;
181813
+ }
181814
+ function writeOverlayAtomically(overlayPath, data) {
181815
+ const dir = path35.dirname(overlayPath);
181816
+ if (!fs24.existsSync(dir)) {
181817
+ fs24.mkdirSync(dir, { recursive: true });
181818
+ }
181819
+ const tmp = `${overlayPath}.${process.pid}.${Date.now()}.tmp`;
181820
+ try {
181821
+ fs24.writeFileSync(tmp, JSON.stringify(data, null, 2));
181822
+ fs24.renameSync(tmp, overlayPath);
181823
+ } catch (e) {
181824
+ try {
181825
+ fs24.unlinkSync(tmp);
181826
+ } catch {}
181827
+ throw e;
181828
+ }
181829
+ }
181830
+
181278
181831
  // src/middleware/error.ts
181279
181832
  init_dist();
181280
- var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path35, request }) => {
181833
+ var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path36, request }) => {
181281
181834
  logger.error("[massa-ai-api] Request failed", undefined, {
181282
181835
  ...safeErrorSummary(error51),
181283
181836
  code,
181284
- path: path35,
181837
+ path: path36,
181285
181838
  method: request.method
181286
181839
  });
181287
181840
  if (error51 instanceof SearchServiceError) {
@@ -181397,7 +181950,7 @@ var app = new Elysia({ adapter: node() }).use(cors(buildCorsOptions(config.get("
181397
181950
  },
181398
181951
  security: [{ ApiKeyAuth: [] }]
181399
181952
  }
181400
- })).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).get("/health", () => buildHealthResponse(getParserReadiness()));
181953
+ })).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).get("/health", () => buildHealthResponse(getParserReadiness()));
181401
181954
  initAuthOrExit();
181402
181955
  warnIfTrustOverrideEnabled();
181403
181956
  await listenAfterParserValidation({