@sentry/junior-github 0.154.0 → 0.155.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/dist/index.js CHANGED
@@ -333,22 +333,36 @@ ${footer}` : footer;
333
333
  // src/tool-support/attribution.ts
334
334
  var GITHUB_REQUEST_ATTRIBUTION_START = "<!-- junior-request-attribution:start -->";
335
335
  var GITHUB_REQUEST_ATTRIBUTION_END = "<!-- junior-request-attribution:end -->";
336
- function cleanDisplayValue(value) {
336
+ var SLACK_USER_ID_DISPLAY_PATTERN = /^[UW][A-Z0-9]{5,}$/;
337
+ function cleanDisplayValue(value, userId) {
337
338
  const cleaned = value?.replace(/[\r\n<>]/g, " ").trim();
338
- return cleaned || void 0;
339
+ if (!cleaned) {
340
+ return void 0;
341
+ }
342
+ if (cleaned.toLowerCase() === "unknown") {
343
+ return void 0;
344
+ }
345
+ if (userId && cleaned === userId) {
346
+ return void 0;
347
+ }
348
+ if (SLACK_USER_ID_DISPLAY_PATTERN.test(cleaned)) {
349
+ return void 0;
350
+ }
351
+ return cleaned;
339
352
  }
340
- function actorLabel(actor) {
353
+ function requesterLabel(args) {
354
+ const { actor, identity, user } = args;
341
355
  if (!actor) {
342
356
  return void 0;
343
357
  }
344
358
  if (actor.platform === "system") {
345
359
  return `Junior system actor \`${actor.name}\``;
346
360
  }
347
- const display = cleanDisplayValue(actor.fullName) ?? cleanDisplayValue(actor.userName) ?? cleanDisplayValue(actor.userId);
361
+ const userId = actor.userId;
362
+ const display = cleanDisplayValue(user?.displayName, userId) ?? cleanDisplayValue(identity?.displayName, userId) ?? cleanDisplayValue(identity?.handle, userId) ?? cleanDisplayValue(actor.fullName, userId) ?? cleanDisplayValue(actor.userName, userId);
348
363
  return display ? `**${display.replaceAll("*", "\\*")}**` : void 0;
349
364
  }
350
- function appendGitHubRequesterAttribution(body, actor) {
351
- const label = actorLabel(actor);
365
+ function applyAttribution(body, label) {
352
366
  const attribution = label ? `${GITHUB_REQUEST_ATTRIBUTION_START}
353
367
  Requested by ${label}.
354
368
  ${GITHUB_REQUEST_ATTRIBUTION_END}` : void 0;
@@ -366,6 +380,26 @@ ${GITHUB_REQUEST_ATTRIBUTION_END}` : void 0;
366
380
 
367
381
  ${attribution}` : attribution;
368
382
  }
383
+ async function appendGitHubRequesterAttribution(body, ctx) {
384
+ let resolved;
385
+ if (ctx.actor) {
386
+ try {
387
+ resolved = await ctx.users.resolveActor();
388
+ } catch (error) {
389
+ ctx.log.warn("github.requester_attribution.resolve_actor.failed", {
390
+ "exception.message": error instanceof Error ? error.message : String(error)
391
+ });
392
+ }
393
+ }
394
+ return applyAttribution(
395
+ body,
396
+ requesterLabel({
397
+ actor: ctx.actor,
398
+ identity: resolved?.identity,
399
+ user: resolved?.user
400
+ })
401
+ );
402
+ }
369
403
 
370
404
  // src/tools/create-issue.ts
371
405
  var GITHUB_ISSUE_CREATE_IDEMPOTENCY_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -516,7 +550,7 @@ function isDefinitiveGitHubIssueCreateRejection(error) {
516
550
  }
517
551
  return [400, 401, 404, 410, 422].includes(error.status);
518
552
  }
519
- function createGitHubIssueRequest(conversationId, input, actor, dashboardUrl) {
553
+ async function createGitHubIssueRequest(conversationId, input, ctx, dashboardUrl) {
520
554
  const repo = parseRepo2(input.repo);
521
555
  const labels = input.labels?.map(
522
556
  (label) => nonEmptyString2(label, "labels entry")
@@ -524,7 +558,7 @@ function createGitHubIssueRequest(conversationId, input, actor, dashboardUrl) {
524
558
  const payload = {
525
559
  title: nonEmptyString2(input.title, "title"),
526
560
  body: appendGitHubFooter(
527
- appendGitHubRequesterAttribution(input.body ?? "", actor),
561
+ await appendGitHubRequesterAttribution(input.body ?? "", ctx),
528
562
  conversationId,
529
563
  dashboardUrl
530
564
  ),
@@ -624,10 +658,10 @@ function createGitHubIssueTool(ctx) {
624
658
  "GitHub issue creation for this tool call has an uncertain pending result; refusing to create a duplicate issue."
625
659
  );
626
660
  }
627
- const request = createGitHubIssueRequest(
661
+ const request = await createGitHubIssueRequest(
628
662
  conversationId,
629
663
  parsedInput,
630
- ctx.actor,
664
+ ctx,
631
665
  ctx.slack?.conversationLink?.url
632
666
  );
633
667
  const pendingState = {
@@ -1047,14 +1081,14 @@ function isDefinitiveGitHubPullRequestCreateRejection(error) {
1047
1081
  }
1048
1082
  return [400, 401, 404, 410, 422].includes(error.status);
1049
1083
  }
1050
- function createGitHubPullRequestRequest(conversationId, input, actor, dashboardUrl) {
1084
+ async function createGitHubPullRequestRequest(conversationId, input, ctx, dashboardUrl) {
1051
1085
  const repo = parseRepo4(input.repo);
1052
1086
  const payload = {
1053
1087
  title: nonEmptyString3(input.title, "title"),
1054
1088
  head: nonEmptyString3(input.head, "head"),
1055
1089
  base: nonEmptyString3(input.base, "base"),
1056
1090
  body: appendGitHubFooter(
1057
- appendGitHubRequesterAttribution(input.body ?? "", actor),
1091
+ await appendGitHubRequesterAttribution(input.body ?? "", ctx),
1058
1092
  conversationId,
1059
1093
  dashboardUrl
1060
1094
  ),
@@ -1173,10 +1207,10 @@ function createGitHubPullRequestTool(ctx) {
1173
1207
  "GitHub pull request creation for this tool call has an uncertain pending result; refusing to create a duplicate pull request."
1174
1208
  );
1175
1209
  }
1176
- const request = createGitHubPullRequestRequest(
1210
+ const request = await createGitHubPullRequestRequest(
1177
1211
  conversationId,
1178
1212
  parsedInput,
1179
- ctx.actor,
1213
+ ctx,
1180
1214
  ctx.slack?.conversationLink?.url
1181
1215
  );
1182
1216
  const pendingState = {
@@ -1674,7 +1708,7 @@ function createGitHubUpdatePullRequestTool(ctx) {
1674
1708
  ...update.title !== void 0 ? { title: update.title } : {},
1675
1709
  ...update.body !== void 0 ? {
1676
1710
  body: appendGitHubFooter(
1677
- appendGitHubRequesterAttribution(update.body, ctx.actor),
1711
+ await appendGitHubRequesterAttribution(update.body, ctx),
1678
1712
  nonEmptyString4(ctx.conversationId, "conversationId"),
1679
1713
  ctx.slack?.conversationLink?.url
1680
1714
  )
@@ -1822,7 +1856,8 @@ var juniorGitHubPullRequests = pgTable(
1822
1856
  index("junior_github_pull_requests_opened_at_idx").on(table.openedAt),
1823
1857
  index("junior_github_pull_requests_merged_at_idx").on(table.mergedAt),
1824
1858
  index("junior_github_pull_requests_closed_at_idx").on(table.closedAt),
1825
- index("junior_github_pull_requests_open_idx").on(table.pullRequestId).where(sql`${table.state} = 'open'`)
1859
+ index("junior_github_pull_requests_open_idx").on(table.pullRequestId).where(sql`${table.state} = 'open'`),
1860
+ index("junior_github_pull_requests_unmerged_conversations_idx").using("gin", table.conversationIds).where(sql`${table.state} <> 'merged'`)
1826
1861
  ]
1827
1862
  );
1828
1863
  var juniorGitHubPullRequestIssues = pgTable(
@@ -1912,7 +1947,7 @@ async function recordGitHubIssueConversations(db, input) {
1912
1947
  }
1913
1948
 
1914
1949
  // src/pull-request-outcomes/store.ts
1915
- import { and as and2, eq as eq2, lte as lte2, sql as sql3 } from "drizzle-orm";
1950
+ import { and as and2, eq as eq2, lte as lte2, ne, sql as sql3 } from "drizzle-orm";
1916
1951
  import { z as z11 } from "zod";
1917
1952
  var githubPullRequestOutcomeInputSchema = z11.object({
1918
1953
  candidateOwned: z11.boolean(),
@@ -1986,6 +2021,29 @@ async function recordGitHubPullRequestOutcome(db, input) {
1986
2021
  conversationIds: inserted[0]?.conversationIds ?? []
1987
2022
  };
1988
2023
  }
2024
+ async function listGitHubUnfinishedWork(db, conversationIds) {
2025
+ if (conversationIds.length === 0) return [];
2026
+ const values = sql3.join(
2027
+ conversationIds.map((id) => sql3`${id}`),
2028
+ sql3`, `
2029
+ );
2030
+ const rows = await db.select({ conversationIds: juniorGitHubPullRequests.conversationIds }).from(juniorGitHubPullRequests).where(
2031
+ and2(
2032
+ ne(juniorGitHubPullRequests.state, "merged"),
2033
+ sql3`${juniorGitHubPullRequests.conversationIds} && ARRAY[${values}]::text[]`
2034
+ )
2035
+ );
2036
+ const candidates = new Set(conversationIds);
2037
+ return [
2038
+ ...new Set(
2039
+ rows.flatMap(
2040
+ (row) => row.conversationIds.filter(
2041
+ (conversationId) => candidates.has(conversationId)
2042
+ )
2043
+ )
2044
+ )
2045
+ ];
2046
+ }
1989
2047
  async function recordGitHubPullRequestConversations(db, input) {
1990
2048
  const association = githubPullRequestConversationsInputSchema.parse(input);
1991
2049
  const conversationIds = sql3.join(
@@ -4647,6 +4705,14 @@ function githubPlugin(options = {}) {
4647
4705
  ]
4648
4706
  },
4649
4707
  hooks: {
4708
+ async unfinishedWork(ctx) {
4709
+ return {
4710
+ conversationIds: await listGitHubUnfinishedWork(
4711
+ ctx.db,
4712
+ ctx.conversationIds
4713
+ )
4714
+ };
4715
+ },
4650
4716
  routes(ctx) {
4651
4717
  return [
4652
4718
  createGitHubWebhookRoute({
@@ -46,6 +46,8 @@ export declare function recordGitHubPullRequestOutcome(db: GitHubDb, input: GitH
46
46
  commitComposition: GitHubPullRequestCommitComposition | undefined;
47
47
  conversationIds: string[];
48
48
  }>;
49
+ /** Return candidate conversations that have an associated unmerged pull request. */
50
+ export declare function listGitHubUnfinishedWork(db: GitHubDb, conversationIds: string[]): Promise<string[]>;
49
51
  /** Append native conversation ids to an existing Junior-owned PR projection. */
50
52
  export declare function recordGitHubPullRequestConversations(db: GitHubDb, input: GitHubPullRequestConversationsInput): Promise<boolean>;
51
53
  /** Link an existing Junior-owned PR to tracked issues across repositories. */
@@ -1,5 +1,10 @@
1
- import type { Actor } from "@sentry/junior-plugin-api";
1
+ import type { ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
2
2
  export declare const GITHUB_REQUEST_ATTRIBUTION_START = "<!-- junior-request-attribution:start -->";
3
3
  export declare const GITHUB_REQUEST_ATTRIBUTION_END = "<!-- junior-request-attribution:end -->";
4
- /** Append or replace runtime-owned requester attribution in a GitHub body. */
5
- export declare function appendGitHubRequesterAttribution(body: string, actor: Actor | undefined): string;
4
+ /**
5
+ * Append or replace runtime-owned requester attribution in a GitHub body.
6
+ *
7
+ * Identity lookup is best-effort presentation data. A storage failure falls
8
+ * back to the already-hydrated actor profile instead of blocking the write.
9
+ */
10
+ export declare function appendGitHubRequesterAttribution(body: string, ctx: Pick<ToolRegistrationHookContext, "actor" | "log" | "users">): Promise<string>;
@@ -0,0 +1 @@
1
+ CREATE INDEX "junior_github_pull_requests_unmerged_conversations_idx" ON "junior_github_pull_requests" USING gin ("conversation_ids") WHERE "junior_github_pull_requests"."state" <> 'merged';
@@ -0,0 +1,352 @@
1
+ {
2
+ "id": "a54d392c-28bb-4cd3-ba14-1bcfa793fcce",
3
+ "prevId": "5c4638ae-9d00-4ebe-8d93-989a8c3f879b",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.junior_github_issues": {
8
+ "name": "junior_github_issues",
9
+ "schema": "",
10
+ "columns": {
11
+ "issue_id": {
12
+ "name": "issue_id",
13
+ "type": "text",
14
+ "primaryKey": true,
15
+ "notNull": true
16
+ },
17
+ "repository_id": {
18
+ "name": "repository_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true
22
+ },
23
+ "repository_full_name": {
24
+ "name": "repository_full_name",
25
+ "type": "text",
26
+ "primaryKey": false,
27
+ "notNull": true
28
+ },
29
+ "number": {
30
+ "name": "number",
31
+ "type": "integer",
32
+ "primaryKey": false,
33
+ "notNull": true
34
+ },
35
+ "state": {
36
+ "name": "state",
37
+ "type": "text",
38
+ "primaryKey": false,
39
+ "notNull": true
40
+ },
41
+ "state_reason": {
42
+ "name": "state_reason",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": false
46
+ },
47
+ "conversation_ids": {
48
+ "name": "conversation_ids",
49
+ "type": "text[]",
50
+ "primaryKey": false,
51
+ "notNull": true,
52
+ "default": "ARRAY[]::text[]"
53
+ },
54
+ "opened_at": {
55
+ "name": "opened_at",
56
+ "type": "timestamp with time zone",
57
+ "primaryKey": false,
58
+ "notNull": true
59
+ },
60
+ "closed_at": {
61
+ "name": "closed_at",
62
+ "type": "timestamp with time zone",
63
+ "primaryKey": false,
64
+ "notNull": false
65
+ },
66
+ "updated_at": {
67
+ "name": "updated_at",
68
+ "type": "timestamp with time zone",
69
+ "primaryKey": false,
70
+ "notNull": true
71
+ }
72
+ },
73
+ "indexes": {
74
+ "junior_github_issues_opened_at_idx": {
75
+ "name": "junior_github_issues_opened_at_idx",
76
+ "columns": [
77
+ {
78
+ "expression": "opened_at",
79
+ "isExpression": false,
80
+ "asc": true,
81
+ "nulls": "last"
82
+ }
83
+ ],
84
+ "isUnique": false,
85
+ "concurrently": false,
86
+ "method": "btree",
87
+ "with": {}
88
+ },
89
+ "junior_github_issues_closed_at_idx": {
90
+ "name": "junior_github_issues_closed_at_idx",
91
+ "columns": [
92
+ {
93
+ "expression": "closed_at",
94
+ "isExpression": false,
95
+ "asc": true,
96
+ "nulls": "last"
97
+ }
98
+ ],
99
+ "isUnique": false,
100
+ "concurrently": false,
101
+ "method": "btree",
102
+ "with": {}
103
+ },
104
+ "junior_github_issues_open_idx": {
105
+ "name": "junior_github_issues_open_idx",
106
+ "columns": [
107
+ {
108
+ "expression": "issue_id",
109
+ "isExpression": false,
110
+ "asc": true,
111
+ "nulls": "last"
112
+ }
113
+ ],
114
+ "isUnique": false,
115
+ "where": "\"junior_github_issues\".\"state\" = 'open'",
116
+ "concurrently": false,
117
+ "method": "btree",
118
+ "with": {}
119
+ }
120
+ },
121
+ "foreignKeys": {},
122
+ "compositePrimaryKeys": {},
123
+ "uniqueConstraints": {},
124
+ "policies": {},
125
+ "checkConstraints": {},
126
+ "isRLSEnabled": false
127
+ },
128
+ "public.junior_github_pull_request_issues": {
129
+ "name": "junior_github_pull_request_issues",
130
+ "schema": "",
131
+ "columns": {
132
+ "pull_request_id": {
133
+ "name": "pull_request_id",
134
+ "type": "text",
135
+ "primaryKey": false,
136
+ "notNull": true
137
+ },
138
+ "issue_repository_full_name": {
139
+ "name": "issue_repository_full_name",
140
+ "type": "text",
141
+ "primaryKey": false,
142
+ "notNull": true
143
+ },
144
+ "issue_number": {
145
+ "name": "issue_number",
146
+ "type": "integer",
147
+ "primaryKey": false,
148
+ "notNull": true
149
+ }
150
+ },
151
+ "indexes": {},
152
+ "foreignKeys": {
153
+ "junior_github_pull_request_issues_pull_request_id_junior_github_pull_requests_pull_request_id_fk": {
154
+ "name": "junior_github_pull_request_issues_pull_request_id_junior_github_pull_requests_pull_request_id_fk",
155
+ "tableFrom": "junior_github_pull_request_issues",
156
+ "tableTo": "junior_github_pull_requests",
157
+ "columnsFrom": [
158
+ "pull_request_id"
159
+ ],
160
+ "columnsTo": [
161
+ "pull_request_id"
162
+ ],
163
+ "onDelete": "cascade",
164
+ "onUpdate": "no action"
165
+ }
166
+ },
167
+ "compositePrimaryKeys": {
168
+ "junior_github_pull_request_issues_pull_request_id_issue_repository_full_name_issue_number_pk": {
169
+ "name": "junior_github_pull_request_issues_pull_request_id_issue_repository_full_name_issue_number_pk",
170
+ "columns": [
171
+ "pull_request_id",
172
+ "issue_repository_full_name",
173
+ "issue_number"
174
+ ]
175
+ }
176
+ },
177
+ "uniqueConstraints": {},
178
+ "policies": {},
179
+ "checkConstraints": {},
180
+ "isRLSEnabled": false
181
+ },
182
+ "public.junior_github_pull_requests": {
183
+ "name": "junior_github_pull_requests",
184
+ "schema": "",
185
+ "columns": {
186
+ "pull_request_id": {
187
+ "name": "pull_request_id",
188
+ "type": "text",
189
+ "primaryKey": true,
190
+ "notNull": true
191
+ },
192
+ "repository_id": {
193
+ "name": "repository_id",
194
+ "type": "text",
195
+ "primaryKey": false,
196
+ "notNull": true
197
+ },
198
+ "repository_full_name": {
199
+ "name": "repository_full_name",
200
+ "type": "text",
201
+ "primaryKey": false,
202
+ "notNull": true
203
+ },
204
+ "number": {
205
+ "name": "number",
206
+ "type": "integer",
207
+ "primaryKey": false,
208
+ "notNull": true
209
+ },
210
+ "state": {
211
+ "name": "state",
212
+ "type": "text",
213
+ "primaryKey": false,
214
+ "notNull": true
215
+ },
216
+ "commit_composition": {
217
+ "name": "commit_composition",
218
+ "type": "text",
219
+ "primaryKey": false,
220
+ "notNull": false
221
+ },
222
+ "conversation_ids": {
223
+ "name": "conversation_ids",
224
+ "type": "text[]",
225
+ "primaryKey": false,
226
+ "notNull": true,
227
+ "default": "ARRAY[]::text[]"
228
+ },
229
+ "opened_at": {
230
+ "name": "opened_at",
231
+ "type": "timestamp with time zone",
232
+ "primaryKey": false,
233
+ "notNull": true
234
+ },
235
+ "merged_at": {
236
+ "name": "merged_at",
237
+ "type": "timestamp with time zone",
238
+ "primaryKey": false,
239
+ "notNull": false
240
+ },
241
+ "closed_at": {
242
+ "name": "closed_at",
243
+ "type": "timestamp with time zone",
244
+ "primaryKey": false,
245
+ "notNull": false
246
+ },
247
+ "updated_at": {
248
+ "name": "updated_at",
249
+ "type": "timestamp with time zone",
250
+ "primaryKey": false,
251
+ "notNull": true
252
+ }
253
+ },
254
+ "indexes": {
255
+ "junior_github_pull_requests_opened_at_idx": {
256
+ "name": "junior_github_pull_requests_opened_at_idx",
257
+ "columns": [
258
+ {
259
+ "expression": "opened_at",
260
+ "isExpression": false,
261
+ "asc": true,
262
+ "nulls": "last"
263
+ }
264
+ ],
265
+ "isUnique": false,
266
+ "concurrently": false,
267
+ "method": "btree",
268
+ "with": {}
269
+ },
270
+ "junior_github_pull_requests_merged_at_idx": {
271
+ "name": "junior_github_pull_requests_merged_at_idx",
272
+ "columns": [
273
+ {
274
+ "expression": "merged_at",
275
+ "isExpression": false,
276
+ "asc": true,
277
+ "nulls": "last"
278
+ }
279
+ ],
280
+ "isUnique": false,
281
+ "concurrently": false,
282
+ "method": "btree",
283
+ "with": {}
284
+ },
285
+ "junior_github_pull_requests_closed_at_idx": {
286
+ "name": "junior_github_pull_requests_closed_at_idx",
287
+ "columns": [
288
+ {
289
+ "expression": "closed_at",
290
+ "isExpression": false,
291
+ "asc": true,
292
+ "nulls": "last"
293
+ }
294
+ ],
295
+ "isUnique": false,
296
+ "concurrently": false,
297
+ "method": "btree",
298
+ "with": {}
299
+ },
300
+ "junior_github_pull_requests_open_idx": {
301
+ "name": "junior_github_pull_requests_open_idx",
302
+ "columns": [
303
+ {
304
+ "expression": "pull_request_id",
305
+ "isExpression": false,
306
+ "asc": true,
307
+ "nulls": "last"
308
+ }
309
+ ],
310
+ "isUnique": false,
311
+ "where": "\"junior_github_pull_requests\".\"state\" = 'open'",
312
+ "concurrently": false,
313
+ "method": "btree",
314
+ "with": {}
315
+ },
316
+ "junior_github_pull_requests_unmerged_conversations_idx": {
317
+ "name": "junior_github_pull_requests_unmerged_conversations_idx",
318
+ "columns": [
319
+ {
320
+ "expression": "conversation_ids",
321
+ "isExpression": false,
322
+ "asc": true,
323
+ "nulls": "last"
324
+ }
325
+ ],
326
+ "isUnique": false,
327
+ "where": "\"junior_github_pull_requests\".\"state\" <> 'merged'",
328
+ "concurrently": false,
329
+ "method": "gin",
330
+ "with": {}
331
+ }
332
+ },
333
+ "foreignKeys": {},
334
+ "compositePrimaryKeys": {},
335
+ "uniqueConstraints": {},
336
+ "policies": {},
337
+ "checkConstraints": {},
338
+ "isRLSEnabled": false
339
+ }
340
+ },
341
+ "enums": {},
342
+ "schemas": {},
343
+ "sequences": {},
344
+ "roles": {},
345
+ "policies": {},
346
+ "views": {},
347
+ "_meta": {
348
+ "columns": {},
349
+ "schemas": {},
350
+ "tables": {}
351
+ }
352
+ }
@@ -50,6 +50,13 @@
50
50
  "when": 1784947522832,
51
51
  "tag": "0006_fat_korvac",
52
52
  "breakpoints": true
53
+ },
54
+ {
55
+ "idx": 7,
56
+ "version": "7",
57
+ "when": 1786486305688,
58
+ "tag": "0007_shallow_millenium_guard",
59
+ "breakpoints": true
53
60
  }
54
61
  ]
55
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-github",
3
- "version": "0.154.0",
3
+ "version": "0.155.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -31,7 +31,7 @@
31
31
  "@sinclair/typebox": "^0.34.49",
32
32
  "drizzle-orm": "^0.45.2",
33
33
  "zod": "^4.4.3",
34
- "@sentry/junior-plugin-api": "0.154.0"
34
+ "@sentry/junior-plugin-api": "0.155.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^25.9.1",