@sentry/junior 0.12.1 → 0.14.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/README.md +1 -1
- package/dist/app.js +11 -17
- package/dist/{chunk-Y2LVMCQ3.js → chunk-5JHLDXBN.js} +38 -591
- package/dist/{chunk-SCG4PCEG.js → chunk-ESPIOJPM.js} +11 -2
- package/dist/{chunk-IH4T747D.js → chunk-KTBQH6L5.js} +4 -2
- package/dist/chunk-RBB2MZAN.js +342 -0
- package/dist/cli/check.js +3 -2
- package/dist/cli/init.js +42 -11
- package/dist/cli/snapshot-warmup.js +3 -2
- package/dist/nitro.d.ts +13 -0
- package/dist/nitro.js +69 -0
- package/dist/vercel.d.ts +2 -8
- package/dist/vercel.js +12 -5
- package/package.json +3 -1
- package/dist/chunk-ZLVM4R7R.js +0 -25
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
sentry_exports
|
|
3
3
|
} from "./chunk-Z3YD6NHK.js";
|
|
4
|
+
import {
|
|
5
|
+
discoverInstalledPluginPackageContent,
|
|
6
|
+
pluginRoots
|
|
7
|
+
} from "./chunk-RBB2MZAN.js";
|
|
4
8
|
|
|
5
9
|
// src/chat/logging.ts
|
|
6
10
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -859,560 +863,9 @@ function extractGenAiUsageAttributes(...sources) {
|
|
|
859
863
|
};
|
|
860
864
|
}
|
|
861
865
|
|
|
862
|
-
// src/chat/plugins/package-discovery.ts
|
|
863
|
-
import { readFileSync, readdirSync as readdirSync2 } from "fs";
|
|
864
|
-
import path2 from "path";
|
|
865
|
-
import { parse as parseYaml } from "yaml";
|
|
866
|
-
|
|
867
|
-
// src/chat/discovery.ts
|
|
868
|
-
import fs, { readdirSync, statSync } from "fs";
|
|
869
|
-
import path from "path";
|
|
870
|
-
import { fileURLToPath } from "url";
|
|
871
|
-
function isDirectory(targetPath) {
|
|
872
|
-
try {
|
|
873
|
-
return statSync(targetPath).isDirectory();
|
|
874
|
-
} catch {
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
function isFile(targetPath) {
|
|
879
|
-
try {
|
|
880
|
-
return statSync(targetPath).isFile();
|
|
881
|
-
} catch {
|
|
882
|
-
return false;
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
function normalizePath(targetPath) {
|
|
886
|
-
return path.resolve(targetPath);
|
|
887
|
-
}
|
|
888
|
-
function uniqueResolvedPathsInOrder(values) {
|
|
889
|
-
const seen = /* @__PURE__ */ new Set();
|
|
890
|
-
const resolved = [];
|
|
891
|
-
for (const value of values) {
|
|
892
|
-
const normalized = normalizePath(value);
|
|
893
|
-
if (seen.has(normalized)) {
|
|
894
|
-
continue;
|
|
895
|
-
}
|
|
896
|
-
seen.add(normalized);
|
|
897
|
-
resolved.push(normalized);
|
|
898
|
-
}
|
|
899
|
-
return resolved;
|
|
900
|
-
}
|
|
901
|
-
function isNodeModulesPath(candidatePath) {
|
|
902
|
-
return path.basename(candidatePath) === "node_modules";
|
|
903
|
-
}
|
|
904
|
-
function isInsidePnpmStore(candidatePath) {
|
|
905
|
-
return candidatePath.split(path.sep).includes(".pnpm");
|
|
906
|
-
}
|
|
907
|
-
function runningFromInstalledPackage() {
|
|
908
|
-
const currentFile = fileURLToPath(import.meta.url);
|
|
909
|
-
const marker = `${path.sep}node_modules${path.sep}@sentry${path.sep}junior${path.sep}`;
|
|
910
|
-
return currentFile.includes(marker);
|
|
911
|
-
}
|
|
912
|
-
function listInstalledPackageNodeModulesDirs() {
|
|
913
|
-
if (!runningFromInstalledPackage()) {
|
|
914
|
-
return [];
|
|
915
|
-
}
|
|
916
|
-
const dirs = [];
|
|
917
|
-
let current = path.resolve(path.dirname(fileURLToPath(import.meta.url)));
|
|
918
|
-
while (true) {
|
|
919
|
-
if (isNodeModulesPath(current) && !isInsidePnpmStore(current) && isDirectory(current)) {
|
|
920
|
-
dirs.push(current);
|
|
921
|
-
}
|
|
922
|
-
const parent = path.dirname(current);
|
|
923
|
-
if (parent === current) {
|
|
924
|
-
break;
|
|
925
|
-
}
|
|
926
|
-
current = parent;
|
|
927
|
-
}
|
|
928
|
-
return dirs;
|
|
929
|
-
}
|
|
930
|
-
function listCwdAncestorNodeModulesDirs(cwd) {
|
|
931
|
-
const resolvedCwd = normalizePath(cwd);
|
|
932
|
-
const dirs = [];
|
|
933
|
-
let current = resolvedCwd;
|
|
934
|
-
while (true) {
|
|
935
|
-
const nodeModulesDir = path.join(current, "node_modules");
|
|
936
|
-
if (isDirectory(nodeModulesDir)) {
|
|
937
|
-
dirs.push(nodeModulesDir);
|
|
938
|
-
}
|
|
939
|
-
if (isFile(path.join(current, "package.json"))) {
|
|
940
|
-
break;
|
|
941
|
-
}
|
|
942
|
-
const parent = path.dirname(current);
|
|
943
|
-
if (parent === current) {
|
|
944
|
-
break;
|
|
945
|
-
}
|
|
946
|
-
current = parent;
|
|
947
|
-
}
|
|
948
|
-
return dirs;
|
|
949
|
-
}
|
|
950
|
-
function discoverNodeModulesDirs(cwd = process.cwd(), options) {
|
|
951
|
-
const explicit = options?.candidateDirs?.filter((dir) => isDirectory(dir)) ?? [];
|
|
952
|
-
if (explicit.length > 0) {
|
|
953
|
-
return uniqueResolvedPathsInOrder(explicit);
|
|
954
|
-
}
|
|
955
|
-
return uniqueResolvedPathsInOrder([
|
|
956
|
-
...listInstalledPackageNodeModulesDirs(),
|
|
957
|
-
...listCwdAncestorNodeModulesDirs(cwd)
|
|
958
|
-
]);
|
|
959
|
-
}
|
|
960
|
-
function discoverProjectRoots(cwd = process.cwd(), options) {
|
|
961
|
-
const roots = discoverNodeModulesDirs(
|
|
962
|
-
cwd,
|
|
963
|
-
options?.nodeModulesDirs ? { candidateDirs: options.nodeModulesDirs } : void 0
|
|
964
|
-
).map((nodeModulesDir) => path.dirname(nodeModulesDir));
|
|
965
|
-
return uniqueResolvedPathsInOrder([cwd, ...roots]);
|
|
966
|
-
}
|
|
967
|
-
function listTopLevelPackages(nodeModulesDir) {
|
|
968
|
-
const entries = readdirSync(nodeModulesDir, { withFileTypes: true }).filter(
|
|
969
|
-
(entry) => !entry.name.startsWith(".") && entry.name !== ".bin" && entry.name !== ".pnpm"
|
|
970
|
-
).sort((left, right) => left.name.localeCompare(right.name));
|
|
971
|
-
const packages = [];
|
|
972
|
-
for (const entry of entries) {
|
|
973
|
-
const entryPath = path.join(nodeModulesDir, entry.name);
|
|
974
|
-
if (entry.name.startsWith("@")) {
|
|
975
|
-
if (!isDirectory(entryPath)) {
|
|
976
|
-
continue;
|
|
977
|
-
}
|
|
978
|
-
const scopedEntries = readdirSync(entryPath, {
|
|
979
|
-
withFileTypes: true
|
|
980
|
-
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
981
|
-
for (const scopedEntry of scopedEntries) {
|
|
982
|
-
const packageName = `${entry.name}/${scopedEntry.name}`;
|
|
983
|
-
const packagePath = path.join(entryPath, scopedEntry.name);
|
|
984
|
-
if (!isDirectory(packagePath)) {
|
|
985
|
-
continue;
|
|
986
|
-
}
|
|
987
|
-
packages.push({ name: packageName, dir: packagePath });
|
|
988
|
-
}
|
|
989
|
-
continue;
|
|
990
|
-
}
|
|
991
|
-
if (!isDirectory(entryPath)) {
|
|
992
|
-
continue;
|
|
993
|
-
}
|
|
994
|
-
packages.push({ name: entry.name, dir: entryPath });
|
|
995
|
-
}
|
|
996
|
-
return packages;
|
|
997
|
-
}
|
|
998
|
-
function unique(values) {
|
|
999
|
-
return [...new Set(values)];
|
|
1000
|
-
}
|
|
1001
|
-
function pathExists(targetPath) {
|
|
1002
|
-
try {
|
|
1003
|
-
fs.accessSync(targetPath);
|
|
1004
|
-
return true;
|
|
1005
|
-
} catch {
|
|
1006
|
-
return false;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
function hasAnyDataMarkers(appDir) {
|
|
1010
|
-
return pathExists(path.join(appDir, "SOUL.md")) || pathExists(path.join(appDir, "ABOUT.md"));
|
|
1011
|
-
}
|
|
1012
|
-
function scoreAppCandidate(appDir) {
|
|
1013
|
-
let score = 0;
|
|
1014
|
-
if (pathExists(path.join(appDir, "SOUL.md"))) {
|
|
1015
|
-
score += 4;
|
|
1016
|
-
}
|
|
1017
|
-
if (pathExists(path.join(appDir, "ABOUT.md"))) {
|
|
1018
|
-
score += 2;
|
|
1019
|
-
}
|
|
1020
|
-
if (pathExists(path.join(appDir, "skills"))) {
|
|
1021
|
-
score += 1;
|
|
1022
|
-
}
|
|
1023
|
-
if (pathExists(path.join(appDir, "plugins"))) {
|
|
1024
|
-
score += 1;
|
|
1025
|
-
}
|
|
1026
|
-
return score;
|
|
1027
|
-
}
|
|
1028
|
-
function resolveCandidateAppDirs(cwd, projectRoots) {
|
|
1029
|
-
const roots = projectRoots ?? discoverProjectRoots(cwd);
|
|
1030
|
-
const resolved = [];
|
|
1031
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1032
|
-
for (const root of roots) {
|
|
1033
|
-
const appDir = path.resolve(root, "app");
|
|
1034
|
-
if (!pathExists(appDir)) {
|
|
1035
|
-
continue;
|
|
1036
|
-
}
|
|
1037
|
-
if (seen.has(appDir)) {
|
|
1038
|
-
continue;
|
|
1039
|
-
}
|
|
1040
|
-
seen.add(appDir);
|
|
1041
|
-
resolved.push(appDir);
|
|
1042
|
-
}
|
|
1043
|
-
return resolved;
|
|
1044
|
-
}
|
|
1045
|
-
function homeDir() {
|
|
1046
|
-
return resolveHomeDir();
|
|
1047
|
-
}
|
|
1048
|
-
function resolveHomeDir(cwd = process.cwd(), options) {
|
|
1049
|
-
const resolvedCwd = path.resolve(cwd);
|
|
1050
|
-
const directApp = path.resolve(resolvedCwd, "app");
|
|
1051
|
-
if (pathExists(directApp) && hasAnyDataMarkers(directApp)) {
|
|
1052
|
-
return directApp;
|
|
1053
|
-
}
|
|
1054
|
-
const candidates = resolveCandidateAppDirs(
|
|
1055
|
-
resolvedCwd,
|
|
1056
|
-
options?.projectRoots
|
|
1057
|
-
);
|
|
1058
|
-
if (candidates.length === 0) {
|
|
1059
|
-
return directApp;
|
|
1060
|
-
}
|
|
1061
|
-
candidates.sort((left, right) => {
|
|
1062
|
-
const leftScore = scoreAppCandidate(left);
|
|
1063
|
-
const rightScore = scoreAppCandidate(right);
|
|
1064
|
-
if (leftScore !== rightScore) {
|
|
1065
|
-
return rightScore - leftScore;
|
|
1066
|
-
}
|
|
1067
|
-
const leftDistance = path.relative(resolvedCwd, left).split(path.sep).length;
|
|
1068
|
-
const rightDistance = path.relative(resolvedCwd, right).split(path.sep).length;
|
|
1069
|
-
if (leftDistance !== rightDistance) {
|
|
1070
|
-
return leftDistance - rightDistance;
|
|
1071
|
-
}
|
|
1072
|
-
return left.localeCompare(right);
|
|
1073
|
-
});
|
|
1074
|
-
return candidates[0];
|
|
1075
|
-
}
|
|
1076
|
-
function resolveContentRoots(subdir) {
|
|
1077
|
-
if (subdir === "data") {
|
|
1078
|
-
return [homeDir()];
|
|
1079
|
-
}
|
|
1080
|
-
return [path.join(homeDir(), subdir)];
|
|
1081
|
-
}
|
|
1082
|
-
function dataRoots() {
|
|
1083
|
-
return unique(resolveContentRoots("data"));
|
|
1084
|
-
}
|
|
1085
|
-
function skillRoots() {
|
|
1086
|
-
return unique(resolveContentRoots("skills"));
|
|
1087
|
-
}
|
|
1088
|
-
function pluginRoots() {
|
|
1089
|
-
return unique(resolveContentRoots("plugins"));
|
|
1090
|
-
}
|
|
1091
|
-
function soulPathCandidates() {
|
|
1092
|
-
const candidates = dataRoots().map((root) => path.join(root, "SOUL.md"));
|
|
1093
|
-
return unique(candidates);
|
|
1094
|
-
}
|
|
1095
|
-
function aboutPathCandidates() {
|
|
1096
|
-
const candidates = dataRoots().map((root) => path.join(root, "ABOUT.md"));
|
|
1097
|
-
return unique(candidates);
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
// src/chat/plugins/package-discovery.ts
|
|
1101
|
-
function normalizeForGlob(targetPath) {
|
|
1102
|
-
return targetPath.split(path2.sep).join("/");
|
|
1103
|
-
}
|
|
1104
|
-
function uniqueStringsInOrder(values) {
|
|
1105
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1106
|
-
const resolved = [];
|
|
1107
|
-
for (const value of values) {
|
|
1108
|
-
if (seen.has(value)) {
|
|
1109
|
-
continue;
|
|
1110
|
-
}
|
|
1111
|
-
seen.add(value);
|
|
1112
|
-
resolved.push(value);
|
|
1113
|
-
}
|
|
1114
|
-
return resolved;
|
|
1115
|
-
}
|
|
1116
|
-
function pathForTracingInclude(cwd, targetPath) {
|
|
1117
|
-
const relative = path2.relative(cwd, targetPath);
|
|
1118
|
-
if (!relative || path2.isAbsolute(relative)) {
|
|
1119
|
-
return null;
|
|
1120
|
-
}
|
|
1121
|
-
const normalized = normalizeForGlob(relative);
|
|
1122
|
-
return normalized.startsWith(".") ? normalized : `./${normalized}`;
|
|
1123
|
-
}
|
|
1124
|
-
function parseRuntimeConfiguredPackageNames(value) {
|
|
1125
|
-
if (!Array.isArray(value)) {
|
|
1126
|
-
return null;
|
|
1127
|
-
}
|
|
1128
|
-
const parsed = value.filter(
|
|
1129
|
-
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
1130
|
-
);
|
|
1131
|
-
return uniqueStringsInOrder(parsed.map((entry) => entry.trim()));
|
|
1132
|
-
}
|
|
1133
|
-
var configuredPluginPackages;
|
|
1134
|
-
function setPluginPackages(packages) {
|
|
1135
|
-
configuredPluginPackages = packages;
|
|
1136
|
-
}
|
|
1137
|
-
function readNextRuntimeConfiguredPackageNames() {
|
|
1138
|
-
if (configuredPluginPackages !== void 0) {
|
|
1139
|
-
return configuredPluginPackages;
|
|
1140
|
-
}
|
|
1141
|
-
const raw = process.env.JUNIOR_PLUGIN_PACKAGES;
|
|
1142
|
-
if (raw === void 0) {
|
|
1143
|
-
return null;
|
|
1144
|
-
}
|
|
1145
|
-
try {
|
|
1146
|
-
return parseRuntimeConfiguredPackageNames(JSON.parse(raw)) ?? [];
|
|
1147
|
-
} catch {
|
|
1148
|
-
return [];
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
function findWorkspaceRoot(cwd) {
|
|
1152
|
-
let current = path2.resolve(cwd);
|
|
1153
|
-
while (true) {
|
|
1154
|
-
const candidate = path2.join(current, "pnpm-workspace.yaml");
|
|
1155
|
-
if (isFile(candidate)) {
|
|
1156
|
-
return current;
|
|
1157
|
-
}
|
|
1158
|
-
const parent = path2.dirname(current);
|
|
1159
|
-
if (parent === current) {
|
|
1160
|
-
return null;
|
|
1161
|
-
}
|
|
1162
|
-
current = parent;
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
function listWorkspacePackageDirs(cwd) {
|
|
1166
|
-
const workspaceRoot = findWorkspaceRoot(cwd);
|
|
1167
|
-
if (!workspaceRoot) {
|
|
1168
|
-
return [];
|
|
1169
|
-
}
|
|
1170
|
-
let packagePatterns = [];
|
|
1171
|
-
try {
|
|
1172
|
-
const raw = readFileSync(
|
|
1173
|
-
path2.join(workspaceRoot, "pnpm-workspace.yaml"),
|
|
1174
|
-
"utf8"
|
|
1175
|
-
);
|
|
1176
|
-
const parsed = parseYaml(raw);
|
|
1177
|
-
packagePatterns = Array.isArray(parsed.packages) ? parsed.packages.filter(
|
|
1178
|
-
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
1179
|
-
) : [];
|
|
1180
|
-
} catch {
|
|
1181
|
-
return [];
|
|
1182
|
-
}
|
|
1183
|
-
const discovered = [];
|
|
1184
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1185
|
-
const addDir = (candidate) => {
|
|
1186
|
-
const normalized = path2.resolve(candidate);
|
|
1187
|
-
if (seen.has(normalized) || !isDirectory(normalized)) {
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
seen.add(normalized);
|
|
1191
|
-
discovered.push(normalized);
|
|
1192
|
-
};
|
|
1193
|
-
for (const pattern of packagePatterns) {
|
|
1194
|
-
const trimmed = pattern.trim();
|
|
1195
|
-
if (!trimmed) {
|
|
1196
|
-
continue;
|
|
1197
|
-
}
|
|
1198
|
-
if (trimmed.endsWith("/*")) {
|
|
1199
|
-
const baseDir = path2.join(workspaceRoot, trimmed.slice(0, -2));
|
|
1200
|
-
if (!isDirectory(baseDir)) {
|
|
1201
|
-
continue;
|
|
1202
|
-
}
|
|
1203
|
-
for (const entry of readdirSync2(baseDir)) {
|
|
1204
|
-
addDir(path2.join(baseDir, entry));
|
|
1205
|
-
}
|
|
1206
|
-
continue;
|
|
1207
|
-
}
|
|
1208
|
-
addDir(path2.join(workspaceRoot, trimmed));
|
|
1209
|
-
}
|
|
1210
|
-
return discovered;
|
|
1211
|
-
}
|
|
1212
|
-
function readPluginPackageFlags(dir) {
|
|
1213
|
-
const hasRootPluginManifest = isFile(path2.join(dir, "plugin.yaml"));
|
|
1214
|
-
const hasPluginsDir = isDirectory(path2.join(dir, "plugins"));
|
|
1215
|
-
const hasSkillsDir = isDirectory(path2.join(dir, "skills"));
|
|
1216
|
-
if (!hasRootPluginManifest && !hasPluginsDir && !hasSkillsDir) {
|
|
1217
|
-
return null;
|
|
1218
|
-
}
|
|
1219
|
-
return {
|
|
1220
|
-
hasRootPluginManifest,
|
|
1221
|
-
hasPluginsDir,
|
|
1222
|
-
hasSkillsDir
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
function discoverWorkspacePluginPackageDirs(cwd, packageNames) {
|
|
1226
|
-
if (packageNames !== null) {
|
|
1227
|
-
return [];
|
|
1228
|
-
}
|
|
1229
|
-
return listWorkspacePackageDirs(cwd).filter(
|
|
1230
|
-
(candidate) => readPluginPackageFlags(candidate) !== null
|
|
1231
|
-
);
|
|
1232
|
-
}
|
|
1233
|
-
function readWorkspacePackageName(dir) {
|
|
1234
|
-
try {
|
|
1235
|
-
const raw = readFileSync(path2.join(dir, "package.json"), "utf8");
|
|
1236
|
-
const name = JSON.parse(raw).name;
|
|
1237
|
-
return typeof name === "string" && name.trim().length > 0 ? name : null;
|
|
1238
|
-
} catch {
|
|
1239
|
-
return null;
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
function resolveWorkspacePackageDirFromName(cwd, packageName) {
|
|
1243
|
-
for (const candidate of listWorkspacePackageDirs(cwd)) {
|
|
1244
|
-
if (readWorkspacePackageName(candidate) !== packageName) {
|
|
1245
|
-
continue;
|
|
1246
|
-
}
|
|
1247
|
-
return candidate;
|
|
1248
|
-
}
|
|
1249
|
-
return null;
|
|
1250
|
-
}
|
|
1251
|
-
function resolvePackageDirFromName(packageName, candidateNodeModulesDirs) {
|
|
1252
|
-
for (const nodeModulesDir of candidateNodeModulesDirs) {
|
|
1253
|
-
const packageDir = path2.join(nodeModulesDir, ...packageName.split("/"));
|
|
1254
|
-
if (isDirectory(packageDir)) {
|
|
1255
|
-
return {
|
|
1256
|
-
dir: path2.resolve(packageDir),
|
|
1257
|
-
nodeModulesDir: path2.resolve(nodeModulesDir)
|
|
1258
|
-
};
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
return null;
|
|
1262
|
-
}
|
|
1263
|
-
function discoverDeclaredPackages(cwd, packageNames, candidateNodeModulesDirs) {
|
|
1264
|
-
const discovered = [];
|
|
1265
|
-
const seenPackageNames = /* @__PURE__ */ new Set();
|
|
1266
|
-
const seenPackageDirs = /* @__PURE__ */ new Set();
|
|
1267
|
-
for (const packageName of packageNames) {
|
|
1268
|
-
const resolved = resolvePackageDirFromName(
|
|
1269
|
-
packageName,
|
|
1270
|
-
candidateNodeModulesDirs
|
|
1271
|
-
);
|
|
1272
|
-
const workspaceDir = resolved ? null : resolveWorkspacePackageDirFromName(cwd, packageName);
|
|
1273
|
-
if (!resolved && !workspaceDir) {
|
|
1274
|
-
continue;
|
|
1275
|
-
}
|
|
1276
|
-
const packageDir = resolved?.dir ?? workspaceDir;
|
|
1277
|
-
if (seenPackageNames.has(packageName) || seenPackageDirs.has(packageDir)) {
|
|
1278
|
-
continue;
|
|
1279
|
-
}
|
|
1280
|
-
const pluginFlags = readPluginPackageFlags(packageDir);
|
|
1281
|
-
if (!pluginFlags) {
|
|
1282
|
-
continue;
|
|
1283
|
-
}
|
|
1284
|
-
seenPackageNames.add(packageName);
|
|
1285
|
-
seenPackageDirs.add(packageDir);
|
|
1286
|
-
discovered.push({
|
|
1287
|
-
name: packageName,
|
|
1288
|
-
dir: packageDir,
|
|
1289
|
-
nodeModulesDir: resolved?.nodeModulesDir ?? null,
|
|
1290
|
-
...pluginFlags
|
|
1291
|
-
});
|
|
1292
|
-
}
|
|
1293
|
-
return discovered;
|
|
1294
|
-
}
|
|
1295
|
-
function discoverInstalledJuniorContentPackages(cwd = process.cwd(), nodeModulesDirs, packageNames) {
|
|
1296
|
-
const resolvedCwd = path2.resolve(cwd);
|
|
1297
|
-
const candidateNodeModulesDirs = nodeModulesDirs ?? discoverNodeModulesDirs(resolvedCwd);
|
|
1298
|
-
const configuredPackageNames = packageNames ?? readNextRuntimeConfiguredPackageNames();
|
|
1299
|
-
const declaredPackages = discoverDeclaredPackages(
|
|
1300
|
-
resolvedCwd,
|
|
1301
|
-
configuredPackageNames ?? [],
|
|
1302
|
-
candidateNodeModulesDirs
|
|
1303
|
-
);
|
|
1304
|
-
const useFallbackScan = configuredPackageNames === null;
|
|
1305
|
-
const discovered = [...declaredPackages];
|
|
1306
|
-
const seenPackageNames = /* @__PURE__ */ new Set();
|
|
1307
|
-
const seenPackageDirs = /* @__PURE__ */ new Set();
|
|
1308
|
-
for (const pkg of declaredPackages) {
|
|
1309
|
-
seenPackageNames.add(pkg.name);
|
|
1310
|
-
seenPackageDirs.add(pkg.dir);
|
|
1311
|
-
}
|
|
1312
|
-
if (!useFallbackScan) {
|
|
1313
|
-
return discovered;
|
|
1314
|
-
}
|
|
1315
|
-
for (const nodeModulesDir of candidateNodeModulesDirs) {
|
|
1316
|
-
for (const pkg of listTopLevelPackages(nodeModulesDir)) {
|
|
1317
|
-
const resolvedDir = path2.resolve(pkg.dir);
|
|
1318
|
-
if (seenPackageNames.has(pkg.name) || seenPackageDirs.has(resolvedDir)) {
|
|
1319
|
-
continue;
|
|
1320
|
-
}
|
|
1321
|
-
seenPackageNames.add(pkg.name);
|
|
1322
|
-
seenPackageDirs.add(resolvedDir);
|
|
1323
|
-
const hasRootPluginManifest = isFile(
|
|
1324
|
-
path2.join(resolvedDir, "plugin.yaml")
|
|
1325
|
-
);
|
|
1326
|
-
const hasPluginsDir = isDirectory(path2.join(resolvedDir, "plugins"));
|
|
1327
|
-
const hasSkillsDir = isDirectory(path2.join(resolvedDir, "skills"));
|
|
1328
|
-
if (!hasRootPluginManifest && !hasPluginsDir && !hasSkillsDir) {
|
|
1329
|
-
continue;
|
|
1330
|
-
}
|
|
1331
|
-
discovered.push({
|
|
1332
|
-
name: pkg.name,
|
|
1333
|
-
dir: resolvedDir,
|
|
1334
|
-
nodeModulesDir: path2.resolve(nodeModulesDir),
|
|
1335
|
-
hasRootPluginManifest,
|
|
1336
|
-
hasPluginsDir,
|
|
1337
|
-
hasSkillsDir
|
|
1338
|
-
});
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
return discovered;
|
|
1342
|
-
}
|
|
1343
|
-
function discoverInstalledPluginPackageContent(cwd = process.cwd(), options) {
|
|
1344
|
-
const resolvedCwd = path2.resolve(cwd);
|
|
1345
|
-
const configuredPackageNames = options?.packageNames ?? readNextRuntimeConfiguredPackageNames();
|
|
1346
|
-
const discoveredPackages = discoverInstalledJuniorContentPackages(
|
|
1347
|
-
resolvedCwd,
|
|
1348
|
-
options?.nodeModulesDirs,
|
|
1349
|
-
configuredPackageNames
|
|
1350
|
-
);
|
|
1351
|
-
const workspacePluginDirs = discoverWorkspacePluginPackageDirs(
|
|
1352
|
-
resolvedCwd,
|
|
1353
|
-
configuredPackageNames
|
|
1354
|
-
);
|
|
1355
|
-
const manifestRoots = [];
|
|
1356
|
-
const skillRoots2 = [];
|
|
1357
|
-
const tracingIncludes = [];
|
|
1358
|
-
for (const pkg of discoveredPackages) {
|
|
1359
|
-
const tracingBasePath = pkg.nodeModulesDir ? pathForTracingInclude(
|
|
1360
|
-
resolvedCwd,
|
|
1361
|
-
path2.join(pkg.nodeModulesDir, ...pkg.name.split("/"))
|
|
1362
|
-
) : pathForTracingInclude(resolvedCwd, pkg.dir);
|
|
1363
|
-
if (pkg.hasRootPluginManifest) {
|
|
1364
|
-
manifestRoots.push(pkg.dir);
|
|
1365
|
-
if (tracingBasePath) {
|
|
1366
|
-
tracingIncludes.push(`${tracingBasePath}/plugin.yaml`);
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
if (pkg.hasPluginsDir) {
|
|
1370
|
-
manifestRoots.push(path2.join(pkg.dir, "plugins"));
|
|
1371
|
-
if (tracingBasePath) {
|
|
1372
|
-
tracingIncludes.push(`${tracingBasePath}/plugins/**/*`);
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
if (pkg.hasSkillsDir) {
|
|
1376
|
-
skillRoots2.push(path2.join(pkg.dir, "skills"));
|
|
1377
|
-
if (tracingBasePath) {
|
|
1378
|
-
tracingIncludes.push(`${tracingBasePath}/skills/**/*`);
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
}
|
|
1382
|
-
for (const pluginDir of workspacePluginDirs) {
|
|
1383
|
-
const tracingBasePath = pathForTracingInclude(resolvedCwd, pluginDir);
|
|
1384
|
-
if (isFile(path2.join(pluginDir, "plugin.yaml"))) {
|
|
1385
|
-
manifestRoots.push(pluginDir);
|
|
1386
|
-
if (tracingBasePath) {
|
|
1387
|
-
tracingIncludes.push(`${tracingBasePath}/plugin.yaml`);
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
if (isDirectory(path2.join(pluginDir, "plugins"))) {
|
|
1391
|
-
manifestRoots.push(path2.join(pluginDir, "plugins"));
|
|
1392
|
-
if (tracingBasePath) {
|
|
1393
|
-
tracingIncludes.push(`${tracingBasePath}/plugins/**/*`);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
if (isDirectory(path2.join(pluginDir, "skills"))) {
|
|
1397
|
-
skillRoots2.push(path2.join(pluginDir, "skills"));
|
|
1398
|
-
if (tracingBasePath) {
|
|
1399
|
-
tracingIncludes.push(`${tracingBasePath}/skills/**/*`);
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
}
|
|
1403
|
-
return {
|
|
1404
|
-
packageNames: uniqueStringsInOrder(
|
|
1405
|
-
discoveredPackages.map((pkg) => pkg.name)
|
|
1406
|
-
),
|
|
1407
|
-
manifestRoots: uniqueStringsInOrder(manifestRoots),
|
|
1408
|
-
skillRoots: uniqueStringsInOrder(skillRoots2),
|
|
1409
|
-
tracingIncludes: uniqueStringsInOrder(tracingIncludes)
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
866
|
// src/chat/plugins/manifest.ts
|
|
1414
867
|
import { z } from "zod";
|
|
1415
|
-
import { parse as
|
|
868
|
+
import { parse as parseYaml } from "yaml";
|
|
1416
869
|
var PLUGIN_NAME_RE = /^[a-z][a-z0-9-]*$/;
|
|
1417
870
|
var SHORT_CAPABILITY_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
|
|
1418
871
|
var SHORT_CONFIG_KEY_RE = /^[a-z0-9]+(\.[a-z0-9-]+)*$/;
|
|
@@ -1622,8 +1075,8 @@ var manifestSourceSchema = z.object({
|
|
|
1622
1075
|
error: "must be an object"
|
|
1623
1076
|
}).optional()
|
|
1624
1077
|
}).passthrough();
|
|
1625
|
-
function formatPath(
|
|
1626
|
-
return
|
|
1078
|
+
function formatPath(path2) {
|
|
1079
|
+
return path2.map((segment) => String(segment)).join(".");
|
|
1627
1080
|
}
|
|
1628
1081
|
function issueMessage(error, prefix) {
|
|
1629
1082
|
const issue = error.issues[0];
|
|
@@ -1838,7 +1291,7 @@ function normalizeMcp(data, name) {
|
|
|
1838
1291
|
function parsePluginManifest(raw, dir) {
|
|
1839
1292
|
let parsedYaml;
|
|
1840
1293
|
try {
|
|
1841
|
-
parsedYaml =
|
|
1294
|
+
parsedYaml = parseYaml(raw);
|
|
1842
1295
|
} catch (error) {
|
|
1843
1296
|
throw new Error(
|
|
1844
1297
|
`Invalid plugin manifest in ${dir}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -1850,51 +1303,51 @@ function parsePluginManifest(raw, dir) {
|
|
|
1850
1303
|
const sourceResult = manifestSourceSchema.safeParse(parsedYaml);
|
|
1851
1304
|
if (!sourceResult.success) {
|
|
1852
1305
|
const issue = sourceResult.error.issues[0];
|
|
1853
|
-
const
|
|
1854
|
-
if (
|
|
1306
|
+
const path2 = formatPath(issue?.path ?? []);
|
|
1307
|
+
if (path2 === "name") {
|
|
1855
1308
|
throw new Error(
|
|
1856
1309
|
`Invalid plugin name in ${dir}: "${parsedYaml.name}"`
|
|
1857
1310
|
);
|
|
1858
1311
|
}
|
|
1859
|
-
if (
|
|
1312
|
+
if (path2 === "description") {
|
|
1860
1313
|
throw new Error(`Invalid plugin description in ${dir}`);
|
|
1861
1314
|
}
|
|
1862
|
-
if (
|
|
1315
|
+
if (path2 === "capabilities") {
|
|
1863
1316
|
throw new Error(
|
|
1864
1317
|
`Plugin ${parsedYaml.name ?? "unknown"} capabilities must be an array when provided`
|
|
1865
1318
|
);
|
|
1866
1319
|
}
|
|
1867
|
-
if (
|
|
1320
|
+
if (path2 === "config-keys") {
|
|
1868
1321
|
throw new Error(
|
|
1869
1322
|
`Plugin ${parsedYaml.name ?? "unknown"} config-keys must be an array when provided`
|
|
1870
1323
|
);
|
|
1871
1324
|
}
|
|
1872
|
-
if (
|
|
1325
|
+
if (path2 === "credentials") {
|
|
1873
1326
|
throw new Error(
|
|
1874
1327
|
`Plugin ${parsedYaml.name ?? "unknown"} credentials must be an object when provided`
|
|
1875
1328
|
);
|
|
1876
1329
|
}
|
|
1877
|
-
if (
|
|
1330
|
+
if (path2 === "runtime-dependencies") {
|
|
1878
1331
|
throw new Error(
|
|
1879
1332
|
`Plugin ${parsedYaml.name ?? "unknown"} runtime-dependencies must be an array`
|
|
1880
1333
|
);
|
|
1881
1334
|
}
|
|
1882
|
-
if (
|
|
1335
|
+
if (path2 === "runtime-postinstall") {
|
|
1883
1336
|
throw new Error(
|
|
1884
1337
|
`Plugin ${parsedYaml.name ?? "unknown"} runtime-postinstall must be an array`
|
|
1885
1338
|
);
|
|
1886
1339
|
}
|
|
1887
|
-
if (
|
|
1340
|
+
if (path2 === "mcp") {
|
|
1888
1341
|
throw new Error(
|
|
1889
1342
|
`Plugin ${parsedYaml.name ?? "unknown"} mcp must be an object`
|
|
1890
1343
|
);
|
|
1891
1344
|
}
|
|
1892
|
-
if (
|
|
1345
|
+
if (path2 === "oauth") {
|
|
1893
1346
|
throw new Error(
|
|
1894
1347
|
`Plugin ${parsedYaml.name ?? "unknown"} oauth must be an object`
|
|
1895
1348
|
);
|
|
1896
1349
|
}
|
|
1897
|
-
if (
|
|
1350
|
+
if (path2 === "target") {
|
|
1898
1351
|
throw new Error(
|
|
1899
1352
|
`Plugin ${parsedYaml.name ?? "unknown"} target must be an object`
|
|
1900
1353
|
);
|
|
@@ -1990,8 +1443,8 @@ function parsePluginManifest(raw, dir) {
|
|
|
1990
1443
|
}
|
|
1991
1444
|
|
|
1992
1445
|
// src/chat/plugins/registry.ts
|
|
1993
|
-
import { readFileSync
|
|
1994
|
-
import
|
|
1446
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
1447
|
+
import path from "path";
|
|
1995
1448
|
|
|
1996
1449
|
// src/chat/plugins/auth/github-app-broker.ts
|
|
1997
1450
|
import { createPrivateKey, createSign, randomUUID } from "crypto";
|
|
@@ -2072,8 +1525,8 @@ function createAppJwt(appId, privateKeyEnv) {
|
|
|
2072
1525
|
const signature = signer.sign(getPrivateKey(privateKeyEnv)).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
2073
1526
|
return `${signingInput}.${signature}`;
|
|
2074
1527
|
}
|
|
2075
|
-
async function githubRequest(apiBase,
|
|
2076
|
-
const response = await fetch(`${apiBase}${
|
|
1528
|
+
async function githubRequest(apiBase, path2, params) {
|
|
1529
|
+
const response = await fetch(`${apiBase}${path2}`, {
|
|
2077
1530
|
method: params.method ?? "GET",
|
|
2078
1531
|
headers: {
|
|
2079
1532
|
Accept: "application/vnd.github+json",
|
|
@@ -2523,7 +1976,7 @@ function registerPluginManifest(state, raw, pluginDir) {
|
|
|
2523
1976
|
const definition = {
|
|
2524
1977
|
manifest,
|
|
2525
1978
|
dir: pluginDir,
|
|
2526
|
-
skillsDir:
|
|
1979
|
+
skillsDir: path.join(pluginDir, "skills")
|
|
2527
1980
|
};
|
|
2528
1981
|
state.pluginDefinitions.push(definition);
|
|
2529
1982
|
state.pluginsByName.set(manifest.name, definition);
|
|
@@ -2538,7 +1991,7 @@ function normalizePluginRoots(roots) {
|
|
|
2538
1991
|
const resolved = [];
|
|
2539
1992
|
const seen = /* @__PURE__ */ new Set();
|
|
2540
1993
|
for (const root of roots) {
|
|
2541
|
-
const normalized =
|
|
1994
|
+
const normalized = path.resolve(root);
|
|
2542
1995
|
if (seen.has(normalized)) {
|
|
2543
1996
|
continue;
|
|
2544
1997
|
}
|
|
@@ -2565,7 +2018,7 @@ function getExtraPluginRoots() {
|
|
|
2565
2018
|
}
|
|
2566
2019
|
}
|
|
2567
2020
|
return normalizePluginRoots(
|
|
2568
|
-
raw.split(
|
|
2021
|
+
raw.split(path.delimiter).map((entry) => entry.trim()).filter((entry) => entry.length > 0)
|
|
2569
2022
|
);
|
|
2570
2023
|
}
|
|
2571
2024
|
function getPluginCatalogSource() {
|
|
@@ -2599,7 +2052,7 @@ function buildLoadedPluginState(source) {
|
|
|
2599
2052
|
let entries;
|
|
2600
2053
|
let rootStat;
|
|
2601
2054
|
try {
|
|
2602
|
-
rootStat =
|
|
2055
|
+
rootStat = statSync(pluginsRoot);
|
|
2603
2056
|
} catch (error) {
|
|
2604
2057
|
logWarn(
|
|
2605
2058
|
"plugin_root_read_failed",
|
|
@@ -2613,21 +2066,21 @@ function buildLoadedPluginState(source) {
|
|
|
2613
2066
|
continue;
|
|
2614
2067
|
}
|
|
2615
2068
|
if (rootStat.isDirectory()) {
|
|
2616
|
-
const manifestPath =
|
|
2069
|
+
const manifestPath = path.join(pluginsRoot, "plugin.yaml");
|
|
2617
2070
|
let hasRootManifest = false;
|
|
2618
2071
|
try {
|
|
2619
|
-
hasRootManifest =
|
|
2072
|
+
hasRootManifest = statSync(manifestPath).isFile();
|
|
2620
2073
|
} catch {
|
|
2621
2074
|
hasRootManifest = false;
|
|
2622
2075
|
}
|
|
2623
2076
|
if (hasRootManifest) {
|
|
2624
|
-
const rawRootManifest =
|
|
2077
|
+
const rawRootManifest = readFileSync(manifestPath, "utf8");
|
|
2625
2078
|
registerPluginManifest(state, rawRootManifest, pluginsRoot);
|
|
2626
2079
|
continue;
|
|
2627
2080
|
}
|
|
2628
2081
|
}
|
|
2629
2082
|
try {
|
|
2630
|
-
entries =
|
|
2083
|
+
entries = readdirSync(pluginsRoot);
|
|
2631
2084
|
} catch (error) {
|
|
2632
2085
|
logWarn(
|
|
2633
2086
|
"plugin_root_read_failed",
|
|
@@ -2641,17 +2094,17 @@ function buildLoadedPluginState(source) {
|
|
|
2641
2094
|
continue;
|
|
2642
2095
|
}
|
|
2643
2096
|
for (const entry of entries.sort()) {
|
|
2644
|
-
const pluginDir =
|
|
2097
|
+
const pluginDir = path.join(pluginsRoot, entry);
|
|
2645
2098
|
try {
|
|
2646
|
-
const stat =
|
|
2099
|
+
const stat = statSync(pluginDir);
|
|
2647
2100
|
if (!stat.isDirectory()) continue;
|
|
2648
2101
|
} catch {
|
|
2649
2102
|
continue;
|
|
2650
2103
|
}
|
|
2651
|
-
const manifestPath =
|
|
2104
|
+
const manifestPath = path.join(pluginDir, "plugin.yaml");
|
|
2652
2105
|
let raw;
|
|
2653
2106
|
try {
|
|
2654
|
-
raw =
|
|
2107
|
+
raw = readFileSync(manifestPath, "utf8");
|
|
2655
2108
|
} catch {
|
|
2656
2109
|
continue;
|
|
2657
2110
|
}
|
|
@@ -2784,10 +2237,10 @@ function getPluginSkillRoots() {
|
|
|
2784
2237
|
}
|
|
2785
2238
|
function getPluginForSkillPath(skillPath) {
|
|
2786
2239
|
const state = ensurePluginsLoaded();
|
|
2787
|
-
const resolvedSkillPath =
|
|
2240
|
+
const resolvedSkillPath = path.resolve(skillPath);
|
|
2788
2241
|
return state.pluginDefinitions.find((plugin) => {
|
|
2789
|
-
const resolvedSkillsDir =
|
|
2790
|
-
return resolvedSkillPath === resolvedSkillsDir || resolvedSkillPath.startsWith(`${resolvedSkillsDir}${
|
|
2242
|
+
const resolvedSkillsDir = path.resolve(plugin.skillsDir);
|
|
2243
|
+
return resolvedSkillPath === resolvedSkillsDir || resolvedSkillPath.startsWith(`${resolvedSkillsDir}${path.sep}`);
|
|
2791
2244
|
});
|
|
2792
2245
|
}
|
|
2793
2246
|
function getPluginDefinition(provider) {
|
|
@@ -2838,12 +2291,6 @@ export {
|
|
|
2838
2291
|
resolveErrorReference,
|
|
2839
2292
|
serializeGenAiAttribute,
|
|
2840
2293
|
extractGenAiUsageAttributes,
|
|
2841
|
-
homeDir,
|
|
2842
|
-
skillRoots,
|
|
2843
|
-
soulPathCandidates,
|
|
2844
|
-
aboutPathCandidates,
|
|
2845
|
-
setPluginPackages,
|
|
2846
|
-
discoverInstalledPluginPackageContent,
|
|
2847
2294
|
resolveAuthTokenPlaceholder,
|
|
2848
2295
|
parsePluginManifest,
|
|
2849
2296
|
CredentialUnavailableError,
|