@sentry/junior 0.63.0 → 0.64.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.
@@ -5,7 +5,7 @@ import {
5
5
  discoverInstalledPluginPackageContent,
6
6
  normalizePluginPackageNames,
7
7
  pluginRoots
8
- } from "./chunk-5LUISFEY.js";
8
+ } from "./chunk-KVZL5NZS.js";
9
9
 
10
10
  // src/chat/coerce.ts
11
11
  function toOptionalString(value) {
@@ -119,6 +119,16 @@ var CONSOLE_PREVIEW_KEYS = /* @__PURE__ */ new Set([
119
119
  "gen_ai.tool.call.arguments",
120
120
  "gen_ai.tool.call.result"
121
121
  ]);
122
+ var SENTRY_TAG_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
123
+ "app.platform",
124
+ "messaging.system",
125
+ "app.actor.type",
126
+ "gen_ai.agent.name",
127
+ "gen_ai.request.model",
128
+ "app.skill.name",
129
+ "http.request.method",
130
+ "url.path"
131
+ ]);
122
132
  function getSentryEnvironment() {
123
133
  return (process.env.SENTRY_ENVIRONMENT ?? process.env.VERCEL_ENV ?? process.env.NODE_ENV ?? "").trim().toLowerCase();
124
134
  }
@@ -857,7 +867,7 @@ var log = {
857
867
  error(eventName, attrs = {}, body) {
858
868
  emit("error", eventName, attrs, body);
859
869
  },
860
- exception(eventName, error, attrs = {}, body) {
870
+ exception(eventName, error, attrs = {}, body, context) {
861
871
  const normalizedError = error instanceof Error ? error : new Error(String(error));
862
872
  emit(
863
873
  "error",
@@ -876,6 +886,9 @@ var log = {
876
886
  const sentryCaptureException = sentry_exports.captureException;
877
887
  if (typeof sentryWithScope === "function" && typeof sentryCaptureException === "function") {
878
888
  sentryWithScope((scope) => {
889
+ if (context) {
890
+ setSentryScopeContext(scope, context);
891
+ }
879
892
  for (const [key, value] of Object.entries(
880
893
  mergeAttributes(contextStorage.getStore(), attrs)
881
894
  )) {
@@ -886,6 +899,9 @@ var log = {
886
899
  return eventId;
887
900
  }
888
901
  if (typeof sentryCaptureException === "function") {
902
+ if (context) {
903
+ setSentryUser(sentryUserIdentityFromContext(context));
904
+ }
889
905
  eventId = sentryCaptureException(normalizedError);
890
906
  }
891
907
  return eventId;
@@ -1007,16 +1023,51 @@ function toSpanAttributes(context) {
1007
1023
  function setSentryTagsFromContext(context) {
1008
1024
  const attrs = contextToAttributes(context);
1009
1025
  for (const [key, value] of Object.entries(attrs)) {
1026
+ if (!SENTRY_TAG_ATTRIBUTE_KEYS.has(key)) {
1027
+ continue;
1028
+ }
1010
1029
  if (typeof value === "string" && value.length > 0) {
1011
1030
  sentry_exports.setTag(key, value);
1012
1031
  }
1013
1032
  }
1033
+ }
1034
+ function sentryUserIdentityFromContext(context) {
1014
1035
  if (context.slackUserId) {
1015
- sentry_exports.setUser({
1036
+ return {
1016
1037
  id: context.slackUserId,
1017
- username: context.slackUserName
1018
- });
1038
+ ...context.slackUserName ? { username: context.slackUserName } : {},
1039
+ ...context.slackUserEmail ? { email: context.slackUserEmail } : {}
1040
+ };
1019
1041
  }
1042
+ return void 0;
1043
+ }
1044
+ function sentryUserFromIdentity(identity) {
1045
+ return {
1046
+ id: identity.id,
1047
+ ip_address: null,
1048
+ ...identity.username ? { username: identity.username } : {},
1049
+ ...identity.email ? { email: identity.email } : {}
1050
+ };
1051
+ }
1052
+ function setSentryUser(identity) {
1053
+ if (!identity) return;
1054
+ sentry_exports.setUser(sentryUserFromIdentity(identity));
1055
+ }
1056
+ function setSentryScopeContext(scope, context) {
1057
+ const attrs = contextToAttributes(context);
1058
+ for (const [key, value] of Object.entries(attrs)) {
1059
+ if (!SENTRY_TAG_ATTRIBUTE_KEYS.has(key)) {
1060
+ continue;
1061
+ }
1062
+ if (typeof value === "string" && value.length > 0) {
1063
+ scope.setTag(key, value);
1064
+ }
1065
+ }
1066
+ const identity = sentryUserIdentityFromContext(context);
1067
+ if (identity) {
1068
+ scope.setUser(sentryUserFromIdentity(identity));
1069
+ }
1070
+ scope.setContext("app", attrs);
1020
1071
  }
1021
1072
  function toSpanAttributeValue(value) {
1022
1073
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
@@ -1058,12 +1109,14 @@ function logException(error, eventName, context = {}, attributes = {}, body) {
1058
1109
  eventName,
1059
1110
  normalizedError,
1060
1111
  { ...toSpanAttributes(context), ...attributes },
1061
- body
1112
+ body,
1113
+ context
1062
1114
  );
1063
1115
  }
1064
1116
  function setTags(context = {}) {
1065
1117
  setLogContext(context);
1066
1118
  setSentryTagsFromContext(context);
1119
+ setSentryUser(sentryUserIdentityFromContext(context));
1067
1120
  }
1068
1121
  function createRequestContext(request, context = {}) {
1069
1122
  return createLogContextFromRequest(request, context);
@@ -1151,7 +1204,7 @@ function sanitizeGenAiValue(value, seen, depth, keyName) {
1151
1204
  if (shouldTreatAsBlob) {
1152
1205
  return `[omitted:${value.length}]`;
1153
1206
  }
1154
- return truncateGenAiString(value, GEN_AI_MAX_STRING_CHARS);
1207
+ return truncateGenAiString(redactSecrets(value), GEN_AI_MAX_STRING_CHARS);
1155
1208
  }
1156
1209
  if (typeof value === "number") {
1157
1210
  return Number.isFinite(value) ? value : void 0;
@@ -1166,7 +1219,7 @@ function sanitizeGenAiValue(value, seen, depth, keyName) {
1166
1219
  return value.slice(0, GEN_AI_MAX_ARRAY_ITEMS).map((entry) => sanitizeGenAiValue(entry, seen, depth + 1)).filter((entry) => entry !== void 0);
1167
1220
  }
1168
1221
  if (typeof value !== "object") {
1169
- return String(value);
1222
+ return redactSecrets(String(value));
1170
1223
  }
1171
1224
  if (seen.has(value)) {
1172
1225
  return "[circular]";
@@ -1194,7 +1247,7 @@ function serializeGenAiAttribute(value, maxChars = GEN_AI_DEFAULT_MAX_ATTRIBUTE_
1194
1247
  if (!serialized) {
1195
1248
  return void 0;
1196
1249
  }
1197
- return truncateGenAiString(serialized, maxChars);
1250
+ return truncateGenAiString(redactSecrets(serialized), maxChars);
1198
1251
  }
1199
1252
  function asRecord(value) {
1200
1253
  return value && typeof value === "object" ? value : void 0;
@@ -1270,6 +1323,125 @@ function extractGenAiUsageAttributes(...sources) {
1270
1323
  // src/chat/plugins/manifest.ts
1271
1324
  import { z } from "zod";
1272
1325
  import { parse as parseYaml } from "yaml";
1326
+
1327
+ // src/chat/plugins/inline-manifest-source.ts
1328
+ function setDefined(target, key, value) {
1329
+ if (value !== void 0) {
1330
+ target[key] = value;
1331
+ }
1332
+ }
1333
+ function isRecord2(value) {
1334
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
1335
+ }
1336
+ function unqualifyManifestToken(name, value) {
1337
+ if (typeof name === "string" && typeof value === "string" && value.startsWith(`${name}.`)) {
1338
+ return value.slice(name.length + 1);
1339
+ }
1340
+ return value;
1341
+ }
1342
+ function inlineTokenListSource(name, values) {
1343
+ if (values === void 0 || !Array.isArray(values)) {
1344
+ return values;
1345
+ }
1346
+ return values.map((value) => unqualifyManifestToken(name, value));
1347
+ }
1348
+ function inlineCredentialsSource(credentials) {
1349
+ if (credentials === void 0 || !isRecord2(credentials)) {
1350
+ return credentials;
1351
+ }
1352
+ const result = {};
1353
+ setDefined(result, "type", credentials.type);
1354
+ setDefined(result, "domains", credentials.domains);
1355
+ setDefined(result, "api-headers", credentials.apiHeaders);
1356
+ setDefined(result, "auth-token-env", credentials.authTokenEnv);
1357
+ setDefined(
1358
+ result,
1359
+ "auth-token-placeholder",
1360
+ credentials.authTokenPlaceholder
1361
+ );
1362
+ if (credentials.type === "github-app") {
1363
+ setDefined(result, "app-id-env", credentials.appIdEnv);
1364
+ setDefined(result, "private-key-env", credentials.privateKeyEnv);
1365
+ setDefined(result, "installation-id-env", credentials.installationIdEnv);
1366
+ }
1367
+ return result;
1368
+ }
1369
+ function inlineMcpSource(mcp) {
1370
+ if (mcp === void 0 || !isRecord2(mcp)) {
1371
+ return mcp;
1372
+ }
1373
+ const result = {};
1374
+ setDefined(result, "transport", mcp.transport);
1375
+ setDefined(result, "url", mcp.url);
1376
+ setDefined(result, "headers", mcp.headers);
1377
+ setDefined(result, "allowed-tools", mcp.allowedTools);
1378
+ return result;
1379
+ }
1380
+ function inlineOauthSource(oauth) {
1381
+ if (oauth === void 0 || !isRecord2(oauth)) {
1382
+ return oauth;
1383
+ }
1384
+ const result = {};
1385
+ setDefined(result, "client-id-env", oauth.clientIdEnv);
1386
+ setDefined(result, "client-secret-env", oauth.clientSecretEnv);
1387
+ setDefined(result, "authorize-endpoint", oauth.authorizeEndpoint);
1388
+ setDefined(result, "token-endpoint", oauth.tokenEndpoint);
1389
+ setDefined(result, "scope", oauth.scope);
1390
+ setDefined(result, "authorize-params", oauth.authorizeParams);
1391
+ setDefined(result, "token-auth-method", oauth.tokenAuthMethod);
1392
+ setDefined(result, "token-extra-headers", oauth.tokenExtraHeaders);
1393
+ return result;
1394
+ }
1395
+ function inlineTargetSource(name, target) {
1396
+ if (target === void 0 || !isRecord2(target)) {
1397
+ return target;
1398
+ }
1399
+ const result = {};
1400
+ setDefined(result, "type", target.type);
1401
+ setDefined(
1402
+ result,
1403
+ "config-key",
1404
+ unqualifyManifestToken(name, target.configKey)
1405
+ );
1406
+ setDefined(result, "command-flags", target.commandFlags);
1407
+ return result;
1408
+ }
1409
+ function inlineManifestSource(manifest) {
1410
+ const result = {};
1411
+ setDefined(result, "name", manifest.name);
1412
+ setDefined(result, "description", manifest.description);
1413
+ setDefined(
1414
+ result,
1415
+ "capabilities",
1416
+ inlineTokenListSource(manifest.name, manifest.capabilities)
1417
+ );
1418
+ setDefined(
1419
+ result,
1420
+ "config-keys",
1421
+ inlineTokenListSource(manifest.name, manifest.configKeys)
1422
+ );
1423
+ setDefined(result, "domains", manifest.domains);
1424
+ setDefined(result, "api-headers", manifest.apiHeaders);
1425
+ setDefined(result, "command-env", manifest.commandEnv);
1426
+ setDefined(result, "env-vars", manifest.envVars);
1427
+ setDefined(
1428
+ result,
1429
+ "credentials",
1430
+ inlineCredentialsSource(manifest.credentials)
1431
+ );
1432
+ setDefined(result, "runtime-dependencies", manifest.runtimeDependencies);
1433
+ setDefined(result, "runtime-postinstall", manifest.runtimePostinstall);
1434
+ setDefined(result, "mcp", inlineMcpSource(manifest.mcp));
1435
+ setDefined(result, "oauth", inlineOauthSource(manifest.oauth));
1436
+ setDefined(
1437
+ result,
1438
+ "target",
1439
+ inlineTargetSource(manifest.name, manifest.target)
1440
+ );
1441
+ return result;
1442
+ }
1443
+
1444
+ // src/chat/plugins/manifest.ts
1273
1445
  var PLUGIN_NAME_RE = /^[a-z][a-z0-9-]*$/;
1274
1446
  var SHORT_CAPABILITY_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*$/;
1275
1447
  var SHORT_CONFIG_KEY_RE = /^[a-z0-9]+(\.[a-z0-9-]+)*$/;
@@ -1489,45 +1661,45 @@ var manifestSourceSchema = z.object({
1489
1661
  error: "must be an object"
1490
1662
  }).optional()
1491
1663
  }).passthrough();
1492
- function setDefined(target, key, value) {
1664
+ function setDefined2(target, key, value) {
1493
1665
  if (value !== void 0) {
1494
1666
  target[key] = value;
1495
1667
  }
1496
1668
  }
1497
1669
  function manifestConfigPatch(config) {
1498
1670
  const result = {};
1499
- setDefined(result, "description", config.description);
1500
- setDefined(result, "capabilities", config.capabilities);
1501
- setDefined(result, "config-keys", config.configKeys);
1502
- setDefined(result, "domains", config.domains);
1503
- setDefined(result, "api-headers", config.apiHeaders);
1504
- setDefined(result, "command-env", config.commandEnv);
1505
- setDefined(result, "env-vars", config.envVars);
1671
+ setDefined2(result, "description", config.description);
1672
+ setDefined2(result, "capabilities", config.capabilities);
1673
+ setDefined2(result, "config-keys", config.configKeys);
1674
+ setDefined2(result, "domains", config.domains);
1675
+ setDefined2(result, "api-headers", config.apiHeaders);
1676
+ setDefined2(result, "command-env", config.commandEnv);
1677
+ setDefined2(result, "env-vars", config.envVars);
1506
1678
  if (config.credentials !== void 0) {
1507
1679
  if (!config.credentials) {
1508
1680
  result.credentials = null;
1509
1681
  } else {
1510
1682
  const credentials = {};
1511
- setDefined(credentials, "type", config.credentials.type);
1512
- setDefined(credentials, "domains", config.credentials.domains);
1513
- setDefined(credentials, "api-headers", config.credentials.apiHeaders);
1514
- setDefined(
1683
+ setDefined2(credentials, "type", config.credentials.type);
1684
+ setDefined2(credentials, "domains", config.credentials.domains);
1685
+ setDefined2(credentials, "api-headers", config.credentials.apiHeaders);
1686
+ setDefined2(
1515
1687
  credentials,
1516
1688
  "auth-token-env",
1517
1689
  config.credentials.authTokenEnv
1518
1690
  );
1519
- setDefined(
1691
+ setDefined2(
1520
1692
  credentials,
1521
1693
  "auth-token-placeholder",
1522
1694
  config.credentials.authTokenPlaceholder
1523
1695
  );
1524
- setDefined(credentials, "app-id-env", config.credentials.appIdEnv);
1525
- setDefined(
1696
+ setDefined2(credentials, "app-id-env", config.credentials.appIdEnv);
1697
+ setDefined2(
1526
1698
  credentials,
1527
1699
  "private-key-env",
1528
1700
  config.credentials.privateKeyEnv
1529
1701
  );
1530
- setDefined(
1702
+ setDefined2(
1531
1703
  credentials,
1532
1704
  "installation-id-env",
1533
1705
  config.credentials.installationIdEnv
@@ -1535,17 +1707,17 @@ function manifestConfigPatch(config) {
1535
1707
  result.credentials = credentials;
1536
1708
  }
1537
1709
  }
1538
- setDefined(result, "runtime-dependencies", config.runtimeDependencies);
1539
- setDefined(result, "runtime-postinstall", config.runtimePostinstall);
1710
+ setDefined2(result, "runtime-dependencies", config.runtimeDependencies);
1711
+ setDefined2(result, "runtime-postinstall", config.runtimePostinstall);
1540
1712
  if (config.mcp !== void 0) {
1541
1713
  if (!config.mcp) {
1542
1714
  result.mcp = null;
1543
1715
  } else {
1544
1716
  const mcp = {};
1545
- setDefined(mcp, "transport", config.mcp.transport);
1546
- setDefined(mcp, "url", config.mcp.url);
1547
- setDefined(mcp, "headers", config.mcp.headers);
1548
- setDefined(mcp, "allowed-tools", config.mcp.allowedTools);
1717
+ setDefined2(mcp, "transport", config.mcp.transport);
1718
+ setDefined2(mcp, "url", config.mcp.url);
1719
+ setDefined2(mcp, "headers", config.mcp.headers);
1720
+ setDefined2(mcp, "allowed-tools", config.mcp.allowedTools);
1549
1721
  result.mcp = mcp;
1550
1722
  }
1551
1723
  }
@@ -1554,14 +1726,14 @@ function manifestConfigPatch(config) {
1554
1726
  result.oauth = null;
1555
1727
  } else {
1556
1728
  const oauth = {};
1557
- setDefined(oauth, "client-id-env", config.oauth.clientIdEnv);
1558
- setDefined(oauth, "client-secret-env", config.oauth.clientSecretEnv);
1559
- setDefined(oauth, "authorize-endpoint", config.oauth.authorizeEndpoint);
1560
- setDefined(oauth, "token-endpoint", config.oauth.tokenEndpoint);
1561
- setDefined(oauth, "scope", config.oauth.scope);
1562
- setDefined(oauth, "authorize-params", config.oauth.authorizeParams);
1563
- setDefined(oauth, "token-auth-method", config.oauth.tokenAuthMethod);
1564
- setDefined(oauth, "token-extra-headers", config.oauth.tokenExtraHeaders);
1729
+ setDefined2(oauth, "client-id-env", config.oauth.clientIdEnv);
1730
+ setDefined2(oauth, "client-secret-env", config.oauth.clientSecretEnv);
1731
+ setDefined2(oauth, "authorize-endpoint", config.oauth.authorizeEndpoint);
1732
+ setDefined2(oauth, "token-endpoint", config.oauth.tokenEndpoint);
1733
+ setDefined2(oauth, "scope", config.oauth.scope);
1734
+ setDefined2(oauth, "authorize-params", config.oauth.authorizeParams);
1735
+ setDefined2(oauth, "token-auth-method", config.oauth.tokenAuthMethod);
1736
+ setDefined2(oauth, "token-extra-headers", config.oauth.tokenExtraHeaders);
1565
1737
  result.oauth = oauth;
1566
1738
  }
1567
1739
  }
@@ -1570,9 +1742,9 @@ function manifestConfigPatch(config) {
1570
1742
  result.target = null;
1571
1743
  } else {
1572
1744
  const target = {};
1573
- setDefined(target, "type", config.target.type);
1574
- setDefined(target, "config-key", config.target.configKey);
1575
- setDefined(target, "command-flags", config.target.commandFlags);
1745
+ setDefined2(target, "type", config.target.type);
1746
+ setDefined2(target, "config-key", config.target.configKey);
1747
+ setDefined2(target, "command-flags", config.target.commandFlags);
1576
1748
  result.target = target;
1577
1749
  }
1578
1750
  }
@@ -1985,89 +2157,76 @@ function normalizeMcp(data, envVars, name) {
1985
2157
  ...result.data["allowed-tools"] ? { allowedTools: result.data["allowed-tools"] } : {}
1986
2158
  };
1987
2159
  }
1988
- function parsePluginManifest(raw, dir, config) {
1989
- let parsedYaml;
1990
- try {
1991
- parsedYaml = parseYaml(raw);
1992
- } catch (error) {
1993
- throw new Error(
1994
- `Invalid plugin manifest in ${dir}: ${error instanceof Error ? error.message : String(error)}`
1995
- );
1996
- }
1997
- if (!parsedYaml || typeof parsedYaml !== "object" || Array.isArray(parsedYaml)) {
1998
- throw new Error(`Invalid plugin manifest in ${dir}: expected an object`);
1999
- }
2000
- const source = applyManifestConfig(parsedYaml, config);
2160
+ function parseManifestSource(parsedSource, dir, config) {
2161
+ const source = applyManifestConfig(parsedSource, config);
2001
2162
  const sourceResult = manifestSourceSchema.safeParse(source);
2002
2163
  if (!sourceResult.success) {
2003
2164
  const issue = sourceResult.error.issues[0];
2004
2165
  const path3 = formatPath(issue?.path ?? []);
2005
2166
  if (path3 === "name") {
2006
- throw new Error(
2007
- `Invalid plugin name in ${dir}: "${parsedYaml.name}"`
2008
- );
2167
+ throw new Error(`Invalid plugin name in ${dir}: "${parsedSource.name}"`);
2009
2168
  }
2010
2169
  if (path3 === "description") {
2011
2170
  throw new Error(`Invalid plugin description in ${dir}`);
2012
2171
  }
2013
2172
  if (path3 === "capabilities") {
2014
2173
  throw new Error(
2015
- `Plugin ${parsedYaml.name ?? "unknown"} capabilities must be an array when provided`
2174
+ `Plugin ${String(parsedSource.name ?? "unknown")} capabilities must be an array when provided`
2016
2175
  );
2017
2176
  }
2018
2177
  if (path3 === "config-keys") {
2019
2178
  throw new Error(
2020
- `Plugin ${parsedYaml.name ?? "unknown"} config-keys must be an array when provided`
2179
+ `Plugin ${String(parsedSource.name ?? "unknown")} config-keys must be an array when provided`
2021
2180
  );
2022
2181
  }
2023
2182
  if (path3 === "domains") {
2024
2183
  throw new Error(
2025
- `Plugin ${parsedYaml.name ?? "unknown"} ${path3} must be a non-empty array of domains`
2184
+ `Plugin ${String(parsedSource.name ?? "unknown")} ${path3} must be a non-empty array of domains`
2026
2185
  );
2027
2186
  }
2028
2187
  if (path3 === "api-headers") {
2029
2188
  throw new Error(
2030
- `Plugin ${parsedYaml.name ?? "unknown"} api-headers must be an object when provided`
2189
+ `Plugin ${String(parsedSource.name ?? "unknown")} api-headers must be an object when provided`
2031
2190
  );
2032
2191
  }
2033
2192
  if (path3 === "command-env") {
2034
2193
  throw new Error(
2035
- `Plugin ${parsedYaml.name ?? "unknown"} command-env must be an object when provided`
2194
+ `Plugin ${String(parsedSource.name ?? "unknown")} command-env must be an object when provided`
2036
2195
  );
2037
2196
  }
2038
2197
  if (path3 === "credentials") {
2039
2198
  throw new Error(
2040
- `Plugin ${parsedYaml.name ?? "unknown"} credentials must be an object when provided`
2199
+ `Plugin ${String(parsedSource.name ?? "unknown")} credentials must be an object when provided`
2041
2200
  );
2042
2201
  }
2043
2202
  if (path3 === "runtime-dependencies") {
2044
2203
  throw new Error(
2045
- `Plugin ${parsedYaml.name ?? "unknown"} runtime-dependencies must be an array`
2204
+ `Plugin ${String(parsedSource.name ?? "unknown")} runtime-dependencies must be an array`
2046
2205
  );
2047
2206
  }
2048
2207
  if (path3 === "runtime-postinstall") {
2049
2208
  throw new Error(
2050
- `Plugin ${parsedYaml.name ?? "unknown"} runtime-postinstall must be an array`
2209
+ `Plugin ${String(parsedSource.name ?? "unknown")} runtime-postinstall must be an array`
2051
2210
  );
2052
2211
  }
2053
2212
  if (path3 === "env-vars") {
2054
2213
  throw new Error(
2055
- `Plugin ${parsedYaml.name ?? "unknown"} env-vars must be an object`
2214
+ `Plugin ${String(parsedSource.name ?? "unknown")} env-vars must be an object`
2056
2215
  );
2057
2216
  }
2058
2217
  if (path3 === "mcp") {
2059
2218
  throw new Error(
2060
- `Plugin ${parsedYaml.name ?? "unknown"} mcp must be an object`
2219
+ `Plugin ${String(parsedSource.name ?? "unknown")} mcp must be an object`
2061
2220
  );
2062
2221
  }
2063
2222
  if (path3 === "oauth") {
2064
2223
  throw new Error(
2065
- `Plugin ${parsedYaml.name ?? "unknown"} oauth must be an object`
2224
+ `Plugin ${String(parsedSource.name ?? "unknown")} oauth must be an object`
2066
2225
  );
2067
2226
  }
2068
2227
  if (path3 === "target") {
2069
2228
  throw new Error(
2070
- `Plugin ${parsedYaml.name ?? "unknown"} target must be an object`
2229
+ `Plugin ${String(parsedSource.name ?? "unknown")} target must be an object`
2071
2230
  );
2072
2231
  }
2073
2232
  throw new Error(issue?.message ?? `Invalid plugin manifest in ${dir}`);
@@ -2205,6 +2364,23 @@ function parsePluginManifest(raw, dir, config) {
2205
2364
  }
2206
2365
  return manifest;
2207
2366
  }
2367
+ function parsePluginManifest(raw, dir, config) {
2368
+ let parsedYaml;
2369
+ try {
2370
+ parsedYaml = parseYaml(raw);
2371
+ } catch (error) {
2372
+ throw new Error(
2373
+ `Invalid plugin manifest in ${dir}: ${error instanceof Error ? error.message : String(error)}`
2374
+ );
2375
+ }
2376
+ if (!parsedYaml || typeof parsedYaml !== "object" || Array.isArray(parsedYaml)) {
2377
+ throw new Error(`Invalid plugin manifest in ${dir}: expected an object`);
2378
+ }
2379
+ return parseManifestSource(parsedYaml, dir, config);
2380
+ }
2381
+ function parseInlinePluginManifest(manifest, dir, config) {
2382
+ return parseManifestSource(inlineManifestSource(manifest), dir, config);
2383
+ }
2208
2384
 
2209
2385
  // src/chat/plugins/registry.ts
2210
2386
  import { readFileSync, readdirSync, statSync } from "fs";
@@ -2852,8 +3028,7 @@ function providerDomains(manifest) {
2852
3028
  ])
2853
3029
  ].sort((left, right) => left.localeCompare(right));
2854
3030
  }
2855
- function registerPluginManifest(state, raw, pluginDir) {
2856
- const manifest = parsePluginManifest(raw, pluginDir, pluginConfig);
3031
+ function registerPluginManifest(state, manifest, pluginDir, skillsDir) {
2857
3032
  if (state.pluginsByName.has(manifest.name)) {
2858
3033
  throw new Error(`Duplicate plugin name "${manifest.name}"`);
2859
3034
  }
@@ -2868,14 +3043,14 @@ function registerPluginManifest(state, raw, pluginDir) {
2868
3043
  const owner = state.domainToPlugin.get(domain);
2869
3044
  if (owner) {
2870
3045
  throw new Error(
2871
- `Duplicate provider domain "${domain}" in plugin "${manifest.name}" already declared by plugin "${owner}". Use plugins.manifests in PluginConfig to change one plugin's domains or credentials.`
3046
+ `Duplicate provider domain "${domain}" in plugin "${manifest.name}" already declared by plugin "${owner}". Use plugins.manifests in PluginCatalogConfig to change one plugin's domains or credentials.`
2872
3047
  );
2873
3048
  }
2874
3049
  }
2875
3050
  const definition = {
2876
3051
  manifest,
2877
3052
  dir: pluginDir,
2878
- skillsDir: path2.join(pluginDir, "skills")
3053
+ ...skillsDir ? { skillsDir } : {}
2879
3054
  };
2880
3055
  state.pluginDefinitions.push(definition);
2881
3056
  state.pluginsByName.set(manifest.name, definition);
@@ -2889,6 +3064,15 @@ function registerPluginManifest(state, raw, pluginDir) {
2889
3064
  state.domainToPlugin.set(domain, manifest.name);
2890
3065
  }
2891
3066
  }
3067
+ function registerYamlPluginManifest(state, raw, pluginDir) {
3068
+ const manifest = parsePluginManifest(raw, pluginDir, pluginConfig);
3069
+ registerPluginManifest(
3070
+ state,
3071
+ manifest,
3072
+ pluginDir,
3073
+ path2.join(pluginDir, "skills")
3074
+ );
3075
+ }
2892
3076
  function normalizePluginRoots(roots) {
2893
3077
  const resolved = [];
2894
3078
  const seen = /* @__PURE__ */ new Set();
@@ -2910,10 +3094,14 @@ function getPluginCatalogSource() {
2910
3094
  ...packagedContent.manifestRoots
2911
3095
  ]);
2912
3096
  const packagedSkillRoots = normalizePluginRoots(packagedContent.skillRoots);
3097
+ const inlineManifests = pluginConfig?.inlineManifests ?? [];
2913
3098
  return {
3099
+ inlineManifests,
2914
3100
  manifestRoots,
2915
3101
  packagedSkillRoots,
3102
+ packagedContent,
2916
3103
  signature: JSON.stringify({
3104
+ inlineManifests,
2917
3105
  manifestRoots,
2918
3106
  packagedSkillRoots,
2919
3107
  packageNames: [...packagedContent.packageNames].sort(),
@@ -2921,24 +3109,42 @@ function getPluginCatalogSource() {
2921
3109
  })
2922
3110
  };
2923
3111
  }
2924
- function normalizePluginConfig(config) {
3112
+ function normalizePluginCatalogConfig(config) {
2925
3113
  if (!config) {
2926
3114
  return void 0;
2927
3115
  }
2928
3116
  return {
3117
+ inlineManifests: config.inlineManifests ? structuredClone(config.inlineManifests) : void 0,
2929
3118
  packages: normalizePluginPackageNames(config.packages),
2930
3119
  ...config.manifests ? { manifests: structuredClone(config.manifests) } : {}
2931
3120
  };
2932
3121
  }
2933
- function clonePluginConfig(config) {
3122
+ function clonePluginCatalogConfig(config) {
2934
3123
  if (!config) {
2935
3124
  return void 0;
2936
3125
  }
2937
3126
  return {
3127
+ ...config.inlineManifests ? { inlineManifests: structuredClone(config.inlineManifests) } : {},
2938
3128
  packages: [...config.packages ?? []],
2939
3129
  ...config.manifests ? { manifests: structuredClone(config.manifests) } : {}
2940
3130
  };
2941
3131
  }
3132
+ function packageContentByName(packagedContent, packageName) {
3133
+ return packagedContent.packages.find((pkg) => pkg.name === packageName);
3134
+ }
3135
+ function registerInlineManifests(state, source) {
3136
+ for (const definition of source.inlineManifests) {
3137
+ const pkg = definition.packageName ? packageContentByName(source.packagedContent, definition.packageName) : void 0;
3138
+ const dir = pkg?.dir ?? process.cwd();
3139
+ const skillsDir = pkg?.hasSkillsDir ? path2.join(pkg.dir, "skills") : void 0;
3140
+ const manifest = parseInlinePluginManifest(
3141
+ definition.manifest,
3142
+ dir,
3143
+ pluginConfig
3144
+ );
3145
+ registerPluginManifest(state, manifest, dir, skillsDir);
3146
+ }
3147
+ }
2942
3148
  function discoverConfiguredPluginPackageContent() {
2943
3149
  return discoverInstalledPluginPackageContent(process.cwd(), {
2944
3150
  packageNames: pluginConfig?.packages
@@ -2949,6 +3155,7 @@ function buildLoadedPluginState(source) {
2949
3155
  for (const skillRoot of source.packagedSkillRoots) {
2950
3156
  state.packageSkillRoots.add(skillRoot);
2951
3157
  }
3158
+ registerInlineManifests(state, source);
2952
3159
  const roots = source.manifestRoots;
2953
3160
  for (const pluginsRoot of roots) {
2954
3161
  let entries;
@@ -2977,7 +3184,7 @@ function buildLoadedPluginState(source) {
2977
3184
  }
2978
3185
  if (hasRootManifest) {
2979
3186
  const rawRootManifest = readFileSync(manifestPath, "utf8");
2980
- registerPluginManifest(state, rawRootManifest, pluginsRoot);
3187
+ registerYamlPluginManifest(state, rawRootManifest, pluginsRoot);
2981
3188
  continue;
2982
3189
  }
2983
3190
  }
@@ -3010,7 +3217,7 @@ function buildLoadedPluginState(source) {
3010
3217
  } catch {
3011
3218
  continue;
3012
3219
  }
3013
- registerPluginManifest(state, raw, pluginDir);
3220
+ registerYamlPluginManifest(state, raw, pluginDir);
3014
3221
  }
3015
3222
  }
3016
3223
  for (const name of Object.keys(pluginConfig?.manifests ?? {})) {
@@ -3040,7 +3247,7 @@ function logLoadedPlugins(state) {
3040
3247
  "app.plugin.config_key_count": plugin.manifest.configKeys.length,
3041
3248
  "app.plugin.has_mcp": Boolean(plugin.manifest.mcp),
3042
3249
  "file.directory": plugin.dir,
3043
- "app.file.skill_directory": plugin.skillsDir
3250
+ ...plugin.skillsDir ? { "app.file.skill_directory": plugin.skillsDir } : {}
3044
3251
  },
3045
3252
  "Loaded plugin"
3046
3253
  );
@@ -3056,9 +3263,9 @@ function ensurePluginsLoaded() {
3056
3263
  logLoadedPlugins(state);
3057
3264
  return state;
3058
3265
  }
3059
- function setPluginConfig(config) {
3060
- const previousConfig = clonePluginConfig(pluginConfig);
3061
- pluginConfig = normalizePluginConfig(config);
3266
+ function setPluginCatalogConfig(config) {
3267
+ const previousConfig = clonePluginCatalogConfig(pluginConfig);
3268
+ pluginConfig = normalizePluginCatalogConfig(config);
3062
3269
  return previousConfig;
3063
3270
  }
3064
3271
  function getPluginPackageContent() {
@@ -3152,7 +3359,9 @@ function getPluginSkillRoots() {
3152
3359
  const state = ensurePluginsLoaded();
3153
3360
  return [
3154
3361
  .../* @__PURE__ */ new Set([
3155
- ...state.pluginDefinitions.map((plugin) => plugin.skillsDir),
3362
+ ...state.pluginDefinitions.flatMap(
3363
+ (plugin) => plugin.skillsDir ? [plugin.skillsDir] : []
3364
+ ),
3156
3365
  ...state.packageSkillRoots
3157
3366
  ])
3158
3367
  ];
@@ -3161,6 +3370,9 @@ function getPluginForSkillPath(skillPath) {
3161
3370
  const state = ensurePluginsLoaded();
3162
3371
  const resolvedSkillPath = path2.resolve(skillPath);
3163
3372
  return state.pluginDefinitions.find((plugin) => {
3373
+ if (!plugin.skillsDir) {
3374
+ return false;
3375
+ }
3164
3376
  const resolvedSkillsDir = path2.resolve(plugin.skillsDir);
3165
3377
  return resolvedSkillPath === resolvedSkillsDir || resolvedSkillPath.startsWith(`${resolvedSkillsDir}${path2.sep}`);
3166
3378
  });
@@ -3210,6 +3422,7 @@ export {
3210
3422
  normalizeGenAiFinishReason,
3211
3423
  createChatSdkLogger,
3212
3424
  getLogContextAttributes,
3425
+ setSentryUser,
3213
3426
  logInfo,
3214
3427
  logWarn,
3215
3428
  logError,
@@ -3232,7 +3445,7 @@ export {
3232
3445
  hasRequiredOAuthScope,
3233
3446
  buildOAuthTokenRequest,
3234
3447
  parseOAuthTokenResponse,
3235
- setPluginConfig,
3448
+ setPluginCatalogConfig,
3236
3449
  getPluginPackageContent,
3237
3450
  getPluginCatalogSignature,
3238
3451
  getPluginCapabilityProviders,