@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.
- package/README.md +5 -1
- package/dist/api-reference.d.ts +2 -0
- package/dist/app.d.ts +5 -10
- package/dist/app.js +107 -54
- package/dist/build/virtual-config.d.ts +18 -2
- package/dist/chat/logging.d.ts +12 -2
- package/dist/chat/plugins/agent-hooks.d.ts +4 -4
- package/dist/chat/plugins/inline-manifest-source.d.ts +5 -0
- package/dist/chat/plugins/manifest.d.ts +5 -3
- package/dist/chat/plugins/package-discovery.d.ts +5 -0
- package/dist/chat/plugins/registry.d.ts +2 -2
- package/dist/chat/plugins/types.d.ts +8 -3
- package/dist/chat/state/turn-session.d.ts +1 -1
- package/dist/{chunk-ITZ2F7UE.js → chunk-4CRYMG7M.js} +10 -22
- package/dist/chunk-5VDO6LSG.js +104 -0
- package/dist/{chunk-ITOW4DED.js → chunk-D23WCM66.js} +2 -2
- package/dist/{chunk-PEF6UXTY.js → chunk-IGVHCX2U.js} +1 -1
- package/dist/{chunk-5LUISFEY.js → chunk-KVZL5NZS.js} +6 -1
- package/dist/{chunk-H652GMDH.js → chunk-WDPWFMCE.js} +297 -84
- package/dist/{chunk-LRVKJAR2.js → chunk-WZFQQ6SP.js} +2 -2
- package/dist/cli/check.js +9 -4
- package/dist/cli/snapshot-warmup.js +4 -4
- package/dist/nitro.d.ts +10 -3
- package/dist/nitro.js +161 -6
- package/dist/plugins.d.ts +22 -0
- package/dist/reporting.d.ts +1 -1
- package/dist/reporting.js +20 -11
- package/package.json +3 -3
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
discoverInstalledPluginPackageContent,
|
|
6
6
|
normalizePluginPackageNames,
|
|
7
7
|
pluginRoots
|
|
8
|
-
} from "./chunk-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
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
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
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
|
-
|
|
1691
|
+
setDefined2(
|
|
1520
1692
|
credentials,
|
|
1521
1693
|
"auth-token-placeholder",
|
|
1522
1694
|
config.credentials.authTokenPlaceholder
|
|
1523
1695
|
);
|
|
1524
|
-
|
|
1525
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1539
|
-
|
|
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
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
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
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
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
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
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
|
|
1989
|
-
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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,
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
3060
|
-
const previousConfig =
|
|
3061
|
-
pluginConfig =
|
|
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.
|
|
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
|
-
|
|
3448
|
+
setPluginCatalogConfig,
|
|
3236
3449
|
getPluginPackageContent,
|
|
3237
3450
|
getPluginCatalogSignature,
|
|
3238
3451
|
getPluginCapabilityProviders,
|