@massa-ai/tools-api 1.40.1 → 1.42.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 +873 -135
  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) {
@@ -108615,6 +108904,48 @@ var init_postgres_vector_store = __esm(() => {
108615
108904
  lastIndexed: row.last_updated?.toISOString() ?? null
108616
108905
  }));
108617
108906
  }
108907
+ async getPool() {
108908
+ if (this.pool)
108909
+ return this.pool;
108910
+ const pg = await import("pg");
108911
+ const PgPool = pg.default?.Pool ?? pg.Pool;
108912
+ const poolConfig = {
108913
+ connectionString: this.config.connectionString,
108914
+ max: this.config.poolSize,
108915
+ idleTimeoutMillis: 30000,
108916
+ connectionTimeoutMillis: 5000
108917
+ };
108918
+ this.pool = new PgPool(poolConfig);
108919
+ return this.pool;
108920
+ }
108921
+ async listAllProjectsAcrossDimensions() {
108922
+ const pool = await this.getPool();
108923
+ const { rows: tables } = await pool.query(`
108924
+ SELECT tablename FROM pg_tables
108925
+ WHERE tablename = 'vector_documents'
108926
+ OR tablename ~ '^vector_documents_[0-9]+d$'
108927
+ ORDER BY tablename
108928
+ `);
108929
+ if (tables.length === 0)
108930
+ return [];
108931
+ const unionParts = tables.map((t2) => `SELECT project_id, COUNT(*)::int AS doc_count, MAX(updated_at) AS last_updated, SUM(LENGTH(content))::bigint AS total_size FROM ${t2.tablename} WHERE id NOT LIKE '_metadata:%' GROUP BY project_id`).join(" UNION ALL ");
108932
+ const { rows } = await pool.query(`
108933
+ SELECT project_id,
108934
+ SUM(doc_count)::int AS doc_count,
108935
+ MAX(last_updated) AS last_updated,
108936
+ SUM(total_size)::bigint AS total_size
108937
+ FROM (${unionParts}) AS merged
108938
+ GROUP BY project_id
108939
+ ORDER BY last_updated DESC
108940
+ `);
108941
+ return rows.map((row) => ({
108942
+ projectId: row.project_id,
108943
+ projectPath: null,
108944
+ documentCount: parseInt(row.doc_count),
108945
+ totalSize: parseInt(row.total_size ?? "0"),
108946
+ lastIndexed: row.last_updated?.toISOString() ?? null
108947
+ }));
108948
+ }
108618
108949
  async getCollection(name26) {
108619
108950
  const pool = await this.ensureInitialized();
108620
108951
  return new PostgresVectorCollection(pool, name26, this.tableName, this);
@@ -115803,7 +116134,7 @@ var init_managed_run_repository_pg = __esm(() => {
115803
116134
  });
115804
116135
 
115805
116136
  // ../../packages/core/dist/services/search/project-indexer.js
115806
- import fs9 from "fs/promises";
116137
+ import fs10 from "fs/promises";
115807
116138
  import path14 from "path";
115808
116139
  import { randomUUID as randomUUID3 } from "crypto";
115809
116140
  async function runWithIndexLock(lockMap, projectId, work) {
@@ -116063,7 +116394,7 @@ async function checkSearchAdmission(deps, projectId, projectPath) {
116063
116394
  }
116064
116395
  async function indexFile(deps, filePath, projectId, projectRoot, centralityMap) {
116065
116396
  projectId = await getProjectIdentityAliasResolver().resolve(projectId);
116066
- const content = await fs9.readFile(filePath, "utf-8");
116397
+ const content = await fs10.readFile(filePath, "utf-8");
116067
116398
  const relativePath = path14.relative(projectRoot, filePath);
116068
116399
  const maxFileSize = config.get("security").maxFileSize || 1024 * 1024;
116069
116400
  if (content.length > maxFileSize) {
@@ -116929,7 +117260,7 @@ function stripNul(content) {
116929
117260
  }
116930
117261
 
116931
117262
  // ../../packages/core/dist/services/etl/stages/discover.js
116932
- import fs10 from "fs/promises";
117263
+ import fs11 from "fs/promises";
116933
117264
  import path15 from "path";
116934
117265
  import { createHash as createHash5 } from "crypto";
116935
117266
 
@@ -117017,8 +117348,8 @@ class DiscoverStage {
117017
117348
  async processFile(ctx, relativePath, forceReindex) {
117018
117349
  const absolutePath = path15.join(ctx.projectPath, relativePath);
117019
117350
  try {
117020
- const stat2 = await fs10.stat(absolutePath);
117021
- const content = stripNul(await fs10.readFile(absolutePath, "utf-8"));
117351
+ const stat2 = await fs11.stat(absolutePath);
117352
+ const content = stripNul(await fs11.readFile(absolutePath, "utf-8"));
117022
117353
  const contentHash = createHash5("sha256").update(content).digest("hex");
117023
117354
  let needsReparse = forceReindex;
117024
117355
  if (!forceReindex) {
@@ -117062,7 +117393,7 @@ class DiscoverStage {
117062
117393
  }
117063
117394
  try {
117064
117395
  const gitignorePath = path15.join(projectPath, ".gitignore");
117065
- const gitignoreContent = await fs10.readFile(gitignorePath, "utf8");
117396
+ const gitignoreContent = await fs11.readFile(gitignorePath, "utf8");
117066
117397
  const rules = gitignoreContent.split(`
117067
117398
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
117068
117399
  ig.add(rules);
@@ -119391,7 +119722,7 @@ var init_structural_runtime = __esm(() => {
119391
119722
 
119392
119723
  // ../../packages/core/dist/services/etl/stages/parse.js
119393
119724
  import path16 from "path";
119394
- import fs11 from "fs/promises";
119725
+ import fs12 from "fs/promises";
119395
119726
  function resolveChunkerMaxChars() {
119396
119727
  const global2 = Number(process.env.EMBEDDING_MAX_CHARS);
119397
119728
  if (Number.isFinite(global2) && global2 > 0)
@@ -119483,7 +119814,7 @@ class ParseStage {
119483
119814
  if (!file3.needsReparse) {
119484
119815
  const extension = path16.extname(file3.relativePath).toLowerCase();
119485
119816
  if ([".c", ".cpp", ".hpp"].includes(extension)) {
119486
- const content = file3.snapshotContent ?? await fs11.readFile(file3.absolutePath, "utf8");
119817
+ const content = file3.snapshotContent ?? await fs12.readFile(file3.absolutePath, "utf8");
119487
119818
  const outcome = await this.runtime.parse({ extension, source: Buffer.from(content) });
119488
119819
  if (outcome.status === "failed")
119489
119820
  throw new StructuralEtlParseError(file3.relativePath, outcome.failureKind, `Structural evidence parse failed (${outcome.failureKind})`, outcome.diagnosticCount, outcome.diagnostics.slice(0, 10));
@@ -119495,7 +119826,7 @@ class ParseStage {
119495
119826
  return { file: file3, chunks: [], symbols: [], rawImports: [], rawEdges: [] };
119496
119827
  }
119497
119828
  try {
119498
- const content = file3.snapshotContent ?? await fs11.readFile(file3.absolutePath, "utf-8");
119829
+ const content = file3.snapshotContent ?? await fs12.readFile(file3.absolutePath, "utf-8");
119499
119830
  const ext2 = path16.extname(file3.relativePath).toLowerCase();
119500
119831
  const chunkerMaxChars = resolveChunkerMaxChars();
119501
119832
  const chunks = smartChunk(content, file3.relativePath, chunkerMaxChars ? { maxChunkChars: chunkerMaxChars } : {});
@@ -120536,7 +120867,7 @@ var init_data_document2 = __esm(() => {
120536
120867
 
120537
120868
  // ../../packages/core/dist/services/etl/stages/resolve.js
120538
120869
  import path19 from "path";
120539
- import fs12 from "fs";
120870
+ import fs13 from "fs";
120540
120871
 
120541
120872
  class ResolveStage {
120542
120873
  symbolRepository;
@@ -120853,7 +121184,7 @@ class ResolveStage {
120853
121184
  const aliases = [];
120854
121185
  const tsconfigPath = path19.join(projectPath, "tsconfig.json");
120855
121186
  try {
120856
- const raw2 = fs12.readFileSync(tsconfigPath, "utf-8");
121187
+ const raw2 = fs13.readFileSync(tsconfigPath, "utf-8");
120857
121188
  const stripped = raw2.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
120858
121189
  const tsconfig = JSON.parse(stripped);
120859
121190
  const paths = tsconfig?.compilerOptions?.paths ?? {};
@@ -123149,7 +123480,7 @@ __export(exports_symbol_graph_service, {
123149
123480
  SymbolGraphService: () => SymbolGraphService
123150
123481
  });
123151
123482
  import path23 from "path";
123152
- import fs13 from "fs/promises";
123483
+ import fs14 from "fs/promises";
123153
123484
 
123154
123485
  class SymbolGraphService {
123155
123486
  identityLookup;
@@ -123477,7 +123808,7 @@ class SymbolGraphService {
123477
123808
  async readSnippet(relativePath, lineStart, lineEnd, projectId) {
123478
123809
  try {
123479
123810
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123480
- const content = await fs13.readFile(absolutePath, "utf-8");
123811
+ const content = await fs14.readFile(absolutePath, "utf-8");
123481
123812
  const lines = content.split(`
123482
123813
  `);
123483
123814
  return lines.slice(Math.max(0, lineStart - 1), Math.min(lines.length, lineEnd)).join(`
@@ -123489,7 +123820,7 @@ class SymbolGraphService {
123489
123820
  async readContext(relativePath, lineNumber, contextLines, projectId) {
123490
123821
  try {
123491
123822
  const absolutePath = await this.resolveToAbsolute(relativePath, projectId);
123492
- const content = await fs13.readFile(absolutePath, "utf-8");
123823
+ const content = await fs14.readFile(absolutePath, "utf-8");
123493
123824
  const lines = content.split(`
123494
123825
  `);
123495
123826
  const start = Math.max(0, lineNumber - contextLines - 1);
@@ -130662,7 +130993,7 @@ var init_l1_memory_cache = __esm(() => {
130662
130993
  });
130663
130994
 
130664
130995
  // ../../packages/core/dist/services/health/local-health-checker.js
130665
- import fs16 from "fs/promises";
130996
+ import fs17 from "fs/promises";
130666
130997
  import { existsSync as existsSync3 } from "fs";
130667
130998
  import path28 from "path";
130668
130999
 
@@ -130698,10 +131029,10 @@ class LocalHealthChecker {
130698
131029
  const start = Date.now();
130699
131030
  try {
130700
131031
  if (!existsSync3(this.dataDir))
130701
- await fs16.mkdir(this.dataDir, { recursive: true });
131032
+ await fs17.mkdir(this.dataDir, { recursive: true });
130702
131033
  const probe2 = path28.join(this.dataDir, ".health-check-test");
130703
- await fs16.writeFile(probe2, "ok");
130704
- await fs16.unlink(probe2);
131034
+ await fs17.writeFile(probe2, "ok");
131035
+ await fs17.unlink(probe2);
130705
131036
  return { available: true, latency: Date.now() - start, details: { path: this.dataDir, writable: true } };
130706
131037
  } catch (error51) {
130707
131038
  return { available: false, latency: Date.now() - start, error: `Data directory error: ${error51.message}` };
@@ -132625,7 +132956,7 @@ var init_scheduler2 = __esm(() => {
132625
132956
  });
132626
132957
 
132627
132958
  // ../../packages/core/dist/services/pricing/models-dev-client.js
132628
- import fs17 from "fs/promises";
132959
+ import fs18 from "fs/promises";
132629
132960
  import { existsSync as existsSync4 } from "fs";
132630
132961
  import path29 from "path";
132631
132962
  function getModelsDevClient() {
@@ -132655,7 +132986,7 @@ var init_models_dev_client = __esm(() => {
132655
132986
  if (!existsSync4(cachePath)) {
132656
132987
  return null;
132657
132988
  }
132658
- const content = await fs17.readFile(cachePath, "utf-8");
132989
+ const content = await fs18.readFile(cachePath, "utf-8");
132659
132990
  const data = JSON.parse(content);
132660
132991
  const age = Date.now() - data.timestamp;
132661
132992
  if (age > ModelsDevClient.LOCAL_CACHE_TTL) {
@@ -132683,13 +133014,13 @@ var init_models_dev_client = __esm(() => {
132683
133014
  const cachePath = this.getLocalCachePath();
132684
133015
  try {
132685
133016
  const dir = path29.dirname(cachePath);
132686
- await fs17.mkdir(dir, { recursive: true });
133017
+ await fs18.mkdir(dir, { recursive: true });
132687
133018
  const data = {
132688
133019
  timestamp: Date.now(),
132689
133020
  version: "1.0.0",
132690
133021
  models: Object.fromEntries(models)
132691
133022
  };
132692
- await fs17.writeFile(cachePath, JSON.stringify(data), "utf-8");
133023
+ await fs18.writeFile(cachePath, JSON.stringify(data), "utf-8");
132693
133024
  logger.debug("Saved pricing to local cache", {
132694
133025
  models: models.size,
132695
133026
  path: cachePath
@@ -133018,7 +133349,7 @@ var init_models_dev_client = __esm(() => {
133018
133349
  const cachePath = this.getLocalCachePath();
133019
133350
  try {
133020
133351
  if (existsSync4(cachePath)) {
133021
- await fs17.unlink(cachePath);
133352
+ await fs18.unlink(cachePath);
133022
133353
  logger.debug("Local pricing cache file deleted");
133023
133354
  }
133024
133355
  } catch (error51) {
@@ -158254,20 +158585,20 @@ class ElysiaFile {
158254
158585
  warnMissing();
158255
158586
  return;
158256
158587
  }
158257
- const fs3 = process.getBuiltinModule("fs");
158258
- if (!fs3) {
158588
+ const fs4 = process.getBuiltinModule("fs");
158589
+ if (!fs4) {
158259
158590
  warnMissing();
158260
158591
  return;
158261
158592
  }
158262
- if (typeof fs3.createReadStream != "function") {
158593
+ if (typeof fs4.createReadStream != "function") {
158263
158594
  warnMissing();
158264
158595
  return;
158265
158596
  }
158266
- if (typeof fs3.promises?.stat != "function") {
158597
+ if (typeof fs4.promises?.stat != "function") {
158267
158598
  warnMissing();
158268
158599
  return;
158269
158600
  }
158270
- createReadStream = fs3.createReadStream, stat = fs3.promises.stat;
158601
+ createReadStream = fs4.createReadStream, stat = fs4.promises.stat;
158271
158602
  }
158272
158603
  this.value = createReadStream(path6), this.stats = stat(path6);
158273
158604
  }
@@ -175718,7 +176049,7 @@ init_dist();
175718
176049
  init_db_connection();
175719
176050
  init_alias_resolver();
175720
176051
  init_safe_error_summary();
175721
- import fs14 from "fs";
176052
+ import fs15 from "fs";
175722
176053
  import os6 from "os";
175723
176054
  import path25 from "path";
175724
176055
 
@@ -175902,7 +176233,7 @@ class AttributionResolver {
175902
176233
  }
175903
176234
  function defaultCanonicalize(cwd) {
175904
176235
  try {
175905
- return fs14.realpathSync(cwd);
176236
+ return fs15.realpathSync(cwd);
175906
176237
  } catch {
175907
176238
  try {
175908
176239
  return path25.resolve(cwd);
@@ -176442,7 +176773,7 @@ init_code_compressor();
176442
176773
 
176443
176774
  // ../../packages/core/dist/services/file-read/file-content-cache.js
176444
176775
  init_dist();
176445
- import fs15 from "fs/promises";
176776
+ import fs16 from "fs/promises";
176446
176777
 
176447
176778
  class FileContentCache {
176448
176779
  extractMetadata;
@@ -176475,7 +176806,7 @@ class FileContentCache {
176475
176806
  metadata: cached2.metadata
176476
176807
  };
176477
176808
  }
176478
- const content = await fs15.readFile(filePath, "utf-8");
176809
+ const content = await fs16.readFile(filePath, "utf-8");
176479
176810
  const metadata = await this.extractMetadata(content, filePath, options);
176480
176811
  evictOldest(this.fileCache, this.FILE_CACHE_MAX_ENTRIES - 1);
176481
176812
  this.fileCache.set(cacheKey, {
@@ -177516,7 +177847,7 @@ init_event_bus();
177516
177847
  init_llm_client();
177517
177848
  init_symbol_graph_service();
177518
177849
  import { randomUUID as randomUUID9 } from "crypto";
177519
- import fs18 from "fs";
177850
+ import fs19 from "fs";
177520
177851
  import path30 from "path";
177521
177852
  import { spawn as spawn2 } from "child_process";
177522
177853
  var FALLBACK_BOOTSTRAP = {
@@ -177702,8 +178033,8 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177702
178033
  try {
177703
178034
  for (const name26 of README_CANDIDATES) {
177704
178035
  const p = path30.join(projectRoot, name26);
177705
- if (fs18.existsSync(p) && fs18.statSync(p).isFile()) {
177706
- const buf = fs18.readFileSync(p);
178036
+ if (fs19.existsSync(p) && fs19.statSync(p).isFile()) {
178037
+ const buf = fs19.readFileSync(p);
177707
178038
  signals.readme = buf.slice(0, MAX_README_BYTES).toString("utf8");
177708
178039
  break;
177709
178040
  }
@@ -177713,11 +178044,11 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177713
178044
  }
177714
178045
  try {
177715
178046
  const docsDir = path30.join(projectRoot, "docs");
177716
- if (fs18.existsSync(docsDir) && fs18.statSync(docsDir).isDirectory()) {
178047
+ if (fs19.existsSync(docsDir) && fs19.statSync(docsDir).isDirectory()) {
177717
178048
  const entries = walkMarkdown(docsDir).slice(0, MAX_DOCS);
177718
178049
  for (const rel of entries) {
177719
178050
  try {
177720
- const buf = fs18.readFileSync(rel);
178051
+ const buf = fs19.readFileSync(rel);
177721
178052
  signals.docs.push({
177722
178053
  path: path30.relative(projectRoot, rel),
177723
178054
  snippet: buf.slice(0, MAX_DOC_BYTES).toString("utf8")
@@ -177731,9 +178062,9 @@ async function scanSignals(_projectId, projectRoot, caps, symbolGraph, gitRunner
177731
178062
  try {
177732
178063
  for (const name26 of MANIFEST_FILES) {
177733
178064
  const p = path30.join(projectRoot, name26);
177734
- if (!fs18.existsSync(p) || !fs18.statSync(p).isFile())
178065
+ if (!fs19.existsSync(p) || !fs19.statSync(p).isFile())
177735
178066
  continue;
177736
- const raw2 = fs18.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
178067
+ const raw2 = fs19.readFileSync(p).slice(0, MAX_MANIFEST_BYTES).toString("utf8");
177737
178068
  const kind = name26;
177738
178069
  if (name26 === "package.json") {
177739
178070
  try {
@@ -177773,7 +178104,7 @@ function walkMarkdown(dir) {
177773
178104
  const cur = stack.pop();
177774
178105
  let entries;
177775
178106
  try {
177776
- entries = fs18.readdirSync(cur, { withFileTypes: true });
178107
+ entries = fs19.readdirSync(cur, { withFileTypes: true });
177777
178108
  } catch {
177778
178109
  continue;
177779
178110
  }
@@ -178697,6 +179028,7 @@ var memoryRoutes = new Elysia({ prefix: "/api/v1/memory" }).post("/store", async
178697
179028
  });
178698
179029
 
178699
179030
  // src/routes/checkpoints.ts
179031
+ init_services();
178700
179032
  init_dist();
178701
179033
  var listCheckpointsTool = null;
178702
179034
  var createCheckpointTool = null;
@@ -178719,6 +179051,13 @@ function getRestoreCheckpointTool() {
178719
179051
  }
178720
179052
  return restoreCheckpointTool;
178721
179053
  }
179054
+ var checkpointManager = null;
179055
+ function getCheckpointManager() {
179056
+ if (!checkpointManager) {
179057
+ checkpointManager = CheckpointManager.getInstance();
179058
+ }
179059
+ return checkpointManager;
179060
+ }
178722
179061
  var checkpointRoutes = new Elysia({ prefix: "/api/v1/checkpoints" }).post("/list", async ({ body }) => {
178723
179062
  try {
178724
179063
  return await getListCheckpointsTool().handle(body);
@@ -178807,11 +179146,39 @@ var checkpointRoutes = new Elysia({ prefix: "/api/v1/checkpoints" }).post("/list
178807
179146
  summary: "Restore checkpoint",
178808
179147
  description: "Restore a saved checkpoint and return its state plus integrity checks."
178809
179148
  }
179149
+ }).post("/delete", ({ body, set: set3 }) => {
179150
+ try {
179151
+ const { id } = body;
179152
+ const existed = getCheckpointManager().deleteCheckpoint(id);
179153
+ if (!existed) {
179154
+ set3.status = 404;
179155
+ return { success: false, error: "not found" };
179156
+ }
179157
+ set3.status = 200;
179158
+ return { success: true, data: { ok: true } };
179159
+ } catch (error51) {
179160
+ logger.error("Failed to delete checkpoint", error51);
179161
+ set3.status = 500;
179162
+ return {
179163
+ success: false,
179164
+ error: `Checkpoint service error: ${error51.message}`
179165
+ };
179166
+ }
179167
+ }, {
179168
+ body: t.Object({
179169
+ id: t.String({ description: "Checkpoint ID to delete" }),
179170
+ projectId: t.Optional(t.String({ description: "Project ID (unused, for API parity)" }))
179171
+ }),
179172
+ detail: {
179173
+ tags: ["checkpoint"],
179174
+ summary: "Delete checkpoint by ID",
179175
+ 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)."
179176
+ }
178810
179177
  });
178811
179178
 
178812
179179
  // src/routes/project.ts
178813
179180
  init_dist();
178814
- import fs19 from "fs/promises";
179181
+ import fs20 from "fs/promises";
178815
179182
  import path31 from "path";
178816
179183
  var indexProjectTool = null;
178817
179184
  var indexStatusTool = null;
@@ -178884,7 +179251,12 @@ var identityBodySchema = t.Object({
178884
179251
  var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async () => {
178885
179252
  try {
178886
179253
  const vectorStore = await getVectorStore();
178887
- const projects = await vectorStore.listProjects();
179254
+ let projects;
179255
+ try {
179256
+ projects = await vectorStore.listProjects();
179257
+ } catch {
179258
+ projects = await vectorStore.listAllProjectsAcrossDimensions?.() ?? [];
179259
+ }
178888
179260
  return {
178889
179261
  success: true,
178890
179262
  data: {
@@ -179023,8 +179395,8 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
179023
179395
  const finalProjectId = rawBase.replace(/[^a-zA-Z0-9_.-]/g, "_").slice(0, 128);
179024
179396
  const uploadRoot = process.env.MASSA_AI_UPLOAD_DIR || path31.join(getGlobalDataDir(), "uploads");
179025
179397
  const stagingDir = path31.resolve(uploadRoot, finalProjectId);
179026
- await fs19.rm(stagingDir, { recursive: true, force: true });
179027
- await fs19.mkdir(stagingDir, { recursive: true });
179398
+ await fs20.rm(stagingDir, { recursive: true, force: true });
179399
+ await fs20.mkdir(stagingDir, { recursive: true });
179028
179400
  const WRITE_BATCH = 20;
179029
179401
  for (let i = 0;i < body.files.length; i += WRITE_BATCH) {
179030
179402
  await Promise.all(body.files.slice(i, i + WRITE_BATCH).map(async (file3) => {
@@ -179035,8 +179407,8 @@ var projectRoutes = new Elysia({ prefix: "/api/v1/project" }).get("/list", async
179035
179407
  if (!dest.startsWith(stagingDir + path31.sep)) {
179036
179408
  throw new Error(`Path escapes staging directory: ${file3.relativePath}`);
179037
179409
  }
179038
- await fs19.mkdir(path31.dirname(dest), { recursive: true });
179039
- await fs19.writeFile(dest, file3.content, "utf-8");
179410
+ await fs20.mkdir(path31.dirname(dest), { recursive: true });
179411
+ await fs20.writeFile(dest, file3.content, "utf-8");
179040
179412
  }));
179041
179413
  }
179042
179414
  return await getIndexProjectTool().handle({
@@ -179191,7 +179563,7 @@ var analyticsRoutes = new Elysia({ prefix: "/api/v1/analytics" }).post("/", asyn
179191
179563
  // src/routes/system.ts
179192
179564
  init_dist();
179193
179565
  import path32 from "path";
179194
- import fs20 from "fs";
179566
+ import fs21 from "fs";
179195
179567
  import os7 from "os";
179196
179568
  function databaseUrlParts() {
179197
179569
  const url2 = new URL(process.env.DATABASE_URL);
@@ -179267,9 +179639,9 @@ var systemRoutes = new Elysia({ prefix: "/api/v1/system" }).get("/info", async (
179267
179639
  }).get("/metrics", async () => {
179268
179640
  const metricsPath = path32.join(process.cwd(), "data", "metrics.json");
179269
179641
  let metrics2 = {};
179270
- if (fs20.existsSync(metricsPath)) {
179642
+ if (fs21.existsSync(metricsPath)) {
179271
179643
  try {
179272
- metrics2 = JSON.parse(fs20.readFileSync(metricsPath, "utf-8"));
179644
+ metrics2 = JSON.parse(fs21.readFileSync(metricsPath, "utf-8"));
179273
179645
  } catch {}
179274
179646
  }
179275
179647
  const database = await getDatabaseInfo();
@@ -179419,7 +179791,7 @@ var eventsRoutes = new Elysia({ prefix: "/api/v1" }).get("/events", async ({ que
179419
179791
  });
179420
179792
 
179421
179793
  // src/routes/workspace.ts
179422
- import fs21 from "fs/promises";
179794
+ import fs22 from "fs/promises";
179423
179795
  import path33 from "path";
179424
179796
  import { realpathSync as realpathSync4 } from "fs";
179425
179797
  var indexProjectTool2 = null;
@@ -179945,7 +180317,7 @@ var workspaceRoutes = new Elysia({ prefix: "/api/v1" }).get("/workspace/list", a
179945
180317
  end = start + 20;
179946
180318
  }
179947
180319
  const absolutePath = path33.join(workspace.project_path, file3);
179948
- const content = await fs21.readFile(absolutePath, "utf-8");
180320
+ const content = await fs22.readFile(absolutePath, "utf-8");
179949
180321
  const lines = content.split(/\r?\n/);
179950
180322
  const slice = lines.slice(start - 1, Math.min(lines.length, end));
179951
180323
  const formatted = slice.map((text3, idx) => ({
@@ -180870,7 +181242,7 @@ var webRoutes = new Elysia({ prefix: "/api/v1/web" }).post("/fetch_and_index", a
180870
181242
  });
180871
181243
 
180872
181244
  // src/routes/web-ui.ts
180873
- import fs22 from "fs/promises";
181245
+ import fs23 from "fs/promises";
180874
181246
  import path34 from "path";
180875
181247
  import { fileURLToPath as fileURLToPath3 } from "url";
180876
181248
 
@@ -180929,7 +181301,7 @@ var STATIC_DIR_CANDIDATES = buildStaticDirCandidates(path34.dirname(fileURLToPat
180929
181301
  async function resolveStaticDir() {
180930
181302
  for (const dir of STATIC_DIR_CANDIDATES) {
180931
181303
  try {
180932
- const st = await fs22.stat(dir);
181304
+ const st = await fs23.stat(dir);
180933
181305
  if (st.isDirectory())
180934
181306
  return dir;
180935
181307
  } catch {}
@@ -180967,7 +181339,7 @@ async function resolveSafePath(staticDir, sub) {
180967
181339
  return null;
180968
181340
  }
180969
181341
  try {
180970
- await fs22.stat(abs);
181342
+ await fs23.stat(abs);
180971
181343
  return { abs, exists: true };
180972
181344
  } catch {
180973
181345
  return { abs, exists: false };
@@ -180990,7 +181362,7 @@ function injectAccessMarkup(html, apiKey, trusted) {
180990
181362
  return out;
180991
181363
  }
180992
181364
  async function readShell(indexPath, remoteAddress) {
180993
- const raw2 = await fs22.readFile(indexPath, "utf-8");
181365
+ const raw2 = await fs23.readFile(indexPath, "utf-8");
180994
181366
  const trusted = isTrustedWebUiCaller(remoteAddress);
180995
181367
  return Buffer.from(injectAccessMarkup(raw2, getConfiguredApiKey(), trusted), "utf-8");
180996
181368
  }
@@ -181040,7 +181412,7 @@ var webUiRoutes = new Elysia().get("/ui", async ({ set: set3, request }) => {
181040
181412
  }
181041
181413
  if (resolved.exists) {
181042
181414
  try {
181043
- const body = await fs22.readFile(resolved.abs);
181415
+ const body = await fs23.readFile(resolved.abs);
181044
181416
  set3.headers["content-type"] = contentTypeFor(resolved.abs);
181045
181417
  return body;
181046
181418
  } catch {
@@ -181275,13 +181647,379 @@ var profileRoutes = new Elysia({ prefix: "/api/v1/profiles" }).get("/", ({ query
181275
181647
  }
181276
181648
  });
181277
181649
 
181650
+ // src/routes/config.ts
181651
+ init_dist();
181652
+ var CONFIG_DETAIL = {
181653
+ tags: ["config"]
181654
+ };
181655
+ var SENSITIVE_FIELDS = {
181656
+ database: ["url"],
181657
+ embedding: ["apiKey"],
181658
+ llm: ["apiKey"],
181659
+ security: ["apiKey"]
181660
+ };
181661
+ function getFieldByPath(config3, section, field3) {
181662
+ const sec = config3[section];
181663
+ if (!sec || typeof sec !== "object")
181664
+ return;
181665
+ const parts = field3.split(".");
181666
+ let val = sec;
181667
+ for (const p of parts) {
181668
+ if (val && typeof val === "object")
181669
+ val = val[p];
181670
+ else
181671
+ return;
181672
+ }
181673
+ return val;
181674
+ }
181675
+ var configRoutes = new Elysia({ prefix: "/api/v1/config" }).get("/", ({ set: set3 }) => {
181676
+ const config3 = loadConfig();
181677
+ const masked = maskSensitive(config3);
181678
+ const restart = restartNeededSections(config3);
181679
+ set3.status = 200;
181680
+ return {
181681
+ success: true,
181682
+ data: { config: masked, restartNeededSections: restart }
181683
+ };
181684
+ }, {
181685
+ detail: {
181686
+ ...CONFIG_DETAIL,
181687
+ summary: "Get current config with sensitive fields masked",
181688
+ 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."
181689
+ }
181690
+ }).get("/reveal", ({ query, set: set3 }) => {
181691
+ const section = query.section;
181692
+ const field3 = query.field;
181693
+ if (!section || !field3) {
181694
+ set3.status = 400;
181695
+ return { success: false, error: "section and field query params are required" };
181696
+ }
181697
+ const allowed = SENSITIVE_FIELDS[section];
181698
+ if (!allowed || !allowed.includes(field3)) {
181699
+ set3.status = 400;
181700
+ return { success: false, error: `field "${section}.${field3}" is not a sensitive field` };
181701
+ }
181702
+ const config3 = loadConfig();
181703
+ const value = getFieldByPath(config3, section, field3);
181704
+ set3.status = 200;
181705
+ return { success: true, data: { section, field: field3, value: value ?? "" } };
181706
+ }, {
181707
+ query: t.Object({
181708
+ section: t.String(),
181709
+ field: t.String()
181710
+ }),
181711
+ detail: {
181712
+ ...CONFIG_DETAIL,
181713
+ summary: "Reveal a single sensitive config field (unmasked)",
181714
+ description: "Returns the unmasked value for one sensitive field (database.url, embedding.apiKey, llm.apiKey, security.apiKey). Requires API key. Only sensitive fields can be revealed."
181715
+ }
181716
+ }).put("/", ({ body, set: set3 }) => {
181717
+ const result = savePartialConfig(body);
181718
+ if (!result.success) {
181719
+ set3.status = 400;
181720
+ return {
181721
+ success: false,
181722
+ error: "validation failed",
181723
+ details: result.details
181724
+ };
181725
+ }
181726
+ const masked = maskSensitive(result.config);
181727
+ set3.status = 200;
181728
+ return {
181729
+ success: true,
181730
+ data: { config: masked, restartNeededSections: result.restartNeededSections }
181731
+ };
181732
+ }, {
181733
+ body: t.Object({}, { additionalProperties: true }),
181734
+ detail: {
181735
+ ...CONFIG_DETAIL,
181736
+ summary: "Update config sections (partial, validated, atomic)",
181737
+ 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."
181738
+ }
181739
+ });
181740
+
181741
+ // src/routes/model-registry.ts
181742
+ init_config();
181743
+ import fs24 from "fs";
181744
+ import path35 from "path";
181745
+ import { spawnSync } from "child_process";
181746
+ var _profilesLib = null;
181747
+ function profilesLib() {
181748
+ if (!_profilesLib) {
181749
+ const libPath = ["..", "..", "..", "..", "scripts", "lib", "model-profiles.ts"].join("/");
181750
+ _profilesLib = __require(libPath);
181751
+ }
181752
+ return _profilesLib;
181753
+ }
181754
+ var REGISTRY_DETAIL = {
181755
+ tags: ["model-registry"]
181756
+ };
181757
+ var OVERLAY_PATH = path35.join(configDir("massa-ai"), "model-profiles.json");
181758
+ var GENERATE_SCRIPT = path35.resolve(import.meta.dirname, "../../../../scripts/generate-subagent-artifacts.ts");
181759
+ var modelRegistryRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).get("/", ({ set: set3 }) => {
181760
+ const lib = profilesLib();
181761
+ const result = lib.loadEffectiveRegistry({ overlayPath: OVERLAY_PATH });
181762
+ set3.status = 200;
181763
+ return {
181764
+ success: true,
181765
+ data: {
181766
+ registry: result.registry,
181767
+ source: result.source,
181768
+ ...result.overlayError ? { overlayError: result.overlayError } : {}
181769
+ }
181770
+ };
181771
+ }, {
181772
+ detail: {
181773
+ ...REGISTRY_DETAIL,
181774
+ summary: "Get effective registry (builtin + overlay) with source attribution",
181775
+ description: "Returns the merged registry (builtin + overlay), source attribution (builtin, overlay, tombstoned), and overlayError if the overlay is corrupted (200 status, never fails)."
181776
+ }
181777
+ }).put("/", ({ body, set: set3 }) => {
181778
+ const lib = profilesLib();
181779
+ const overlay = body;
181780
+ const builtin = lib.loadRegistry(lib.DEFAULT_REGISTRY_PATH);
181781
+ const merged = mergeOverlayForValidation(builtin, overlay);
181782
+ try {
181783
+ lib.validateRegistry(merged);
181784
+ } catch (e) {
181785
+ if (e instanceof lib.RegistryValidationError) {
181786
+ set3.status = 400;
181787
+ return {
181788
+ success: false,
181789
+ error: "validation failed",
181790
+ details: e.violations
181791
+ };
181792
+ }
181793
+ throw e;
181794
+ }
181795
+ try {
181796
+ writeOverlayAtomically(OVERLAY_PATH, overlay);
181797
+ } catch (e) {
181798
+ set3.status = 500;
181799
+ return {
181800
+ success: false,
181801
+ error: `overlay write failed: ${e.message}`
181802
+ };
181803
+ }
181804
+ const result = lib.loadEffectiveRegistry({ overlayPath: OVERLAY_PATH });
181805
+ set3.status = 200;
181806
+ return {
181807
+ success: true,
181808
+ data: {
181809
+ registry: result.registry,
181810
+ source: result.source
181811
+ }
181812
+ };
181813
+ }, {
181814
+ body: t.Object({}, { additionalProperties: true }),
181815
+ detail: {
181816
+ ...REGISTRY_DETAIL,
181817
+ summary: "Write overlay (full-replace, validated, atomic)",
181818
+ 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."
181819
+ }
181820
+ }).post("/regenerate", ({ set: set3 }) => {
181821
+ try {
181822
+ const child = spawnSync("bun", [GENERATE_SCRIPT], {
181823
+ env: { ...process.env },
181824
+ stdio: ["pipe", "pipe", "pipe"]
181825
+ });
181826
+ if (child.exitCode !== 0) {
181827
+ set3.status = 500;
181828
+ return {
181829
+ success: false,
181830
+ error: `regeneration failed (exit ${child.exitCode}): ${child.stderr?.toString().trim()}`
181831
+ };
181832
+ }
181833
+ set3.status = 200;
181834
+ return {
181835
+ success: true,
181836
+ data: { regenerated: true }
181837
+ };
181838
+ } catch (e) {
181839
+ set3.status = 500;
181840
+ return {
181841
+ success: false,
181842
+ error: `regeneration error: ${e.message}`
181843
+ };
181844
+ }
181845
+ }, {
181846
+ detail: {
181847
+ ...REGISTRY_DETAIL,
181848
+ summary: "Regenerate subagent artifacts (spawn child process)",
181849
+ 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."
181850
+ }
181851
+ }).delete("/overlay", ({ set: set3 }) => {
181852
+ const lib = profilesLib();
181853
+ try {
181854
+ if (fs24.existsSync(OVERLAY_PATH)) {
181855
+ fs24.unlinkSync(OVERLAY_PATH);
181856
+ }
181857
+ const builtin = lib.loadRegistry(lib.DEFAULT_REGISTRY_PATH);
181858
+ set3.status = 200;
181859
+ return {
181860
+ success: true,
181861
+ data: {
181862
+ registry: builtin,
181863
+ source: { builtin, overlay: null, tombstoned: [] }
181864
+ }
181865
+ };
181866
+ } catch (e) {
181867
+ set3.status = 500;
181868
+ return {
181869
+ success: false,
181870
+ error: `failed to delete overlay: ${e.message}`
181871
+ };
181872
+ }
181873
+ }, {
181874
+ detail: {
181875
+ ...REGISTRY_DETAIL,
181876
+ summary: "Delete overlay (reset to built-in)",
181877
+ description: "Deletes the overlay file at ~/.config/massa-ai/model-profiles.json and returns the builtin registry."
181878
+ }
181879
+ });
181880
+ function mergeOverlayForValidation(builtin, overlay) {
181881
+ const result = JSON.parse(JSON.stringify(builtin));
181882
+ if (overlay.tiers && Array.isArray(overlay.tiers)) {
181883
+ result.tiers = [...overlay.tiers];
181884
+ }
181885
+ if (overlay.hostDefaults) {
181886
+ result.hostDefaults = { ...overlay.hostDefaults };
181887
+ }
181888
+ if (overlay.workflowTiers) {
181889
+ result.workflowTiers = { ...overlay.workflowTiers };
181890
+ }
181891
+ if (overlay.profiles) {
181892
+ const profiles = result.profiles;
181893
+ for (const [key, val] of Object.entries(overlay.profiles)) {
181894
+ if (val && typeof val === "object" && !Array.isArray(val)) {
181895
+ if (val._delete === true) {
181896
+ delete profiles[key];
181897
+ continue;
181898
+ }
181899
+ const { _delete: _unused, ...profileData } = val;
181900
+ profiles[key] = profileData;
181901
+ }
181902
+ }
181903
+ result.profiles = profiles;
181904
+ }
181905
+ return result;
181906
+ }
181907
+ function writeOverlayAtomically(overlayPath, data) {
181908
+ const dir = path35.dirname(overlayPath);
181909
+ if (!fs24.existsSync(dir)) {
181910
+ fs24.mkdirSync(dir, { recursive: true });
181911
+ }
181912
+ const tmp = `${overlayPath}.${process.pid}.${Date.now()}.tmp`;
181913
+ try {
181914
+ fs24.writeFileSync(tmp, JSON.stringify(data, null, 2));
181915
+ fs24.renameSync(tmp, overlayPath);
181916
+ } catch (e) {
181917
+ try {
181918
+ fs24.unlinkSync(tmp);
181919
+ } catch {}
181920
+ throw e;
181921
+ }
181922
+ }
181923
+
181924
+ // src/routes/model-registry-stream.ts
181925
+ init_config();
181926
+ import path36 from "path";
181927
+ import { spawn as spawn3 } from "child_process";
181928
+ var GENERATE_SCRIPT2 = path36.resolve(import.meta.dirname, "../../../../scripts/generate-subagent-artifacts.ts");
181929
+ var encoder3 = new TextEncoder;
181930
+ function sseFrame(data) {
181931
+ return encoder3.encode(`data: ${JSON.stringify(data)}
181932
+
181933
+ `);
181934
+ }
181935
+ var modelRegistryStreamRoutes = new Elysia({ prefix: "/api/v1/model-registry" }).post("/regenerate-stream", () => {
181936
+ let child = null;
181937
+ let closed = false;
181938
+ const stream2 = new ReadableStream({
181939
+ start(controller2) {
181940
+ try {
181941
+ child = spawn3("bun", [GENERATE_SCRIPT2], {
181942
+ env: { ...process.env },
181943
+ stdio: ["pipe", "pipe", "pipe"]
181944
+ });
181945
+ } catch (e) {
181946
+ controller2.enqueue(sseFrame({
181947
+ type: "done",
181948
+ exitCode: null,
181949
+ error: `spawn failed: ${e.message}`
181950
+ }));
181951
+ controller2.close();
181952
+ closed = true;
181953
+ return;
181954
+ }
181955
+ const emitLine = (streamName, chunk) => {
181956
+ if (closed)
181957
+ return;
181958
+ const text3 = chunk.toString();
181959
+ const lines = text3.split(`
181960
+ `);
181961
+ for (const line of lines) {
181962
+ if (line.length === 0)
181963
+ continue;
181964
+ try {
181965
+ controller2.enqueue(sseFrame({ type: "line", stream: streamName, text: line }));
181966
+ } catch {
181967
+ closed = true;
181968
+ return;
181969
+ }
181970
+ }
181971
+ };
181972
+ child.stdout?.on("data", (chunk) => emitLine("stdout", chunk));
181973
+ child.stderr?.on("data", (chunk) => emitLine("stderr", chunk));
181974
+ child.on("error", (e) => {
181975
+ if (closed)
181976
+ return;
181977
+ closed = true;
181978
+ try {
181979
+ controller2.enqueue(sseFrame({ type: "done", exitCode: null, error: `spawn error: ${e.message}` }));
181980
+ controller2.close();
181981
+ } catch {}
181982
+ });
181983
+ child.on("close", (code) => {
181984
+ if (closed)
181985
+ return;
181986
+ closed = true;
181987
+ try {
181988
+ controller2.enqueue(sseFrame({ type: "done", exitCode: code }));
181989
+ controller2.close();
181990
+ } catch {}
181991
+ });
181992
+ },
181993
+ cancel() {
181994
+ closed = true;
181995
+ try {
181996
+ child?.kill();
181997
+ } catch {}
181998
+ }
181999
+ });
182000
+ return new Response(stream2, {
182001
+ headers: {
182002
+ "Content-Type": "text/event-stream",
182003
+ "Cache-Control": "no-cache",
182004
+ Connection: "keep-alive",
182005
+ "X-Accel-Buffering": "no"
182006
+ }
182007
+ });
182008
+ }, {
182009
+ detail: {
182010
+ tags: ["model-registry"],
182011
+ summary: "Regenerate subagent artifacts (streaming SSE)",
182012
+ description: 'Spawns `bun scripts/generate-subagent-artifacts.ts` with child_process.spawn (non-blocking). Pipes stdout/stderr line-by-line as SSE `data: {"type":"line","stream":"stdout|stderr","text":"..."}` events, then a terminal `data: {"type":"done","exitCode":<n>}` event. On spawn failure emits `done` with `exitCode:null` + `error`. The existing blocking POST /regenerate route stays for API compatibility.'
182013
+ }
182014
+ });
182015
+
181278
182016
  // src/middleware/error.ts
181279
182017
  init_dist();
181280
- var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path35, request }) => {
182018
+ var errorHandler = new Elysia({ name: "error-handler" }).onError(({ code, error: error51, set: set3, path: path37, request }) => {
181281
182019
  logger.error("[massa-ai-api] Request failed", undefined, {
181282
182020
  ...safeErrorSummary(error51),
181283
182021
  code,
181284
- path: path35,
182022
+ path: path37,
181285
182023
  method: request.method
181286
182024
  });
181287
182025
  if (error51 instanceof SearchServiceError) {
@@ -181397,7 +182135,7 @@ var app = new Elysia({ adapter: node() }).use(cors(buildCorsOptions(config.get("
181397
182135
  },
181398
182136
  security: [{ ApiKeyAuth: [] }]
181399
182137
  }
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()));
182138
+ })).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()));
181401
182139
  initAuthOrExit();
181402
182140
  warnIfTrustOverrideEnabled();
181403
182141
  await listenAfterParserValidation({