@sentry/junior 0.156.0 → 0.157.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 (80) hide show
  1. package/dist/{agent-hooks-CCAR46PQ.js → agent-hooks-QI5EPOKQ.js} +10 -10
  2. package/dist/api/conversations/attachments.d.ts +32 -0
  3. package/dist/api/conversations/priority.d.ts +21 -0
  4. package/dist/api/conversations/routes.d.ts +4 -1
  5. package/dist/api/locations/detail.d.ts +3 -1
  6. package/dist/api/schema/conversation.d.ts +14 -4
  7. package/dist/api/schema/location.d.ts +3 -1
  8. package/dist/api/schema/person.d.ts +3 -1
  9. package/dist/api/schema/task.d.ts +8 -8
  10. package/dist/api/schema.js +1 -1
  11. package/dist/api.js +158 -36
  12. package/dist/app.js +35 -54
  13. package/dist/{catalog-runtime-3SNKYCBG.js → catalog-runtime-HUGHAFUN.js} +5 -5
  14. package/dist/chat/agent-invocations/types.d.ts +12 -12
  15. package/dist/chat/attachments/storage.d.ts +2 -0
  16. package/dist/chat/attachments/store.d.ts +16 -0
  17. package/dist/chat/event-tasks/tool-support.d.ts +1 -1
  18. package/dist/chat/event-tasks/types.d.ts +1 -1
  19. package/dist/chat/plugins/unfinished-work.d.ts +6 -1
  20. package/dist/chat/scheduled-tasks/tool-support.d.ts +5 -5
  21. package/dist/chat/scheduled-tasks/tools/create.d.ts +2 -2
  22. package/dist/chat/scheduled-tasks/tools/delete.d.ts +2 -2
  23. package/dist/chat/scheduled-tasks/tools/list.d.ts +2 -2
  24. package/dist/chat/scheduled-tasks/tools/run-now.d.ts +2 -2
  25. package/dist/chat/scheduled-tasks/tools/update.d.ts +2 -2
  26. package/dist/chat/task-execution/slack-work.d.ts +2 -2
  27. package/dist/{chunk-AIJRG227.js → chunk-3GS7O66Z.js} +1 -1
  28. package/dist/{chunk-KBGMYLSV.js → chunk-46ADYIPE.js} +1 -1
  29. package/dist/{chunk-SE3D225X.js → chunk-4M25PSFB.js} +1 -1
  30. package/dist/{chunk-TN4LVILT.js → chunk-5TIH5GOE.js} +5 -5
  31. package/dist/{chunk-EDJ64P2P.js → chunk-6MI43QZO.js} +1 -1
  32. package/dist/{chunk-WD7SEUZO.js → chunk-77QB5FNI.js} +1 -1
  33. package/dist/{chunk-CN2XSVKF.js → chunk-7J65DOBL.js} +6 -6
  34. package/dist/{chunk-4ZZDTHFC.js → chunk-AFQ47JQ7.js} +8 -8
  35. package/dist/{chunk-6CINHXIL.js → chunk-BLCVTEE7.js} +4 -4
  36. package/dist/{chunk-X5NZQH5U.js → chunk-CZCMFRUQ.js} +16 -0
  37. package/dist/{chunk-MJE7XKWP.js → chunk-D7BNWRYL.js} +1 -1
  38. package/dist/{chunk-OGZPRMZA.js → chunk-F7VOY4VQ.js} +1 -1
  39. package/dist/{chunk-IIO5PFZX.js → chunk-G2FN3I66.js} +3 -3
  40. package/dist/{chunk-3L2PMOSR.js → chunk-GEY6IFXH.js} +4 -4
  41. package/dist/{chunk-6JUU7J2B.js → chunk-GO2W3VZY.js} +4 -4
  42. package/dist/{chunk-KCA5MKHU.js → chunk-HJ3EZHIX.js} +351 -5
  43. package/dist/{chunk-MC57E5U5.js → chunk-I3OQVVMV.js} +1 -1
  44. package/dist/{chunk-NTNU6T2D.js → chunk-MDZQ62PB.js} +2 -2
  45. package/dist/{chunk-3FFUC32L.js → chunk-MGJW3SW4.js} +6 -6
  46. package/dist/{chunk-X7W45B5G.js → chunk-MKA3T2R6.js} +1 -1
  47. package/dist/{chunk-IZEBHYI4.js → chunk-MXO6VFB3.js} +1 -1
  48. package/dist/{chunk-53W3LZEW.js → chunk-OWASYHHV.js} +64 -361
  49. package/dist/{chunk-GSBPZHLQ.js → chunk-PP4UQTH3.js} +9 -9
  50. package/dist/{chunk-SRJA6QLM.js → chunk-RQBRGPUF.js} +2 -2
  51. package/dist/{chunk-A6WPDFHQ.js → chunk-S4PFOWRA.js} +1 -1
  52. package/dist/{chunk-OMQJB7YN.js → chunk-TA5R6BME.js} +18 -18
  53. package/dist/{chunk-GKC43TLS.js → chunk-UJYA75N5.js} +2 -2
  54. package/dist/{chunk-PMFGVLDU.js → chunk-VBKFO65J.js} +35 -10
  55. package/dist/{chunk-7RAETIYO.js → chunk-VDAEXEBB.js} +6 -6
  56. package/dist/{chunk-JUJR6WTL.js → chunk-VIBHFGQC.js} +4 -4
  57. package/dist/{chunk-CK2H7CFO.js → chunk-VYDM7HUF.js} +1 -1
  58. package/dist/{chunk-ZNWRYNCA.js → chunk-WNNYOPXX.js} +5 -5
  59. package/dist/{chunk-TNXGMFWV.js → chunk-XRERMHPN.js} +1 -1
  60. package/dist/cli/chat.js +30 -30
  61. package/dist/cli/check.js +6 -6
  62. package/dist/cli/plugins.js +13 -13
  63. package/dist/cli/snapshot-create.js +9 -9
  64. package/dist/cli/upgrade.js +7 -7
  65. package/dist/db/schema/agent-invocations.d.ts +4 -4
  66. package/dist/db/schema.d.ts +4 -4
  67. package/dist/{db-TYUUKGJX.js → db-VQAV4PJ3.js} +7 -7
  68. package/dist/instrumentation.js +4 -4
  69. package/dist/nitro.js +2 -2
  70. package/dist/{oauth-callback-server-AWVDKPR5.js → oauth-callback-server-K5KQAAAX.js} +23 -23
  71. package/dist/{runner-JUQXMACC.js → runner-U7QI7P4S.js} +14 -15
  72. package/dist/{skills-4GZTZX4V.js → skills-ENKRBZ7K.js} +6 -6
  73. package/dist/spawn-4XGNONLS.js +37 -0
  74. package/dist/{validation-DRLNJRND.js → validation-VKCDVGA6.js} +6 -6
  75. package/dist/version.js +1 -1
  76. package/dist/{work-TGIXRRJY.js → work-IBD6PWP2.js} +17 -17
  77. package/dist/worker-TJFXOZRC.js +24 -0
  78. package/package.json +4 -4
  79. package/dist/spawn-32SSRWU4.js +0 -37
  80. package/dist/worker-IFXZOYED.js +0 -24
@@ -7,7 +7,7 @@ import {
7
7
  PluginCredentialFailureError,
8
8
  agentNameSchema,
9
9
  createPluginAuthOrchestration
10
- } from "./chunk-ZNWRYNCA.js";
10
+ } from "./chunk-WNNYOPXX.js";
11
11
  import {
12
12
  authorizationId
13
13
  } from "./chunk-DIB4GX3G.js";
@@ -32,7 +32,7 @@ import {
32
32
  searchSlackUsers,
33
33
  selectPluginGrant,
34
34
  toMcpProviderError
35
- } from "./chunk-4ZZDTHFC.js";
35
+ } from "./chunk-AFQ47JQ7.js";
36
36
  import {
37
37
  RetryableDeliveryError,
38
38
  actorFromRun,
@@ -48,7 +48,7 @@ import {
48
48
  getSlackMessagePermalink,
49
49
  resolveBaseUrl,
50
50
  uploadFilesToConversation
51
- } from "./chunk-7RAETIYO.js";
51
+ } from "./chunk-VDAEXEBB.js";
52
52
  import {
53
53
  parseSandboxEgressAuthRequiredSignal,
54
54
  parseSandboxEgressPermissionDeniedSignal,
@@ -74,7 +74,7 @@ import {
74
74
  runNonInteractiveCommand,
75
75
  throwSandboxOperationError,
76
76
  wrapSandboxSetupError
77
- } from "./chunk-6JUU7J2B.js";
77
+ } from "./chunk-GO2W3VZY.js";
78
78
  import {
79
79
  SCHEDULED_TASK_SYSTEM_ACTOR,
80
80
  compactEventTask,
@@ -105,11 +105,12 @@ import {
105
105
  resolveLocalScheduleAtMs,
106
106
  saveEventTask,
107
107
  scheduledTaskAttributes,
108
+ storeAttachments,
108
109
  writableEventTask
109
- } from "./chunk-KCA5MKHU.js";
110
+ } from "./chunk-HJ3EZHIX.js";
110
111
  import {
111
112
  parseSlackThreadId
112
- } from "./chunk-CK2H7CFO.js";
113
+ } from "./chunk-VYDM7HUF.js";
113
114
  import {
114
115
  AGENTS_REMOVAL_NOTICE,
115
116
  AGENTS_REPLACEMENT_NOTICE,
@@ -179,7 +180,7 @@ import {
179
180
  stripRuntimeTurnContext,
180
181
  trimTrailingAssistantMessages,
181
182
  truncateText
182
- } from "./chunk-3L2PMOSR.js";
183
+ } from "./chunk-GEY6IFXH.js";
183
184
  import {
184
185
  JUNIOR_THREAD_STATE_TTL_MS
185
186
  } from "./chunk-3Y47VMHV.js";
@@ -195,7 +196,7 @@ import {
195
196
  getSlackToolContext,
196
197
  readActorIdentity,
197
198
  resolveChannelCapabilities
198
- } from "./chunk-3FFUC32L.js";
199
+ } from "./chunk-MGJW3SW4.js";
199
200
  import {
200
201
  SlackActionError,
201
202
  downloadPrivateSlackFile,
@@ -204,7 +205,7 @@ import {
204
205
  isConversationScopedChannel,
205
206
  normalizeSlackConversationId,
206
207
  withSlackRetries
207
- } from "./chunk-NTNU6T2D.js";
208
+ } from "./chunk-MDZQ62PB.js";
208
209
  import {
209
210
  KNOWN_CONVERSATION_EVENT_TYPES,
210
211
  contextProvenance,
@@ -216,12 +217,10 @@ import {
216
217
  instructionActors,
217
218
  instructionProvenanceFor,
218
219
  sameActorIdentity
219
- } from "./chunk-IIO5PFZX.js";
220
+ } from "./chunk-G2FN3I66.js";
220
221
  import {
221
- juniorAttachments,
222
- juniorConversations,
223
222
  juniorIdentities
224
- } from "./chunk-AIJRG227.js";
223
+ } from "./chunk-3GS7O66Z.js";
225
224
  import {
226
225
  SANDBOX_DATA_ROOT,
227
226
  SANDBOX_SKILLS_ROOT,
@@ -233,7 +232,7 @@ import {
233
232
  } from "./chunk-EM225ITJ.js";
234
233
  import {
235
234
  getStateAdapter
236
- } from "./chunk-MC57E5U5.js";
235
+ } from "./chunk-I3OQVVMV.js";
237
236
  import {
238
237
  ACTIVE_TURN_COMPACTION_SUMMARY_PREFIX,
239
238
  COMPACTION_SUMMARY_PREFIX,
@@ -266,7 +265,7 @@ import {
266
265
  resolveGatewayCredential,
267
266
  resolveGatewayModel,
268
267
  unwrapCurrentInstruction
269
- } from "./chunk-GKC43TLS.js";
268
+ } from "./chunk-UJYA75N5.js";
270
269
  import {
271
270
  canExposeConversationPayload,
272
271
  resolveConversationPrivacy,
@@ -276,16 +275,16 @@ import {
276
275
  toGenAiMessagesTraceAttributes,
277
276
  toGenAiPayloadMetadata,
278
277
  toGenAiPayloadTraceAttributes
279
- } from "./chunk-MJE7XKWP.js";
278
+ } from "./chunk-D7BNWRYL.js";
280
279
  import {
281
280
  discoverSkills,
282
281
  findSkillByName,
283
282
  loadSkillsByName,
284
283
  parseSkillInvocation
285
- } from "./chunk-SRJA6QLM.js";
284
+ } from "./chunk-RQBRGPUF.js";
286
285
  import {
287
286
  pluginCatalogRuntime
288
- } from "./chunk-EDJ64P2P.js";
287
+ } from "./chunk-6MI43QZO.js";
289
288
  import {
290
289
  CredentialUnavailableError,
291
290
  OAuthProviderError,
@@ -293,7 +292,7 @@ import {
293
292
  getOAuthProviderErrorAttributes,
294
293
  resolveAuthTokenPlaceholder,
295
294
  resolvePluginCommandEnv
296
- } from "./chunk-WD7SEUZO.js";
295
+ } from "./chunk-77QB5FNI.js";
297
296
  import {
298
297
  credentialUserSubjectId
299
298
  } from "./chunk-BDUENQD3.js";
@@ -321,7 +320,7 @@ import {
321
320
  summarizeMessageText,
322
321
  withLogContext,
323
322
  withSpan
324
- } from "./chunk-X7W45B5G.js";
323
+ } from "./chunk-MKA3T2R6.js";
325
324
  import {
326
325
  startInactiveSpan,
327
326
  withActiveSpan
@@ -10537,318 +10536,7 @@ function createSlackMessageAddReactionTool(context, state) {
10537
10536
  }
10538
10537
 
10539
10538
  // src/chat/slack/tools/send-files.ts
10540
- import { createHash as createHash5 } from "crypto";
10541
-
10542
- // src/chat/attachments/store.ts
10543
- import { createHash as createHash4, randomUUID as randomUUID3 } from "crypto";
10544
- import { and, asc, eq, inArray, isNotNull, isNull, or } from "drizzle-orm";
10545
- var ATTACHMENT_GC_BATCH_LIMIT = 200;
10546
- function attachmentDigest(file) {
10547
- return createHash4("sha256").update(file.data).digest("hex");
10548
- }
10549
- function attachmentId(args) {
10550
- return createHash4("sha256").update(
10551
- [
10552
- args.conversationId,
10553
- args.provider,
10554
- args.sha256,
10555
- args.filename,
10556
- args.contentType
10557
- ].join("\0")
10558
- ).digest("hex");
10559
- }
10560
- function attachmentKey(args) {
10561
- return `conversations/${args.conversationId}/attachments/${args.attachmentId}/${args.writeId}/${args.filename}`;
10562
- }
10563
- async function bestEffortDelete(storage, key) {
10564
- try {
10565
- await storage.delete([key]);
10566
- } catch {
10567
- }
10568
- }
10569
- async function isConversationPurged(db, conversationId) {
10570
- const [row] = await db.db().select({
10571
- transcriptPurgedAt: juniorConversations.transcriptPurgedAt
10572
- }).from(juniorConversations).where(eq(juniorConversations.conversationId, conversationId));
10573
- return row?.transcriptPurgedAt != null;
10574
- }
10575
- function purgedConversationError(conversationId) {
10576
- return new Error(
10577
- `Cannot store attachment for purged conversation ${conversationId}`
10578
- );
10579
- }
10580
- async function assertConversationNotPurged(db, conversationId) {
10581
- if (await isConversationPurged(db, conversationId)) {
10582
- throw purgedConversationError(conversationId);
10583
- }
10584
- }
10585
- async function rejectPurgedAttachmentWrite(args) {
10586
- await args.db.db().update(juniorAttachments).set({ deleteRequestedAt: args.now }).where(eq(juniorAttachments.id, args.id));
10587
- await bestEffortDelete(args.storage, args.storageKey);
10588
- throw purgedConversationError(args.conversationId);
10589
- }
10590
- async function reuseLiveAttachment(args) {
10591
- await bestEffortDelete(args.storage, args.storageKey);
10592
- await assertConversationNotPurged(args.db, args.conversationId);
10593
- return { id: args.id };
10594
- }
10595
- async function storeAttachment(args) {
10596
- const now = new Date(args.nowMs ?? Date.now());
10597
- const sha256 = attachmentDigest(args.file);
10598
- const id = attachmentId({
10599
- conversationId: args.conversationId,
10600
- contentType: args.file.mimeType,
10601
- filename: args.file.filename,
10602
- provider: args.storage.provider,
10603
- sha256
10604
- });
10605
- const [existing] = await args.db.db().select({
10606
- contentType: juniorAttachments.contentType,
10607
- conversationId: juniorAttachments.conversationId,
10608
- deleteRequestedAt: juniorAttachments.deleteRequestedAt,
10609
- filename: juniorAttachments.filename,
10610
- id: juniorAttachments.id,
10611
- provider: juniorAttachments.provider,
10612
- sha256: juniorAttachments.sha256,
10613
- storageKey: juniorAttachments.storageKey
10614
- }).from(juniorAttachments).where(eq(juniorAttachments.id, id));
10615
- if (existing) {
10616
- if (existing.contentType !== args.file.mimeType || existing.conversationId !== args.conversationId || existing.filename !== args.file.filename || existing.provider !== args.storage.provider || existing.sha256 !== sha256) {
10617
- throw new Error(`Attachment write conflicts with ${existing.id}`);
10618
- }
10619
- if (existing.deleteRequestedAt === null) {
10620
- await assertConversationNotPurged(args.db, args.conversationId);
10621
- return { id: existing.id };
10622
- }
10623
- }
10624
- await assertConversationNotPurged(args.db, args.conversationId);
10625
- const storageKey = attachmentKey({
10626
- attachmentId: id,
10627
- conversationId: args.conversationId,
10628
- filename: args.file.filename,
10629
- writeId: randomUUID3()
10630
- });
10631
- await args.storage.put({
10632
- body: args.file.data,
10633
- contentType: args.file.mimeType,
10634
- key: storageKey
10635
- });
10636
- if (existing?.deleteRequestedAt != null) {
10637
- if (await isConversationPurged(args.db, args.conversationId)) {
10638
- await bestEffortDelete(args.storage, storageKey);
10639
- throw purgedConversationError(args.conversationId);
10640
- }
10641
- const oldStorageKey = existing.storageKey;
10642
- const revived2 = await args.db.db().update(juniorAttachments).set({
10643
- deleteRequestedAt: null,
10644
- storageKey
10645
- }).where(
10646
- and(
10647
- eq(juniorAttachments.id, id),
10648
- isNotNull(juniorAttachments.deleteRequestedAt)
10649
- )
10650
- ).returning({ id: juniorAttachments.id });
10651
- if (revived2.length > 0) {
10652
- if (await isConversationPurged(args.db, args.conversationId)) {
10653
- await rejectPurgedAttachmentWrite({
10654
- conversationId: args.conversationId,
10655
- db: args.db,
10656
- id,
10657
- now,
10658
- storage: args.storage,
10659
- storageKey
10660
- });
10661
- }
10662
- if (oldStorageKey !== storageKey) {
10663
- await bestEffortDelete(args.storage, oldStorageKey);
10664
- }
10665
- return { id };
10666
- }
10667
- const [afterRace2] = await args.db.db().select({
10668
- deleteRequestedAt: juniorAttachments.deleteRequestedAt,
10669
- id: juniorAttachments.id,
10670
- storageKey: juniorAttachments.storageKey
10671
- }).from(juniorAttachments).where(eq(juniorAttachments.id, id));
10672
- if (afterRace2?.deleteRequestedAt === null) {
10673
- return reuseLiveAttachment({
10674
- conversationId: args.conversationId,
10675
- db: args.db,
10676
- id: afterRace2.id,
10677
- storage: args.storage,
10678
- storageKey
10679
- });
10680
- }
10681
- }
10682
- let inserted = [];
10683
- try {
10684
- inserted = await args.db.db().insert(juniorAttachments).values({
10685
- id,
10686
- conversationId: args.conversationId,
10687
- provider: args.storage.provider,
10688
- storageKey,
10689
- filename: args.file.filename,
10690
- contentType: args.file.mimeType,
10691
- bytes: args.file.bytes,
10692
- sha256,
10693
- createdAt: now
10694
- }).onConflictDoNothing({ target: juniorAttachments.id }).returning({ id: juniorAttachments.id });
10695
- } catch (error) {
10696
- await bestEffortDelete(args.storage, storageKey);
10697
- throw error;
10698
- }
10699
- if (inserted.length > 0) {
10700
- if (await isConversationPurged(args.db, args.conversationId)) {
10701
- await rejectPurgedAttachmentWrite({
10702
- conversationId: args.conversationId,
10703
- db: args.db,
10704
- id,
10705
- now,
10706
- storage: args.storage,
10707
- storageKey
10708
- });
10709
- }
10710
- return { id };
10711
- }
10712
- const [row] = await args.db.db().select({
10713
- deleteRequestedAt: juniorAttachments.deleteRequestedAt,
10714
- id: juniorAttachments.id,
10715
- storageKey: juniorAttachments.storageKey
10716
- }).from(juniorAttachments).where(eq(juniorAttachments.id, id));
10717
- if (!row) {
10718
- await bestEffortDelete(args.storage, storageKey);
10719
- throw new Error(`Attachment row missing after write for ${id}`);
10720
- }
10721
- if (row.deleteRequestedAt === null) {
10722
- return reuseLiveAttachment({
10723
- conversationId: args.conversationId,
10724
- db: args.db,
10725
- id: row.id,
10726
- storage: args.storage,
10727
- storageKey
10728
- });
10729
- }
10730
- if (await isConversationPurged(args.db, args.conversationId)) {
10731
- await bestEffortDelete(args.storage, storageKey);
10732
- throw purgedConversationError(args.conversationId);
10733
- }
10734
- const revived = await args.db.db().update(juniorAttachments).set({
10735
- deleteRequestedAt: null,
10736
- storageKey
10737
- }).where(
10738
- and(
10739
- eq(juniorAttachments.id, id),
10740
- isNotNull(juniorAttachments.deleteRequestedAt)
10741
- )
10742
- ).returning({ id: juniorAttachments.id });
10743
- if (revived.length > 0) {
10744
- if (await isConversationPurged(args.db, args.conversationId)) {
10745
- await rejectPurgedAttachmentWrite({
10746
- conversationId: args.conversationId,
10747
- db: args.db,
10748
- id,
10749
- now,
10750
- storage: args.storage,
10751
- storageKey
10752
- });
10753
- }
10754
- if (row.storageKey !== storageKey) {
10755
- await bestEffortDelete(args.storage, row.storageKey);
10756
- }
10757
- return { id };
10758
- }
10759
- const [afterRace] = await args.db.db().select({
10760
- deleteRequestedAt: juniorAttachments.deleteRequestedAt,
10761
- id: juniorAttachments.id
10762
- }).from(juniorAttachments).where(eq(juniorAttachments.id, id));
10763
- if (afterRace?.deleteRequestedAt === null) {
10764
- return reuseLiveAttachment({
10765
- conversationId: args.conversationId,
10766
- db: args.db,
10767
- id: afterRace.id,
10768
- storage: args.storage,
10769
- storageKey
10770
- });
10771
- }
10772
- await bestEffortDelete(args.storage, storageKey);
10773
- throw new Error(`Attachment ${id} disappeared while reviving`);
10774
- }
10775
- async function storeAttachments(args) {
10776
- const stored = [];
10777
- for (const file of args.files) {
10778
- stored.push(
10779
- await storeAttachment({
10780
- conversationId: args.conversationId,
10781
- db: args.db,
10782
- file,
10783
- ...args.nowMs !== void 0 ? { nowMs: args.nowMs } : {},
10784
- storage: args.storage
10785
- })
10786
- );
10787
- }
10788
- return stored;
10789
- }
10790
- async function requestAttachmentDeletion(db, conversationIds, nowMs) {
10791
- if (conversationIds.length === 0) return;
10792
- await db.db().update(juniorAttachments).set({ deleteRequestedAt: new Date(nowMs) }).where(
10793
- and(
10794
- inArray(juniorAttachments.conversationId, conversationIds),
10795
- isNull(juniorAttachments.deleteRequestedAt)
10796
- )
10797
- );
10798
- }
10799
- async function collectAttachmentGarbage(args) {
10800
- void args.nowMs;
10801
- const rows = await args.db.db().select({
10802
- id: juniorAttachments.id,
10803
- storageKey: juniorAttachments.storageKey
10804
- }).from(juniorAttachments).innerJoin(
10805
- juniorConversations,
10806
- eq(
10807
- juniorAttachments.conversationId,
10808
- juniorConversations.conversationId
10809
- )
10810
- ).where(
10811
- and(
10812
- eq(juniorAttachments.provider, args.storage.provider),
10813
- or(
10814
- isNotNull(juniorAttachments.deleteRequestedAt),
10815
- isNotNull(juniorConversations.transcriptPurgedAt)
10816
- )
10817
- )
10818
- ).orderBy(asc(juniorAttachments.createdAt), asc(juniorAttachments.id)).limit(args.limit ?? ATTACHMENT_GC_BATCH_LIMIT);
10819
- if (rows.length === 0) return { deleted: 0 };
10820
- await args.storage.delete(rows.map((row) => row.storageKey));
10821
- const stillEligible = await args.db.db().select({ id: juniorAttachments.id }).from(juniorAttachments).innerJoin(
10822
- juniorConversations,
10823
- eq(
10824
- juniorAttachments.conversationId,
10825
- juniorConversations.conversationId
10826
- )
10827
- ).where(
10828
- and(
10829
- inArray(
10830
- juniorAttachments.id,
10831
- rows.map((row) => row.id)
10832
- ),
10833
- or(
10834
- isNotNull(juniorAttachments.deleteRequestedAt),
10835
- isNotNull(juniorConversations.transcriptPurgedAt)
10836
- )
10837
- )
10838
- );
10839
- if (stillEligible.length === 0) return { deleted: 0 };
10840
- const removed = await args.db.db().delete(juniorAttachments).where(
10841
- inArray(
10842
- juniorAttachments.id,
10843
- stillEligible.map((row) => row.id)
10844
- )
10845
- ).returning({
10846
- id: juniorAttachments.id
10847
- });
10848
- return { deleted: removed.length };
10849
- }
10850
-
10851
- // src/chat/slack/tools/send-files.ts
10539
+ import { createHash as createHash4 } from "crypto";
10852
10540
  import { z as z42 } from "zod";
10853
10541
  var sendFilesResultSchema = juniorToolOutputSchema.extend({
10854
10542
  deduplicated: z42.boolean().optional(),
@@ -10867,7 +10555,7 @@ function normalizeFiles(files) {
10867
10555
  }));
10868
10556
  }
10869
10557
  function fileContentDigest(data) {
10870
- return createHash5("sha256").update(data).digest("hex");
10558
+ return createHash4("sha256").update(data).digest("hex");
10871
10559
  }
10872
10560
  function fileOperationInput(files) {
10873
10561
  return files.map((file) => ({
@@ -12322,7 +12010,7 @@ function createSlackThreadReadTool(context) {
12322
12010
  }
12323
12011
 
12324
12012
  // src/chat/tools/user-lookup.ts
12325
- import { and as and2, eq as eq2, or as or2, sql } from "drizzle-orm";
12013
+ import { and, eq, or, sql } from "drizzle-orm";
12326
12014
  import { alias } from "drizzle-orm/pg-core";
12327
12015
  import { z as z54 } from "zod";
12328
12016
  var linkedSlackIdentity = alias(juniorIdentities, "user_lookup_slack_identity");
@@ -12388,12 +12076,12 @@ async function storedSlackUserByEmail(teamId, email) {
12388
12076
  const emailNormalized = normalizeIdentityEmail(email);
12389
12077
  if (!emailNormalized) return void 0;
12390
12078
  const identities = await getSqlExecutor().db().select().from(juniorIdentities).where(
12391
- and2(
12392
- eq2(juniorIdentities.provider, "slack"),
12393
- eq2(juniorIdentities.providerTenantId, teamId),
12394
- eq2(juniorIdentities.kind, "user"),
12395
- eq2(juniorIdentities.emailVerified, true),
12396
- eq2(juniorIdentities.emailNormalized, emailNormalized)
12079
+ and(
12080
+ eq(juniorIdentities.provider, "slack"),
12081
+ eq(juniorIdentities.providerTenantId, teamId),
12082
+ eq(juniorIdentities.kind, "user"),
12083
+ eq(juniorIdentities.emailVerified, true),
12084
+ eq(juniorIdentities.emailNormalized, emailNormalized)
12397
12085
  )
12398
12086
  ).limit(2);
12399
12087
  if (identities.length > 1) {
@@ -12445,18 +12133,18 @@ async function resolveSlack(teamId, query) {
12445
12133
  async function resolveStoredProvider(teamId, provider, query) {
12446
12134
  const rows = await getSqlExecutor().db().select({ slack: linkedSlackIdentity }).from(juniorIdentities).innerJoin(
12447
12135
  linkedSlackIdentity,
12448
- and2(
12449
- eq2(linkedSlackIdentity.userId, juniorIdentities.userId),
12450
- eq2(linkedSlackIdentity.kind, "user"),
12451
- eq2(linkedSlackIdentity.provider, "slack"),
12452
- eq2(linkedSlackIdentity.providerTenantId, teamId)
12136
+ and(
12137
+ eq(linkedSlackIdentity.userId, juniorIdentities.userId),
12138
+ eq(linkedSlackIdentity.kind, "user"),
12139
+ eq(linkedSlackIdentity.provider, "slack"),
12140
+ eq(linkedSlackIdentity.providerTenantId, teamId)
12453
12141
  )
12454
12142
  ).where(
12455
- and2(
12456
- eq2(juniorIdentities.kind, "user"),
12457
- eq2(juniorIdentities.provider, provider),
12458
- or2(
12459
- eq2(juniorIdentities.providerSubjectId, query),
12143
+ and(
12144
+ eq(juniorIdentities.kind, "user"),
12145
+ eq(juniorIdentities.provider, provider),
12146
+ or(
12147
+ eq(juniorIdentities.providerSubjectId, query),
12460
12148
  sql`lower(${juniorIdentities.handle}) = lower(${query})`
12461
12149
  )
12462
12150
  )
@@ -14990,7 +14678,7 @@ function createMcpAuthOrchestration(input) {
14990
14678
  }
14991
14679
 
14992
14680
  // src/chat/egress/plugin.ts
14993
- import { randomUUID as randomUUID4 } from "crypto";
14681
+ import { randomUUID as randomUUID3 } from "crypto";
14994
14682
 
14995
14683
  // src/chat/sandbox/egress/credentials.ts
14996
14684
  var HTTP_READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
@@ -15318,17 +15006,34 @@ async function requestBodyBytes(request) {
15318
15006
  }
15319
15007
  return await request.arrayBuffer();
15320
15008
  }
15321
- function isGrantSelectionBodyVisible(input) {
15322
- return input.provider === "github" && input.upstreamUrl.hostname.toLowerCase() === "api.github.com" && input.upstreamUrl.pathname.toLowerCase().endsWith("/graphql");
15009
+ function githubBodyInspection(input) {
15010
+ if (input.provider !== "github" || input.requestMethod.toUpperCase() !== "POST" || input.upstreamUrl.hostname.toLowerCase() !== "api.github.com") {
15011
+ return void 0;
15012
+ }
15013
+ const pathname = input.upstreamUrl.pathname.toLowerCase();
15014
+ if (pathname.endsWith("/graphql")) {
15015
+ return "graphql";
15016
+ }
15017
+ return /^\/repos\/[^/]+\/[^/]+\/pulls\/[^/]+\/reviews(?:\/[^/]+\/events)?$/.test(
15018
+ pathname
15019
+ ) ? "pull-request-review" : void 0;
15020
+ }
15021
+ function grantSelectionBodyTooLargeMessage(inspection) {
15022
+ return inspection === "graphql" ? "GitHub GraphQL request body is too large for Junior to inspect before issuing credentials." : "GitHub pull request review request body is too large for Junior to inspect before issuing credentials.";
15323
15023
  }
15324
15024
  function grantSelectionBodyText(input) {
15325
15025
  if (input.body === void 0) {
15326
15026
  return void 0;
15327
15027
  }
15328
15028
  if (input.body.byteLength > GRANT_SELECTION_BODY_TEXT_LIMIT_BYTES) {
15329
- if (!input.operation && input.provider === "github" && input.request.method.toUpperCase() === "POST" && input.upstreamUrl.hostname.toLowerCase() === "api.github.com" && input.upstreamUrl.pathname.toLowerCase().endsWith("/graphql")) {
15029
+ const inspection = githubBodyInspection({
15030
+ provider: input.provider,
15031
+ requestMethod: input.request.method,
15032
+ upstreamUrl: input.upstreamUrl
15033
+ });
15034
+ if (inspection) {
15330
15035
  throw new EgressPolicyDenied(
15331
- "GitHub GraphQL request body is too large for Junior to inspect before issuing credentials."
15036
+ grantSelectionBodyTooLargeMessage(inspection)
15332
15037
  );
15333
15038
  }
15334
15039
  return void 0;
@@ -15486,8 +15191,9 @@ async function executeCredentialedEgressRequest(input) {
15486
15191
  request,
15487
15192
  upstreamUrl
15488
15193
  } = input;
15489
- const bodyForGrantSelection = isGrantSelectionBodyVisible({
15194
+ const bodyForGrantSelection = githubBodyInspection({
15490
15195
  provider,
15196
+ requestMethod: request.method,
15491
15197
  upstreamUrl
15492
15198
  }) ? await requestBodyBytes(request) : void 0;
15493
15199
  let grantSelection;
@@ -15495,7 +15201,6 @@ async function executeCredentialedEgressRequest(input) {
15495
15201
  grantSelection = await selectSandboxEgressGrant({
15496
15202
  bodyText: grantSelectionBodyText({
15497
15203
  body: bodyForGrantSelection,
15498
- ...operation ? { operation } : {},
15499
15204
  provider,
15500
15205
  request,
15501
15206
  upstreamUrl
@@ -15727,8 +15432,8 @@ async function executeCredentialedEgressRequest(input) {
15727
15432
  function credentialContextForPluginEgress(credentialContext) {
15728
15433
  return {
15729
15434
  credentials: credentialContext,
15730
- contextId: randomUUID4(),
15731
- egressId: `plugin-egress:${randomUUID4()}`,
15435
+ contextId: randomUUID3(),
15436
+ egressId: `plugin-egress:${randomUUID3()}`,
15732
15437
  expiresAtMs: Date.now() + 30 * 60 * 1e3
15733
15438
  };
15734
15439
  }
@@ -18458,8 +18163,6 @@ export {
18458
18163
  deliverResourceEventSubscription,
18459
18164
  sanitizeScheduledTaskPrincipal,
18460
18165
  listThreadReplies,
18461
- requestAttachmentDeletion,
18462
- collectAttachmentGarbage,
18463
18166
  renderBlockText,
18464
18167
  renderAttachmentText,
18465
18168
  latestReportedProgress,
@@ -2,7 +2,7 @@ import {
2
2
  coerceThreadConversationState,
3
3
  getPersistedThreadState,
4
4
  persistThreadStateById
5
- } from "./chunk-TN4LVILT.js";
5
+ } from "./chunk-5TIH5GOE.js";
6
6
  import {
7
7
  pluginTaskId,
8
8
  pluginTaskParamsSchema,
@@ -22,7 +22,7 @@ import {
22
22
  markTurnCompleted,
23
23
  normalizeToolNameFromResult,
24
24
  stripRuntimeTurnContext
25
- } from "./chunk-3L2PMOSR.js";
25
+ } from "./chunk-GEY6IFXH.js";
26
26
  import {
27
27
  JUNIOR_THREAD_STATE_TTL_MS
28
28
  } from "./chunk-3Y47VMHV.js";
@@ -33,25 +33,25 @@ import {
33
33
  createPluginModel,
34
34
  createPluginState,
35
35
  getPlugins
36
- } from "./chunk-3FFUC32L.js";
36
+ } from "./chunk-MGJW3SW4.js";
37
37
  import {
38
38
  getConversationStore,
39
39
  getDb,
40
40
  sameActorIdentity
41
- } from "./chunk-IIO5PFZX.js";
41
+ } from "./chunk-G2FN3I66.js";
42
42
  import {
43
43
  juniorConversations,
44
44
  juniorTaskExecutions
45
- } from "./chunk-AIJRG227.js";
45
+ } from "./chunk-3GS7O66Z.js";
46
46
  import {
47
47
  getStateAdapter
48
- } from "./chunk-MC57E5U5.js";
48
+ } from "./chunk-I3OQVVMV.js";
49
49
  import {
50
50
  ProviderError,
51
51
  findProviderError,
52
52
  getProviderErrorAttributes,
53
53
  getProviderErrorUserMessage
54
- } from "./chunk-GKC43TLS.js";
54
+ } from "./chunk-UJYA75N5.js";
55
55
  import {
56
56
  credentialSubjectSchema
57
57
  } from "./chunk-BDUENQD3.js";
@@ -61,7 +61,7 @@ import {
61
61
  import {
62
62
  buildTurnFailureResponse,
63
63
  logWarn
64
- } from "./chunk-X7W45B5G.js";
64
+ } from "./chunk-MKA3T2R6.js";
65
65
 
66
66
  // src/chat/runtime/delivered-turn-state.ts
67
67
  function buildDeliveredTurnStatePatch(args) {
@@ -87,7 +87,7 @@ import { pluginRunContextSchema } from "@sentry/junior-plugin-api";
87
87
 
88
88
  // src/chat/services/turn-session-routing.ts
89
89
  async function resolveTurnSessionRouting(args) {
90
- const conversationStore = args.conversationStore ?? (await import("./db-TYUUKGJX.js")).getConversationStore();
90
+ const conversationStore = args.conversationStore ?? (await import("./db-VQAV4PJ3.js")).getConversationStore();
91
91
  const conversation = await conversationStore.get({
92
92
  conversationId: args.conversationId
93
93
  });
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-EDJ64P2P.js";
3
+ } from "./chunk-6MI43QZO.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-X7W45B5G.js";
6
+ } from "./chunk-MKA3T2R6.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-H4HBKISO.js";