@sentry/junior 0.181.0 → 0.182.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 (81) hide show
  1. package/dist/{agent-hooks-IQUW6ERD.js → agent-hooks-3S25UIHO.js} +11 -11
  2. package/dist/api.js +125 -51
  3. package/dist/app-adapter.d.ts +85 -0
  4. package/dist/app.d.ts +6 -1
  5. package/dist/app.js +343 -487
  6. package/dist/{catalog-runtime-PMQWNIXA.js → catalog-runtime-ESLMBQBV.js} +4 -4
  7. package/dist/chat/api-turns/adapter-conversations.d.ts +15 -0
  8. package/dist/chat/api-turns/stop.d.ts +12 -0
  9. package/dist/chat/api-turns/work.d.ts +9 -1
  10. package/dist/chat/app/conversation-work.d.ts +1 -1
  11. package/dist/chat/event-tasks/tool-support.d.ts +7 -1
  12. package/dist/chat/event-tasks/types.d.ts +1 -0
  13. package/dist/chat/experimental.d.ts +1 -1
  14. package/dist/chat/resource-events/catalog.d.ts +11 -1
  15. package/dist/chat/resource-events/store.d.ts +5 -1
  16. package/dist/chat/services/subscribed-decision.d.ts +2 -1
  17. package/dist/chat/tools/create-event-task.d.ts +3 -0
  18. package/dist/chat/tools/delete-event-task.d.ts +2 -0
  19. package/dist/chat/tools/list-event-tasks.d.ts +2 -0
  20. package/dist/chat/tools/list-resource-event-subscriptions.d.ts +2 -0
  21. package/dist/chat/tools/search-resource-event-types.d.ts +10 -0
  22. package/dist/chat/tools/update-event-task.d.ts +3 -0
  23. package/dist/chat/tools/watch-resource-events.d.ts +3 -0
  24. package/dist/{chunk-D6ZD7VXP.js → chunk-2CEOXDG2.js} +20 -11
  25. package/dist/{chunk-VRS6WDK5.js → chunk-2LYHWMR4.js} +1 -1
  26. package/dist/{chunk-IKKETMQC.js → chunk-3ENUMZNG.js} +3 -3
  27. package/dist/{chunk-IJ6SS4WB.js → chunk-3NFHI2NA.js} +1 -1
  28. package/dist/{chunk-GREV5PJK.js → chunk-3THPTNN6.js} +4 -4
  29. package/dist/{chunk-KKSVCHDO.js → chunk-44BQ3TSK.js} +1 -1
  30. package/dist/{chunk-4IX32NSL.js → chunk-4DZ62L36.js} +1 -1
  31. package/dist/{chunk-RNMASWLP.js → chunk-6TSWXBTQ.js} +3 -3
  32. package/dist/{chunk-PBKZQAUA.js → chunk-A7THOQ6N.js} +58 -32
  33. package/dist/{chunk-DSA6WTRP.js → chunk-BDDWVY32.js} +19 -19
  34. package/dist/{chunk-TJHSAHQN.js → chunk-BZD4ADQH.js} +3 -2
  35. package/dist/{chunk-EU7KJDOG.js → chunk-CVBIM4Z3.js} +1 -1
  36. package/dist/{chunk-LZOQFC5F.js → chunk-D6OHGAIO.js} +5 -5
  37. package/dist/{chunk-KQZX24QQ.js → chunk-DZR3L74W.js} +3 -3
  38. package/dist/{chunk-3KCQEG6W.js → chunk-GGYA5NPN.js} +9 -9
  39. package/dist/{chunk-EM7EECT5.js → chunk-JIOKUIAS.js} +2 -2
  40. package/dist/{chunk-3X55QRAG.js → chunk-KGMHUDVF.js} +6 -6
  41. package/dist/{chunk-3KSSALN4.js → chunk-LB4FWMCV.js} +92 -8
  42. package/dist/{chunk-XYTJUHRZ.js → chunk-LHQK5XCU.js} +2 -2
  43. package/dist/{chunk-LCNPXLE7.js → chunk-LT4QYGKM.js} +7 -7
  44. package/dist/{chunk-TDT2R77B.js → chunk-MJISSOWB.js} +1 -1
  45. package/dist/{chunk-FWILPBVQ.js → chunk-PQES5LB5.js} +5 -5
  46. package/dist/{chunk-GWFRPQNP.js → chunk-QHALFHZA.js} +9 -9
  47. package/dist/{chunk-PPYDHUEL.js → chunk-S35OZMSL.js} +130 -200
  48. package/dist/{chunk-ETJTXYHY.js → chunk-SVFSYQMT.js} +1 -1
  49. package/dist/{chunk-NQTA72Q3.js → chunk-SXOZIG5X.js} +6 -6
  50. package/dist/{chunk-Q2KY27IX.js → chunk-TEFNHMO2.js} +63 -7
  51. package/dist/{chunk-KMBU4PJP.js → chunk-UKIHNBBD.js} +3 -3
  52. package/dist/{chunk-EBMRB6Z6.js → chunk-UQP54CXZ.js} +1 -1
  53. package/dist/{chunk-GPA3ZSYY.js → chunk-UUMBHORH.js} +1 -1
  54. package/dist/{chunk-LG5MYY6U.js → chunk-V5UZCCNW.js} +6 -6
  55. package/dist/{chunk-HZHUMCNV.js → chunk-VHMAFMHB.js} +1 -1
  56. package/dist/{chunk-HEBMSITT.js → chunk-WOIALVN2.js} +1 -1
  57. package/dist/{chunk-HJ27A6YB.js → chunk-YHL2L2ZZ.js} +1 -1
  58. package/dist/{chunk-PL57B6NC.js → chunk-Z7ALSQS3.js} +1 -1
  59. package/dist/cli/chat.js +34 -34
  60. package/dist/cli/check.js +5 -5
  61. package/dist/cli/plugins.js +12 -12
  62. package/dist/cli/snapshot-create.js +9 -9
  63. package/dist/cli/upgrade.js +6 -6
  64. package/dist/{db-QNPVCQPT.js → db-NYIWZ4L5.js} +6 -6
  65. package/dist/{experimental-SIJSRDJD.js → experimental-P5FZM4CU.js} +1 -1
  66. package/dist/instrumentation.js +3 -3
  67. package/dist/nitro.js +6 -6
  68. package/dist/{oauth-callback-server-KYMPJOTC.js → oauth-callback-server-A2YTPVVX.js} +26 -26
  69. package/dist/{runner-3RS2D2ZR.js → runner-VKAEU52J.js} +18 -18
  70. package/dist/{skills-5B3Y6XX6.js → skills-52GMXUTY.js} +5 -5
  71. package/dist/spawn-GSS4EBLR.js +37 -0
  72. package/dist/task-runner-DUGDWF5O.js +32 -0
  73. package/dist/{validation-Q65QD27B.js → validation-VD2YQX2W.js} +5 -5
  74. package/dist/version.js +1 -1
  75. package/dist/{work-DCMQWAAP.js → work-ZWBTGEQP.js} +18 -18
  76. package/dist/worker-XUWD5WS7.js +22 -0
  77. package/package.json +6 -5
  78. package/dist/api/acp/route.d.ts +0 -13
  79. package/dist/spawn-VYARS3DU.js +0 -37
  80. package/dist/task-runner-4IXKKZHL.js +0 -32
  81. package/dist/worker-QL3CHLZL.js +0 -22
@@ -13,24 +13,24 @@ import {
13
13
  getPlugins,
14
14
  setPlugins,
15
15
  validatePlugins
16
- } from "./chunk-D6ZD7VXP.js";
16
+ } from "./chunk-2CEOXDG2.js";
17
17
  import "./chunk-3Y47VMHV.js";
18
- import "./chunk-RNMASWLP.js";
19
- import "./chunk-KKSVCHDO.js";
20
- import "./chunk-KMBU4PJP.js";
21
- import "./chunk-PL57B6NC.js";
18
+ import "./chunk-6TSWXBTQ.js";
19
+ import "./chunk-44BQ3TSK.js";
20
+ import "./chunk-UKIHNBBD.js";
21
+ import "./chunk-Z7ALSQS3.js";
22
22
  import "./chunk-VFUK3X5B.js";
23
- import "./chunk-XYTJUHRZ.js";
24
- import "./chunk-ETJTXYHY.js";
25
- import "./chunk-HEBMSITT.js";
26
- import "./chunk-4IX32NSL.js";
23
+ import "./chunk-LHQK5XCU.js";
24
+ import "./chunk-SVFSYQMT.js";
25
+ import "./chunk-WOIALVN2.js";
26
+ import "./chunk-4DZ62L36.js";
27
27
  import "./chunk-CEMMLV5L.js";
28
28
  import "./chunk-N7TMSOZH.js";
29
29
  import "./chunk-DWPN6SCH.js";
30
30
  import "./chunk-TXKUKMVO.js";
31
- import "./chunk-EBMRB6Z6.js";
31
+ import "./chunk-UQP54CXZ.js";
32
32
  import "./chunk-PEQXYSSE.js";
33
- import "./chunk-TJHSAHQN.js";
33
+ import "./chunk-BZD4ADQH.js";
34
34
  export {
35
35
  PluginHookDeniedError,
36
36
  applyPluginFormatMarkdown,
package/dist/api.js CHANGED
@@ -44,7 +44,6 @@ import {
44
44
  } from "./chunk-CZYNWPWD.js";
45
45
  import {
46
46
  appendAndEnqueueApiConversationMessage,
47
- authenticatePersonalToken,
48
47
  conversationArchiveTimes,
49
48
  conversationArchivedForEmail,
50
49
  conversationArchivedForUser,
@@ -53,22 +52,19 @@ import {
53
52
  conversationNotArchivedForEmail,
54
53
  conversationNotArchivedForUser,
55
54
  createAndEnqueueApiConversation,
56
- createPersonalToken,
57
55
  createVercelAttachmentStorage,
58
56
  formatSlackConversationRedactedLabel,
59
- listPersonalTokens,
60
57
  readConversationAccessFromSql,
61
58
  readHealthReport,
62
59
  resolveSlackConversationContextFromThreadId,
63
- revokePersonalToken,
64
60
  viewerConversationMembership,
65
61
  webActorFromEmail
66
- } from "./chunk-PPYDHUEL.js";
62
+ } from "./chunk-S35OZMSL.js";
67
63
  import {
68
64
  buildSentryConversationUrl,
69
65
  getWebAuthorization
70
- } from "./chunk-EU7KJDOG.js";
71
- import "./chunk-LZOQFC5F.js";
66
+ } from "./chunk-CVBIM4Z3.js";
67
+ import "./chunk-D6OHGAIO.js";
72
68
  import {
73
69
  readTaskExecutionByConversationId,
74
70
  readTaskExecutionDays,
@@ -76,9 +72,9 @@ import {
76
72
  readTaskExecutionSummaries,
77
73
  readTaskExecutions,
78
74
  readTaskRuns
79
- } from "./chunk-GWFRPQNP.js";
75
+ } from "./chunk-QHALFHZA.js";
80
76
  import "./chunk-M3QYTBQ6.js";
81
- import "./chunk-FWILPBVQ.js";
77
+ import "./chunk-PQES5LB5.js";
82
78
  import {
83
79
  healthReportSchema,
84
80
  pluginOperationalReportFeedSchema,
@@ -86,7 +82,7 @@ import {
86
82
  runtimeInfoReportSchema,
87
83
  skillReportsSchema
88
84
  } from "./chunk-UTL3MHPC.js";
89
- import "./chunk-KQZX24QQ.js";
85
+ import "./chunk-DZR3L74W.js";
90
86
  import {
91
87
  deleteEventTask,
92
88
  eventTaskBelongsToUser,
@@ -103,31 +99,31 @@ import {
103
99
  readScheduledTask,
104
100
  readStats,
105
101
  saveScheduledTask
106
- } from "./chunk-3KSSALN4.js";
102
+ } from "./chunk-LB4FWMCV.js";
107
103
  import {
108
104
  parseSlackThreadId
109
- } from "./chunk-TDT2R77B.js";
105
+ } from "./chunk-MJISSOWB.js";
110
106
  import {
111
107
  cancelHumanFacingPendingMessages,
112
108
  getConversation
113
- } from "./chunk-Q2KY27IX.js";
114
- import "./chunk-HJ27A6YB.js";
109
+ } from "./chunk-TEFNHMO2.js";
110
+ import "./chunk-YHL2L2ZZ.js";
115
111
  import {
116
112
  agentTurnUsageSchema,
117
113
  fallbackShortTitle,
118
114
  hasAgentTurnUsage,
119
115
  renderJuniorNativeConversationEvent
120
- } from "./chunk-NQTA72Q3.js";
116
+ } from "./chunk-SXOZIG5X.js";
121
117
  import {
122
118
  getCachedSnapshot
123
- } from "./chunk-IKKETMQC.js";
119
+ } from "./chunk-3ENUMZNG.js";
124
120
  import "./chunk-PDO5BLNM.js";
125
121
  import {
126
122
  getVercelConversationWorkQueue
127
123
  } from "./chunk-DKIJ2RP5.js";
128
124
  import "./chunk-JAL3CH4G.js";
129
125
  import "./chunk-7H2VZTWN.js";
130
- import "./chunk-GPA3ZSYY.js";
126
+ import "./chunk-UUMBHORH.js";
131
127
  import {
132
128
  SANDBOX_RUNTIME,
133
129
  WorkspaceValidationError,
@@ -147,7 +143,7 @@ import {
147
143
  updateWorkspace,
148
144
  withSlackRetries,
149
145
  workspaceRepoCheckoutPath
150
- } from "./chunk-D6ZD7VXP.js";
146
+ } from "./chunk-2CEOXDG2.js";
151
147
  import "./chunk-3Y47VMHV.js";
152
148
  import {
153
149
  decodeStoredConversationEvent,
@@ -157,28 +153,29 @@ import {
157
153
  locationFromRow,
158
154
  parseSessionSource,
159
155
  resolveRootConversationId
160
- } from "./chunk-RNMASWLP.js";
156
+ } from "./chunk-6TSWXBTQ.js";
161
157
  import {
162
158
  conversationReadColumns,
159
+ juniorApiTokens,
163
160
  juniorConversationEvents,
164
161
  juniorConversationParticipants,
165
162
  juniorConversations,
166
163
  juniorIdentities,
167
164
  juniorSchedulerTasks,
168
165
  juniorUsers
169
- } from "./chunk-KKSVCHDO.js";
166
+ } from "./chunk-44BQ3TSK.js";
170
167
  import {
171
168
  create,
172
169
  hash
173
- } from "./chunk-KMBU4PJP.js";
174
- import "./chunk-PL57B6NC.js";
170
+ } from "./chunk-UKIHNBBD.js";
171
+ import "./chunk-Z7ALSQS3.js";
175
172
  import {
176
173
  juniorDestinations
177
174
  } from "./chunk-VFUK3X5B.js";
178
- import "./chunk-XYTJUHRZ.js";
179
- import "./chunk-ETJTXYHY.js";
180
- import "./chunk-HEBMSITT.js";
181
- import "./chunk-4IX32NSL.js";
175
+ import "./chunk-LHQK5XCU.js";
176
+ import "./chunk-SVFSYQMT.js";
177
+ import "./chunk-WOIALVN2.js";
178
+ import "./chunk-4DZ62L36.js";
182
179
  import "./chunk-CEMMLV5L.js";
183
180
  import {
184
181
  parseSlackChannelId,
@@ -190,9 +187,9 @@ import "./chunk-TXKUKMVO.js";
190
187
  import {
191
188
  logException,
192
189
  logWarn
193
- } from "./chunk-EBMRB6Z6.js";
190
+ } from "./chunk-UQP54CXZ.js";
194
191
  import "./chunk-PEQXYSSE.js";
195
- import "./chunk-TJHSAHQN.js";
192
+ import "./chunk-BZD4ADQH.js";
196
193
 
197
194
  // src/api.ts
198
195
  import { Hono as Hono8 } from "hono";
@@ -2789,19 +2786,19 @@ var slackMailboxMetadataSchema = z4.object({
2789
2786
  function isoFromMs(value) {
2790
2787
  return new Date(value).toISOString();
2791
2788
  }
2792
- function actorIdentityFromApiMetadata(metadata) {
2789
+ function actorIdentityFromApiMetadata(metadata2) {
2793
2790
  return {
2794
- email: metadata.authorEmail.trim().toLowerCase(),
2795
- ...metadata.authorFullName ? { fullName: metadata.authorFullName } : void 0
2791
+ email: metadata2.authorEmail.trim().toLowerCase(),
2792
+ ...metadata2.authorFullName ? { fullName: metadata2.authorFullName } : void 0
2796
2793
  };
2797
2794
  }
2798
- async function actorIdentityFromSlackMetadata(metadata, teamId) {
2799
- if (metadata.message.author.isMe === true) return void 0;
2800
- const slackUserId = metadata.message.author.userId.trim();
2795
+ async function actorIdentityFromSlackMetadata(metadata2, teamId) {
2796
+ if (metadata2.message.author.isMe === true) return void 0;
2797
+ const slackUserId = metadata2.message.author.userId.trim();
2801
2798
  if (!slackUserId) return void 0;
2802
2799
  const profile = teamId ? await lookupSlackUser(teamId, slackUserId) : null;
2803
- const slackUserName = profile?.userName?.trim() || metadata.message.author.userName?.trim();
2804
- const fullName = profile?.fullName?.trim() || metadata.message.author.fullName?.trim();
2800
+ const slackUserName = profile?.userName?.trim() || metadata2.message.author.userName?.trim();
2801
+ const fullName = profile?.fullName?.trim() || metadata2.message.author.fullName?.trim();
2805
2802
  const email = profile?.email?.trim().toLowerCase();
2806
2803
  return {
2807
2804
  slackUserId,
@@ -2812,32 +2809,32 @@ async function actorIdentityFromSlackMetadata(metadata, teamId) {
2812
2809
  }
2813
2810
  async function projectPendingMessage(message2, canExposePayload) {
2814
2811
  if (message2.source === "web") {
2815
- const metadata = apiTurnMailboxMetadataSchema.safeParse(
2812
+ const metadata2 = apiTurnMailboxMetadataSchema.safeParse(
2816
2813
  message2.input.metadata
2817
2814
  );
2818
- if (!metadata.success) return void 0;
2815
+ if (!metadata2.success) return void 0;
2819
2816
  const text = message2.input.text.trim();
2820
2817
  if (!text) return void 0;
2821
2818
  return {
2822
2819
  createdAt: isoFromMs(message2.createdAtMs),
2823
2820
  delivery: message2.delivery,
2824
2821
  inboundMessageId: message2.inboundMessageId,
2825
- messageId: metadata.data.messageId,
2822
+ messageId: metadata2.data.messageId,
2826
2823
  receivedAt: isoFromMs(message2.receivedAtMs),
2827
2824
  role: "user",
2828
2825
  source: "web",
2829
2826
  ...canExposePayload ? {
2830
- actorIdentity: actorIdentityFromApiMetadata(metadata.data),
2827
+ actorIdentity: actorIdentityFromApiMetadata(metadata2.data),
2831
2828
  text
2832
2829
  } : { redacted: true }
2833
2830
  };
2834
2831
  }
2835
2832
  if (message2.source === "slack") {
2836
- const metadata = slackMailboxMetadataSchema.safeParse(
2833
+ const metadata2 = slackMailboxMetadataSchema.safeParse(
2837
2834
  message2.input.metadata
2838
2835
  );
2839
- if (!metadata.success) return void 0;
2840
- if (metadata.data.message.author.isMe === true) return void 0;
2836
+ if (!metadata2.success) return void 0;
2837
+ if (metadata2.data.message.author.isMe === true) return void 0;
2841
2838
  const text = message2.input.text.trim();
2842
2839
  if (!text) return void 0;
2843
2840
  if (!canExposePayload) {
@@ -2845,7 +2842,7 @@ async function projectPendingMessage(message2, canExposePayload) {
2845
2842
  createdAt: isoFromMs(message2.createdAtMs),
2846
2843
  delivery: message2.delivery,
2847
2844
  inboundMessageId: message2.inboundMessageId,
2848
- messageId: metadata.data.message.id,
2845
+ messageId: metadata2.data.message.id,
2849
2846
  receivedAt: isoFromMs(message2.receivedAtMs),
2850
2847
  redacted: true,
2851
2848
  role: "user",
@@ -2853,14 +2850,14 @@ async function projectPendingMessage(message2, canExposePayload) {
2853
2850
  };
2854
2851
  }
2855
2852
  const actorIdentity = await actorIdentityFromSlackMetadata(
2856
- metadata.data,
2853
+ metadata2.data,
2857
2854
  message2.destination?.platform === "slack" ? message2.destination.teamId : void 0
2858
2855
  );
2859
2856
  return {
2860
2857
  createdAt: isoFromMs(message2.createdAtMs),
2861
2858
  delivery: message2.delivery,
2862
2859
  inboundMessageId: message2.inboundMessageId,
2863
- messageId: metadata.data.message.id,
2860
+ messageId: metadata2.data.message.id,
2864
2861
  receivedAt: isoFromMs(message2.receivedAtMs),
2865
2862
  role: "user",
2866
2863
  source: "slack",
@@ -4194,7 +4191,7 @@ async function readPeoplePluginReports(args) {
4194
4191
  source: "plugins"
4195
4192
  });
4196
4193
  }
4197
- const { getPluginProfileReports } = await import("./agent-hooks-IQUW6ERD.js");
4194
+ const { getPluginProfileReports } = await import("./agent-hooks-3S25UIHO.js");
4198
4195
  return pluginOperationalReportFeedSchema.parse({
4199
4196
  generatedAt: new Date(nowMs).toISOString(),
4200
4197
  reports: await getPluginProfileReports({
@@ -4523,6 +4520,83 @@ function createPeopleRoutes() {
4523
4520
 
4524
4521
  // src/api/personal-tokens/routes.ts
4525
4522
  import { Hono as Hono4 } from "hono";
4523
+
4524
+ // src/personal-tokens/store.ts
4525
+ import { createHash, randomBytes, randomUUID } from "crypto";
4526
+ import { and as and16, desc as desc6, eq as eq16, gt, isNull as isNull7 } from "drizzle-orm";
4527
+ var TOKEN_PREFIX = "jr_pat_";
4528
+ var TOKEN_SUFFIX_LENGTH = 8;
4529
+ var DEFAULT_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
4530
+ function normalizeEmail2(email) {
4531
+ return email.trim().toLowerCase();
4532
+ }
4533
+ function hashToken(token2) {
4534
+ return createHash("sha256").update(token2, "utf8").digest("hex");
4535
+ }
4536
+ function metadata(row) {
4537
+ return {
4538
+ id: row.id,
4539
+ name: row.name,
4540
+ tokenSuffix: row.tokenSuffix,
4541
+ createdAt: row.createdAt.toISOString(),
4542
+ expiresAt: row.expiresAt.toISOString(),
4543
+ lastUsedAt: row.lastUsedAt?.toISOString() ?? null
4544
+ };
4545
+ }
4546
+ async function createPersonalToken(args) {
4547
+ const now = args.now ?? /* @__PURE__ */ new Date();
4548
+ const token2 = `${TOKEN_PREFIX}${randomBytes(32).toString("base64url")}`;
4549
+ const row = {
4550
+ id: randomUUID(),
4551
+ ownerEmailNormalized: normalizeEmail2(args.email),
4552
+ name: args.name.trim(),
4553
+ tokenHash: hashToken(token2),
4554
+ tokenSuffix: token2.slice(-TOKEN_SUFFIX_LENGTH),
4555
+ createdAt: now,
4556
+ expiresAt: new Date(now.getTime() + DEFAULT_TOKEN_LIFETIME_MS)
4557
+ };
4558
+ await getDb().insert(juniorApiTokens).values(row);
4559
+ return { ...metadata({ ...row, lastUsedAt: null, revokedAt: null }), token: token2 };
4560
+ }
4561
+ async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
4562
+ const rows = await getDb().select().from(juniorApiTokens).where(
4563
+ and16(
4564
+ eq16(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(email)),
4565
+ isNull7(juniorApiTokens.revokedAt),
4566
+ gt(juniorApiTokens.expiresAt, now)
4567
+ )
4568
+ ).orderBy(desc6(juniorApiTokens.createdAt));
4569
+ return rows.map(metadata);
4570
+ }
4571
+ async function revokePersonalToken(args) {
4572
+ const rows = await getDb().update(juniorApiTokens).set({ revokedAt: args.now ?? /* @__PURE__ */ new Date() }).where(
4573
+ and16(
4574
+ eq16(juniorApiTokens.id, args.id),
4575
+ eq16(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(args.email)),
4576
+ isNull7(juniorApiTokens.revokedAt)
4577
+ )
4578
+ ).returning({ id: juniorApiTokens.id });
4579
+ return rows.length > 0;
4580
+ }
4581
+ async function authenticatePersonalToken(token2, now = /* @__PURE__ */ new Date()) {
4582
+ if (!token2.startsWith(TOKEN_PREFIX)) return void 0;
4583
+ const rows = await getDb().select({
4584
+ id: juniorApiTokens.id,
4585
+ ownerEmailNormalized: juniorApiTokens.ownerEmailNormalized
4586
+ }).from(juniorApiTokens).where(
4587
+ and16(
4588
+ eq16(juniorApiTokens.tokenHash, hashToken(token2)),
4589
+ isNull7(juniorApiTokens.revokedAt),
4590
+ gt(juniorApiTokens.expiresAt, now)
4591
+ )
4592
+ ).limit(1);
4593
+ const match = rows[0];
4594
+ if (!match) return void 0;
4595
+ await getDb().update(juniorApiTokens).set({ lastUsedAt: now }).where(eq16(juniorApiTokens.id, match.id));
4596
+ return match.ownerEmailNormalized;
4597
+ }
4598
+
4599
+ // src/api/personal-tokens/routes.ts
4526
4600
  function createPersonalTokenRoutes() {
4527
4601
  const app = new Hono4();
4528
4602
  app.get("/", requireViewer, async (context) => {
@@ -4913,7 +4987,7 @@ function readDescriptionText(home) {
4913
4987
  }
4914
4988
  }
4915
4989
  async function readSkillReports() {
4916
- const { discoverSkills } = await import("./skills-5B3Y6XX6.js");
4990
+ const { discoverSkills } = await import("./skills-52GMXUTY.js");
4917
4991
  const skills = await discoverSkills();
4918
4992
  return skillReportsSchema.parse(
4919
4993
  skills.map((skill) => ({
@@ -4923,7 +4997,7 @@ async function readSkillReports() {
4923
4997
  );
4924
4998
  }
4925
4999
  async function readPlugins() {
4926
- const { pluginCatalogRuntime } = await import("./catalog-runtime-PMQWNIXA.js");
5000
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-ESLMBQBV.js");
4927
5001
  return pluginsSchema.parse(
4928
5002
  pluginCatalogRuntime.getProviders().map((plugin) => ({
4929
5003
  configKeys: plugin.manifest.configKeys ?? [],
@@ -4936,7 +5010,7 @@ async function readPlugins() {
4936
5010
  async function readRuntimeInfoReport() {
4937
5011
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
4938
5012
  import("./discovery-DWVDM7UK.js"),
4939
- import("./catalog-runtime-PMQWNIXA.js"),
5013
+ import("./catalog-runtime-ESLMBQBV.js"),
4940
5014
  readPlugins(),
4941
5015
  readSkillReports()
4942
5016
  ]);
@@ -4952,7 +5026,7 @@ async function readRuntimeInfoReport() {
4952
5026
  }
4953
5027
  async function readPluginOperationalReportFeed() {
4954
5028
  const nowMs = Date.now();
4955
- const { getPluginOperationalReports } = await import("./agent-hooks-IQUW6ERD.js");
5029
+ const { getPluginOperationalReports } = await import("./agent-hooks-3S25UIHO.js");
4956
5030
  return pluginOperationalReportFeedSchema.parse({
4957
5031
  source: "plugins",
4958
5032
  generatedAt: new Date(nowMs).toISOString(),
@@ -0,0 +1,85 @@
1
+ import type { StateAdapter } from "chat";
2
+ import type { PluginRoute, PluginRouteMethod, User } from "@sentry/junior-plugin-api";
3
+ /** Shared state operations available to app adapters. */
4
+ export type JuniorAdapterState = Pick<StateAdapter, "acquireLock" | "appendToList" | "delete" | "extendLock" | "get" | "getList" | "releaseLock" | "set">;
5
+ /** One text Message exposed to an app adapter. */
6
+ export interface AdapterMessage {
7
+ id: string;
8
+ role: "assistant" | "user";
9
+ text: string;
10
+ }
11
+ /** Result of admitting one retry-safe prompt to a Conversation. */
12
+ export type AdapterPromptAdmission = {
13
+ afterCursor: number;
14
+ messageId: string;
15
+ status: "accepted";
16
+ turnId: string;
17
+ } | {
18
+ status: "active";
19
+ } | {
20
+ status: "not_found";
21
+ };
22
+ /** Terminal state for one correlated Conversation Turn. */
23
+ export type AdapterTurnTerminal = {
24
+ outcome: "cancelled" | "completed";
25
+ status: "completed";
26
+ } | {
27
+ failureCode: string;
28
+ status: "failed";
29
+ };
30
+ /** One ordered page of Messages and optional terminal Turn state. */
31
+ export interface AdapterTurnPage {
32
+ cursor: number;
33
+ messages: AdapterMessage[];
34
+ terminal?: AdapterTurnTerminal;
35
+ }
36
+ /** Conversation operations available to app adapters. */
37
+ export interface AdapterConversations {
38
+ cancel(args: {
39
+ conversationId: string;
40
+ user: User;
41
+ }): Promise<"cancelled" | "not_found">;
42
+ create(args: {
43
+ conversationId: string;
44
+ user: User;
45
+ }): Promise<void>;
46
+ hasAccess(args: {
47
+ conversationId: string;
48
+ user: User;
49
+ }): Promise<boolean>;
50
+ prompt(args: {
51
+ conversationId: string;
52
+ idempotencyKey: string;
53
+ text: string;
54
+ user: User;
55
+ }): Promise<AdapterPromptAdmission>;
56
+ readMessages(conversationId: string): Promise<AdapterMessage[]>;
57
+ readTurn(args: {
58
+ afterCursor: number;
59
+ conversationId: string;
60
+ messageId: string;
61
+ turnId: string;
62
+ }): Promise<AdapterTurnPage>;
63
+ }
64
+ /** One dashboard-authenticated HTTP route owned by an app adapter. */
65
+ export interface JuniorAuthenticatedRoute {
66
+ handler(request: Request, user: User): Promise<Response> | Response;
67
+ method?: PluginRouteMethod | readonly PluginRouteMethod[];
68
+ path: string;
69
+ }
70
+ /** Capabilities supplied once when Junior configures an app adapter. */
71
+ export interface JuniorAppAdapterContext {
72
+ agentName: string;
73
+ baseURL?: string;
74
+ conversations: AdapterConversations;
75
+ reportError(error: unknown, event: string, attributes?: Record<string, unknown>): void;
76
+ state: JuniorAdapterState;
77
+ version: string;
78
+ }
79
+ /** HTTP routes returned by one configured app adapter. */
80
+ export interface JuniorAppAdapterRoutes {
81
+ authenticatedRoutes?: readonly JuniorAuthenticatedRoute[];
82
+ routes?: readonly PluginRoute[];
83
+ }
84
+ /** Configure one non-plugin app adapter against Junior's runtime capabilities. */
85
+ export type JuniorAppAdapter = (context: JuniorAppAdapterContext) => JuniorAppAdapterRoutes | Promise<JuniorAppAdapterRoutes>;
package/dist/app.d.ts CHANGED
@@ -4,10 +4,15 @@ import { type SandboxResourceConfig } from "@/chat/sandbox/resources";
4
4
  import { type JuniorPluginSet } from "./plugins";
5
5
  import type { ConversationWorkCallbackOptions } from "@/chat/app/conversation-work";
6
6
  import type { WaitUntilFn } from "@/handlers/types";
7
+ import type { JuniorAppAdapter } from "./app-adapter";
8
+ import { JUNIOR_VERSION } from "./version";
7
9
  export { defineJuniorPlugins } from "./plugins";
8
- export { JUNIOR_VERSION } from "./version";
10
+ export { JUNIOR_VERSION };
9
11
  export type { JuniorPluginInput, JuniorPluginSet, JuniorPluginSetOptions, } from "./plugins";
12
+ export type { AdapterConversations, AdapterMessage, AdapterPromptAdmission, AdapterTurnPage, AdapterTurnTerminal, JuniorAdapterState, JuniorAppAdapter, JuniorAppAdapterContext, JuniorAppAdapterRoutes, JuniorAuthenticatedRoute, } from "./app-adapter";
10
13
  export interface JuniorAppOptions {
14
+ /** Non-plugin adapters mounted against Junior's shared runtime. */
15
+ adapters?: readonly JuniorAppAdapter[];
11
16
  /** Authenticated dashboard mounted by core when configured. */
12
17
  dashboard?: JuniorDashboardOptions;
13
18
  /**