@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.
- package/dist/index.js +873 -135
- 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
|
|
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
|
-
|
|
760
|
-
fd =
|
|
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
|
-
|
|
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
|
-
|
|
1069
|
+
fs3.closeSync(fd);
|
|
783
1070
|
try {
|
|
784
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
7124
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
7478
|
+
fs6.mkdirSync(lockDir);
|
|
7190
7479
|
const pid = identity.pid();
|
|
7191
7480
|
const startedAt = identity.processStart(pid);
|
|
7192
7481
|
if (startedAt == null) {
|
|
7193
|
-
|
|
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
|
-
|
|
7205
|
-
|
|
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
|
-
|
|
7509
|
+
fs6.renameSync(lockDir, reclaimDir);
|
|
7221
7510
|
} catch {
|
|
7222
7511
|
throw LockHeldError(lockDir);
|
|
7223
7512
|
}
|
|
7224
|
-
|
|
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
|
|
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 =
|
|
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 (!
|
|
7597
|
+
if (!fs7.existsSync(layout.variantsRoot))
|
|
7309
7598
|
return [];
|
|
7310
|
-
return
|
|
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
|
-
|
|
7612
|
+
fs7.mkdirSync(dir, { recursive: true });
|
|
7324
7613
|
} catch (err) {
|
|
7325
7614
|
throw UnwritableInstallStateError(stateFilePath, err.message);
|
|
7326
7615
|
}
|
|
7327
|
-
const checkPath =
|
|
7616
|
+
const checkPath = fs7.existsSync(stateFilePath) ? stateFilePath : dir;
|
|
7328
7617
|
try {
|
|
7329
|
-
|
|
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
|
-
|
|
7624
|
+
fs7.mkdirSync(layout.activeDir, { recursive: true });
|
|
7336
7625
|
let changed = 0;
|
|
7337
|
-
for (const entry of
|
|
7626
|
+
for (const entry of fs7.readdirSync(variantDir, { withFileTypes: true })) {
|
|
7338
7627
|
if (!entry.isFile() || !matchesGlob(entry.name, layout.activeGlob))
|
|
7339
7628
|
continue;
|
|
7340
|
-
|
|
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
|
-
|
|
7635
|
+
fs7.mkdirSync(layout.activeDir, { recursive: true });
|
|
7347
7636
|
let changed = 0;
|
|
7348
|
-
for (const entry of
|
|
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 =
|
|
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
|
-
|
|
7364
|
-
|
|
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) =>
|
|
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 =
|
|
7679
|
+
const variantsRootExists = fs7.existsSync(h.layout.variantsRoot);
|
|
7391
7680
|
const variantDir = h.layout.variantDir(opts.profile);
|
|
7392
|
-
const available = variantsRootExists &&
|
|
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:
|
|
11601
|
-
this.#fs = fsFromOption(
|
|
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(
|
|
12077
|
-
return new PathWin32(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
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(
|
|
12094
|
-
return new PathPosix(this.rootPath, IFDIR, undefined, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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 (!
|
|
35918
|
+
if (!fs10.existsSync(authPath)) {
|
|
35630
35919
|
return null;
|
|
35631
35920
|
}
|
|
35632
|
-
const content =
|
|
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 (!
|
|
35645
|
-
|
|
35933
|
+
if (!fs10.existsSync(authDir)) {
|
|
35934
|
+
fs10.mkdirSync(authDir, { mode: 504, recursive: true });
|
|
35646
35935
|
}
|
|
35647
|
-
|
|
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
|
|
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 (!
|
|
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(
|
|
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
|
-
|
|
35921
|
-
|
|
35922
|
-
|
|
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 (!
|
|
36220
|
+
if (!fs10.existsSync(tokenPath)) {
|
|
35932
36221
|
return null;
|
|
35933
36222
|
}
|
|
35934
|
-
const token = JSON.parse(
|
|
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
|
|
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 =
|
|
63658
|
+
const fd = fs10.openSync(path13, "r");
|
|
63370
63659
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
63371
|
-
const bytesRead =
|
|
63372
|
-
|
|
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
|
-
|
|
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
|
-
|
|
63670
|
+
fs10.read(fd, buffer, 0, MAX_LENGTH, 0, (_2, bytesRead) => {
|
|
63382
63671
|
resolve4(buffer.subarray(0, bytesRead));
|
|
63383
|
-
|
|
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
|
|
100352
|
+
var fs10 = new WeakMap;
|
|
100064
100353
|
function Ep(e) {
|
|
100065
|
-
let t2 =
|
|
100066
|
-
return t2 || (t2 = Object.entries(e),
|
|
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
|
|
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
|
|
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
|
|
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
|
|
117021
|
-
const content = stripNul(await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
131032
|
+
await fs17.mkdir(this.dataDir, { recursive: true });
|
|
130702
131033
|
const probe2 = path28.join(this.dataDir, ".health-check-test");
|
|
130703
|
-
await
|
|
130704
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
158258
|
-
if (!
|
|
158588
|
+
const fs4 = process.getBuiltinModule("fs");
|
|
158589
|
+
if (!fs4) {
|
|
158259
158590
|
warnMissing();
|
|
158260
158591
|
return;
|
|
158261
158592
|
}
|
|
158262
|
-
if (typeof
|
|
158593
|
+
if (typeof fs4.createReadStream != "function") {
|
|
158263
158594
|
warnMissing();
|
|
158264
158595
|
return;
|
|
158265
158596
|
}
|
|
158266
|
-
if (typeof
|
|
158597
|
+
if (typeof fs4.promises?.stat != "function") {
|
|
158267
158598
|
warnMissing();
|
|
158268
158599
|
return;
|
|
158269
158600
|
}
|
|
158270
|
-
createReadStream =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
177706
|
-
const buf =
|
|
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 (
|
|
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 =
|
|
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 (!
|
|
178065
|
+
if (!fs19.existsSync(p) || !fs19.statSync(p).isFile())
|
|
177735
178066
|
continue;
|
|
177736
|
-
const raw2 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
179027
|
-
await
|
|
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
|
|
179039
|
-
await
|
|
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
|
|
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 (
|
|
179642
|
+
if (fs21.existsSync(metricsPath)) {
|
|
179271
179643
|
try {
|
|
179272
|
-
metrics2 = JSON.parse(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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({
|