@sentry/junior 0.153.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.
Files changed (83) hide show
  1. package/dist/{agent-hooks-7BWOB7SN.js → agent-hooks-AWVTLAV2.js} +11 -12
  2. package/dist/api/conversations/list.d.ts +5 -3
  3. package/dist/api/conversations/membership.d.ts +16 -0
  4. package/dist/api/locations/detail.d.ts +1 -0
  5. package/dist/api/schema/conversation.d.ts +3 -0
  6. package/dist/api/schema/location.d.ts +1 -0
  7. package/dist/api/schema/person.d.ts +1 -0
  8. package/dist/api/schema.js +1 -1
  9. package/dist/api.js +318 -187
  10. package/dist/app.js +39 -39
  11. package/dist/catalog-runtime-V6YD6KH5.js +16 -0
  12. package/dist/chat/conversations/sql/event-actor.d.ts +14 -0
  13. package/dist/chat/conversations/sql/event-lock.d.ts +1 -1
  14. package/dist/chat/conversations/sql/participants.d.ts +17 -0
  15. package/dist/chat/plugins/unfinished-work.d.ts +2 -0
  16. package/dist/chat/runtime/agent-runner.d.ts +2 -0
  17. package/dist/chat/runtime/slack-resume.d.ts +1 -1
  18. package/dist/chat/state/conversation.d.ts +1 -0
  19. package/dist/{chunk-O2YXWWPM.js → chunk-2AHVM3HK.js} +92 -9
  20. package/dist/{chunk-VXWTGOLW.js → chunk-2WLJDM23.js} +1 -1
  21. package/dist/{chunk-4TWLKHOM.js → chunk-37G5HJ2X.js} +4 -4
  22. package/dist/{chunk-ISEROVYZ.js → chunk-4K5N6HTX.js} +5 -5
  23. package/dist/{chunk-ET54Q4TD.js → chunk-773XC7P4.js} +116 -82
  24. package/dist/{chunk-HUO3UTAQ.js → chunk-7MA4HV4W.js} +1 -1
  25. package/dist/{chunk-HMU2QP5M.js → chunk-7NYEB2TM.js} +1 -1
  26. package/dist/{chunk-URFV5RWN.js → chunk-AENPRXCG.js} +23 -56
  27. package/dist/{chunk-TIV3PX5H.js → chunk-APHDJYN7.js} +2 -2
  28. package/dist/{chunk-RUIXF3YQ.js → chunk-BDUENQD3.js} +1 -1
  29. package/dist/{chunk-5TXDKTET.js → chunk-CPQBTTI6.js} +7 -7
  30. package/dist/{chunk-A5SROS6H.js → chunk-ELOTIL5F.js} +5 -5
  31. package/dist/{chunk-JJAMURMR.js → chunk-EORR34UB.js} +1 -1
  32. package/dist/{chunk-5QBK3QHJ.js → chunk-J2SYI36O.js} +6 -8
  33. package/dist/{chunk-K4LK6KYO.js → chunk-J7MWZFFP.js} +4 -4
  34. package/dist/{chunk-COC65LIW.js → chunk-JFZBGFNX.js} +3 -1
  35. package/dist/{chunk-YECBSG77.js → chunk-JIC33O5L.js} +2 -2
  36. package/dist/{chunk-XAYXN4EG.js → chunk-JJX77MB7.js} +366 -138
  37. package/dist/{chunk-FLEY546A.js → chunk-KBT2I5ER.js} +7 -7
  38. package/dist/{chunk-37LMRT7G.js → chunk-KTVHAHUV.js} +1 -1
  39. package/dist/{chunk-PMJAY6JS.js → chunk-LQT3SWFA.js} +5 -5
  40. package/dist/{chunk-HYEAR6HL.js → chunk-MLBH7J7J.js} +1 -1
  41. package/dist/{chunk-5DMPHA4V.js → chunk-NKFRRZIT.js} +27 -37
  42. package/dist/{chunk-HOK7MEWG.js → chunk-NWSKFYOH.js} +1 -1
  43. package/dist/{chunk-JY2HJYJT.js → chunk-RN3AWYEP.js} +2 -2
  44. package/dist/{chunk-RKW5QGGN.js → chunk-RQ62VKM7.js} +1 -1
  45. package/dist/{chunk-XQPKMLRI.js → chunk-SDRJ2LE3.js} +1 -1
  46. package/dist/{chunk-JAJVUQV7.js → chunk-TKJ7277U.js} +3 -3
  47. package/dist/{chunk-EPOA52SD.js → chunk-TVXAN43I.js} +1 -1
  48. package/dist/{chunk-2NS3ACHB.js → chunk-UWTXAYBP.js} +11 -11
  49. package/dist/{chunk-2J4VCHRX.js → chunk-V57LZDHN.js} +8 -10
  50. package/dist/{chunk-HZF5P5UN.js → chunk-V7YE4WCP.js} +58 -7
  51. package/dist/{chunk-PGJBNO3I.js → chunk-XFZLQANQ.js} +2 -2
  52. package/dist/{chunk-5XBRH3N7.js → chunk-Y6MVGU7L.js} +12 -11
  53. package/dist/{chunk-WTKAALLV.js → chunk-Y7ZUBP2K.js} +6 -6
  54. package/dist/{chunk-UG5UCHHJ.js → chunk-ZLSFOSDK.js} +2 -1
  55. package/dist/cli/chat.js +36 -36
  56. package/dist/cli/check.js +8 -9
  57. package/dist/cli/init.js +41 -7
  58. package/dist/cli/plugins.js +15 -16
  59. package/dist/cli/snapshot-create.js +11 -12
  60. package/dist/cli/upgrade.js +9 -10
  61. package/dist/db/schema/conversation-events.d.ts +20 -0
  62. package/dist/db/schema/conversation-participants.d.ts +63 -0
  63. package/dist/db/schema.d.ts +77 -1
  64. package/dist/{db-QNQM5YRR.js → db-WT7P56AH.js} +8 -8
  65. package/dist/instrumentation.js +4 -4
  66. package/dist/nitro.js +2 -2
  67. package/dist/{oauth-callback-server-ERQPIR27.js → oauth-callback-server-R2PK2MCA.js} +26 -26
  68. package/dist/{runner-BX46SQIE.js → runner-O7YYUIHT.js} +15 -16
  69. package/dist/{sandbox-egress-signals-EKPAVWQL.js → sandbox-egress-signals-U3ZX7C5W.js} +3 -4
  70. package/dist/{skills-JL44EIRX.js → skills-S6HLQRH7.js} +8 -9
  71. package/dist/spawn-B4SBFFA2.js +37 -0
  72. package/dist/{validation-UU2AIJIY.js → validation-46WD2OAR.js} +8 -9
  73. package/dist/version.js +1 -1
  74. package/dist/{work-SS7RU5CH.js → work-YT5QUBS3.js} +20 -21
  75. package/dist/worker-4C5BEDWN.js +24 -0
  76. package/migrations/0026_conversation_event_actor_and_participants.sql +140 -0
  77. package/migrations/meta/0026_snapshot.json +2424 -0
  78. package/migrations/meta/_journal.json +7 -0
  79. package/package.json +8 -6
  80. package/dist/catalog-runtime-CGUDNL3D.js +0 -17
  81. package/dist/chunk-F3B2YJ76.js +0 -57
  82. package/dist/spawn-W6FO32T4.js +0 -38
  83. package/dist/worker-5P2E7LVI.js +0 -25
package/dist/api.js CHANGED
@@ -33,7 +33,7 @@ import {
33
33
  taskListSchema,
34
34
  taskParamsSchema,
35
35
  taskRunListSchema
36
- } from "./chunk-UG5UCHHJ.js";
36
+ } from "./chunk-ZLSFOSDK.js";
37
37
  import {
38
38
  appendAndEnqueueApiConversationMessage,
39
39
  createAndEnqueueApiConversation,
@@ -42,14 +42,14 @@ import {
42
42
  readHealthReport,
43
43
  resolveSlackConversationContextFromThreadId,
44
44
  webActorFromEmail
45
- } from "./chunk-5XBRH3N7.js";
45
+ } from "./chunk-Y6MVGU7L.js";
46
46
  import {
47
47
  buildSentryConversationUrl,
48
48
  getWebAuthorization
49
- } from "./chunk-37LMRT7G.js";
49
+ } from "./chunk-KTVHAHUV.js";
50
50
  import {
51
51
  getConversation
52
- } from "./chunk-A5SROS6H.js";
52
+ } from "./chunk-ELOTIL5F.js";
53
53
  import {
54
54
  readTaskExecutionByConversationId,
55
55
  readTaskExecutionDays,
@@ -57,8 +57,8 @@ import {
57
57
  readTaskExecutionSummaries,
58
58
  readTaskExecutions,
59
59
  readTaskRuns
60
- } from "./chunk-2NS3ACHB.js";
61
- import "./chunk-ISEROVYZ.js";
60
+ } from "./chunk-UWTXAYBP.js";
61
+ import "./chunk-4K5N6HTX.js";
62
62
  import {
63
63
  healthReportSchema,
64
64
  pluginOperationalReportFeedSchema,
@@ -82,16 +82,16 @@ import {
82
82
  listPublicEventTasksForTeams,
83
83
  listPublicScheduledTasksForTeams,
84
84
  readStats
85
- } from "./chunk-PMJAY6JS.js";
85
+ } from "./chunk-LQT3SWFA.js";
86
86
  import {
87
87
  parseSlackThreadId
88
- } from "./chunk-TIV3PX5H.js";
88
+ } from "./chunk-APHDJYN7.js";
89
89
  import {
90
90
  agentTurnUsageSchema,
91
91
  fallbackShortTitle,
92
92
  hasAgentTurnUsage,
93
93
  renderJuniorNativeConversationEvent
94
- } from "./chunk-5QBK3QHJ.js";
94
+ } from "./chunk-J2SYI36O.js";
95
95
  import "./chunk-3Y47VMHV.js";
96
96
  import "./chunk-PDO5BLNM.js";
97
97
  import {
@@ -101,11 +101,11 @@ import {
101
101
  renderPluginConversationEvent,
102
102
  resolveViewerUser,
103
103
  updateViewerDisplayName
104
- } from "./chunk-2J4VCHRX.js";
104
+ } from "./chunk-V57LZDHN.js";
105
105
  import {
106
106
  getSlackClient,
107
107
  withSlackRetries
108
- } from "./chunk-JAJVUQV7.js";
108
+ } from "./chunk-TKJ7277U.js";
109
109
  import {
110
110
  decodeStoredConversationEvent,
111
111
  getConversationStore,
@@ -113,36 +113,37 @@ import {
113
113
  getSqlExecutor,
114
114
  locationFromRow,
115
115
  parseSessionSource
116
- } from "./chunk-XAYXN4EG.js";
116
+ } from "./chunk-JJX77MB7.js";
117
117
  import {
118
118
  juniorApiTokens,
119
119
  juniorConversationEvents,
120
+ juniorConversationParticipants,
120
121
  juniorConversations,
121
122
  juniorIdentities,
122
123
  juniorUsers
123
- } from "./chunk-ET54Q4TD.js";
124
+ } from "./chunk-773XC7P4.js";
124
125
  import "./chunk-EM225ITJ.js";
125
- import "./chunk-XQPKMLRI.js";
126
- import "./chunk-PGJBNO3I.js";
126
+ import "./chunk-SDRJ2LE3.js";
127
+ import "./chunk-XFZLQANQ.js";
127
128
  import {
128
129
  juniorDestinations
129
130
  } from "./chunk-VFUK3X5B.js";
130
131
  import {
131
132
  canExposeConversationPayload
132
- } from "./chunk-VXWTGOLW.js";
133
- import "./chunk-RUIXF3YQ.js";
134
- import "./chunk-HZF5P5UN.js";
133
+ } from "./chunk-2WLJDM23.js";
134
+ import "./chunk-BDUENQD3.js";
135
135
  import {
136
136
  parseSlackChannelId,
137
137
  parseSlackMessageTs,
138
138
  parseSlackTeamId
139
- } from "./chunk-F3B2YJ76.js";
139
+ } from "./chunk-V7YE4WCP.js";
140
140
  import {
141
- logException
142
- } from "./chunk-HMU2QP5M.js";
141
+ logException,
142
+ logWarn
143
+ } from "./chunk-7NYEB2TM.js";
143
144
  import "./chunk-6GWA276C.js";
144
- import "./chunk-JJAMURMR.js";
145
- import "./chunk-COC65LIW.js";
145
+ import "./chunk-EORR34UB.js";
146
+ import "./chunk-JFZBGFNX.js";
146
147
  import "./chunk-MLKGABMK.js";
147
148
 
148
149
  // src/api.ts
@@ -227,8 +228,66 @@ async function archiveConversation(conversationId, body) {
227
228
  }
228
229
 
229
230
  // src/api/conversations/access.ts
230
- import { eq as eq2, inArray } from "drizzle-orm";
231
+ import { eq as eq3, inArray as inArray2 } from "drizzle-orm";
231
232
  import { alias } from "drizzle-orm/pg-core";
233
+
234
+ // src/api/conversations/membership.ts
235
+ import { and as and2, eq as eq2, exists, inArray, or } from "drizzle-orm";
236
+ function conversationHasParticipantUser(userId) {
237
+ const participant = getDb().select({
238
+ rootConversationId: juniorConversationParticipants.rootConversationId
239
+ }).from(juniorConversationParticipants).where(
240
+ and2(
241
+ eq2(
242
+ juniorConversationParticipants.rootConversationId,
243
+ juniorConversations.conversationId
244
+ ),
245
+ eq2(juniorConversationParticipants.userId, userId)
246
+ )
247
+ );
248
+ return exists(participant);
249
+ }
250
+ function conversationHasParticipantEmail(email) {
251
+ const participant = getDb().select({
252
+ rootConversationId: juniorConversationParticipants.rootConversationId
253
+ }).from(juniorConversationParticipants).innerJoin(
254
+ juniorUsers,
255
+ eq2(juniorUsers.id, juniorConversationParticipants.userId)
256
+ ).where(
257
+ and2(
258
+ eq2(
259
+ juniorConversationParticipants.rootConversationId,
260
+ juniorConversations.conversationId
261
+ ),
262
+ eq2(juniorUsers.primaryEmailNormalized, email)
263
+ )
264
+ );
265
+ return exists(participant);
266
+ }
267
+ function viewerConversationMembership(args) {
268
+ if (args.actorMatch && args.participantMatch) {
269
+ return or(args.actorMatch, args.participantMatch);
270
+ }
271
+ return args.actorMatch ?? args.participantMatch;
272
+ }
273
+ async function conversationIdsWithParticipantUser(db, conversationIds, userId) {
274
+ if (conversationIds.length === 0) {
275
+ return /* @__PURE__ */ new Set();
276
+ }
277
+ const rows = await db.select({
278
+ rootConversationId: juniorConversationParticipants.rootConversationId
279
+ }).from(juniorConversationParticipants).where(
280
+ and2(
281
+ eq2(juniorConversationParticipants.userId, userId),
282
+ inArray(juniorConversationParticipants.rootConversationId, [
283
+ ...conversationIds
284
+ ])
285
+ )
286
+ );
287
+ return new Set(rows.map((row) => row.rootConversationId));
288
+ }
289
+
290
+ // src/api/conversations/access.ts
232
291
  var rootConversation = alias(juniorConversations, "access_root_conversation");
233
292
  var rootDestination = alias(juniorDestinations, "access_root_destination");
234
293
  var rootIdentity = alias(juniorIdentities, "access_root_identity");
@@ -248,23 +307,37 @@ async function readConversationAccessFromSql(db, conversationIds, viewer) {
248
307
  rootUserId: rootIdentity.userId
249
308
  }).from(juniorConversations).leftJoin(
250
309
  rootConversation,
251
- eq2(
310
+ eq3(
252
311
  rootConversation.conversationId,
253
312
  juniorConversations.rootConversationId
254
313
  )
255
314
  ).leftJoin(
256
315
  rootDestination,
257
- eq2(rootDestination.id, rootConversation.destinationId)
316
+ eq3(rootDestination.id, rootConversation.destinationId)
258
317
  ).leftJoin(
259
318
  rootIdentity,
260
- eq2(rootIdentity.id, rootConversation.actorIdentityId)
261
- ).where(inArray(juniorConversations.conversationId, [...conversationIds]));
319
+ eq3(rootIdentity.id, rootConversation.actorIdentityId)
320
+ ).where(inArray2(juniorConversations.conversationId, [...conversationIds]));
321
+ const membershipConversationIds = /* @__PURE__ */ new Set();
322
+ for (const row of rows) {
323
+ membershipConversationIds.add(row.conversationId);
324
+ if (row.storedRootConversationId) {
325
+ membershipConversationIds.add(row.storedRootConversationId);
326
+ }
327
+ }
328
+ const participantRootIds = viewer !== void 0 ? await conversationIdsWithParticipantUser(
329
+ db,
330
+ [...membershipConversationIds],
331
+ viewer.id
332
+ ) : /* @__PURE__ */ new Set();
262
333
  return new Map(
263
334
  rows.map((row) => {
264
335
  const hasValidRoot = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId);
265
336
  const validRootConversationId = hasValidRoot ? row.rootConversationId ?? void 0 : void 0;
266
337
  const visibility = validRootConversationId === void 0 ? null : row.visibility;
267
- const isParticipant = validRootConversationId !== void 0 && viewer !== void 0 && (row.rootUserId === viewer.id || normalizedViewerEmail !== void 0 && row.rootEmailVerified === true && row.rootEmailNormalized === normalizedViewerEmail);
338
+ const isRootActor = validRootConversationId !== void 0 && viewer !== void 0 && (row.rootUserId === viewer.id || normalizedViewerEmail !== void 0 && row.rootEmailVerified === true && row.rootEmailNormalized === normalizedViewerEmail);
339
+ const isMaterializedParticipant = participantRootIds.has(row.conversationId) || validRootConversationId !== void 0 && participantRootIds.has(validRootConversationId);
340
+ const isParticipant = isRootActor || isMaterializedParticipant;
268
341
  const canViewPrivateContent = isParticipant || validRootConversationId !== void 0 && canExposeConversationPayload({
269
342
  visibility: visibility ?? void 0
270
343
  });
@@ -459,7 +532,7 @@ async function resolveSlackTeamDomains(teamIds) {
459
532
  }
460
533
 
461
534
  // src/chat/pi/sql-model-usage.ts
462
- import { and as and2, eq as eq3, sql } from "drizzle-orm";
535
+ import { and as and3, eq as eq4, sql } from "drizzle-orm";
463
536
  var message = sql`${juniorConversationEvents.payload}`;
464
537
  var usage = sql`${message}->'usage'`;
465
538
  var cost = sql`${usage}->'cost'`;
@@ -557,14 +630,14 @@ async function readConversationModelUsageFromSql(executor, options) {
557
630
  costTotal: summedCost(nonnegativeNumber(cost, "total"))
558
631
  }).from(juniorConversationEvents).innerJoin(
559
632
  juniorConversations,
560
- eq3(
633
+ eq4(
561
634
  juniorConversations.conversationId,
562
635
  juniorConversationEvents.conversationId
563
636
  )
564
637
  ).where(
565
- and2(
566
- options.includeDescendants ? eq3(juniorConversations.rootConversationId, options.conversationId) : eq3(juniorConversationEvents.conversationId, options.conversationId),
567
- eq3(juniorConversationEvents.type, "assistant_message"),
638
+ and3(
639
+ options.includeDescendants ? eq4(juniorConversations.rootConversationId, options.conversationId) : eq4(juniorConversationEvents.conversationId, options.conversationId),
640
+ eq4(juniorConversationEvents.type, "assistant_message"),
568
641
  sql`jsonb_typeof(${message}->'provider') = 'string'`,
569
642
  sql`jsonb_typeof(${message}->'model') = 'string'`,
570
643
  sql`coalesce(${message}->>'provider', '') <> ''`,
@@ -626,12 +699,12 @@ function decodeConversationCursor(args) {
626
699
 
627
700
  // src/api/conversations/event-page.ts
628
701
  import {
629
- and as and3,
702
+ and as and4,
630
703
  asc,
631
704
  desc,
632
- eq as eq4,
705
+ eq as eq5,
633
706
  getTableColumns,
634
- inArray as inArray2,
707
+ inArray as inArray3,
635
708
  lt,
636
709
  sql as sql2
637
710
  } from "drizzle-orm";
@@ -1045,18 +1118,18 @@ async function readConversationEventRows(executor, args) {
1045
1118
  else ${juniorConversationEvents.payload}
1046
1119
  end`
1047
1120
  }).from(juniorConversationEvents).where(
1048
- and3(
1049
- eq4(juniorConversationEvents.conversationId, args.conversationId),
1121
+ and4(
1122
+ eq5(juniorConversationEvents.conversationId, args.conversationId),
1050
1123
  args.beforeSeq === void 0 ? void 0 : lt(juniorConversationEvents.seq, args.beforeSeq),
1051
- inArray2(
1124
+ inArray3(
1052
1125
  juniorConversationEvents.type,
1053
1126
  args.types ?? [...conversationReportSourceEventTypes]
1054
1127
  ),
1055
- args.subagentInvocationIds === void 0 ? void 0 : inArray2(
1128
+ args.subagentInvocationIds === void 0 ? void 0 : inArray3(
1056
1129
  sql2`${juniorConversationEvents.payload}->>'subagentInvocationId'`,
1057
1130
  args.subagentInvocationIds
1058
1131
  ),
1059
- args.toolCallIds === void 0 ? void 0 : inArray2(
1132
+ args.toolCallIds === void 0 ? void 0 : inArray3(
1060
1133
  sql2`${juniorConversationEvents.payload}->>'toolCallId'`,
1061
1134
  args.toolCallIds
1062
1135
  )
@@ -1137,7 +1210,7 @@ async function readConversationEventPage(executor, args) {
1137
1210
  }
1138
1211
 
1139
1212
  // src/api/conversations/list.ts
1140
- import { and as and6, asc as asc2, desc as desc2, eq as eq7, isNull as isNull3 } from "drizzle-orm";
1213
+ import { and as and7, asc as asc2, desc as desc2, eq as eq8, isNull as isNull3 } from "drizzle-orm";
1141
1214
 
1142
1215
  // src/api/conversations/shared.ts
1143
1216
  function slackStatsLocationLabel(input) {
@@ -1320,7 +1393,7 @@ function conversationSummaryFromStoredConversation(args) {
1320
1393
  }
1321
1394
 
1322
1395
  // src/api/conversations/usage.ts
1323
- import { and as and4, eq as eq5, inArray as inArray3, isNull, sql as sql3 } from "drizzle-orm";
1396
+ import { and as and5, eq as eq6, inArray as inArray4, isNull, sql as sql3 } from "drizzle-orm";
1324
1397
  import { alias as alias2 } from "drizzle-orm/pg-core";
1325
1398
  var usage2 = juniorConversations.usage;
1326
1399
  var metricRootConversation = alias2(
@@ -1394,19 +1467,19 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
1394
1467
  costTotal: summedCostNumber("total")
1395
1468
  }).from(juniorConversations).innerJoin(
1396
1469
  metricRootConversation,
1397
- and4(
1398
- eq5(
1470
+ and5(
1471
+ eq6(
1399
1472
  metricRootConversation.conversationId,
1400
1473
  juniorConversations.rootConversationId
1401
1474
  ),
1402
1475
  isNull(metricRootConversation.parentConversationId),
1403
- eq5(
1476
+ eq6(
1404
1477
  metricRootConversation.rootConversationId,
1405
1478
  metricRootConversation.conversationId
1406
1479
  )
1407
1480
  )
1408
1481
  ).where(
1409
- inArray3(juniorConversations.rootConversationId, [...rootConversationIds])
1482
+ inArray4(juniorConversations.rootConversationId, [...rootConversationIds])
1410
1483
  ).groupBy(juniorConversations.rootConversationId);
1411
1484
  return new Map(
1412
1485
  rows.flatMap((row) => {
@@ -1424,12 +1497,12 @@ async function readRootConversationMetricsFromSql(db, rootConversationIds) {
1424
1497
 
1425
1498
  // src/api/conversations/auxiliary-costs.ts
1426
1499
  import {
1427
- and as and5,
1428
- eq as eq6,
1429
- inArray as inArray4,
1500
+ and as and6,
1501
+ eq as eq7,
1502
+ inArray as inArray5,
1430
1503
  isNotNull as isNotNull2,
1431
1504
  isNull as isNull2,
1432
- or,
1505
+ or as or2,
1433
1506
  sql as sql4
1434
1507
  } from "drizzle-orm";
1435
1508
  import { alias as alias3 } from "drizzle-orm/pg-core";
@@ -1466,13 +1539,13 @@ async function readConversationAuxiliaryCostsFromSql(db, conversationIds, option
1466
1539
  ELSE ${juniorConversationEvents.type}
1467
1540
  END`;
1468
1541
  const cost2 = eventCost();
1469
- const selectedConversation = options.includeDescendants ? or(
1470
- and5(
1471
- inArray4(juniorConversations.rootConversationId, selectedIds),
1542
+ const selectedConversation = options.includeDescendants ? or2(
1543
+ and6(
1544
+ inArray5(juniorConversations.rootConversationId, selectedIds),
1472
1545
  isNotNull2(auxiliaryRootConversation.conversationId)
1473
1546
  ),
1474
- inArray4(juniorConversations.conversationId, selectedIds)
1475
- ) : inArray4(juniorConversations.conversationId, selectedIds);
1547
+ inArray5(juniorConversations.conversationId, selectedIds)
1548
+ ) : inArray5(juniorConversations.conversationId, selectedIds);
1476
1549
  const rows = await db.select({
1477
1550
  conversationId,
1478
1551
  costUsd: sql4`round(sum(${cost2}), 12)::double precision`.mapWith(
@@ -1483,29 +1556,29 @@ async function readConversationAuxiliaryCostsFromSql(db, conversationIds, option
1483
1556
  namespace
1484
1557
  }).from(juniorConversationEvents).innerJoin(
1485
1558
  juniorConversations,
1486
- eq6(
1559
+ eq7(
1487
1560
  juniorConversations.conversationId,
1488
1561
  juniorConversationEvents.conversationId
1489
1562
  )
1490
1563
  ).leftJoin(
1491
1564
  auxiliaryRootConversation,
1492
- and5(
1493
- eq6(
1565
+ and6(
1566
+ eq7(
1494
1567
  auxiliaryRootConversation.conversationId,
1495
1568
  juniorConversations.rootConversationId
1496
1569
  ),
1497
1570
  isNull2(auxiliaryRootConversation.parentConversationId),
1498
- eq6(
1571
+ eq7(
1499
1572
  auxiliaryRootConversation.rootConversationId,
1500
1573
  auxiliaryRootConversation.conversationId
1501
1574
  )
1502
1575
  )
1503
1576
  ).where(
1504
- and5(
1577
+ and6(
1505
1578
  selectedConversation,
1506
- or(
1507
- eq6(juniorConversationEvents.type, "structured_event"),
1508
- inArray4(juniorConversationEvents.type, [
1579
+ or2(
1580
+ eq7(juniorConversationEvents.type, "structured_event"),
1581
+ inArray5(juniorConversationEvents.type, [
1509
1582
  "guardian_action_reviewed",
1510
1583
  "turn_routed"
1511
1584
  ])
@@ -1531,8 +1604,54 @@ async function readConversationAuxiliaryCostsFromSql(db, conversationIds, option
1531
1604
  return result;
1532
1605
  }
1533
1606
 
1607
+ // src/chat/plugins/unfinished-work.ts
1608
+ async function listUnfinishedWork(conversationIds) {
1609
+ if (conversationIds.length === 0) return [];
1610
+ const candidates = new Set(conversationIds);
1611
+ const unfinished = /* @__PURE__ */ new Set();
1612
+ for (const plugin of getPlugins()) {
1613
+ const hook = plugin.hooks?.unfinishedWork;
1614
+ if (!hook) continue;
1615
+ try {
1616
+ const result = await hook({
1617
+ conversationIds,
1618
+ db: getDb(),
1619
+ log: createPluginLogger(plugin.manifest.name),
1620
+ plugin: { name: plugin.manifest.name }
1621
+ });
1622
+ for (const conversationId of result.conversationIds) {
1623
+ if (candidates.has(conversationId)) unfinished.add(conversationId);
1624
+ }
1625
+ } catch (error) {
1626
+ logWarn("plugin.unfinished_work.hook.failed", {
1627
+ "app.plugin.name": plugin.manifest.name,
1628
+ "exception.message": error instanceof Error ? error.message : String(error)
1629
+ });
1630
+ for (const conversationId of conversationIds) {
1631
+ unfinished.add(conversationId);
1632
+ }
1633
+ }
1634
+ }
1635
+ return conversationIds.filter(
1636
+ (conversationId) => unfinished.has(conversationId)
1637
+ );
1638
+ }
1639
+
1534
1640
  // src/api/conversations/list.ts
1535
1641
  var CONVERSATION_FEED_LIMIT = 50;
1642
+ function conversationFeedMembershipFilter(filter) {
1643
+ if (!filter) return void 0;
1644
+ if (filter.kind === "viewer") {
1645
+ return viewerConversationMembership({
1646
+ actorMatch: eq8(juniorIdentities.userId, filter.userId),
1647
+ participantMatch: conversationHasParticipantUser(filter.userId)
1648
+ });
1649
+ }
1650
+ return viewerConversationMembership({
1651
+ actorMatch: eq8(juniorUsers.primaryEmailNormalized, filter.email),
1652
+ participantMatch: conversationHasParticipantEmail(filter.email)
1653
+ });
1654
+ }
1536
1655
  async function conversationRows(db, limit, filter) {
1537
1656
  return db.select({
1538
1657
  conversation: juniorConversations,
@@ -1546,15 +1665,15 @@ async function conversationRows(db, limit, filter) {
1546
1665
  userDisplayName: juniorUsers.displayName
1547
1666
  }).from(juniorConversations).leftJoin(
1548
1667
  juniorDestinations,
1549
- eq7(juniorDestinations.id, juniorConversations.destinationId)
1668
+ eq8(juniorDestinations.id, juniorConversations.destinationId)
1550
1669
  ).leftJoin(
1551
1670
  juniorIdentities,
1552
- eq7(juniorIdentities.id, juniorConversations.actorIdentityId)
1553
- ).leftJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(
1554
- and6(
1671
+ eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
1672
+ ).leftJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(
1673
+ and7(
1555
1674
  isNull3(juniorConversations.parentConversationId),
1556
1675
  isNull3(juniorConversations.archivedAt),
1557
- filter?.kind === "viewer" ? eq7(juniorIdentities.userId, filter.userId) : filter?.kind === "actorEmail" ? eq7(juniorUsers.primaryEmailNormalized, filter.email) : void 0
1676
+ conversationFeedMembershipFilter(filter)
1558
1677
  )
1559
1678
  ).orderBy(
1560
1679
  desc2(juniorConversations.lastActivityAt),
@@ -1612,11 +1731,11 @@ async function readConversationRecordFromSql(conversationId) {
1612
1731
  userDisplayName: juniorUsers.displayName
1613
1732
  }).from(juniorConversations).leftJoin(
1614
1733
  juniorDestinations,
1615
- eq7(juniorDestinations.id, juniorConversations.destinationId)
1734
+ eq8(juniorDestinations.id, juniorConversations.destinationId)
1616
1735
  ).leftJoin(
1617
1736
  juniorIdentities,
1618
- eq7(juniorIdentities.id, juniorConversations.actorIdentityId)
1619
- ).leftJoin(juniorUsers, eq7(juniorUsers.id, juniorIdentities.userId)).where(eq7(juniorConversations.conversationId, conversationId)).limit(1);
1737
+ eq8(juniorIdentities.id, juniorConversations.actorIdentityId)
1738
+ ).leftJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(eq8(juniorConversations.conversationId, conversationId)).limit(1);
1620
1739
  const row = rows[0];
1621
1740
  return row ? {
1622
1741
  conversation: conversationFromRow(row),
@@ -1628,10 +1747,16 @@ async function readConversationRecordFromSql(conversationId) {
1628
1747
  }
1629
1748
  function conversationFeedFilter(options) {
1630
1749
  if (options.viewer) {
1631
- return { kind: "viewer", userId: options.viewer.id };
1750
+ return {
1751
+ kind: "viewer",
1752
+ userId: options.viewer.id
1753
+ };
1632
1754
  }
1633
1755
  if (options.actorEmail) {
1634
- return { kind: "actorEmail", email: options.actorEmail };
1756
+ return {
1757
+ kind: "actorEmail",
1758
+ email: options.actorEmail
1759
+ };
1635
1760
  }
1636
1761
  return void 0;
1637
1762
  }
@@ -1651,7 +1776,8 @@ async function readConversationFeedFromSql(options = {}) {
1651
1776
  accessByConversation,
1652
1777
  auxiliaryCostsByRoot,
1653
1778
  metricsByRoot,
1654
- teamDomainByTeamId
1779
+ teamDomainByTeamId,
1780
+ unfinishedWorkIds
1655
1781
  ] = await Promise.all([
1656
1782
  readConversationAccessFromSql(db, conversationIds, options.viewer),
1657
1783
  readConversationAuxiliaryCostsFromSql(db, conversationIds, {
@@ -1662,21 +1788,26 @@ async function readConversationFeedFromSql(options = {}) {
1662
1788
  conversations.flatMap(
1663
1789
  (conversation) => conversation.sessionSource?.platform === "slack" ? [conversation.sessionSource.teamId] : []
1664
1790
  )
1665
- )
1791
+ ),
1792
+ listUnfinishedWork(conversationIds)
1666
1793
  ]);
1794
+ const unfinishedWork = new Set(unfinishedWorkIds);
1667
1795
  return {
1668
1796
  conversations: conversations.map((conversation, index) => {
1669
1797
  const row = rows[index];
1670
1798
  const metrics = metricsByRoot.get(conversation.conversationId);
1671
- return conversationSummaryFromStoredConversation({
1672
- conversation,
1673
- access: accessByConversation.get(conversation.conversationId),
1674
- auxiliaryCosts: auxiliaryCostsByRoot.get(conversation.conversationId),
1675
- durationMs: metrics?.durationMs ?? row.conversation.durationMs,
1676
- teamDomainByTeamId,
1677
- ...row.destination?.visibility === "public" ? { locationId: row.destination.id } : {},
1678
- usage: metrics?.usage ?? row.conversation.usage ?? void 0
1679
- });
1799
+ return {
1800
+ ...conversationSummaryFromStoredConversation({
1801
+ conversation,
1802
+ access: accessByConversation.get(conversation.conversationId),
1803
+ auxiliaryCosts: auxiliaryCostsByRoot.get(conversation.conversationId),
1804
+ durationMs: metrics?.durationMs ?? row.conversation.durationMs,
1805
+ teamDomainByTeamId,
1806
+ ...row.destination?.visibility === "public" ? { locationId: row.destination.id } : {},
1807
+ usage: metrics?.usage ?? row.conversation.usage ?? void 0
1808
+ }),
1809
+ ...unfinishedWork.has(conversation.conversationId) ? { unfinishedWork: true } : {}
1810
+ };
1680
1811
  }),
1681
1812
  generatedAt: new Date(nowMs).toISOString(),
1682
1813
  source: "conversation_index"
@@ -1689,7 +1820,7 @@ async function readConversationFeed(options = {}) {
1689
1820
  }
1690
1821
 
1691
1822
  // src/chat/tasks/read.ts
1692
- import { and as and7, eq as eq8, or as or2 } from "drizzle-orm";
1823
+ import { and as and8, eq as eq9, or as or3 } from "drizzle-orm";
1693
1824
 
1694
1825
  // src/chat/scheduled-tasks/personal.ts
1695
1826
  import { z as z3 } from "zod";
@@ -1799,16 +1930,16 @@ async function creatorProfileEmails(candidates) {
1799
1930
  email: juniorUsers.primaryEmailNormalized,
1800
1931
  slackUserId: juniorIdentities.providerSubjectId,
1801
1932
  teamId: juniorIdentities.providerTenantId
1802
- }).from(juniorIdentities).innerJoin(juniorUsers, eq8(juniorUsers.id, juniorIdentities.userId)).where(
1803
- and7(
1804
- eq8(juniorIdentities.kind, "user"),
1805
- eq8(juniorIdentities.provider, "slack"),
1806
- eq8(juniorIdentities.emailVerified, true),
1807
- or2(
1933
+ }).from(juniorIdentities).innerJoin(juniorUsers, eq9(juniorUsers.id, juniorIdentities.userId)).where(
1934
+ and8(
1935
+ eq9(juniorIdentities.kind, "user"),
1936
+ eq9(juniorIdentities.provider, "slack"),
1937
+ eq9(juniorIdentities.emailVerified, true),
1938
+ or3(
1808
1939
  ...[...selectors.values()].map(
1809
- (selector) => and7(
1810
- eq8(juniorIdentities.providerTenantId, selector.teamId),
1811
- eq8(juniorIdentities.providerSubjectId, selector.slackUserId)
1940
+ (selector) => and8(
1941
+ eq9(juniorIdentities.providerTenantId, selector.teamId),
1942
+ eq9(juniorIdentities.providerSubjectId, selector.slackUserId)
1812
1943
  )
1813
1944
  )
1814
1945
  )
@@ -1844,12 +1975,12 @@ async function destinationDetails(destinations) {
1844
1975
  providerTenantId: juniorDestinations.providerTenantId,
1845
1976
  visibility: juniorDestinations.visibility
1846
1977
  }).from(juniorDestinations).where(
1847
- or2(
1978
+ or3(
1848
1979
  ...[...selectors.values()].map(
1849
- (destination) => and7(
1850
- eq8(juniorDestinations.provider, "slack"),
1851
- eq8(juniorDestinations.providerTenantId, destination.teamId),
1852
- eq8(juniorDestinations.providerDestinationId, destination.channelId)
1980
+ (destination) => and8(
1981
+ eq9(juniorDestinations.provider, "slack"),
1982
+ eq9(juniorDestinations.providerTenantId, destination.teamId),
1983
+ eq9(juniorDestinations.providerDestinationId, destination.channelId)
1853
1984
  )
1854
1985
  )
1855
1986
  )
@@ -2502,7 +2633,7 @@ async function requireConversationPendingMessages(conversationId, options = {})
2502
2633
  }
2503
2634
 
2504
2635
  // src/api/conversations/stats.query.ts
2505
- import { and as and8, eq as eq9, gte, isNull as isNull4, lte, sql as sql6 } from "drizzle-orm";
2636
+ import { and as and9, eq as eq10, gte, isNull as isNull4, lte, sql as sql6 } from "drizzle-orm";
2506
2637
  import { alias as alias4 } from "drizzle-orm/pg-core";
2507
2638
 
2508
2639
  // src/api/conversations/aggregate.ts
@@ -2646,7 +2777,7 @@ function statsItems(map) {
2646
2777
  );
2647
2778
  }
2648
2779
  function statsWhere(start, end) {
2649
- return and8(
2780
+ return and9(
2650
2781
  isNull4(juniorConversations.parentConversationId),
2651
2782
  gte(juniorConversations.lastActivityAt, start),
2652
2783
  lte(juniorConversations.lastActivityAt, end)
@@ -2730,7 +2861,7 @@ async function aggregateStats(db, start, end) {
2730
2861
  const [totalsRows, actorRows, locationRows, metricRows] = await Promise.all([
2731
2862
  db.select(treeAggregateColumns).from(juniorConversations).innerJoin(
2732
2863
  treeConversation,
2733
- eq9(
2864
+ eq10(
2734
2865
  treeConversation.rootConversationId,
2735
2866
  juniorConversations.conversationId
2736
2867
  )
@@ -2745,14 +2876,14 @@ async function aggregateStats(db, start, end) {
2745
2876
  ...treeAggregateColumns
2746
2877
  }).from(juniorConversations).innerJoin(
2747
2878
  treeConversation,
2748
- eq9(
2879
+ eq10(
2749
2880
  treeConversation.rootConversationId,
2750
2881
  juniorConversations.conversationId
2751
2882
  )
2752
2883
  ).leftJoin(
2753
2884
  juniorIdentities,
2754
- eq9(juniorIdentities.id, juniorConversations.actorIdentityId)
2755
- ).leftJoin(juniorUsers, eq9(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
2885
+ eq10(juniorIdentities.id, juniorConversations.actorIdentityId)
2886
+ ).leftJoin(juniorUsers, eq10(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
2756
2887
  juniorIdentities.displayName,
2757
2888
  juniorIdentities.emailNormalized,
2758
2889
  juniorIdentities.handle,
@@ -2770,13 +2901,13 @@ async function aggregateStats(db, start, end) {
2770
2901
  ...treeAggregateColumns
2771
2902
  }).from(juniorConversations).innerJoin(
2772
2903
  treeConversation,
2773
- eq9(
2904
+ eq10(
2774
2905
  treeConversation.rootConversationId,
2775
2906
  juniorConversations.conversationId
2776
2907
  )
2777
2908
  ).leftJoin(
2778
2909
  juniorDestinations,
2779
- eq9(juniorDestinations.id, juniorConversations.destinationId)
2910
+ eq10(juniorDestinations.id, juniorConversations.destinationId)
2780
2911
  ).where(where).groupBy(
2781
2912
  juniorConversations.channelName,
2782
2913
  juniorConversations.source,
@@ -2795,7 +2926,7 @@ async function aggregateStats(db, start, end) {
2795
2926
  tokens: treeAggregateColumns.tokens
2796
2927
  }).from(juniorConversations).innerJoin(
2797
2928
  treeConversation,
2798
- eq9(
2929
+ eq10(
2799
2930
  treeConversation.rootConversationId,
2800
2931
  juniorConversations.conversationId
2801
2932
  )
@@ -2822,8 +2953,8 @@ async function aggregateGuardianStats(db, start, end) {
2822
2953
  deny: sql6`COUNT(*) FILTER (WHERE ${decision} = 'deny')::integer`,
2823
2954
  requests: sql6`COUNT(*)::integer`
2824
2955
  }).from(juniorConversationEvents).where(
2825
- and8(
2826
- eq9(juniorConversationEvents.type, "guardian_action_reviewed"),
2956
+ and9(
2957
+ eq10(juniorConversationEvents.type, "guardian_action_reviewed"),
2827
2958
  gte(juniorConversationEvents.createdAt, start),
2828
2959
  lte(juniorConversationEvents.createdAt, end)
2829
2960
  )
@@ -3032,7 +3163,7 @@ function createConversationRoutes() {
3032
3163
  import { Hono as Hono2 } from "hono";
3033
3164
 
3034
3165
  // src/api/locations/query.ts
3035
- import { and as and9, asc as asc3, desc as desc3, eq as eq10, gte as gte2, isNull as isNull5, sql as sql7 } from "drizzle-orm";
3166
+ import { and as and10, asc as asc3, desc as desc3, eq as eq11, gte as gte2, isNull as isNull5, sql as sql7 } from "drizzle-orm";
3036
3167
  import { alias as alias5 } from "drizzle-orm/pg-core";
3037
3168
 
3038
3169
  // src/api/conversations/reporting.ts
@@ -3140,10 +3271,10 @@ function topLevelWhere() {
3140
3271
  return isNull5(juniorConversations.parentConversationId);
3141
3272
  }
3142
3273
  function publicLocationWhere(destinationId) {
3143
- return and9(
3274
+ return and10(
3144
3275
  topLevelWhere(),
3145
- eq10(juniorDestinations.id, destinationId),
3146
- eq10(juniorDestinations.visibility, "public")
3276
+ eq11(juniorDestinations.id, destinationId),
3277
+ eq11(juniorDestinations.visibility, "public")
3147
3278
  );
3148
3279
  }
3149
3280
  function locationColumns() {
@@ -3194,13 +3325,13 @@ async function directoryRows(db) {
3194
3325
  ...conversationRangeColumns()
3195
3326
  }).from(juniorConversations).innerJoin(
3196
3327
  treeConversation2,
3197
- eq10(
3328
+ eq11(
3198
3329
  treeConversation2.rootConversationId,
3199
3330
  juniorConversations.conversationId
3200
3331
  )
3201
3332
  ).leftJoin(
3202
3333
  juniorDestinations,
3203
- eq10(juniorDestinations.id, juniorConversations.destinationId)
3334
+ eq11(juniorDestinations.id, juniorConversations.destinationId)
3204
3335
  ).where(topLevelWhere()).groupBy(...locationGroupBy());
3205
3336
  }
3206
3337
  async function directoryActivityRows(db, start) {
@@ -3214,8 +3345,8 @@ async function directoryActivityRows(db, start) {
3214
3345
  visibility: juniorDestinations.visibility
3215
3346
  }).from(juniorConversations).leftJoin(
3216
3347
  juniorDestinations,
3217
- eq10(juniorDestinations.id, juniorConversations.destinationId)
3218
- ).where(and9(topLevelWhere(), gte2(juniorConversations.lastActivityAt, start))).groupBy(date, juniorDestinations.visibility);
3348
+ eq11(juniorDestinations.id, juniorConversations.destinationId)
3349
+ ).where(and10(topLevelWhere(), gte2(juniorConversations.lastActivityAt, start))).groupBy(date, juniorDestinations.visibility);
3219
3350
  }
3220
3351
  function directoryActivityDays(rows, nowMs) {
3221
3352
  const days = /* @__PURE__ */ new Map();
@@ -3308,12 +3439,12 @@ async function recentLocationRows(db, locationId) {
3308
3439
  usage: juniorConversations.usage
3309
3440
  }).from(juniorConversations).innerJoin(
3310
3441
  juniorDestinations,
3311
- eq10(juniorDestinations.id, juniorConversations.destinationId)
3442
+ eq11(juniorDestinations.id, juniorConversations.destinationId)
3312
3443
  ).leftJoin(
3313
3444
  juniorIdentities,
3314
- eq10(juniorIdentities.id, juniorConversations.actorIdentityId)
3315
- ).leftJoin(juniorUsers, eq10(juniorUsers.id, juniorIdentities.userId)).where(
3316
- and9(
3445
+ eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
3446
+ ).leftJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).where(
3447
+ and10(
3317
3448
  publicLocationWhere(locationId),
3318
3449
  isNull5(juniorConversations.archivedAt)
3319
3450
  )
@@ -3340,27 +3471,27 @@ async function readLocationDetailFromSql(locationId, options = {}) {
3340
3471
  ...conversationRangeColumns()
3341
3472
  }).from(juniorConversations).innerJoin(
3342
3473
  treeConversation2,
3343
- eq10(
3474
+ eq11(
3344
3475
  treeConversation2.rootConversationId,
3345
3476
  juniorConversations.conversationId
3346
3477
  )
3347
3478
  ).innerJoin(
3348
3479
  juniorDestinations,
3349
- eq10(juniorDestinations.id, juniorConversations.destinationId)
3480
+ eq11(juniorDestinations.id, juniorConversations.destinationId)
3350
3481
  ).where(where).groupBy(...locationGroupBy()),
3351
3482
  getDb().select({
3352
3483
  date: activityDate,
3353
3484
  ...treeAggregateColumns2
3354
3485
  }).from(juniorConversations).innerJoin(
3355
3486
  treeConversation2,
3356
- eq10(
3487
+ eq11(
3357
3488
  treeConversation2.rootConversationId,
3358
3489
  juniorConversations.conversationId
3359
3490
  )
3360
3491
  ).innerJoin(
3361
3492
  juniorDestinations,
3362
- eq10(juniorDestinations.id, juniorConversations.destinationId)
3363
- ).where(and9(where, gte2(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
3493
+ eq11(juniorDestinations.id, juniorConversations.destinationId)
3494
+ ).where(and10(where, gte2(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
3364
3495
  getDb().select({
3365
3496
  actorIdentityId: juniorConversations.actorIdentityId,
3366
3497
  email: juniorUsers.primaryEmailNormalized,
@@ -3372,17 +3503,17 @@ async function readLocationDetailFromSql(locationId, options = {}) {
3372
3503
  ...treeAggregateColumns2
3373
3504
  }).from(juniorConversations).innerJoin(
3374
3505
  treeConversation2,
3375
- eq10(
3506
+ eq11(
3376
3507
  treeConversation2.rootConversationId,
3377
3508
  juniorConversations.conversationId
3378
3509
  )
3379
3510
  ).innerJoin(
3380
3511
  juniorDestinations,
3381
- eq10(juniorDestinations.id, juniorConversations.destinationId)
3512
+ eq11(juniorDestinations.id, juniorConversations.destinationId)
3382
3513
  ).leftJoin(
3383
3514
  juniorIdentities,
3384
- eq10(juniorIdentities.id, juniorConversations.actorIdentityId)
3385
- ).leftJoin(juniorUsers, eq10(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
3515
+ eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
3516
+ ).leftJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).where(where).groupBy(
3386
3517
  juniorConversations.actorIdentityId,
3387
3518
  juniorUsers.primaryEmailNormalized,
3388
3519
  juniorUsers.displayName,
@@ -3495,10 +3626,10 @@ function createLocationRoutes() {
3495
3626
  import { Hono as Hono3 } from "hono";
3496
3627
 
3497
3628
  // src/api/people/list.query.ts
3498
- import { and as and11, eq as eq12, gte as gte3, sql as sql9 } from "drizzle-orm";
3629
+ import { and as and12, eq as eq13, gte as gte3, sql as sql9 } from "drizzle-orm";
3499
3630
 
3500
3631
  // src/api/people/shared.ts
3501
- import { and as and10, asc as asc4, desc as desc4, eq as eq11, isNull as isNull6, notExists, or as or3, sql as sql8 } from "drizzle-orm";
3632
+ import { and as and11, asc as asc4, desc as desc4, eq as eq12, isNull as isNull6, notExists, or as or4, sql as sql8 } from "drizzle-orm";
3502
3633
  import { alias as alias6 } from "drizzle-orm/pg-core";
3503
3634
  var RECENT_LIMIT2 = 25;
3504
3635
  var ACTIVITY_DAYS2 = 365;
@@ -3518,37 +3649,37 @@ var peopleTreeAggregateColumns = conversationAggregateColumns({
3518
3649
  function peopleTreeMetricsJoin() {
3519
3650
  const rootOwnedByActor = getDb().select({ conversationId: peopleRootConversation.conversationId }).from(peopleRootConversation).innerJoin(
3520
3651
  peopleRootIdentity,
3521
- eq11(peopleRootIdentity.id, peopleRootConversation.actorIdentityId)
3652
+ eq12(peopleRootIdentity.id, peopleRootConversation.actorIdentityId)
3522
3653
  ).where(
3523
- and10(
3524
- eq11(
3654
+ and11(
3655
+ eq12(
3525
3656
  peopleRootConversation.conversationId,
3526
3657
  juniorConversations.rootConversationId
3527
3658
  ),
3528
3659
  isNull6(peopleRootConversation.parentConversationId),
3529
- eq11(
3660
+ eq12(
3530
3661
  peopleRootConversation.rootConversationId,
3531
3662
  peopleRootConversation.conversationId
3532
3663
  ),
3533
- eq11(
3664
+ eq12(
3534
3665
  peopleRootIdentity.emailNormalized,
3535
3666
  juniorUsers.primaryEmailNormalized
3536
3667
  ),
3537
- eq11(peopleRootIdentity.emailVerified, true)
3668
+ eq12(peopleRootIdentity.emailVerified, true)
3538
3669
  )
3539
3670
  );
3540
- return and10(
3541
- eq11(
3671
+ return and11(
3672
+ eq12(
3542
3673
  peopleTreeConversation.rootConversationId,
3543
3674
  juniorConversations.rootConversationId
3544
3675
  ),
3545
- or3(
3546
- eq11(
3676
+ or4(
3677
+ eq12(
3547
3678
  juniorConversations.rootConversationId,
3548
3679
  juniorConversations.conversationId
3549
3680
  ),
3550
- and10(
3551
- eq11(
3681
+ and11(
3682
+ eq12(
3552
3683
  peopleTreeConversation.conversationId,
3553
3684
  juniorConversations.conversationId
3554
3685
  ),
@@ -3598,11 +3729,11 @@ function statsItems2(map) {
3598
3729
  }
3599
3730
  function verifiedActorWhere(email) {
3600
3731
  const normalizedEmail = normalizeEmail(email);
3601
- return and10(
3602
- eq11(juniorIdentities.provider, "slack"),
3603
- eq11(juniorIdentities.emailVerified, true),
3732
+ return and11(
3733
+ eq12(juniorIdentities.provider, "slack"),
3734
+ eq12(juniorIdentities.emailVerified, true),
3604
3735
  sql8`${juniorUsers.primaryEmailNormalized} IS NOT NULL`,
3605
- normalizedEmail ? eq11(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
3736
+ normalizedEmail ? eq12(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
3606
3737
  );
3607
3738
  }
3608
3739
  async function recentActorRows(email) {
@@ -3625,12 +3756,12 @@ async function recentActorRows(email) {
3625
3756
  usage: juniorConversations.usage
3626
3757
  }).from(juniorConversations).innerJoin(
3627
3758
  juniorIdentities,
3628
- eq11(juniorIdentities.id, juniorConversations.actorIdentityId)
3629
- ).innerJoin(juniorUsers, eq11(juniorUsers.id, juniorIdentities.userId)).leftJoin(
3759
+ eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
3760
+ ).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(
3630
3761
  juniorDestinations,
3631
- eq11(juniorDestinations.id, juniorConversations.destinationId)
3762
+ eq12(juniorDestinations.id, juniorConversations.destinationId)
3632
3763
  ).where(
3633
- and10(verifiedActorWhere(email), isNull6(juniorConversations.archivedAt))
3764
+ and11(verifiedActorWhere(email), isNull6(juniorConversations.archivedAt))
3634
3765
  ).orderBy(
3635
3766
  desc4(juniorConversations.lastActivityAt),
3636
3767
  asc4(juniorConversations.conversationId)
@@ -3674,17 +3805,17 @@ async function readPeopleListFromSql() {
3674
3805
  ...conversationRangeColumns()
3675
3806
  }).from(juniorConversations).innerJoin(
3676
3807
  juniorIdentities,
3677
- eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
3678
- ).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, peopleTreeMetricsJoin()).where(verifiedActorWhere()).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
3808
+ eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
3809
+ ).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, peopleTreeMetricsJoin()).where(verifiedActorWhere()).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
3679
3810
  getDb().select({
3680
3811
  activePeople: sql9`COUNT(DISTINCT ${juniorUsers.id})::int`,
3681
3812
  conversations: sql9`COUNT(*)::int`,
3682
3813
  date: activityDate
3683
3814
  }).from(juniorConversations).innerJoin(
3684
3815
  juniorIdentities,
3685
- eq12(juniorIdentities.id, juniorConversations.actorIdentityId)
3686
- ).innerJoin(juniorUsers, eq12(juniorUsers.id, juniorIdentities.userId)).where(
3687
- and11(
3816
+ eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
3817
+ ).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).where(
3818
+ and12(
3688
3819
  verifiedActorWhere(),
3689
3820
  gte3(juniorConversations.lastActivityAt, start)
3690
3821
  )
@@ -3727,7 +3858,7 @@ async function readPeopleList() {
3727
3858
  }
3728
3859
 
3729
3860
  // src/api/people/profile.query.ts
3730
- import { and as and12, eq as eq13, gte as gte4, sql as sql10 } from "drizzle-orm";
3861
+ import { and as and13, eq as eq14, gte as gte4, sql as sql10 } from "drizzle-orm";
3731
3862
  function emptyProfile(email, nowMs) {
3732
3863
  const end = new Date(nowMs);
3733
3864
  end.setUTCHours(0, 0, 0, 0);
@@ -3806,15 +3937,15 @@ async function readPeopleProfileFromSql(email, options = {}) {
3806
3937
  ...peopleTreeAggregateColumns
3807
3938
  }).from(juniorConversations).innerJoin(
3808
3939
  juniorIdentities,
3809
- eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
3810
- ).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
3940
+ eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
3941
+ ).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(juniorUsers.primaryEmailNormalized, juniorUsers.displayName),
3811
3942
  getDb().select({
3812
3943
  date: activityDate,
3813
3944
  ...peopleTreeAggregateColumns
3814
3945
  }).from(juniorConversations).innerJoin(
3815
3946
  juniorIdentities,
3816
- eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
3817
- ).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(and12(where, gte4(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
3947
+ eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
3948
+ ).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(and13(where, gte4(juniorConversations.lastActivityAt, start))).groupBy(activityDate),
3818
3949
  getDb().select({
3819
3950
  channel,
3820
3951
  channelName: juniorConversations.channelName,
@@ -3823,10 +3954,10 @@ async function readPeopleProfileFromSql(email, options = {}) {
3823
3954
  ...peopleTreeAggregateColumns
3824
3955
  }).from(juniorConversations).innerJoin(
3825
3956
  juniorIdentities,
3826
- eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
3827
- ).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).leftJoin(
3957
+ eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
3958
+ ).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).leftJoin(
3828
3959
  juniorDestinations,
3829
- eq13(juniorDestinations.id, juniorConversations.destinationId)
3960
+ eq14(juniorDestinations.id, juniorConversations.destinationId)
3830
3961
  ).where(where).groupBy(
3831
3962
  channel,
3832
3963
  juniorConversations.channelName,
@@ -3835,8 +3966,8 @@ async function readPeopleProfileFromSql(email, options = {}) {
3835
3966
  ),
3836
3967
  getDb().select({ surface, ...peopleTreeAggregateColumns }).from(juniorConversations).innerJoin(
3837
3968
  juniorIdentities,
3838
- eq13(juniorIdentities.id, juniorConversations.actorIdentityId)
3839
- ).innerJoin(juniorUsers, eq13(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(surface),
3969
+ eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
3970
+ ).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(where).groupBy(surface),
3840
3971
  recentActorRows(normalizedEmail)
3841
3972
  ]);
3842
3973
  const totalsRow = totalsRows[0];
@@ -3914,7 +4045,7 @@ async function readPeopleProfile(email, options = {}) {
3914
4045
  }
3915
4046
 
3916
4047
  // src/api/people/spend.query.ts
3917
- import { and as and13, eq as eq14, gte as gte5, lte as lte2, sql as sql11 } from "drizzle-orm";
4048
+ import { and as and14, eq as eq15, gte as gte5, lte as lte2, sql as sql11 } from "drizzle-orm";
3918
4049
  var SEVEN_DAY_OFFSET = 6;
3919
4050
  var THIRTY_DAY_OFFSET = 29;
3920
4051
  function addUsd2(current, next) {
@@ -3943,9 +4074,9 @@ async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
3943
4074
  date: activityDate
3944
4075
  }).from(juniorConversations).innerJoin(
3945
4076
  juniorIdentities,
3946
- eq14(juniorIdentities.id, juniorConversations.actorIdentityId)
3947
- ).innerJoin(juniorUsers, eq14(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(
3948
- and13(
4077
+ eq15(juniorIdentities.id, juniorConversations.actorIdentityId)
4078
+ ).innerJoin(juniorUsers, eq15(juniorUsers.id, juniorIdentities.userId)).leftJoin(peopleTreeConversation, metricsJoin).where(
4079
+ and14(
3949
4080
  verifiedActorWhere(normalizedEmail),
3950
4081
  gte5(juniorConversations.lastActivityAt, thirtyDayStart),
3951
4082
  lte2(juniorConversations.lastActivityAt, end)
@@ -4033,7 +4164,7 @@ import { Hono as Hono4 } from "hono";
4033
4164
 
4034
4165
  // src/personal-tokens/store.ts
4035
4166
  import { createHash, randomBytes, randomUUID } from "crypto";
4036
- import { and as and14, desc as desc5, eq as eq15, gt, isNull as isNull7 } from "drizzle-orm";
4167
+ import { and as and15, desc as desc5, eq as eq16, gt, isNull as isNull7 } from "drizzle-orm";
4037
4168
  var TOKEN_PREFIX = "jr_pat_";
4038
4169
  var TOKEN_SUFFIX_LENGTH = 8;
4039
4170
  var DEFAULT_TOKEN_LIFETIME_MS = 90 * 24 * 60 * 60 * 1e3;
@@ -4070,8 +4201,8 @@ async function createPersonalToken(args) {
4070
4201
  }
4071
4202
  async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
4072
4203
  const rows = await getDb().select().from(juniorApiTokens).where(
4073
- and14(
4074
- eq15(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(email)),
4204
+ and15(
4205
+ eq16(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(email)),
4075
4206
  isNull7(juniorApiTokens.revokedAt),
4076
4207
  gt(juniorApiTokens.expiresAt, now)
4077
4208
  )
@@ -4080,9 +4211,9 @@ async function listPersonalTokens(email, now = /* @__PURE__ */ new Date()) {
4080
4211
  }
4081
4212
  async function revokePersonalToken(args) {
4082
4213
  const rows = await getDb().update(juniorApiTokens).set({ revokedAt: args.now ?? /* @__PURE__ */ new Date() }).where(
4083
- and14(
4084
- eq15(juniorApiTokens.id, args.id),
4085
- eq15(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(args.email)),
4214
+ and15(
4215
+ eq16(juniorApiTokens.id, args.id),
4216
+ eq16(juniorApiTokens.ownerEmailNormalized, normalizeEmail2(args.email)),
4086
4217
  isNull7(juniorApiTokens.revokedAt)
4087
4218
  )
4088
4219
  ).returning({ id: juniorApiTokens.id });
@@ -4094,15 +4225,15 @@ async function authenticatePersonalToken(token2, now = /* @__PURE__ */ new Date(
4094
4225
  id: juniorApiTokens.id,
4095
4226
  ownerEmailNormalized: juniorApiTokens.ownerEmailNormalized
4096
4227
  }).from(juniorApiTokens).where(
4097
- and14(
4098
- eq15(juniorApiTokens.tokenHash, hashToken(token2)),
4228
+ and15(
4229
+ eq16(juniorApiTokens.tokenHash, hashToken(token2)),
4099
4230
  isNull7(juniorApiTokens.revokedAt),
4100
4231
  gt(juniorApiTokens.expiresAt, now)
4101
4232
  )
4102
4233
  ).limit(1);
4103
4234
  const match = rows[0];
4104
4235
  if (!match) return void 0;
4105
- await getDb().update(juniorApiTokens).set({ lastUsedAt: now }).where(eq15(juniorApiTokens.id, match.id));
4236
+ await getDb().update(juniorApiTokens).set({ lastUsedAt: now }).where(eq16(juniorApiTokens.id, match.id));
4106
4237
  return match.ownerEmailNormalized;
4107
4238
  }
4108
4239
 
@@ -4359,7 +4490,7 @@ function readDescriptionText(home) {
4359
4490
  }
4360
4491
  }
4361
4492
  async function readSkillReports() {
4362
- const { discoverSkills } = await import("./skills-JL44EIRX.js");
4493
+ const { discoverSkills } = await import("./skills-S6HLQRH7.js");
4363
4494
  const skills = await discoverSkills();
4364
4495
  return skillReportsSchema.parse(
4365
4496
  skills.map((skill) => ({
@@ -4369,7 +4500,7 @@ async function readSkillReports() {
4369
4500
  );
4370
4501
  }
4371
4502
  async function readPlugins() {
4372
- const { pluginCatalogRuntime } = await import("./catalog-runtime-CGUDNL3D.js");
4503
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-V6YD6KH5.js");
4373
4504
  return pluginsSchema.parse(
4374
4505
  pluginCatalogRuntime.getProviders().map((plugin) => ({
4375
4506
  configKeys: plugin.manifest.configKeys ?? [],
@@ -4382,7 +4513,7 @@ async function readPlugins() {
4382
4513
  async function readRuntimeInfoReport() {
4383
4514
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
4384
4515
  import("./discovery-GUFTFBTL.js"),
4385
- import("./catalog-runtime-CGUDNL3D.js"),
4516
+ import("./catalog-runtime-V6YD6KH5.js"),
4386
4517
  readPlugins(),
4387
4518
  readSkillReports()
4388
4519
  ]);
@@ -4398,7 +4529,7 @@ async function readRuntimeInfoReport() {
4398
4529
  }
4399
4530
  async function readPluginOperationalReportFeed() {
4400
4531
  const nowMs = Date.now();
4401
- const { getPluginOperationalReports } = await import("./agent-hooks-7BWOB7SN.js");
4532
+ const { getPluginOperationalReports } = await import("./agent-hooks-AWVTLAV2.js");
4402
4533
  return pluginOperationalReportFeedSchema.parse({
4403
4534
  source: "plugins",
4404
4535
  generatedAt: new Date(nowMs).toISOString(),