@sentry/junior 0.145.0 → 0.147.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 (171) hide show
  1. package/dist/{agent-hooks-L7D2BDVV.js → agent-hooks-HS6VGUPM.js} +10 -10
  2. package/dist/api/conversations/detail.d.ts +1 -0
  3. package/dist/api/conversations/event-list.d.ts +1 -0
  4. package/dist/api/schema/conversation.d.ts +4 -0
  5. package/dist/api/schema.js +1 -1
  6. package/dist/api.js +26 -22
  7. package/dist/app.js +285 -290
  8. package/dist/{catalog-runtime-QLAC4Q3W.js → catalog-runtime-M6ZTPYRV.js} +5 -5
  9. package/dist/chat/agent/prompt.d.ts +0 -2
  10. package/dist/chat/agent/request.d.ts +2 -5
  11. package/dist/chat/agent/resume.d.ts +0 -3
  12. package/dist/chat/agent/sandbox.d.ts +2 -2
  13. package/dist/chat/agent/skills.d.ts +0 -1
  14. package/dist/chat/agent/tools.d.ts +0 -3
  15. package/dist/chat/agent-dispatch/types.d.ts +2 -2
  16. package/dist/chat/capabilities/jr-rpc-command.d.ts +2 -2
  17. package/dist/chat/configuration/service.d.ts +5 -2
  18. package/dist/chat/configuration/sql.d.ts +9 -0
  19. package/dist/chat/configuration/types.d.ts +17 -13
  20. package/dist/chat/conversations/history.d.ts +3 -0
  21. package/dist/chat/conversations/message-search.d.ts +32 -0
  22. package/dist/chat/conversations/projection.d.ts +10 -0
  23. package/dist/chat/conversations/sql/message-search.d.ts +4 -0
  24. package/dist/chat/conversations/tool-source.d.ts +5 -0
  25. package/dist/chat/credentials/unlink-provider.d.ts +2 -1
  26. package/dist/chat/credentials/user-token-store.d.ts +2 -0
  27. package/dist/chat/db.d.ts +2 -2
  28. package/dist/chat/event-tasks/tool-support.d.ts +2 -0
  29. package/dist/chat/identities/sql.d.ts +8 -0
  30. package/dist/chat/logging.d.ts +2 -0
  31. package/dist/chat/mcp/auth-store.d.ts +0 -2
  32. package/dist/chat/mcp/oauth.d.ts +0 -2
  33. package/dist/chat/oauth-flow.d.ts +3 -1
  34. package/dist/chat/pi/client.d.ts +2 -0
  35. package/dist/chat/plugins/credential-hooks.d.ts +2 -0
  36. package/dist/chat/prompt.d.ts +0 -2
  37. package/dist/chat/resource-events/notification.d.ts +2 -1
  38. package/dist/chat/runtime/delivered-turn-state.d.ts +1 -4
  39. package/dist/chat/runtime/thread-state.d.ts +8 -11
  40. package/dist/chat/runtime/turn-input.d.ts +4 -2
  41. package/dist/chat/runtime/turn-preparation.d.ts +2 -4
  42. package/dist/chat/sandbox/command-result.d.ts +2 -0
  43. package/dist/chat/sandbox/egress/schemas.d.ts +6 -0
  44. package/dist/chat/scheduled-tasks/tool-support.d.ts +2 -0
  45. package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -0
  46. package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -0
  47. package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -0
  48. package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -0
  49. package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -0
  50. package/dist/chat/services/mcp-auth-orchestration.d.ts +0 -3
  51. package/dist/chat/services/plugin-auth-orchestration.d.ts +2 -1
  52. package/dist/chat/services/provider-default-config.d.ts +2 -2
  53. package/dist/chat/services/subscribed-decision.d.ts +3 -0
  54. package/dist/chat/services/subscribed-reply-policy.d.ts +1 -0
  55. package/dist/chat/services/turn-result.d.ts +0 -3
  56. package/dist/chat/services/turn-router.d.ts +3 -0
  57. package/dist/chat/slack/assistant-thread/lifecycle.d.ts +0 -1
  58. package/dist/chat/slack/assistant-thread/title.d.ts +0 -3
  59. package/dist/chat/slack/dispatch-turn.d.ts +1 -1
  60. package/dist/chat/slack/message/attachments.d.ts +2 -0
  61. package/dist/chat/slack/message/blocks.d.ts +2 -0
  62. package/dist/chat/slack/message/content.d.ts +18 -0
  63. package/dist/chat/slack/message/identity.d.ts +7 -0
  64. package/dist/chat/slack/tools/canvas/context.d.ts +0 -10
  65. package/dist/chat/slack/tools/canvas/create.d.ts +2 -0
  66. package/dist/chat/slack/tools/canvas/edit.d.ts +2 -0
  67. package/dist/chat/slack/tools/canvas/read.d.ts +2 -0
  68. package/dist/chat/slack/tools/canvas/write.d.ts +2 -0
  69. package/dist/chat/slack/tools/channel-list-messages.d.ts +2 -0
  70. package/dist/chat/slack/tools/{conversation-search.d.ts → conversation-message-search.d.ts} +23 -14
  71. package/dist/chat/slack/tools/list/add-items.d.ts +4 -1
  72. package/dist/chat/slack/tools/list/api.d.ts +8 -1
  73. package/dist/chat/slack/tools/list/create.d.ts +2 -0
  74. package/dist/chat/slack/tools/list/get-items.d.ts +5 -3
  75. package/dist/chat/slack/tools/list/update-item.d.ts +5 -1
  76. package/dist/chat/slack/tools/message-add-reaction.d.ts +2 -0
  77. package/dist/chat/slack/tools/public-search.d.ts +2 -0
  78. package/dist/chat/slack/tools/send-files.d.ts +2 -0
  79. package/dist/chat/slack/tools/thread-read.d.ts +2 -0
  80. package/dist/chat/slack/vision-cache.d.ts +5 -0
  81. package/dist/chat/state/conversation.d.ts +4 -5
  82. package/dist/chat/task-execution/checkpoint.d.ts +1 -3
  83. package/dist/chat/task-execution/turn-cursor.d.ts +0 -9
  84. package/dist/chat/tool-support/structured-result.d.ts +1 -0
  85. package/dist/chat/tool-support/timed-out-tool-result.d.ts +11 -0
  86. package/dist/chat/tools/create-event-task.d.ts +2 -0
  87. package/dist/chat/tools/delete-event-task.d.ts +2 -0
  88. package/dist/chat/tools/handoff/tool.d.ts +2 -0
  89. package/dist/chat/tools/list-event-tasks.d.ts +2 -0
  90. package/dist/chat/tools/list-resource-event-subscriptions.d.ts +2 -0
  91. package/dist/chat/tools/runtime/report-progress.d.ts +2 -0
  92. package/dist/chat/tools/runtime/spawn-agent.d.ts +2 -0
  93. package/dist/chat/tools/{query-conversation-events.d.ts → search-conversation-events.d.ts} +5 -3
  94. package/dist/chat/tools/search-resource-event-types.d.ts +2 -0
  95. package/dist/chat/tools/search-tools.d.ts +2 -0
  96. package/dist/chat/tools/skill/load-skill.d.ts +2 -0
  97. package/dist/chat/tools/skill/search-mcp-tools.d.ts +2 -0
  98. package/dist/chat/tools/stop-watching-resources.d.ts +2 -0
  99. package/dist/chat/tools/system-time.d.ts +2 -0
  100. package/dist/chat/tools/types.d.ts +0 -6
  101. package/dist/chat/tools/update-event-task.d.ts +2 -0
  102. package/dist/chat/tools/user-lookup.d.ts +29 -0
  103. package/dist/chat/tools/watch-resource-events.d.ts +2 -0
  104. package/dist/chat/tools/web/fetch-tool.d.ts +2 -0
  105. package/dist/chat/tools/web/image-generate.d.ts +2 -0
  106. package/dist/chat/tools/web/search.d.ts +2 -0
  107. package/dist/{chunk-PJ4NMVQB.js → chunk-34GS7B6L.js} +2 -2
  108. package/dist/{chunk-2LWPFSB4.js → chunk-4LJO56OJ.js} +9 -1
  109. package/dist/{chunk-QJBDABQA.js → chunk-6H5SZR24.js} +16 -20
  110. package/dist/{chunk-LVVSIMBB.js → chunk-745QJ3ZA.js} +1 -1
  111. package/dist/{chunk-64SBYW2O.js → chunk-7A4M7PCV.js} +613 -561
  112. package/dist/{chunk-XFKIRN3Q.js → chunk-7NVJVJID.js} +4 -3
  113. package/dist/{chunk-FUBRJA5F.js → chunk-7UQIVT6G.js} +13 -6
  114. package/dist/{chunk-ZIAMN2UW.js → chunk-AIOK6LAG.js} +40 -513
  115. package/dist/{chunk-EIX2LQ6L.js → chunk-AVOCH2Z5.js} +3 -3
  116. package/dist/{chunk-GUWLDMGF.js → chunk-AVZDSUFB.js} +4 -4
  117. package/dist/{chunk-2XET6PKP.js → chunk-AYU72WO7.js} +102 -73
  118. package/dist/chunk-AZ7EAOBE.js +566 -0
  119. package/dist/{chunk-DXEQAIUV.js → chunk-CSZINQJ2.js} +1 -1
  120. package/dist/{chunk-HLOUZC5C.js → chunk-CWP5RHVX.js} +4 -4
  121. package/dist/{chunk-DS3J6WGY.js → chunk-DLDRQHG5.js} +1 -1
  122. package/dist/{chunk-27TEJTZO.js → chunk-DU74WPIC.js} +55 -37
  123. package/dist/{chunk-YD54Q45G.js → chunk-EFLJ2WJH.js} +6 -4
  124. package/dist/{chunk-CD2XFGYQ.js → chunk-GGB4WL5A.js} +1 -1
  125. package/dist/{chunk-GDV5LXRA.js → chunk-IIOOO4FQ.js} +1 -1
  126. package/dist/{chunk-SIN3MXH6.js → chunk-JUUKWRBE.js} +1 -1
  127. package/dist/{chunk-VTDMB7XX.js → chunk-K4SZAP3K.js} +1 -1
  128. package/dist/{chunk-QUG4JSZK.js → chunk-ORO3PWKQ.js} +1 -1
  129. package/dist/{chunk-RUSS62EN.js → chunk-PVNG6UMU.js} +3 -3
  130. package/dist/{chunk-I47UGQPJ.js → chunk-Q4R73I43.js} +365 -206
  131. package/dist/{chunk-JTGS3ZZE.js → chunk-RXBVB2JM.js} +1 -1
  132. package/dist/{chunk-TZRXYWRE.js → chunk-SGZO7UWH.js} +2 -2
  133. package/dist/{chunk-JLMVCNXL.js → chunk-SVHUEHUL.js} +1 -0
  134. package/dist/{chunk-B46ZMVOV.js → chunk-X5UY34KT.js} +6 -5
  135. package/dist/{chunk-5PNPQYTO.js → chunk-YBVXBNSV.js} +2 -2
  136. package/dist/{chunk-HISR3DTV.js → chunk-YEO3VX72.js} +10 -25
  137. package/dist/{chunk-ZIMRGFYL.js → chunk-YHDERDRO.js} +7 -6
  138. package/dist/{chunk-WF5HVH3M.js → chunk-YNTTROJT.js} +1 -1
  139. package/dist/{chunk-2UH3JI64.js → chunk-YSB2N563.js} +87 -34
  140. package/dist/{chunk-ZYAJMESY.js → chunk-Z4YU7Z4L.js} +3 -2
  141. package/dist/cli/chat.js +32 -32
  142. package/dist/cli/check.js +6 -6
  143. package/dist/cli/plugins.js +13 -13
  144. package/dist/cli/snapshot-create.js +9 -9
  145. package/dist/cli/upgrade.js +7 -7
  146. package/dist/db/schema/location-configurations.d.ts +127 -0
  147. package/dist/db/schema.d.ts +128 -1
  148. package/dist/{db-62PW6LM3.js → db-CSEW4RII.js} +9 -9
  149. package/dist/instrumentation.js +4 -4
  150. package/dist/nitro.js +2 -2
  151. package/dist/{oauth-callback-server-6NZNHJAM.js → oauth-callback-server-FUEV5HNG.js} +24 -24
  152. package/dist/{runner-GCRPG3GQ.js → runner-U3XHSKSH.js} +21 -41
  153. package/dist/{skills-2S3MDFIQ.js → skills-AKE6W3WI.js} +6 -6
  154. package/dist/spawn-B6GDTWJ4.js +39 -0
  155. package/dist/{validation-HAOLCJ5A.js → validation-WDTAULUF.js} +6 -6
  156. package/dist/version.js +1 -1
  157. package/dist/{work-R4XYKMUW.js → work-C3HAO2BG.js} +17 -17
  158. package/dist/{worker-U2UCVR7M.js → worker-LNP4YKBM.js} +10 -10
  159. package/migrations/0024_misty_typhoid_mary.sql +12 -0
  160. package/migrations/meta/0024_snapshot.json +2275 -0
  161. package/migrations/meta/_journal.json +7 -0
  162. package/package.json +4 -4
  163. package/dist/chat/conversations/search.d.ts +0 -24
  164. package/dist/chat/conversations/sql/search.d.ts +0 -4
  165. package/dist/chat/slack/legacy-attachments.d.ts +0 -4
  166. package/dist/chat/slack/message.d.ts +0 -12
  167. package/dist/chat/slack/tools/user-lookup.d.ts +0 -26
  168. package/dist/chat/state/artifacts.d.ts +0 -30
  169. package/dist/chat/tool-support/turn-deadline-result.d.ts +0 -3
  170. package/dist/chunk-Q6QZTTLS.js +0 -55
  171. package/dist/spawn-7WK37BTD.js +0 -39
@@ -1,30 +1,34 @@
1
1
  import {
2
2
  resolveBaseUrl
3
- } from "./chunk-FUBRJA5F.js";
3
+ } from "./chunk-7UQIVT6G.js";
4
4
  import {
5
5
  createPluginLogger,
6
6
  getPlugins
7
- } from "./chunk-ZIMRGFYL.js";
7
+ } from "./chunk-YHDERDRO.js";
8
+ import {
9
+ getSlackClient,
10
+ withSlackRetries
11
+ } from "./chunk-SGZO7UWH.js";
8
12
  import {
9
13
  getDb,
10
14
  parseDestination
11
- } from "./chunk-2UH3JI64.js";
15
+ } from "./chunk-YSB2N563.js";
12
16
  import {
13
17
  sleep
14
18
  } from "./chunk-EM225ITJ.js";
15
19
  import {
16
20
  acquireActiveLock,
17
21
  getStateAdapter
18
- } from "./chunk-QUG4JSZK.js";
22
+ } from "./chunk-ORO3PWKQ.js";
19
23
  import {
20
24
  pluginCatalogRuntime
21
- } from "./chunk-SIN3MXH6.js";
25
+ } from "./chunk-JUUKWRBE.js";
22
26
  import {
23
27
  fetchWithBoundedOAuthErrorBodies
24
- } from "./chunk-CD2XFGYQ.js";
28
+ } from "./chunk-GGB4WL5A.js";
25
29
  import {
26
30
  isRecord
27
- } from "./chunk-2LWPFSB4.js";
31
+ } from "./chunk-4LJO56OJ.js";
28
32
 
29
33
  // src/chat/capabilities/router.ts
30
34
  var ProviderCredentialRouter = class {
@@ -209,6 +213,349 @@ function getMcpAwareTelemetryMessage(error, _privacy) {
209
213
  return getMcpAwareErrorMessage(error);
210
214
  }
211
215
 
216
+ // src/chat/slack/users.ts
217
+ function normalizeUser(raw) {
218
+ const rawFields = raw.profile?.fields;
219
+ const profileFields = [];
220
+ if (rawFields && typeof rawFields === "object") {
221
+ for (const [id, field] of Object.entries(rawFields)) {
222
+ if (!field) continue;
223
+ profileFields.push({
224
+ id,
225
+ label: field.label || void 0,
226
+ value: field.value || void 0,
227
+ alt: field.alt || void 0
228
+ });
229
+ }
230
+ }
231
+ return {
232
+ id: raw.id ?? "",
233
+ team_id: raw.team_id || void 0,
234
+ name: raw.name || void 0,
235
+ real_name: raw.real_name || raw.profile?.real_name || void 0,
236
+ display_name: raw.profile?.display_name || void 0,
237
+ title: raw.profile?.title || void 0,
238
+ email: raw.profile?.email || void 0,
239
+ status_text: raw.profile?.status_text ?? void 0,
240
+ status_emoji: raw.profile?.status_emoji ?? void 0,
241
+ is_bot: raw.is_bot ?? false,
242
+ is_deleted: raw.deleted ?? false,
243
+ timezone: raw.tz || void 0,
244
+ ...profileFields.length > 0 ? { profile_fields: profileFields } : {}
245
+ };
246
+ }
247
+ async function lookupSlackUserProfile(userId) {
248
+ const client = getSlackClient();
249
+ const result = await withSlackRetries(
250
+ () => client.users.info({ user: userId }),
251
+ 3,
252
+ { action: "users.info" }
253
+ );
254
+ const user = result.user;
255
+ if (!user) {
256
+ throw new Error(`Slack users.info returned no user for ${userId}`);
257
+ }
258
+ return normalizeUser(user);
259
+ }
260
+ async function lookupSlackUserByEmail(email) {
261
+ const client = getSlackClient();
262
+ let result;
263
+ try {
264
+ result = await withSlackRetries(
265
+ () => client.users.lookupByEmail({ email }),
266
+ 3,
267
+ { action: "users.lookupByEmail" }
268
+ );
269
+ } catch (error) {
270
+ const apiError = error.apiError;
271
+ if (apiError === "users_not_found") {
272
+ return null;
273
+ }
274
+ throw error;
275
+ }
276
+ const user = result.user;
277
+ if (!user) {
278
+ return null;
279
+ }
280
+ return normalizeUser(user);
281
+ }
282
+ function scoreMatch(user, queryLower) {
283
+ const name = (user.name ?? "").toLowerCase();
284
+ const realName = (user.real_name ?? user.profile?.real_name ?? "").toLowerCase();
285
+ const displayName = (user.profile?.display_name ?? "").toLowerCase();
286
+ if (name === queryLower || displayName === queryLower) return 100;
287
+ if (realName === queryLower) return 90;
288
+ if (name.startsWith(queryLower) || displayName.startsWith(queryLower))
289
+ return 70;
290
+ if (realName.startsWith(queryLower)) return 60;
291
+ const realNameWords = realName.split(/\s+/);
292
+ if (realNameWords.some((w) => w === queryLower)) return 55;
293
+ if (realNameWords.some((w) => w.startsWith(queryLower))) return 50;
294
+ if (name.includes(queryLower) || displayName.includes(queryLower)) return 30;
295
+ if (realName.includes(queryLower)) return 20;
296
+ return 0;
297
+ }
298
+ async function listWorkspaceUsers(options) {
299
+ const client = getSlackClient();
300
+ const matches = [];
301
+ let cursor;
302
+ let pages = 0;
303
+ let totalScanned = 0;
304
+ while (pages < options.maxPages) {
305
+ pages++;
306
+ const result = await withSlackRetries(
307
+ () => client.users.list({
308
+ limit: 200,
309
+ ...cursor ? { cursor } : {}
310
+ }),
311
+ 3,
312
+ { action: "users.list" }
313
+ );
314
+ const members = result.members ?? [];
315
+ totalScanned += members.length;
316
+ for (const member of members) {
317
+ if (!options.includeDeleted && member.deleted) continue;
318
+ if (!options.includeBots && member.is_bot) continue;
319
+ if (member.id === "USLACKBOT") continue;
320
+ const score = options.score(member);
321
+ if (score <= 0) continue;
322
+ matches.push({ user: member, score });
323
+ }
324
+ const nextCursor = result.response_metadata?.next_cursor;
325
+ if (!nextCursor) {
326
+ cursor = void 0;
327
+ break;
328
+ }
329
+ cursor = nextCursor;
330
+ }
331
+ return {
332
+ matches,
333
+ searched_pages: pages,
334
+ searched_user_count: totalScanned,
335
+ // True only when we hit the page cap with more data remaining.
336
+ truncated: pages >= options.maxPages && Boolean(cursor)
337
+ };
338
+ }
339
+ async function searchSlackUsers(options) {
340
+ const {
341
+ query,
342
+ limit = 10,
343
+ maxPages = 3,
344
+ includeDeleted = false,
345
+ includeBots = false
346
+ } = options;
347
+ const queryLower = query.toLowerCase().trim();
348
+ const listed = await listWorkspaceUsers({
349
+ maxPages,
350
+ includeDeleted,
351
+ includeBots,
352
+ score: (member) => scoreMatch(member, queryLower)
353
+ });
354
+ listed.matches.sort((a, b) => {
355
+ if (b.score !== a.score) return b.score - a.score;
356
+ return (a.user.name ?? "").localeCompare(b.user.name ?? "");
357
+ });
358
+ return {
359
+ users: listed.matches.slice(0, limit).map((m) => normalizeUser(m.user)),
360
+ searched_pages: listed.searched_pages,
361
+ searched_user_count: listed.searched_user_count,
362
+ truncated: listed.truncated
363
+ };
364
+ }
365
+
366
+ // src/chat/plugins/credential-hooks.ts
367
+ import {
368
+ pluginAuthorizationSchema,
369
+ pluginCredentialResultSchema,
370
+ pluginGrantSchema,
371
+ pluginProviderAccountSchema
372
+ } from "@sentry/junior-plugin-api";
373
+ function parseSchema(schema, value, message) {
374
+ const result = schema.safeParse(value);
375
+ if (!result.success) {
376
+ throw new Error(message);
377
+ }
378
+ return result.data;
379
+ }
380
+ function parseAuthorization(value, pluginName) {
381
+ if (value === void 0) {
382
+ return void 0;
383
+ }
384
+ const authorization = parseSchema(
385
+ pluginAuthorizationSchema,
386
+ value,
387
+ `Plugin "${pluginName}" grant authorization is invalid`
388
+ );
389
+ if (authorization.provider !== pluginName) {
390
+ throw new Error(
391
+ `Plugin "${pluginName}" grant authorization provider must match the issuing plugin`
392
+ );
393
+ }
394
+ return authorization;
395
+ }
396
+ function parseGrant(value, pluginName) {
397
+ return parseSchema(
398
+ pluginGrantSchema,
399
+ value,
400
+ `Plugin "${pluginName}" grantForEgress returned an invalid grant`
401
+ );
402
+ }
403
+ function pluginFor(provider) {
404
+ return getPlugins().find((candidate) => candidate.manifest.name === provider);
405
+ }
406
+ function basePluginContext(plugin) {
407
+ const pluginName = plugin.manifest.name;
408
+ return {
409
+ plugin: { name: pluginName },
410
+ log: createPluginLogger(pluginName),
411
+ db: getDb()
412
+ };
413
+ }
414
+ function parseCredentialResult(value, pluginName) {
415
+ const result = parseSchema(
416
+ pluginCredentialResultSchema,
417
+ value,
418
+ `Plugin "${pluginName}" issueCredential result is invalid`
419
+ );
420
+ if (result.type === "lease") {
421
+ parseAuthorization(result.lease.authorization, pluginName);
422
+ return result;
423
+ }
424
+ if (result.type === "unavailable") {
425
+ return result;
426
+ }
427
+ parseAuthorization(result.authorization, pluginName);
428
+ return result;
429
+ }
430
+ async function selectPluginGrant(input) {
431
+ const plugin = pluginFor(input.provider);
432
+ const hook = plugin?.hooks?.grantForEgress;
433
+ if (!plugin || !hook) {
434
+ return void 0;
435
+ }
436
+ const result = await hook({
437
+ ...basePluginContext(plugin),
438
+ request: {
439
+ ...input.bodyText !== void 0 ? { bodyText: input.bodyText } : {},
440
+ method: input.method,
441
+ ...input.operation ? { operation: input.operation } : {},
442
+ url: input.upstreamUrl.toString()
443
+ }
444
+ });
445
+ return result === void 0 ? void 0 : parseGrant(result, plugin.manifest.name);
446
+ }
447
+ async function onPluginEgressResponse(input) {
448
+ const plugin = pluginFor(input.provider);
449
+ const hook = plugin?.hooks?.onEgressResponse;
450
+ if (!plugin || !hook) {
451
+ return {};
452
+ }
453
+ let permissionDenied;
454
+ await hook({
455
+ ...basePluginContext(plugin),
456
+ grant: input.grant,
457
+ permissionDenied(message) {
458
+ const trimmed = message.trim();
459
+ if (!trimmed) {
460
+ throw new Error(
461
+ `Plugin "${plugin.manifest.name}" onEgressResponse permissionDenied message is empty`
462
+ );
463
+ }
464
+ permissionDenied = { message: trimmed };
465
+ },
466
+ request: {
467
+ method: input.method,
468
+ ...input.operation ? { operation: input.operation } : {},
469
+ url: input.upstreamUrl.toString()
470
+ },
471
+ response: input.response
472
+ });
473
+ return permissionDenied ? { permissionDenied } : {};
474
+ }
475
+ function hasEgressCredentialHooks(provider) {
476
+ const hooks = pluginFor(provider)?.hooks;
477
+ return Boolean(hooks?.grantForEgress || hooks?.issueCredential);
478
+ }
479
+ function getOAuthAccountProviders() {
480
+ return getPlugins().filter((plugin) => Boolean(plugin.hooks?.resolveOAuthAccount)).map((plugin) => plugin.manifest.name);
481
+ }
482
+ async function resolvePluginOAuthAccount(input) {
483
+ const plugin = pluginFor(input.provider);
484
+ const hook = plugin?.hooks?.resolveOAuthAccount;
485
+ if (!plugin || !hook) {
486
+ return void 0;
487
+ }
488
+ const account = await hook({
489
+ ...basePluginContext(plugin),
490
+ tokens: input.tokens
491
+ });
492
+ return account === void 0 ? void 0 : parseSchema(
493
+ pluginProviderAccountSchema,
494
+ account,
495
+ `Plugin "${plugin.manifest.name}" resolveOAuthAccount returned an invalid account`
496
+ );
497
+ }
498
+ async function issuePluginCredential(input) {
499
+ const plugin = pluginFor(input.provider);
500
+ const hook = plugin?.hooks?.issueCredential;
501
+ if (!plugin || !hook) {
502
+ throw new Error(`Plugin "${input.provider}" has no issueCredential hook`);
503
+ }
504
+ const currentUserId = "type" in input.actor ? input.actor.userId : void 0;
505
+ const credentialSubjectUserId = input.credentialSubject?.userId;
506
+ const result = await hook({
507
+ ...basePluginContext(plugin),
508
+ actor: input.actor,
509
+ grant: input.grant,
510
+ ...input.credentialSubject ? { credentialSubject: input.credentialSubject } : {},
511
+ tokens: {
512
+ ...currentUserId ? {
513
+ currentUser: {
514
+ userId: currentUserId,
515
+ get: async () => await input.userTokenStore.get(
516
+ currentUserId,
517
+ plugin.manifest.name
518
+ ),
519
+ set: async (tokens) => {
520
+ await input.userTokenStore.set(
521
+ currentUserId,
522
+ plugin.manifest.name,
523
+ tokens
524
+ );
525
+ },
526
+ withRefresh: async (callback) => await input.userTokenStore.withRefresh(
527
+ currentUserId,
528
+ plugin.manifest.name,
529
+ callback
530
+ )
531
+ }
532
+ } : {},
533
+ ...credentialSubjectUserId ? {
534
+ credentialSubject: {
535
+ userId: credentialSubjectUserId,
536
+ get: async () => await input.userTokenStore.get(
537
+ credentialSubjectUserId,
538
+ plugin.manifest.name
539
+ ),
540
+ set: async (tokens) => {
541
+ await input.userTokenStore.set(
542
+ credentialSubjectUserId,
543
+ plugin.manifest.name,
544
+ tokens
545
+ );
546
+ },
547
+ withRefresh: async (callback) => await input.userTokenStore.withRefresh(
548
+ credentialSubjectUserId,
549
+ plugin.manifest.name,
550
+ callback
551
+ )
552
+ }
553
+ } : {}
554
+ }
555
+ });
556
+ return parseCredentialResult(result, plugin.manifest.name);
557
+ }
558
+
212
559
  // src/chat/mcp/auth-store.ts
213
560
  import {
214
561
  sourceSchema
@@ -284,7 +631,6 @@ function parseMcpAuthSession(value) {
284
631
  ...typeof parsed.threadTs === "string" ? { threadTs: parsed.threadTs } : {},
285
632
  ...typeof parsed.toolChannelId === "string" ? { toolChannelId: parsed.toolChannelId } : {},
286
633
  ...isRecord(parsed.configuration) ? { configuration: parsed.configuration } : {},
287
- ...isRecord(parsed.artifactState) ? { artifactState: parsed.artifactState } : {},
288
634
  ...typeof parsed.authorizationUrl === "string" ? { authorizationUrl: parsed.authorizationUrl } : {},
289
635
  ...typeof parsed.codeVerifier === "string" ? { codeVerifier: parsed.codeVerifier } : {}
290
636
  };
@@ -683,8 +1029,7 @@ async function createMcpOAuthClientProvider(input) {
683
1029
  ...input.channelId ? { channelId: input.channelId } : {},
684
1030
  ...input.threadTs ? { threadTs: input.threadTs } : {},
685
1031
  ...input.toolChannelId ? { toolChannelId: input.toolChannelId } : {},
686
- ...input.configuration ? { configuration: input.configuration } : {},
687
- ...input.artifactState ? { artifactState: input.artifactState } : {}
1032
+ ...input.configuration ? { configuration: input.configuration } : {}
688
1033
  }
689
1034
  );
690
1035
  }
@@ -758,196 +1103,6 @@ async function finalizeMcpAuthorization(provider, authSessionId, authorizationCo
758
1103
  return nextSession;
759
1104
  }
760
1105
 
761
- // src/chat/plugins/credential-hooks.ts
762
- import {
763
- pluginAuthorizationSchema,
764
- pluginCredentialResultSchema,
765
- pluginGrantSchema,
766
- pluginProviderAccountSchema
767
- } from "@sentry/junior-plugin-api";
768
- function parseSchema(schema, value, message) {
769
- const result = schema.safeParse(value);
770
- if (!result.success) {
771
- throw new Error(message);
772
- }
773
- return result.data;
774
- }
775
- function parseAuthorization(value, pluginName) {
776
- if (value === void 0) {
777
- return void 0;
778
- }
779
- const authorization = parseSchema(
780
- pluginAuthorizationSchema,
781
- value,
782
- `Plugin "${pluginName}" grant authorization is invalid`
783
- );
784
- if (authorization.provider !== pluginName) {
785
- throw new Error(
786
- `Plugin "${pluginName}" grant authorization provider must match the issuing plugin`
787
- );
788
- }
789
- return authorization;
790
- }
791
- function parseGrant(value, pluginName) {
792
- return parseSchema(
793
- pluginGrantSchema,
794
- value,
795
- `Plugin "${pluginName}" grantForEgress returned an invalid grant`
796
- );
797
- }
798
- function pluginFor(provider) {
799
- return getPlugins().find((candidate) => candidate.manifest.name === provider);
800
- }
801
- function basePluginContext(plugin) {
802
- const pluginName = plugin.manifest.name;
803
- return {
804
- plugin: { name: pluginName },
805
- log: createPluginLogger(pluginName),
806
- db: getDb()
807
- };
808
- }
809
- function parseCredentialResult(value, pluginName) {
810
- const result = parseSchema(
811
- pluginCredentialResultSchema,
812
- value,
813
- `Plugin "${pluginName}" issueCredential result is invalid`
814
- );
815
- if (result.type === "lease") {
816
- parseAuthorization(result.lease.authorization, pluginName);
817
- return result;
818
- }
819
- if (result.type === "unavailable") {
820
- return result;
821
- }
822
- parseAuthorization(result.authorization, pluginName);
823
- return result;
824
- }
825
- async function selectPluginGrant(input) {
826
- const plugin = pluginFor(input.provider);
827
- const hook = plugin?.hooks?.grantForEgress;
828
- if (!plugin || !hook) {
829
- return void 0;
830
- }
831
- const result = await hook({
832
- ...basePluginContext(plugin),
833
- request: {
834
- ...input.bodyText !== void 0 ? { bodyText: input.bodyText } : {},
835
- method: input.method,
836
- ...input.operation ? { operation: input.operation } : {},
837
- url: input.upstreamUrl.toString()
838
- }
839
- });
840
- return result === void 0 ? void 0 : parseGrant(result, plugin.manifest.name);
841
- }
842
- async function onPluginEgressResponse(input) {
843
- const plugin = pluginFor(input.provider);
844
- const hook = plugin?.hooks?.onEgressResponse;
845
- if (!plugin || !hook) {
846
- return {};
847
- }
848
- let permissionDenied;
849
- await hook({
850
- ...basePluginContext(plugin),
851
- grant: input.grant,
852
- permissionDenied(message) {
853
- const trimmed = message.trim();
854
- if (!trimmed) {
855
- throw new Error(
856
- `Plugin "${plugin.manifest.name}" onEgressResponse permissionDenied message is empty`
857
- );
858
- }
859
- permissionDenied = { message: trimmed };
860
- },
861
- request: {
862
- method: input.method,
863
- ...input.operation ? { operation: input.operation } : {},
864
- url: input.upstreamUrl.toString()
865
- },
866
- response: input.response
867
- });
868
- return permissionDenied ? { permissionDenied } : {};
869
- }
870
- function hasEgressCredentialHooks(provider) {
871
- const hooks = pluginFor(provider)?.hooks;
872
- return Boolean(hooks?.grantForEgress || hooks?.issueCredential);
873
- }
874
- async function resolvePluginOAuthAccount(input) {
875
- const plugin = pluginFor(input.provider);
876
- const hook = plugin?.hooks?.resolveOAuthAccount;
877
- if (!plugin || !hook) {
878
- return void 0;
879
- }
880
- const account = await hook({
881
- ...basePluginContext(plugin),
882
- tokens: input.tokens
883
- });
884
- return account === void 0 ? void 0 : parseSchema(
885
- pluginProviderAccountSchema,
886
- account,
887
- `Plugin "${plugin.manifest.name}" resolveOAuthAccount returned an invalid account`
888
- );
889
- }
890
- async function issuePluginCredential(input) {
891
- const plugin = pluginFor(input.provider);
892
- const hook = plugin?.hooks?.issueCredential;
893
- if (!plugin || !hook) {
894
- throw new Error(`Plugin "${input.provider}" has no issueCredential hook`);
895
- }
896
- const currentUserId = "type" in input.actor ? input.actor.userId : void 0;
897
- const credentialSubjectUserId = input.credentialSubject?.userId;
898
- const result = await hook({
899
- ...basePluginContext(plugin),
900
- actor: input.actor,
901
- grant: input.grant,
902
- ...input.credentialSubject ? { credentialSubject: input.credentialSubject } : {},
903
- tokens: {
904
- ...currentUserId ? {
905
- currentUser: {
906
- userId: currentUserId,
907
- get: async () => await input.userTokenStore.get(
908
- currentUserId,
909
- plugin.manifest.name
910
- ),
911
- set: async (tokens) => {
912
- await input.userTokenStore.set(
913
- currentUserId,
914
- plugin.manifest.name,
915
- tokens
916
- );
917
- },
918
- withRefresh: async (callback) => await input.userTokenStore.withRefresh(
919
- currentUserId,
920
- plugin.manifest.name,
921
- callback
922
- )
923
- }
924
- } : {},
925
- ...credentialSubjectUserId ? {
926
- credentialSubject: {
927
- userId: credentialSubjectUserId,
928
- get: async () => await input.userTokenStore.get(
929
- credentialSubjectUserId,
930
- plugin.manifest.name
931
- ),
932
- set: async (tokens) => {
933
- await input.userTokenStore.set(
934
- credentialSubjectUserId,
935
- plugin.manifest.name,
936
- tokens
937
- );
938
- },
939
- withRefresh: async (callback) => await input.userTokenStore.withRefresh(
940
- credentialSubjectUserId,
941
- plugin.manifest.name,
942
- callback
943
- )
944
- }
945
- } : {}
946
- }
947
- });
948
- return parseCredentialResult(result, plugin.manifest.name);
949
- }
950
-
951
1106
  export {
952
1107
  createUserTokenStore,
953
1108
  issueProviderCredentialLease,
@@ -957,6 +1112,15 @@ export {
957
1112
  McpToolError,
958
1113
  getMcpAwareErrorType,
959
1114
  getMcpAwareTelemetryMessage,
1115
+ lookupSlackUserProfile,
1116
+ lookupSlackUserByEmail,
1117
+ searchSlackUsers,
1118
+ selectPluginGrant,
1119
+ onPluginEgressResponse,
1120
+ hasEgressCredentialHooks,
1121
+ getOAuthAccountProviders,
1122
+ resolvePluginOAuthAccount,
1123
+ issuePluginCredential,
960
1124
  getMcpAuthSession,
961
1125
  patchMcpAuthSession,
962
1126
  deleteMcpAuthSession,
@@ -965,10 +1129,5 @@ export {
965
1129
  deleteMcpStoredOAuthCredentials,
966
1130
  deleteMcpServerSessionId,
967
1131
  createMcpOAuthClientProvider,
968
- finalizeMcpAuthorization,
969
- selectPluginGrant,
970
- onPluginEgressResponse,
971
- hasEgressCredentialHooks,
972
- resolvePluginOAuthAccount,
973
- issuePluginCredential
1132
+ finalizeMcpAuthorization
974
1133
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logWarn
3
- } from "./chunk-2LWPFSB4.js";
3
+ } from "./chunk-4LJO56OJ.js";
4
4
 
5
5
  // src/chat/conversation-privacy.ts
6
6
  import { AsyncLocalStorage } from "async_hooks";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EM225ITJ.js";
4
4
  import {
5
5
  getSlackBotToken
6
- } from "./chunk-XFKIRN3Q.js";
6
+ } from "./chunk-7NVJVJID.js";
7
7
  import {
8
8
  parseSlackChannelReferenceId
9
9
  } from "./chunk-F3B2YJ76.js";
@@ -12,7 +12,7 @@ import {
12
12
  setSpanAttributes,
13
13
  setSpanStatus,
14
14
  withSpan
15
- } from "./chunk-2LWPFSB4.js";
15
+ } from "./chunk-4LJO56OJ.js";
16
16
 
17
17
  // src/chat/slack/client.ts
18
18
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
@@ -242,6 +242,7 @@ var conversationReportTurnRoutedEventDataSchema = z2.object({
242
242
  turnId: z2.string().min(1),
243
243
  modelProfile: z2.string().min(1),
244
244
  modelId: z2.string().min(1),
245
+ costUsd: z2.number().finite().nonnegative().optional(),
245
246
  reasoningLevel: z2.string().min(1),
246
247
  confidence: z2.number().min(0).max(1).optional(),
247
248
  source: z2.enum(["configured", "inherited", "router"])
@@ -4,24 +4,24 @@ import {
4
4
  import {
5
5
  formatProviderLabel,
6
6
  startOAuthFlow
7
- } from "./chunk-FUBRJA5F.js";
7
+ } from "./chunk-7UQIVT6G.js";
8
8
  import {
9
9
  abandonReplacedPendingAuth,
10
10
  canReusePendingAuthLink,
11
11
  recordAuthorizationRequested
12
- } from "./chunk-ZIAMN2UW.js";
12
+ } from "./chunk-AIOK6LAG.js";
13
13
  import {
14
14
  parseSandboxEgressAuthRequiredSignal
15
15
  } from "./chunk-HUO3UTAQ.js";
16
16
  import {
17
17
  AGENT_INVOCATION_MAILBOX_STATUSES
18
- } from "./chunk-27TEJTZO.js";
18
+ } from "./chunk-DU74WPIC.js";
19
19
  import {
20
20
  TURN_REASONING_LEVELS
21
- } from "./chunk-XFKIRN3Q.js";
21
+ } from "./chunk-7NVJVJID.js";
22
22
  import {
23
23
  pluginCatalogRuntime
24
- } from "./chunk-SIN3MXH6.js";
24
+ } from "./chunk-JUUKWRBE.js";
25
25
  import {
26
26
  credentialContextSchema
27
27
  } from "./chunk-RUIXF3YQ.js";
@@ -128,6 +128,7 @@ function createPluginAuthOrchestration(input) {
128
128
  if (!reusingPendingLink) {
129
129
  const oauthResult = await startOAuthFlow(provider, {
130
130
  actorId: input.actorId,
131
+ ...input.actor ? { actor: input.actor } : {},
131
132
  channelId: input.channelId,
132
133
  destination: input.destination,
133
134
  source: input.source,