@sentry/junior 0.114.0 → 0.115.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.
Files changed (88) hide show
  1. package/dist/{agent-hooks-WNBUY4OB.js → agent-hooks-4EUUXP2F.js} +12 -11
  2. package/dist/api/conversations/detail.d.ts +2 -0
  3. package/dist/api/conversations/event-list.d.ts +2 -0
  4. package/dist/api/health.d.ts +7 -0
  5. package/dist/api/plugin-reports.d.ts +62 -0
  6. package/dist/api/plugins.d.ts +9 -0
  7. package/dist/api/runtime.d.ts +24 -0
  8. package/dist/api/schema/conversation.d.ts +8 -0
  9. package/dist/api/schema.d.ts +2 -2
  10. package/dist/api/schema.js +6 -6
  11. package/dist/api/skills.d.ts +6 -0
  12. package/dist/api.js +123 -99
  13. package/dist/app.js +1104 -5006
  14. package/dist/catalog-runtime-Y32UEQLB.js +18 -0
  15. package/dist/chat/agent/request.d.ts +6 -0
  16. package/dist/chat/agent/sandbox.d.ts +2 -0
  17. package/dist/chat/agent/tools.d.ts +2 -0
  18. package/dist/chat/config.d.ts +2 -0
  19. package/dist/chat/conversations/history.d.ts +6 -0
  20. package/dist/chat/local/credential-sync.d.ts +5 -0
  21. package/dist/chat/local/oauth-relay.d.ts +4 -0
  22. package/dist/chat/mcp/oauth.d.ts +1 -0
  23. package/dist/chat/oauth-authorization.d.ts +17 -0
  24. package/dist/chat/oauth-flow.d.ts +9 -0
  25. package/dist/chat/sandbox/egress/schemas.d.ts +46 -0
  26. package/dist/chat/sandbox/egress/signals.d.ts +9 -0
  27. package/dist/chat/sandbox/sandbox.d.ts +2 -0
  28. package/dist/chat/sentry-payload-filter.d.ts +4 -4
  29. package/dist/chat/services/mcp-auth-orchestration.d.ts +5 -3
  30. package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -0
  31. package/dist/chat/slack/message-control.d.ts +2 -0
  32. package/dist/chat/slack/oauth-authorization-message.d.ts +3 -0
  33. package/dist/chat/task-execution/slack-work.d.ts +2 -0
  34. package/dist/chat/tool-support/zod-tool.d.ts +1 -1
  35. package/dist/chat/tools/definition.d.ts +5 -0
  36. package/dist/{chunk-TLGM5X2M.js → chunk-2QG4MZQ7.js} +2 -2
  37. package/dist/{chunk-WV4UJBAS.js → chunk-43RYMWJ2.js} +523 -2373
  38. package/dist/chunk-4CODA7P5.js +43 -0
  39. package/dist/{chunk-YU6PO42Q.js → chunk-67CVNDJ7.js} +1 -1
  40. package/dist/{chunk-OSKEC4XU.js → chunk-6FKLPVF3.js} +1 -1
  41. package/dist/{chunk-2ZTTXTSZ.js → chunk-6OPTF4BQ.js} +10 -4
  42. package/dist/{chunk-W6RDUAO3.js → chunk-6V762AB4.js} +1 -1
  43. package/dist/{chunk-ABPSDO6M.js → chunk-AGLQYELI.js} +77 -8
  44. package/dist/{chunk-6QWPVTMO.js → chunk-CEYOL62C.js} +9 -7
  45. package/dist/{chunk-RD7EJI7H.js → chunk-CWEZEPD4.js} +3 -3
  46. package/dist/chunk-DIB4GX3G.js +8 -0
  47. package/dist/{chunk-K2W4CK7K.js → chunk-EW5MLKT5.js} +10 -75
  48. package/dist/{chunk-42WRQLJ6.js → chunk-F3B2YJ76.js} +0 -14
  49. package/dist/chunk-FA6POGLH.js +70 -0
  50. package/dist/{chunk-PM3PX42K.js → chunk-FHC4JUSF.js} +1 -1
  51. package/dist/{chunk-6Y5L4BOM.js → chunk-FXOYURO4.js} +5 -3
  52. package/dist/{chunk-S4QDH23A.js → chunk-G36V2YGB.js} +83 -81
  53. package/dist/{chunk-O4GT7LYB.js → chunk-G5SX4UPR.js} +3 -43
  54. package/dist/chunk-HDSDCEPK.js +80 -0
  55. package/dist/{chunk-FIGAF6KL.js → chunk-HWCQRGLL.js} +5 -3
  56. package/dist/{chunk-C4MZ3GP5.js → chunk-HZF5P5UN.js} +1 -1
  57. package/dist/chunk-LYA2AB5G.js +1914 -0
  58. package/dist/{chunk-4FUEG3QY.js → chunk-NVUQSFWX.js} +2 -2
  59. package/dist/chunk-OB42YVAE.js +16 -0
  60. package/dist/{chunk-XLFBQJUO.js → chunk-PVZHG2XZ.js} +4 -4
  61. package/dist/{chunk-VNNBSKCO.js → chunk-RAVKCKXA.js} +7 -7
  62. package/dist/{chunk-ZGXH3REA.js → chunk-SYJT7AKB.js} +12 -2
  63. package/dist/{chunk-5CZ7RETL.js → chunk-TVE25LPW.js} +1 -1
  64. package/dist/chunk-W3U3YQYI.js +71 -0
  65. package/dist/chunk-YCLO7D7M.js +4267 -0
  66. package/dist/cli/chat.js +72 -40
  67. package/dist/cli/check.js +10 -8
  68. package/dist/cli/init.js +1 -0
  69. package/dist/cli/plugins.js +16 -14
  70. package/dist/cli/snapshot-warmup.js +13 -11
  71. package/dist/cli/upgrade.js +10 -8
  72. package/dist/{db-4VLP7KBF.js → db-KBSJHAZU.js} +8 -7
  73. package/dist/handlers/sandbox-egress-signals.d.ts +4 -0
  74. package/dist/instrumentation.js +72 -4
  75. package/dist/nitro.js +2 -2
  76. package/dist/oauth-callback-server-EYRMJTCS.js +231 -0
  77. package/dist/oauth-relay-3ZU72UGL.js +9 -0
  78. package/dist/reporting-schema.d.ts +12 -4
  79. package/dist/reporting.d.ts +5 -5
  80. package/dist/{runner-IPXLWQOF.js → runner-RQGZ5Z2S.js} +139 -72
  81. package/dist/sandbox-egress-signals-CDFAP67O.js +75 -0
  82. package/dist/{skills-QCNZISNF.js → skills-JJQIE3BT.js} +10 -8
  83. package/dist/validation-MZ47PZP5.js +21 -0
  84. package/dist/version.js +1 -1
  85. package/package.json +5 -5
  86. package/dist/catalog-runtime-6O4M6JGA.js +0 -16
  87. package/dist/chat/oauth-authorization-message.d.ts +0 -6
  88. package/dist/validation-I2BW3UHD.js +0 -19
@@ -0,0 +1,43 @@
1
+ import {
2
+ getClient
3
+ } from "./chunk-6GWA276C.js";
4
+
5
+ // src/chat/sentry-links.ts
6
+ function getSentryOrgSlug() {
7
+ const slug = process.env.SENTRY_ORG_SLUG?.trim();
8
+ return slug || void 0;
9
+ }
10
+ function isSentrySaasDsnHost(host) {
11
+ return host === "sentry.io" || host.endsWith(".sentry.io");
12
+ }
13
+ function buildSentryWebBaseUrl(dsn) {
14
+ if (isSentrySaasDsnHost(dsn.host)) {
15
+ return "https://sentry.io";
16
+ }
17
+ const port = dsn.port ? `:${dsn.port}` : "";
18
+ const path = dsn.path ? `/${dsn.path}` : "";
19
+ return `${dsn.protocol}://${dsn.host}${port}${path}`;
20
+ }
21
+ function buildSentryConversationUrl(conversationId) {
22
+ const client = getClient();
23
+ const dsn = client?.getDsn();
24
+ if (!dsn?.host || !dsn.projectId) {
25
+ return void 0;
26
+ }
27
+ const orgSlug = getSentryOrgSlug();
28
+ if (!orgSlug) {
29
+ return void 0;
30
+ }
31
+ const encodedId = encodeURIComponent(conversationId);
32
+ const params = new URLSearchParams();
33
+ params.set("project", dsn.projectId);
34
+ const path = `explore/conversations/${encodedId}/?${params.toString()}`;
35
+ if (isSentrySaasDsnHost(dsn.host)) {
36
+ return `https://${orgSlug}.sentry.io/${path}`;
37
+ }
38
+ return `${buildSentryWebBaseUrl(dsn)}/organizations/${orgSlug}/${path}`;
39
+ }
40
+
41
+ export {
42
+ buildSentryConversationUrl
43
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-ZGXH3REA.js";
3
+ } from "./chunk-SYJT7AKB.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createPluginCatalogRuntime
3
- } from "./chunk-K2W4CK7K.js";
3
+ } from "./chunk-EW5MLKT5.js";
4
4
 
5
5
  // src/chat/plugins/catalog-runtime.ts
6
6
  var pluginCatalogRuntime = createPluginCatalogRuntime();
@@ -5,8 +5,14 @@ var healthReportSchema = z.object({
5
5
  service: z.string(),
6
6
  timestamp: z.string()
7
7
  }).strict();
8
- var pluginReportSchema = z.object({ name: z.string() }).strict();
9
- var pluginReportsSchema = z.array(pluginReportSchema);
8
+ var pluginSchema = z.object({
9
+ capabilities: z.array(z.string()),
10
+ configKeys: z.array(z.string()),
11
+ description: z.string(),
12
+ displayName: z.string(),
13
+ name: z.string()
14
+ }).strict();
15
+ var pluginsSchema = z.array(pluginSchema);
10
16
  var skillReportSchema = z.object({
11
17
  name: z.string(),
12
18
  pluginProvider: z.string().optional()
@@ -97,8 +103,8 @@ var pluginOperationalReportFeedSchema = z.object({
97
103
 
98
104
  export {
99
105
  healthReportSchema,
100
- pluginReportSchema,
101
- pluginReportsSchema,
106
+ pluginSchema,
107
+ pluginsSchema,
102
108
  skillReportSchema,
103
109
  skillReportsSchema,
104
110
  pluginPackageContentItemReportSchema,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-OSKEC4XU.js";
3
+ } from "./chunk-6FKLPVF3.js";
4
4
 
5
5
  // src/chat/plugins/validation.ts
6
6
  import { isDeepStrictEqual } from "util";
@@ -4,6 +4,7 @@ import {
4
4
  sendVercelPluginTask
5
5
  } from "./chunk-KNFROR7R.js";
6
6
  import {
7
+ buildDeterministicTurnId,
7
8
  clearPendingAuth,
8
9
  coerceThreadConversationState,
9
10
  getAgentTurnSessionRecord,
@@ -15,36 +16,38 @@ import {
15
16
  isToolResultError,
16
17
  isToolResultMessage,
17
18
  markConversationMessage,
19
+ markTurnClosed,
18
20
  markTurnCompleted,
19
21
  mergeArtifactsState,
20
22
  normalizeToolNameFromResult,
23
+ persistThreadStateById,
21
24
  stripRuntimeTurnContext,
22
25
  updateConversationStats
23
- } from "./chunk-6QWPVTMO.js";
26
+ } from "./chunk-CEYOL62C.js";
24
27
  import {
25
28
  createPluginEmbedder,
26
29
  createPluginLogger,
27
30
  createPluginModel,
28
31
  createPluginState,
29
32
  getPlugins
30
- } from "./chunk-VNNBSKCO.js";
33
+ } from "./chunk-RAVKCKXA.js";
31
34
  import {
32
35
  getStateAdapter
33
- } from "./chunk-YU6PO42Q.js";
36
+ } from "./chunk-67CVNDJ7.js";
34
37
  import {
35
38
  getDb
36
- } from "./chunk-FIGAF6KL.js";
39
+ } from "./chunk-HWCQRGLL.js";
37
40
  import {
38
41
  ProviderError,
39
42
  getProviderErrorAttributes,
40
43
  getProviderErrorUserMessage
41
- } from "./chunk-ZGXH3REA.js";
44
+ } from "./chunk-SYJT7AKB.js";
42
45
  import {
43
46
  buildTurnFailureResponse
44
- } from "./chunk-4FUEG3QY.js";
47
+ } from "./chunk-NVUQSFWX.js";
45
48
  import {
46
49
  parseSlackMessageTs
47
- } from "./chunk-42WRQLJ6.js";
50
+ } from "./chunk-F3B2YJ76.js";
48
51
 
49
52
  // src/chat/services/turn-failure-response.ts
50
53
  function requireTurnFailureEventId(eventId, eventName) {
@@ -523,6 +526,66 @@ function buildDeliveredTurnStatePatch(args) {
523
526
  };
524
527
  }
525
528
 
529
+ // src/chat/runtime/turn-user-message.ts
530
+ function getTurnUserMessage(conversation, sessionId) {
531
+ for (let index = conversation.messages.length - 1; index >= 0; index -= 1) {
532
+ const message = conversation.messages[index];
533
+ if (message?.role !== "user") {
534
+ continue;
535
+ }
536
+ if (buildDeterministicTurnId(message.id) === sessionId) {
537
+ return message;
538
+ }
539
+ }
540
+ return void 0;
541
+ }
542
+ function getTurnUserMessageId(conversation, sessionId) {
543
+ return getTurnUserMessage(conversation, sessionId)?.id;
544
+ }
545
+ function getTurnUserSlackMessageTs(message) {
546
+ return parseSlackMessageTs(message?.meta?.slackTs);
547
+ }
548
+ function getTurnUserReplyAttachmentContext(message) {
549
+ const inboundAttachmentCount = message?.meta?.attachmentCount ?? 0;
550
+ const imageAttachmentCount = message?.meta?.imageAttachmentCount ?? 0;
551
+ const imagesHydrated = message?.meta?.imagesHydrated === true;
552
+ return {
553
+ ...inboundAttachmentCount > 0 ? { inboundAttachmentCount } : {},
554
+ ...!imagesHydrated && imageAttachmentCount > 0 ? { omittedImageAttachmentCount: imageAttachmentCount } : {}
555
+ };
556
+ }
557
+
558
+ // src/chat/runtime/auth-pause-state.ts
559
+ function completeAuthPauseTurn(args) {
560
+ markConversationMessage(
561
+ args.conversation,
562
+ getTurnUserMessageId(args.conversation, args.sessionId),
563
+ {
564
+ replied: true,
565
+ skippedReason: void 0
566
+ }
567
+ );
568
+ markTurnClosed({
569
+ conversation: args.conversation,
570
+ nowMs: Date.now(),
571
+ sessionId: args.sessionId,
572
+ updateConversationStats
573
+ });
574
+ }
575
+ async function persistAuthPauseTurnState(args) {
576
+ const currentState = await getPersistedThreadState(args.threadStateId);
577
+ const conversation = coerceThreadConversationState(currentState);
578
+ await hydrateConversationMessages({
579
+ conversation,
580
+ conversationId: args.threadStateId
581
+ });
582
+ completeAuthPauseTurn({
583
+ conversation,
584
+ sessionId: args.sessionId
585
+ });
586
+ await persistThreadStateById(args.threadStateId, { conversation });
587
+ }
588
+
526
589
  export {
527
590
  requireTurnFailureEventId,
528
591
  getAgentTurnDiagnosticsAttributes,
@@ -530,5 +593,11 @@ export {
530
593
  ConversationTurnLifecycleService,
531
594
  scheduleSessionCompletedPluginTasks,
532
595
  processPluginTask,
533
- buildDeliveredTurnStatePatch
596
+ buildDeliveredTurnStatePatch,
597
+ getTurnUserMessage,
598
+ getTurnUserMessageId,
599
+ getTurnUserSlackMessageTs,
600
+ getTurnUserReplyAttachmentContext,
601
+ completeAuthPauseTurn,
602
+ persistAuthPauseTurnState
534
603
  };
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-MU6HHZEN.js";
5
5
  import {
6
6
  getStateAdapter
7
- } from "./chunk-YU6PO42Q.js";
7
+ } from "./chunk-67CVNDJ7.js";
8
8
  import {
9
9
  contextProvenance,
10
10
  createSqlConversationEventStore,
@@ -15,7 +15,7 @@ import {
15
15
  instructionProvenanceFor,
16
16
  sanitizePostgresJson,
17
17
  withConversationEventLock
18
- } from "./chunk-FIGAF6KL.js";
18
+ } from "./chunk-HWCQRGLL.js";
19
19
  import {
20
20
  sleep
21
21
  } from "./chunk-4ZNGQH7C.js";
@@ -24,22 +24,24 @@ import {
24
24
  escapeXml,
25
25
  resolveGatewayModel,
26
26
  unwrapCurrentInstruction
27
- } from "./chunk-ZGXH3REA.js";
27
+ } from "./chunk-SYJT7AKB.js";
28
28
  import {
29
29
  toStoredSlackActor
30
- } from "./chunk-C4MZ3GP5.js";
30
+ } from "./chunk-HZF5P5UN.js";
31
31
  import {
32
32
  getActiveTraceId,
33
33
  logException,
34
34
  logWarn,
35
35
  setSpanAttributes
36
- } from "./chunk-4FUEG3QY.js";
36
+ } from "./chunk-NVUQSFWX.js";
37
37
  import {
38
38
  isRecord,
39
- parseSlackMessageTs,
40
39
  toOptionalNumber,
41
40
  toOptionalString
42
- } from "./chunk-42WRQLJ6.js";
41
+ } from "./chunk-OB42YVAE.js";
42
+ import {
43
+ parseSlackMessageTs
44
+ } from "./chunk-F3B2YJ76.js";
43
45
 
44
46
  // src/chat/turn-context-tag.ts
45
47
  var TURN_CONTEXT_TAG = "runtime-turn-context";
@@ -3,16 +3,16 @@ import {
3
3
  } from "./chunk-4ZNGQH7C.js";
4
4
  import {
5
5
  getSlackBotToken
6
- } from "./chunk-ZGXH3REA.js";
6
+ } from "./chunk-SYJT7AKB.js";
7
7
  import {
8
8
  logWarn,
9
9
  setSpanAttributes,
10
10
  setSpanStatus,
11
11
  withSpan
12
- } from "./chunk-4FUEG3QY.js";
12
+ } from "./chunk-NVUQSFWX.js";
13
13
  import {
14
14
  parseSlackChannelReferenceId
15
- } from "./chunk-42WRQLJ6.js";
15
+ } from "./chunk-F3B2YJ76.js";
16
16
 
17
17
  // src/chat/slack/client.ts
18
18
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
@@ -0,0 +1,8 @@
1
+ // src/chat/oauth-authorization.ts
2
+ function authorizationId(args) {
3
+ return `${args.sessionId}:${args.kind}:${args.provider}`;
4
+ }
5
+
6
+ export {
7
+ authorizationId
8
+ };
@@ -1,11 +1,11 @@
1
1
  import {
2
- parseActorUserId
3
- } from "./chunk-C4MZ3GP5.js";
2
+ credentialUserSubjectId
3
+ } from "./chunk-W3U3YQYI.js";
4
4
  import {
5
5
  logInfo,
6
6
  logWarn,
7
7
  setSpanAttributes
8
- } from "./chunk-4FUEG3QY.js";
8
+ } from "./chunk-NVUQSFWX.js";
9
9
  import {
10
10
  discoverInstalledPluginPackageContent,
11
11
  normalizePluginPackageNames
@@ -1083,68 +1083,6 @@ var CredentialUnavailableError = class extends Error {
1083
1083
  }
1084
1084
  };
1085
1085
 
1086
- // src/chat/credentials/context.ts
1087
- import { z as z2 } from "zod";
1088
- var exactActorIdSchema = z2.string().refine((value) => parseActorUserId(value) === value);
1089
- var exactNonBlankStringSchema = z2.string().min(1).refine((value) => value === value.trim());
1090
- var slackDirectCredentialSubjectBindingSchema = z2.object({
1091
- type: z2.literal("slack-direct-conversation"),
1092
- teamId: z2.string().min(1),
1093
- channelId: z2.string().min(1),
1094
- signature: z2.string().min(1)
1095
- }).strict();
1096
- var scheduledTaskCredentialSubjectBindingSchema = z2.object({
1097
- type: z2.literal("scheduled-task"),
1098
- plugin: z2.string().min(1),
1099
- taskId: exactNonBlankStringSchema,
1100
- signature: z2.string().min(1)
1101
- }).strict();
1102
- var credentialSubjectBindingSchema = z2.discriminatedUnion("type", [
1103
- slackDirectCredentialSubjectBindingSchema,
1104
- scheduledTaskCredentialSubjectBindingSchema
1105
- ]);
1106
- var credentialUserActorSchema = z2.object({
1107
- type: z2.literal("user"),
1108
- userId: exactActorIdSchema
1109
- }).strict();
1110
- var credentialSystemActorSchema = z2.object({
1111
- platform: z2.literal("system"),
1112
- name: exactActorIdSchema
1113
- }).strict();
1114
- var credentialSubjectSchema = z2.discriminatedUnion("allowedWhen", [
1115
- z2.object({
1116
- type: z2.literal("user"),
1117
- userId: exactActorIdSchema,
1118
- allowedWhen: z2.literal("private-direct-conversation"),
1119
- binding: slackDirectCredentialSubjectBindingSchema
1120
- }).strict(),
1121
- z2.object({
1122
- type: z2.literal("user"),
1123
- userId: exactActorIdSchema,
1124
- allowedWhen: z2.literal("scheduled-task"),
1125
- taskId: exactNonBlankStringSchema,
1126
- binding: scheduledTaskCredentialSubjectBindingSchema
1127
- }).strict().refine((subject) => subject.binding.taskId === subject.taskId, {
1128
- message: "Scheduled task credential subject requires task binding",
1129
- path: ["binding"]
1130
- })
1131
- ]);
1132
- var credentialContextSchema = z2.union([
1133
- z2.object({
1134
- actor: credentialUserActorSchema
1135
- }).strict(),
1136
- z2.object({
1137
- actor: credentialSystemActorSchema,
1138
- subject: credentialSubjectSchema.optional()
1139
- }).strict()
1140
- ]);
1141
- function credentialUserSubjectId(context) {
1142
- if ("type" in context.actor) {
1143
- return context.actor.userId;
1144
- }
1145
- return "subject" in context ? context.subject?.userId : void 0;
1146
- }
1147
-
1148
1086
  // src/chat/credentials/header-transforms.ts
1149
1087
  function mergeHeaderTransforms(transforms) {
1150
1088
  const byDomain = /* @__PURE__ */ new Map();
@@ -1277,7 +1215,7 @@ function createApiHeadersBroker(manifest) {
1277
1215
  }
1278
1216
 
1279
1217
  // src/chat/plugins/auth/oauth-request.ts
1280
- import { z as z3 } from "zod";
1218
+ import { z as z2 } from "zod";
1281
1219
  var DEFAULT_TOKEN_CONTENT_TYPE = "application/x-www-form-urlencoded";
1282
1220
  function requireNonEmptyTokenField(data, field) {
1283
1221
  const value = data[field];
@@ -1292,12 +1230,12 @@ function requireTokenResponseObject(data) {
1292
1230
  }
1293
1231
  return data;
1294
1232
  }
1295
- var parsedOAuthTokenResponseSchema = z3.object({
1296
- accessToken: z3.string().min(1),
1297
- refreshToken: z3.string().min(1),
1298
- expiresAt: z3.number().positive().optional(),
1299
- refreshTokenExpiresAt: z3.number().positive().optional(),
1300
- scope: z3.string().min(1).optional()
1233
+ var parsedOAuthTokenResponseSchema = z2.object({
1234
+ accessToken: z2.string().min(1),
1235
+ refreshToken: z2.string().min(1),
1236
+ expiresAt: z2.number().positive().optional(),
1237
+ refreshTokenExpiresAt: z2.number().positive().optional(),
1238
+ scope: z2.string().min(1).optional()
1301
1239
  }).strict();
1302
1240
  function contentTypeToBody(contentType, payload) {
1303
1241
  const mediaType = contentType.split(";", 1)[0]?.trim().toLowerCase();
@@ -2070,9 +2008,6 @@ export {
2070
2008
  parsePluginManifest,
2071
2009
  parseInlinePluginManifest,
2072
2010
  CredentialUnavailableError,
2073
- credentialSubjectSchema,
2074
- credentialContextSchema,
2075
- credentialUserSubjectId,
2076
2011
  hasRequiredOAuthScope,
2077
2012
  resolvePluginCommandEnv,
2078
2013
  resolveAuthTokenPlaceholder,
@@ -1,14 +1,3 @@
1
- // src/chat/coerce.ts
2
- function toOptionalString(value) {
3
- return typeof value === "string" && value.trim() ? value : void 0;
4
- }
5
- function toOptionalNumber(value) {
6
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
7
- }
8
- function isRecord(value) {
9
- return typeof value === "object" && value !== null;
10
- }
11
-
12
1
  // src/chat/slack/timestamp.ts
13
2
  import { z } from "zod";
14
3
  var slackMessageTsSchema = z.string().trim().regex(/^\d+(?:\.\d+)?$/).brand();
@@ -60,9 +49,6 @@ function parseSlackUserId(value) {
60
49
  }
61
50
 
62
51
  export {
63
- toOptionalString,
64
- toOptionalNumber,
65
- isRecord,
66
52
  parseSlackMessageTs,
67
53
  parseSlackChannelId,
68
54
  parseSlackChannelReferenceId,
@@ -0,0 +1,70 @@
1
+ // src/chat/local/oauth-relay.ts
2
+ import { randomBytes } from "crypto";
3
+ import { jwtVerify, SignJWT } from "jose";
4
+ import { z } from "zod";
5
+ var LOCAL_OAUTH_STATE_PREFIX = "jr-local";
6
+ var LOCAL_OAUTH_TOKEN_CONTEXT = "junior.local-oauth-relay.v1";
7
+ var LOCAL_OAUTH_TOKEN_TTL = "10m";
8
+ var localOAuthRelayPayloadSchema = z.object({
9
+ aud: z.literal(LOCAL_OAUTH_TOKEN_CONTEXT),
10
+ exp: z.number().int(),
11
+ iss: z.literal(LOCAL_OAUTH_TOKEN_CONTEXT),
12
+ jti: z.string().min(1),
13
+ port: z.number().int().min(1).max(65535)
14
+ }).strict();
15
+ function relayKey() {
16
+ const secret = process.env.JUNIOR_SECRET?.trim();
17
+ if (!secret) {
18
+ throw new Error("Local OAuth requires JUNIOR_SECRET");
19
+ }
20
+ return new TextEncoder().encode(secret);
21
+ }
22
+ async function createLocalOAuthState(port) {
23
+ if (!Number.isSafeInteger(port) || port < 1 || port > 65535) {
24
+ throw new Error("Local OAuth callback port is invalid");
25
+ }
26
+ const token = await new SignJWT({ port }).setProtectedHeader({ alg: "HS256" }).setIssuer(LOCAL_OAUTH_TOKEN_CONTEXT).setAudience(LOCAL_OAUTH_TOKEN_CONTEXT).setJti(randomBytes(24).toString("base64url")).setExpirationTime(LOCAL_OAUTH_TOKEN_TTL).sign(relayKey());
27
+ return `${LOCAL_OAUTH_STATE_PREFIX}.${token}`;
28
+ }
29
+ async function localOAuthRelayPort(state) {
30
+ const prefix = `${LOCAL_OAUTH_STATE_PREFIX}.`;
31
+ if (!state.startsWith(prefix)) {
32
+ return void 0;
33
+ }
34
+ try {
35
+ const { payload } = await jwtVerify(
36
+ state.slice(prefix.length),
37
+ relayKey(),
38
+ {
39
+ algorithms: ["HS256"],
40
+ issuer: LOCAL_OAUTH_TOKEN_CONTEXT,
41
+ audience: LOCAL_OAUTH_TOKEN_CONTEXT
42
+ }
43
+ );
44
+ const parsed = localOAuthRelayPayloadSchema.safeParse(payload);
45
+ return parsed.success ? parsed.data.port : void 0;
46
+ } catch {
47
+ return void 0;
48
+ }
49
+ }
50
+ async function relayLocalOAuthCallback(request) {
51
+ const url = new URL(request.url);
52
+ if (url.searchParams.get("jr_local_relay") === "complete") {
53
+ return void 0;
54
+ }
55
+ const state = url.searchParams.get("state");
56
+ const port = state ? await localOAuthRelayPort(state) : void 0;
57
+ if (!port) {
58
+ return void 0;
59
+ }
60
+ url.protocol = "http:";
61
+ url.hostname = "127.0.0.1";
62
+ url.port = String(port);
63
+ url.searchParams.set("jr_local_relay", "complete");
64
+ return Response.redirect(url, 302);
65
+ }
66
+
67
+ export {
68
+ createLocalOAuthState,
69
+ relayLocalOAuthCallback
70
+ };
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@sentry/junior",
4
- version: "0.114.0",
4
+ version: "0.115.0",
5
5
  private: false,
6
6
  publishConfig: {
7
7
  access: "public"
@@ -1,9 +1,11 @@
1
+ import {
2
+ toOptionalString
3
+ } from "./chunk-OB42YVAE.js";
1
4
  import {
2
5
  parseSlackChannelId,
3
6
  parseSlackMessageTs,
4
- parseSlackTeamId,
5
- toOptionalString
6
- } from "./chunk-42WRQLJ6.js";
7
+ parseSlackTeamId
8
+ } from "./chunk-F3B2YJ76.js";
7
9
 
8
10
  // src/chat/conversation-privacy.ts
9
11
  import { AsyncLocalStorage } from "async_hooks";