@sentry/junior 0.115.0 → 0.116.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 (111) hide show
  1. package/dist/{agent-hooks-4EUUXP2F.js → agent-hooks-67NFITDH.js} +9 -9
  2. package/dist/api/conversations/detail.d.ts +18 -0
  3. package/dist/api/conversations/event-page.d.ts +1 -1
  4. package/dist/api/conversations/events.d.ts +1 -1
  5. package/dist/api/people/profile.d.ts +2 -2
  6. package/dist/api/people/shared.d.ts +1 -1
  7. package/dist/api/personal-tokens/create.d.ts +11 -0
  8. package/dist/api/personal-tokens/list.d.ts +12 -0
  9. package/dist/api/personal-tokens/revoke.d.ts +5 -0
  10. package/dist/api/personal-tokens/routes.d.ts +4 -0
  11. package/dist/api/plugins.d.ts +0 -1
  12. package/dist/api/route.d.ts +1 -1
  13. package/dist/api/schema/conversation.d.ts +18 -0
  14. package/dist/api/schema/person.d.ts +3 -3
  15. package/dist/api/schema/personal-token.d.ts +38 -0
  16. package/dist/api/schema.d.ts +2 -0
  17. package/dist/api/schema.js +15 -3
  18. package/dist/api.d.ts +1 -0
  19. package/dist/api.js +179 -39
  20. package/dist/app.js +1035 -853
  21. package/dist/{catalog-runtime-Y32UEQLB.js → catalog-runtime-CWZY6GTH.js} +5 -5
  22. package/dist/chat/agent/request.d.ts +1 -0
  23. package/dist/chat/agent/resume.d.ts +1 -0
  24. package/dist/chat/agent/sandbox.d.ts +1 -0
  25. package/dist/chat/agent/tools.d.ts +1 -0
  26. package/dist/chat/agent-dispatch/context.d.ts +2 -0
  27. package/dist/chat/agent-dispatch/heartbeat.d.ts +11 -5
  28. package/dist/chat/agent-dispatch/signing.d.ts +14 -5
  29. package/dist/chat/agent-dispatch/store.d.ts +36 -15
  30. package/dist/chat/agent-dispatch/types.d.ts +23 -10
  31. package/dist/chat/agent-dispatch/work.d.ts +58 -0
  32. package/dist/chat/app/factory.d.ts +12 -3
  33. package/dist/chat/conversations/history.d.ts +285 -290
  34. package/dist/chat/conversations/projection.d.ts +2 -2
  35. package/dist/chat/mcp/tool-manager.d.ts +2 -1
  36. package/dist/chat/pi/conversation-events.d.ts +6 -2
  37. package/dist/chat/plugins/annotations.d.ts +8 -0
  38. package/dist/chat/plugins/registry.d.ts +0 -3
  39. package/dist/chat/plugins/types.d.ts +0 -2
  40. package/dist/chat/runtime/agent-continue-runner.d.ts +4 -0
  41. package/dist/chat/runtime/reply-executor.d.ts +6 -1
  42. package/dist/chat/runtime/slack-resume.d.ts +5 -1
  43. package/dist/chat/runtime/turn-input.d.ts +3 -0
  44. package/dist/chat/sandbox/sandbox.d.ts +2 -1
  45. package/dist/chat/sandbox/session.d.ts +2 -11
  46. package/dist/chat/sandbox/workspace.d.ts +10 -2
  47. package/dist/chat/services/turn-session-record.d.ts +14 -1
  48. package/dist/chat/slack/dispatch-turn.d.ts +25 -0
  49. package/dist/chat/state/turn-session.d.ts +11 -0
  50. package/dist/chat/tool-support/text-range-result.d.ts +3 -0
  51. package/dist/chat/tool-support/zod-tool.d.ts +1 -0
  52. package/dist/chat/tools/definition.d.ts +3 -10
  53. package/dist/chat/tools/query-conversation-events.d.ts +68 -0
  54. package/dist/chat/tools/sandbox/file-utils.d.ts +8 -1
  55. package/dist/chat/tools/sandbox/find-files.d.ts +2 -1
  56. package/dist/chat/tools/sandbox/grep.d.ts +2 -1
  57. package/dist/{chunk-6FKLPVF3.js → chunk-25GU5B5E.js} +1 -1
  58. package/dist/{chunk-PVZHG2XZ.js → chunk-3H45VOBZ.js} +32 -7
  59. package/dist/{chunk-NVUQSFWX.js → chunk-3JOGUT46.js} +3 -15
  60. package/dist/{chunk-G5SX4UPR.js → chunk-4DD6AOCG.js} +2 -2
  61. package/dist/{chunk-67CVNDJ7.js → chunk-53ZKTQO6.js} +1 -1
  62. package/dist/{chunk-43RYMWJ2.js → chunk-5UNB623T.js} +809 -213
  63. package/dist/{chunk-2QG4MZQ7.js → chunk-6RQ5GCWH.js} +2 -2
  64. package/dist/{chunk-MIAKQNYX.js → chunk-6ZK6FZIV.js} +1 -1
  65. package/dist/{chunk-6V762AB4.js → chunk-BXLS3I4W.js} +1 -1
  66. package/dist/{chunk-CWEZEPD4.js → chunk-CI3VK7X5.js} +68 -2
  67. package/dist/{chunk-EW5MLKT5.js → chunk-JZPQ5K4V.js} +1 -55
  68. package/dist/{chunk-HWCQRGLL.js → chunk-KBNDFU6J.js} +105 -37
  69. package/dist/{chunk-FHC4JUSF.js → chunk-MGH5ADQS.js} +1 -2
  70. package/dist/{chunk-TVE25LPW.js → chunk-N7TMYLF2.js} +1 -1
  71. package/dist/{chunk-CEYOL62C.js → chunk-OF5FODBL.js} +120 -20
  72. package/dist/{chunk-6OPTF4BQ.js → chunk-PE44LDDQ.js} +0 -1
  73. package/dist/{chunk-LYA2AB5G.js → chunk-PGKWXHYJ.js} +8 -52
  74. package/dist/{chunk-SYJT7AKB.js → chunk-PZGPCOSD.js} +1 -1
  75. package/dist/{chunk-JQFJO5WH.js → chunk-RXRQJF7Y.js} +74 -17
  76. package/dist/{chunk-G36V2YGB.js → chunk-TC4ZEM2D.js} +33 -1
  77. package/dist/{chunk-AGLQYELI.js → chunk-UEVLIYK5.js} +170 -170
  78. package/dist/{chunk-YCLO7D7M.js → chunk-VKZ6WVAY.js} +77 -26
  79. package/dist/{chunk-RAVKCKXA.js → chunk-VZCSLYCE.js} +20 -5
  80. package/dist/{chunk-SG5WAA7H.js → chunk-WKU7TY22.js} +0 -3
  81. package/dist/cli/chat.js +23 -23
  82. package/dist/cli/check.js +6 -6
  83. package/dist/cli/plugins.js +13 -13
  84. package/dist/cli/snapshot-warmup.js +8 -8
  85. package/dist/cli/upgrade.js +7 -7
  86. package/dist/db/schema/api-tokens.d.ts +160 -0
  87. package/dist/db/schema/conversation-annotations.d.ts +142 -0
  88. package/dist/db/schema.d.ts +305 -1
  89. package/dist/{db-KBSJHAZU.js → db-57FHVGGQ.js} +6 -6
  90. package/dist/handlers/agent-dispatch.d.ts +7 -3
  91. package/dist/instrumentation.js +2 -2
  92. package/dist/nitro.js +5 -5
  93. package/dist/{oauth-callback-server-EYRMJTCS.js → oauth-callback-server-PAQRPXZX.js} +18 -18
  94. package/dist/personal-tokens/store.d.ts +27 -0
  95. package/dist/{plugins-PZMDS7AT.js → plugins-IUJA4VBU.js} +1 -1
  96. package/dist/reporting-schema.d.ts +0 -2
  97. package/dist/{runner-RQGZ5Z2S.js → runner-4ISZYJEX.js} +12 -12
  98. package/dist/{skills-JJQIE3BT.js → skills-UE2KXQMB.js} +6 -6
  99. package/dist/{validation-MZ47PZP5.js → validation-PO5LHTJT.js} +6 -6
  100. package/dist/version.js +1 -1
  101. package/migrations/0008_sticky_rage.sql +14 -0
  102. package/migrations/0009_slippery_harrier.sql +12 -0
  103. package/migrations/0010_native_conversation_history.sql +142 -0
  104. package/migrations/meta/0008_snapshot.json +1076 -0
  105. package/migrations/meta/0009_snapshot.json +1146 -0
  106. package/migrations/meta/0010_snapshot.json +1190 -0
  107. package/migrations/meta/_journal.json +22 -1
  108. package/package.json +6 -7
  109. package/dist/chat/agent-dispatch/runner.d.ts +0 -13
  110. package/dist/chat/capabilities/catalog.d.ts +0 -16
  111. package/dist/{chunk-KNFROR7R.js → chunk-5I6ORJUY.js} +1 -1
package/dist/api.js CHANGED
@@ -14,16 +14,21 @@ import {
14
14
  conversationParamsSchema,
15
15
  conversationReportEventSchema,
16
16
  conversationStatsReportSchema,
17
+ createPersonalTokenBodySchema,
18
+ createdPersonalTokenSchema,
17
19
  locationDetailReportSchema,
18
20
  locationDirectoryReportSchema,
19
21
  locationParamsSchema,
20
- personParamsSchema
21
- } from "./chunk-G36V2YGB.js";
22
+ personParamsSchema,
23
+ personalTokenListSchema,
24
+ personalTokenParamsSchema,
25
+ revokePersonalTokenResponseSchema
26
+ } from "./chunk-TC4ZEM2D.js";
22
27
  import {
23
28
  formatSlackConversationRedactedLabel,
24
29
  readHealthReport,
25
30
  resolveSlackConversationContextFromThreadId
26
- } from "./chunk-G5SX4UPR.js";
31
+ } from "./chunk-4DD6AOCG.js";
27
32
  import {
28
33
  buildSentryConversationUrl
29
34
  } from "./chunk-4CODA7P5.js";
@@ -33,26 +38,29 @@ import {
33
38
  pluginsSchema,
34
39
  runtimeInfoReportSchema,
35
40
  skillReportsSchema
36
- } from "./chunk-6OPTF4BQ.js";
41
+ } from "./chunk-PE44LDDQ.js";
37
42
  import {
38
43
  agentTurnUsageSchema,
39
44
  hasAgentTurnUsage
40
45
  } from "./chunk-MU6HHZEN.js";
41
46
  import "./chunk-PDO5BLNM.js";
42
- import "./chunk-CWEZEPD4.js";
47
+ import {
48
+ listConversationAnnotations
49
+ } from "./chunk-CI3VK7X5.js";
43
50
  import {
44
51
  decodeStoredConversationEvent,
45
52
  getDb,
46
53
  getSqlExecutor
47
- } from "./chunk-HWCQRGLL.js";
54
+ } from "./chunk-KBNDFU6J.js";
48
55
  import {
56
+ juniorApiTokens,
49
57
  juniorConversationEvents,
50
58
  juniorConversations,
51
59
  juniorIdentities,
52
60
  juniorUsers
53
- } from "./chunk-JQFJO5WH.js";
61
+ } from "./chunk-RXRQJF7Y.js";
54
62
  import "./chunk-4ZNGQH7C.js";
55
- import "./chunk-SYJT7AKB.js";
63
+ import "./chunk-PZGPCOSD.js";
56
64
  import {
57
65
  juniorDestinations
58
66
  } from "./chunk-VFUK3X5B.js";
@@ -60,16 +68,16 @@ import {
60
68
  canExposeConversationPayload,
61
69
  parseSlackThreadId
62
70
  } from "./chunk-FXOYURO4.js";
63
- import "./chunk-NVUQSFWX.js";
71
+ import "./chunk-3JOGUT46.js";
64
72
  import "./chunk-OB42YVAE.js";
65
73
  import "./chunk-F3B2YJ76.js";
66
74
  import "./chunk-6GWA276C.js";
67
- import "./chunk-TVE25LPW.js";
68
- import "./chunk-FHC4JUSF.js";
75
+ import "./chunk-N7TMYLF2.js";
76
+ import "./chunk-MGH5ADQS.js";
69
77
  import "./chunk-MLKGABMK.js";
70
78
 
71
79
  // src/api.ts
72
- import { Hono as Hono4 } from "hono";
80
+ import { Hono as Hono5 } from "hono";
73
81
 
74
82
  // src/api/conversations/routes.ts
75
83
  import { Hono } from "hono";
@@ -106,8 +114,8 @@ function parseBody(schema, body) {
106
114
  function defineApiRoute(route) {
107
115
  return route;
108
116
  }
109
- function registerApiRoutes(app, routes5) {
110
- for (const route of routes5) {
117
+ function registerApiRoutes(app, routes6) {
118
+ for (const route of routes6) {
111
119
  app.on(
112
120
  route.method,
113
121
  route.path,
@@ -164,7 +172,7 @@ var archive_default = defineApiRoute({
164
172
 
165
173
  // src/chat/pi/sql-model-usage.ts
166
174
  import { and as and2, eq as eq2, sql } from "drizzle-orm";
167
- var message = sql`${juniorConversationEvents.payload}->'message'`;
175
+ var message = sql`${juniorConversationEvents.payload}`;
168
176
  var usage = sql`${message}->'usage'`;
169
177
  var cost = sql`${usage}->'cost'`;
170
178
  function nonnegativeNumber(source, field, fallbackField, floor = false) {
@@ -264,8 +272,7 @@ async function readConversationModelUsageFromSql(executor, options) {
264
272
  ).where(
265
273
  and2(
266
274
  options.includeDescendants ? eq2(juniorConversations.rootConversationId, options.conversationId) : eq2(juniorConversationEvents.conversationId, options.conversationId),
267
- eq2(juniorConversationEvents.type, "agent_step"),
268
- sql`${message}->>'role' = 'assistant'`,
275
+ eq2(juniorConversationEvents.type, "assistant_message"),
269
276
  sql`jsonb_typeof(${message}->'provider') = 'string'`,
270
277
  sql`jsonb_typeof(${message}->'model') = 'string'`,
271
278
  sql`coalesce(${message}->>'provider', '') <> ''`,
@@ -342,7 +349,8 @@ import { z as z2 } from "zod";
342
349
  var conversationReportSourceEventTypes = [
343
350
  "message",
344
351
  "message_handled",
345
- "agent_step",
352
+ "assistant_message",
353
+ "tool_result",
346
354
  "tool_execution_started",
347
355
  "turn_started",
348
356
  "turn_routed",
@@ -354,7 +362,7 @@ var conversationReportSourceEventTypes = [
354
362
  "subagent_ended"
355
363
  ];
356
364
  var reportingAssistantMessageSchema = z2.object({
357
- role: z2.literal("assistant"),
365
+ type: z2.literal("assistant_message"),
358
366
  content: z2.array(z2.unknown())
359
367
  }).passthrough();
360
368
  var reportingToolCallPartSchema = z2.object({
@@ -364,7 +372,7 @@ var reportingToolCallPartSchema = z2.object({
364
372
  arguments: z2.unknown()
365
373
  }).passthrough();
366
374
  var reportingToolResultMessageSchema = z2.object({
367
- role: z2.literal("toolResult"),
375
+ type: z2.literal("tool_result"),
368
376
  toolCallId: z2.string().min(1),
369
377
  toolName: z2.string().min(1).optional(),
370
378
  name: z2.string().min(1).optional(),
@@ -447,10 +455,7 @@ function conversationReportToolResultIds(events) {
447
455
  return [
448
456
  ...new Set(
449
457
  events.flatMap((event) => {
450
- if (event.data.type !== "agent_step") return [];
451
- const result = reportingToolResultMessageSchema.safeParse(
452
- event.data.message
453
- );
458
+ const result = reportingToolResultMessageSchema.safeParse(event.data);
454
459
  return result.success ? [result.data.toolCallId] : [];
455
460
  })
456
461
  )
@@ -540,20 +545,18 @@ function projectConversationReportEventPage(args) {
540
545
  const projected = [];
541
546
  for (const event of args.events) {
542
547
  let data;
543
- if (event.data.type === "agent_step") {
548
+ if (event.data.type === "assistant_message" || event.data.type === "tool_result") {
544
549
  const reportArgs = {
545
550
  canExposePayload: args.canExposePayload,
546
551
  createdAtMs: event.createdAtMs,
547
- message: event.data.message,
552
+ message: event.data,
548
553
  seq: event.seq
549
554
  };
550
- const result = reportingToolResultMessageSchema.safeParse(
551
- event.data.message
552
- );
555
+ const result = reportingToolResultMessageSchema.safeParse(event.data);
553
556
  const start = result.success ? toolStarts.get(result.data.toolCallId) : void 0;
554
557
  data = reportToolCalls(reportArgs) ?? reportToolResult({
555
558
  canExposePayload: args.canExposePayload,
556
- message: event.data.message,
559
+ message: event.data,
557
560
  ...start && start.seq < event.seq ? { start } : {}
558
561
  });
559
562
  } else if (event.data.type === "tool_execution_started") {
@@ -1211,6 +1214,7 @@ function projectConversationDetail(args) {
1211
1214
  ...args.locationId ? { locationId: args.locationId } : {},
1212
1215
  usage: args.usage
1213
1216
  }),
1217
+ annotations: canExposePayload ? args.annotations : [],
1214
1218
  events: args.events,
1215
1219
  ...args.previousSeq !== void 0 ? {
1216
1220
  previousCursor: encodeConversationCursor({
@@ -1232,12 +1236,13 @@ async function readConversationDetailFromSql(conversationId, options) {
1232
1236
  if (!record) return void 0;
1233
1237
  const executor = getSqlExecutor();
1234
1238
  const includeDescendantMetrics = record.rootConversationId === conversationId;
1235
- const [accessByConversation, modelUsage, metricsByRoot] = await Promise.all([
1239
+ const [accessByConversation, annotations, modelUsage, metricsByRoot] = await Promise.all([
1236
1240
  readConversationAccessFromSql(
1237
1241
  getDb(),
1238
1242
  [conversationId],
1239
1243
  options.verifiedViewerEmail
1240
1244
  ),
1245
+ listConversationAnnotations(getDb(), conversationId),
1241
1246
  record.conversation.transcriptPurgedAtMs === void 0 ? readConversationModelUsageFromSql(executor, {
1242
1247
  conversationId,
1243
1248
  includeDescendants: includeDescendantMetrics
@@ -1257,6 +1262,7 @@ async function readConversationDetailFromSql(conversationId, options) {
1257
1262
  return projectConversationDetail({
1258
1263
  ...record,
1259
1264
  access,
1265
+ annotations,
1260
1266
  durationMs: metrics?.durationMs ?? record.durationMs,
1261
1267
  events: page.events,
1262
1268
  modelUsage,
@@ -1671,7 +1677,7 @@ function readDescriptionText(home) {
1671
1677
  }
1672
1678
  }
1673
1679
  async function readSkillReports() {
1674
- const { discoverSkills } = await import("./skills-JJQIE3BT.js");
1680
+ const { discoverSkills } = await import("./skills-UE2KXQMB.js");
1675
1681
  const skills = await discoverSkills();
1676
1682
  return skillReportsSchema.parse(
1677
1683
  skills.map((skill) => ({
@@ -1681,10 +1687,9 @@ async function readSkillReports() {
1681
1687
  );
1682
1688
  }
1683
1689
  async function readPlugins() {
1684
- const { pluginCatalogRuntime } = await import("./catalog-runtime-Y32UEQLB.js");
1690
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-CWZY6GTH.js");
1685
1691
  return pluginsSchema.parse(
1686
1692
  pluginCatalogRuntime.getProviders().map((plugin) => ({
1687
- capabilities: plugin.manifest.capabilities ?? [],
1688
1693
  configKeys: plugin.manifest.configKeys ?? [],
1689
1694
  description: plugin.manifest.description,
1690
1695
  displayName: plugin.manifest.displayName,
@@ -1695,7 +1700,7 @@ async function readPlugins() {
1695
1700
  async function readRuntimeInfoReport() {
1696
1701
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
1697
1702
  import("./discovery-RMHYSRL7.js"),
1698
- import("./catalog-runtime-Y32UEQLB.js"),
1703
+ import("./catalog-runtime-CWZY6GTH.js"),
1699
1704
  readPlugins(),
1700
1705
  readSkillReports()
1701
1706
  ]);
@@ -1711,7 +1716,7 @@ async function readRuntimeInfoReport() {
1711
1716
  }
1712
1717
  async function readPluginOperationalReportFeed() {
1713
1718
  const nowMs = Date.now();
1714
- const { getPluginOperationalReports } = await import("./agent-hooks-4EUUXP2F.js");
1719
+ const { getPluginOperationalReports } = await import("./agent-hooks-67NFITDH.js");
1715
1720
  return pluginOperationalReportFeedSchema.parse({
1716
1721
  source: "plugins",
1717
1722
  generatedAt: new Date(nowMs).toISOString(),
@@ -2648,6 +2653,139 @@ var plugin_reports_default = defineApiRoute({
2648
2653
  handler: readPluginOperationalReportFeed
2649
2654
  });
2650
2655
 
2656
+ // src/api/personal-tokens/routes.ts
2657
+ import { Hono as Hono4 } from "hono";
2658
+
2659
+ // src/personal-tokens/store.ts
2660
+ import { createHash, randomBytes, randomUUID } from "crypto";
2661
+ import { and as and11, desc as desc5, eq as eq12, gt, isNull as isNull6 } from "drizzle-orm";
2662
+ var TOKEN_PREFIX = "jr_pat_";
2663
+ var TOKEN_SUFFIX_LENGTH = 8;
2664
+ var DEFAULT_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
2665
+ function normalizeEmail2(email) {
2666
+ return email.trim().toLowerCase();
2667
+ }
2668
+ function hashToken(token2) {
2669
+ return createHash("sha256").update(token2, "utf8").digest("hex");
2670
+ }
2671
+ function metadata(row) {
2672
+ return {
2673
+ id: row.id,
2674
+ name: row.name,
2675
+ tokenSuffix: row.tokenSuffix,
2676
+ createdAt: row.createdAt.toISOString(),
2677
+ expiresAt: row.expiresAt.toISOString(),
2678
+ lastUsedAt: row.lastUsedAt?.toISOString() ?? null
2679
+ };
2680
+ }
2681
+ async function createPersonalToken(args) {
2682
+ const now = args.now ?? /* @__PURE__ */ new Date();
2683
+ const token2 = `${TOKEN_PREFIX}${randomBytes(32).toString("base64url")}`;
2684
+ const row = {
2685
+ id: randomUUID(),
2686
+ ownerEmailNormalized: normalizeEmail2(args.email),
2687
+ name: args.name.trim(),
2688
+ tokenHash: hashToken(token2),
2689
+ tokenSuffix: token2.slice(-TOKEN_SUFFIX_LENGTH),
2690
+ createdAt: now,
2691
+ expiresAt: new Date(now.getTime() + DEFAULT_TOKEN_LIFETIME_MS)
2692
+ };
2693
+ await getDb().insert(juniorApiTokens).values(row);
2694
+ return { ...metadata({ ...row, lastUsedAt: null, revokedAt: null }), token: token2 };
2695
+ }
2696
+ async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
2697
+ const rows = await getDb().select().from(juniorApiTokens).where(
2698
+ and11(
2699
+ eq12(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(email)),
2700
+ isNull6(juniorApiTokens.revokedAt),
2701
+ gt(juniorApiTokens.expiresAt, now)
2702
+ )
2703
+ ).orderBy(desc5(juniorApiTokens.createdAt));
2704
+ return rows.map(metadata);
2705
+ }
2706
+ async function revokePersonalToken(args) {
2707
+ const rows = await getDb().update(juniorApiTokens).set({ revokedAt: args.now ?? /* @__PURE__ */ new Date() }).where(
2708
+ and11(
2709
+ eq12(juniorApiTokens.id, args.id),
2710
+ eq12(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(args.email)),
2711
+ isNull6(juniorApiTokens.revokedAt)
2712
+ )
2713
+ ).returning({ id: juniorApiTokens.id });
2714
+ return rows.length > 0;
2715
+ }
2716
+ async function authenticatePersonalToken(token2, now = /* @__PURE__ */ new Date()) {
2717
+ if (!token2.startsWith(TOKEN_PREFIX)) return void 0;
2718
+ const rows = await getDb().select({
2719
+ id: juniorApiTokens.id,
2720
+ ownerEmailNormalized: juniorApiTokens.ownerEmailNormalized
2721
+ }).from(juniorApiTokens).where(
2722
+ and11(
2723
+ eq12(juniorApiTokens.tokenHash, hashToken(token2)),
2724
+ isNull6(juniorApiTokens.revokedAt),
2725
+ gt(juniorApiTokens.expiresAt, now)
2726
+ )
2727
+ ).limit(1);
2728
+ const match = rows[0];
2729
+ if (!match) return void 0;
2730
+ await getDb().update(juniorApiTokens).set({ lastUsedAt: now }).where(eq12(juniorApiTokens.id, match.id));
2731
+ return match.ownerEmailNormalized;
2732
+ }
2733
+
2734
+ // src/api/personal-tokens/create.ts
2735
+ var create_default = defineApiRoute({
2736
+ method: "post",
2737
+ path: "/",
2738
+ responseSchema: createdPersonalTokenSchema,
2739
+ handler: async (c) => {
2740
+ const email = c.get("verifiedViewerEmail");
2741
+ if (!email) throwApiError(403, "Verified viewer email required.");
2742
+ let input;
2743
+ try {
2744
+ input = await c.req.json();
2745
+ } catch (error) {
2746
+ throwApiError(400, "Invalid request body.", error);
2747
+ }
2748
+ const body = parseBody(createPersonalTokenBodySchema, input);
2749
+ return createPersonalToken({ email, name: body.name });
2750
+ }
2751
+ });
2752
+
2753
+ // src/api/personal-tokens/list.ts
2754
+ var list_default4 = defineApiRoute({
2755
+ method: "get",
2756
+ path: "/",
2757
+ responseSchema: personalTokenListSchema,
2758
+ handler: async (c) => {
2759
+ const email = c.get("verifiedViewerEmail");
2760
+ if (!email) throwApiError(403, "Verified viewer email required.");
2761
+ return { tokens: await listPersonalTokens(email) };
2762
+ }
2763
+ });
2764
+
2765
+ // src/api/personal-tokens/revoke.ts
2766
+ var revoke_default = defineApiRoute({
2767
+ method: "delete",
2768
+ path: "/:id",
2769
+ responseSchema: revokePersonalTokenResponseSchema,
2770
+ handler: async (c) => {
2771
+ const email = c.get("verifiedViewerEmail");
2772
+ if (!email) throwApiError(403, "Verified viewer email required.");
2773
+ const { id } = parseParams(personalTokenParamsSchema, c.req.param());
2774
+ if (!await revokePersonalToken({ email, id })) {
2775
+ throwApiError(404, "Personal API token not found.");
2776
+ }
2777
+ return { revoked: true };
2778
+ }
2779
+ });
2780
+
2781
+ // src/api/personal-tokens/routes.ts
2782
+ var routes4 = [list_default4, create_default, revoke_default];
2783
+ function createPersonalTokenRoutes() {
2784
+ const app = new Hono4();
2785
+ registerApiRoutes(app, routes4);
2786
+ return app;
2787
+ }
2788
+
2651
2789
  // src/api/plugins.ts
2652
2790
  var plugins_default = defineApiRoute({
2653
2791
  method: "get",
@@ -2673,7 +2811,7 @@ var skills_default = defineApiRoute({
2673
2811
  });
2674
2812
 
2675
2813
  // src/api.ts
2676
- var routes4 = [
2814
+ var routes5 = [
2677
2815
  health_default,
2678
2816
  runtime_default,
2679
2817
  plugins_default,
@@ -2681,9 +2819,10 @@ var routes4 = [
2681
2819
  plugin_reports_default
2682
2820
  ];
2683
2821
  function createJuniorApi() {
2684
- const app = new Hono4();
2685
- registerApiRoutes(app, routes4);
2822
+ const app = new Hono5();
2823
+ registerApiRoutes(app, routes5);
2686
2824
  app.route("/api/conversations", createConversationRoutes());
2825
+ app.route("/api/personal-tokens", createPersonalTokenRoutes());
2687
2826
  app.route("/api/people", createPeopleRoutes());
2688
2827
  app.route("/api/locations", createLocationRoutes());
2689
2828
  app.notFound(
@@ -2698,6 +2837,7 @@ function createJuniorApi() {
2698
2837
  return app;
2699
2838
  }
2700
2839
  export {
2840
+ authenticatePersonalToken,
2701
2841
  createJuniorApi,
2702
2842
  jsonResponse
2703
2843
  };