@sentry/junior 0.11.1 → 0.12.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.
@@ -1,13 +1,22 @@
1
1
  import {
2
2
  sentry_exports
3
3
  } from "./chunk-Z3YD6NHK.js";
4
- import {
5
- discoverInstalledPluginPackageContent,
6
- pluginRoots
7
- } from "./chunk-XH7TV4JS.js";
8
4
 
9
5
  // src/chat/logging.ts
10
6
  import { AsyncLocalStorage } from "async_hooks";
7
+
8
+ // src/chat/coerce.ts
9
+ function toOptionalString(value) {
10
+ return typeof value === "string" && value.trim() ? value : void 0;
11
+ }
12
+ function toOptionalNumber(value) {
13
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
14
+ }
15
+ function isRecord(value) {
16
+ return typeof value === "object" && value !== null;
17
+ }
18
+
19
+ // src/chat/logging.ts
11
20
  var MAX_STRING_VALUE = 1200;
12
21
  var SECRETS_RE = [
13
22
  /\b(sk-[A-Za-z0-9_-]{20,})\b/g,
@@ -679,9 +688,6 @@ function setSpanStatus(status) {
679
688
  }
680
689
  setStatus.call(span, status === "ok" ? "ok" : "internal_error");
681
690
  }
682
- function toOptionalString(value) {
683
- return typeof value === "string" && value.trim() ? value : void 0;
684
- }
685
691
  function getActiveTraceId() {
686
692
  const sentry = sentry_exports;
687
693
  if (typeof sentry.getActiveSpan !== "function" || typeof sentry.spanToJSON !== "function") {
@@ -853,9 +859,560 @@ function extractGenAiUsageAttributes(...sources) {
853
859
  };
854
860
  }
855
861
 
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
+
856
1413
  // src/chat/plugins/manifest.ts
857
1414
  import { z } from "zod";
858
- import { parse as parseYaml } from "yaml";
1415
+ import { parse as parseYaml2 } from "yaml";
859
1416
  var PLUGIN_NAME_RE = /^[a-z][a-z0-9-]*$/;
860
1417
  var SHORT_CAPABILITY_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
861
1418
  var SHORT_CONFIG_KEY_RE = /^[a-z0-9]+(\.[a-z0-9-]+)*$/;
@@ -1065,8 +1622,8 @@ var manifestSourceSchema = z.object({
1065
1622
  error: "must be an object"
1066
1623
  }).optional()
1067
1624
  }).passthrough();
1068
- function formatPath(path2) {
1069
- return path2.map((segment) => String(segment)).join(".");
1625
+ function formatPath(path4) {
1626
+ return path4.map((segment) => String(segment)).join(".");
1070
1627
  }
1071
1628
  function issueMessage(error, prefix) {
1072
1629
  const issue = error.issues[0];
@@ -1281,7 +1838,7 @@ function normalizeMcp(data, name) {
1281
1838
  function parsePluginManifest(raw, dir) {
1282
1839
  let parsedYaml;
1283
1840
  try {
1284
- parsedYaml = parseYaml(raw);
1841
+ parsedYaml = parseYaml2(raw);
1285
1842
  } catch (error) {
1286
1843
  throw new Error(
1287
1844
  `Invalid plugin manifest in ${dir}: ${error instanceof Error ? error.message : String(error)}`
@@ -1293,51 +1850,51 @@ function parsePluginManifest(raw, dir) {
1293
1850
  const sourceResult = manifestSourceSchema.safeParse(parsedYaml);
1294
1851
  if (!sourceResult.success) {
1295
1852
  const issue = sourceResult.error.issues[0];
1296
- const path2 = formatPath(issue?.path ?? []);
1297
- if (path2 === "name") {
1853
+ const path4 = formatPath(issue?.path ?? []);
1854
+ if (path4 === "name") {
1298
1855
  throw new Error(
1299
1856
  `Invalid plugin name in ${dir}: "${parsedYaml.name}"`
1300
1857
  );
1301
1858
  }
1302
- if (path2 === "description") {
1859
+ if (path4 === "description") {
1303
1860
  throw new Error(`Invalid plugin description in ${dir}`);
1304
1861
  }
1305
- if (path2 === "capabilities") {
1862
+ if (path4 === "capabilities") {
1306
1863
  throw new Error(
1307
1864
  `Plugin ${parsedYaml.name ?? "unknown"} capabilities must be an array when provided`
1308
1865
  );
1309
1866
  }
1310
- if (path2 === "config-keys") {
1867
+ if (path4 === "config-keys") {
1311
1868
  throw new Error(
1312
1869
  `Plugin ${parsedYaml.name ?? "unknown"} config-keys must be an array when provided`
1313
1870
  );
1314
1871
  }
1315
- if (path2 === "credentials") {
1872
+ if (path4 === "credentials") {
1316
1873
  throw new Error(
1317
1874
  `Plugin ${parsedYaml.name ?? "unknown"} credentials must be an object when provided`
1318
1875
  );
1319
1876
  }
1320
- if (path2 === "runtime-dependencies") {
1877
+ if (path4 === "runtime-dependencies") {
1321
1878
  throw new Error(
1322
1879
  `Plugin ${parsedYaml.name ?? "unknown"} runtime-dependencies must be an array`
1323
1880
  );
1324
1881
  }
1325
- if (path2 === "runtime-postinstall") {
1882
+ if (path4 === "runtime-postinstall") {
1326
1883
  throw new Error(
1327
1884
  `Plugin ${parsedYaml.name ?? "unknown"} runtime-postinstall must be an array`
1328
1885
  );
1329
1886
  }
1330
- if (path2 === "mcp") {
1887
+ if (path4 === "mcp") {
1331
1888
  throw new Error(
1332
1889
  `Plugin ${parsedYaml.name ?? "unknown"} mcp must be an object`
1333
1890
  );
1334
1891
  }
1335
- if (path2 === "oauth") {
1892
+ if (path4 === "oauth") {
1336
1893
  throw new Error(
1337
1894
  `Plugin ${parsedYaml.name ?? "unknown"} oauth must be an object`
1338
1895
  );
1339
1896
  }
1340
- if (path2 === "target") {
1897
+ if (path4 === "target") {
1341
1898
  throw new Error(
1342
1899
  `Plugin ${parsedYaml.name ?? "unknown"} target must be an object`
1343
1900
  );
@@ -1433,8 +1990,8 @@ function parsePluginManifest(raw, dir) {
1433
1990
  }
1434
1991
 
1435
1992
  // src/chat/plugins/registry.ts
1436
- import { readFileSync, readdirSync, statSync } from "fs";
1437
- import path from "path";
1993
+ import { readFileSync as readFileSync2, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
1994
+ import path3 from "path";
1438
1995
 
1439
1996
  // src/chat/plugins/auth/github-app-broker.ts
1440
1997
  import { createPrivateKey, createSign, randomUUID } from "crypto";
@@ -1515,8 +2072,8 @@ function createAppJwt(appId, privateKeyEnv) {
1515
2072
  const signature = signer.sign(getPrivateKey(privateKeyEnv)).toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1516
2073
  return `${signingInput}.${signature}`;
1517
2074
  }
1518
- async function githubRequest(apiBase, path2, params) {
1519
- const response = await fetch(`${apiBase}${path2}`, {
2075
+ async function githubRequest(apiBase, path4, params) {
2076
+ const response = await fetch(`${apiBase}${path4}`, {
1520
2077
  method: params.method ?? "GET",
1521
2078
  headers: {
1522
2079
  Accept: "application/vnd.github+json",
@@ -1966,7 +2523,7 @@ function registerPluginManifest(state, raw, pluginDir) {
1966
2523
  const definition = {
1967
2524
  manifest,
1968
2525
  dir: pluginDir,
1969
- skillsDir: path.join(pluginDir, "skills")
2526
+ skillsDir: path3.join(pluginDir, "skills")
1970
2527
  };
1971
2528
  state.pluginDefinitions.push(definition);
1972
2529
  state.pluginsByName.set(manifest.name, definition);
@@ -1981,7 +2538,7 @@ function normalizePluginRoots(roots) {
1981
2538
  const resolved = [];
1982
2539
  const seen = /* @__PURE__ */ new Set();
1983
2540
  for (const root of roots) {
1984
- const normalized = path.resolve(root);
2541
+ const normalized = path3.resolve(root);
1985
2542
  if (seen.has(normalized)) {
1986
2543
  continue;
1987
2544
  }
@@ -2008,7 +2565,7 @@ function getExtraPluginRoots() {
2008
2565
  }
2009
2566
  }
2010
2567
  return normalizePluginRoots(
2011
- raw.split(path.delimiter).map((entry) => entry.trim()).filter((entry) => entry.length > 0)
2568
+ raw.split(path3.delimiter).map((entry) => entry.trim()).filter((entry) => entry.length > 0)
2012
2569
  );
2013
2570
  }
2014
2571
  function getPluginCatalogSource() {
@@ -2042,7 +2599,7 @@ function buildLoadedPluginState(source) {
2042
2599
  let entries;
2043
2600
  let rootStat;
2044
2601
  try {
2045
- rootStat = statSync(pluginsRoot);
2602
+ rootStat = statSync2(pluginsRoot);
2046
2603
  } catch (error) {
2047
2604
  logWarn(
2048
2605
  "plugin_root_read_failed",
@@ -2056,21 +2613,21 @@ function buildLoadedPluginState(source) {
2056
2613
  continue;
2057
2614
  }
2058
2615
  if (rootStat.isDirectory()) {
2059
- const manifestPath = path.join(pluginsRoot, "plugin.yaml");
2616
+ const manifestPath = path3.join(pluginsRoot, "plugin.yaml");
2060
2617
  let hasRootManifest = false;
2061
2618
  try {
2062
- hasRootManifest = statSync(manifestPath).isFile();
2619
+ hasRootManifest = statSync2(manifestPath).isFile();
2063
2620
  } catch {
2064
2621
  hasRootManifest = false;
2065
2622
  }
2066
2623
  if (hasRootManifest) {
2067
- const rawRootManifest = readFileSync(manifestPath, "utf8");
2624
+ const rawRootManifest = readFileSync2(manifestPath, "utf8");
2068
2625
  registerPluginManifest(state, rawRootManifest, pluginsRoot);
2069
2626
  continue;
2070
2627
  }
2071
2628
  }
2072
2629
  try {
2073
- entries = readdirSync(pluginsRoot);
2630
+ entries = readdirSync3(pluginsRoot);
2074
2631
  } catch (error) {
2075
2632
  logWarn(
2076
2633
  "plugin_root_read_failed",
@@ -2084,17 +2641,17 @@ function buildLoadedPluginState(source) {
2084
2641
  continue;
2085
2642
  }
2086
2643
  for (const entry of entries.sort()) {
2087
- const pluginDir = path.join(pluginsRoot, entry);
2644
+ const pluginDir = path3.join(pluginsRoot, entry);
2088
2645
  try {
2089
- const stat = statSync(pluginDir);
2646
+ const stat = statSync2(pluginDir);
2090
2647
  if (!stat.isDirectory()) continue;
2091
2648
  } catch {
2092
2649
  continue;
2093
2650
  }
2094
- const manifestPath = path.join(pluginDir, "plugin.yaml");
2651
+ const manifestPath = path3.join(pluginDir, "plugin.yaml");
2095
2652
  let raw;
2096
2653
  try {
2097
- raw = readFileSync(manifestPath, "utf8");
2654
+ raw = readFileSync2(manifestPath, "utf8");
2098
2655
  } catch {
2099
2656
  continue;
2100
2657
  }
@@ -2137,6 +2694,9 @@ function ensurePluginsLoaded() {
2137
2694
  logLoadedPlugins(state);
2138
2695
  return state;
2139
2696
  }
2697
+ function getPluginCatalogSignature() {
2698
+ return ensurePluginsLoaded().signature;
2699
+ }
2140
2700
  function getPluginCapabilityProviders() {
2141
2701
  const state = ensurePluginsLoaded();
2142
2702
  return state.pluginDefinitions.map((plugin) => ({
@@ -2224,10 +2784,10 @@ function getPluginSkillRoots() {
2224
2784
  }
2225
2785
  function getPluginForSkillPath(skillPath) {
2226
2786
  const state = ensurePluginsLoaded();
2227
- const resolvedSkillPath = path.resolve(skillPath);
2787
+ const resolvedSkillPath = path3.resolve(skillPath);
2228
2788
  return state.pluginDefinitions.find((plugin) => {
2229
- const resolvedSkillsDir = path.resolve(plugin.skillsDir);
2230
- return resolvedSkillPath === resolvedSkillsDir || resolvedSkillPath.startsWith(`${resolvedSkillsDir}${path.sep}`);
2789
+ const resolvedSkillsDir = path3.resolve(plugin.skillsDir);
2790
+ return resolvedSkillPath === resolvedSkillsDir || resolvedSkillPath.startsWith(`${resolvedSkillsDir}${path3.sep}`);
2231
2791
  });
2232
2792
  }
2233
2793
  function getPluginDefinition(provider) {
@@ -2262,6 +2822,9 @@ function createPluginBroker(provider, deps) {
2262
2822
  }
2263
2823
 
2264
2824
  export {
2825
+ toOptionalString,
2826
+ toOptionalNumber,
2827
+ isRecord,
2265
2828
  logInfo,
2266
2829
  logWarn,
2267
2830
  logError,
@@ -2272,15 +2835,21 @@ export {
2272
2835
  withSpan,
2273
2836
  setSpanAttributes,
2274
2837
  setSpanStatus,
2275
- toOptionalString,
2276
2838
  resolveErrorReference,
2277
2839
  serializeGenAiAttribute,
2278
2840
  extractGenAiUsageAttributes,
2841
+ homeDir,
2842
+ skillRoots,
2843
+ soulPathCandidates,
2844
+ aboutPathCandidates,
2845
+ setPluginPackages,
2846
+ discoverInstalledPluginPackageContent,
2279
2847
  resolveAuthTokenPlaceholder,
2280
2848
  parsePluginManifest,
2281
2849
  CredentialUnavailableError,
2282
2850
  buildOAuthTokenRequest,
2283
2851
  parseOAuthTokenResponse,
2852
+ getPluginCatalogSignature,
2284
2853
  getPluginCapabilityProviders,
2285
2854
  getPluginProviders,
2286
2855
  getPluginMcpProviders,