@sentry/junior 0.136.1 → 0.137.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 (58) hide show
  1. package/dist/{agent-hooks-2KDSPPO4.js → agent-hooks-MZOKEP3J.js} +9 -9
  2. package/dist/api/conversations/projection.d.ts +1 -0
  3. package/dist/api/conversations/stats.d.ts +1 -0
  4. package/dist/api/schema/conversation.d.ts +2 -0
  5. package/dist/api/schema.js +1 -1
  6. package/dist/api.js +185 -47
  7. package/dist/app.d.ts +1 -1
  8. package/dist/app.js +293 -193
  9. package/dist/{catalog-runtime-WSZQGC4D.js → catalog-runtime-MD66YLFV.js} +5 -5
  10. package/dist/chat/configuration/defaults.d.ts +1 -1
  11. package/dist/chat/conversations/store.d.ts +2 -1
  12. package/dist/chat/pi/client.d.ts +1 -8
  13. package/dist/chat/pi/gateway-auth.d.ts +16 -0
  14. package/dist/chat/sandbox/docker.d.ts +17 -0
  15. package/dist/chat/services/agent-continue.d.ts +2 -0
  16. package/dist/chat/services/subscribed-reply-router-policy.d.ts +12 -0
  17. package/dist/chat/services/turn-session-routing.d.ts +17 -0
  18. package/dist/chat/slack/message.d.ts +6 -1
  19. package/dist/chat/slack/source-link.d.ts +8 -2
  20. package/dist/chat/slack/team-domain.d.ts +4 -0
  21. package/dist/chat/source.d.ts +5 -5
  22. package/dist/{chunk-3QNJOHKG.js → chunk-36EG34YI.js} +1 -1
  23. package/dist/{chunk-FSYXYBWU.js → chunk-3Q342EJJ.js} +2 -2
  24. package/dist/{chunk-4YQ6I6VF.js → chunk-5G34IEK2.js} +1 -1
  25. package/dist/{chunk-BG3KWWDJ.js → chunk-5PNJMOY5.js} +1 -1
  26. package/dist/{chunk-3SUK3UXX.js → chunk-6QW2RRQT.js} +5 -5
  27. package/dist/{chunk-VH6MI4L7.js → chunk-BZAMASJP.js} +1 -1
  28. package/dist/{chunk-CDVCCOMF.js → chunk-DQXAAVTR.js} +43 -20
  29. package/dist/{chunk-G66RYKRS.js → chunk-EWDSB24B.js} +7 -7
  30. package/dist/{chunk-TRZSM67C.js → chunk-HCIVH3JS.js} +1 -0
  31. package/dist/{chunk-UX2TNH5D.js → chunk-K2NCQJKH.js} +3 -3
  32. package/dist/{chunk-OTJMQYVP.js → chunk-KJ4HGRHN.js} +24 -26
  33. package/dist/{chunk-NVVBEJUB.js → chunk-POBSY47Q.js} +6 -4
  34. package/dist/{chunk-MW2QRPGW.js → chunk-RB4NJKEX.js} +1 -1
  35. package/dist/{chunk-Y6JNHTRD.js → chunk-SYCX4DOK.js} +34 -17
  36. package/dist/{chunk-XWPA5KZF.js → chunk-T6Z5S6PQ.js} +1 -1
  37. package/dist/{chunk-XCZ6COFO.js → chunk-UG6ZYPBI.js} +42 -19
  38. package/dist/{chunk-CZZDCH3Q.js → chunk-UOXATPSI.js} +203 -77
  39. package/dist/{chunk-RFDD3Z2I.js → chunk-UZQ4VY3M.js} +1 -1
  40. package/dist/{chunk-KLBYCSLJ.js → chunk-WPPXIAFB.js} +5 -5
  41. package/dist/{chunk-JQRTXJHD.js → chunk-XZ7NPXAB.js} +2 -1
  42. package/dist/{chunk-22Z6MGMK.js → chunk-YNFERGKP.js} +1 -1
  43. package/dist/{chunk-TYNMSQKA.js → chunk-YRPC6MJY.js} +1 -1
  44. package/dist/{chunk-HIRIWTWD.js → chunk-ZFS67WIR.js} +4 -7
  45. package/dist/cli/chat.js +24 -24
  46. package/dist/cli/check.js +7 -7
  47. package/dist/cli/plugins.js +12 -12
  48. package/dist/cli/snapshot-create.js +9 -9
  49. package/dist/cli/upgrade.js +7 -7
  50. package/dist/{db-Z2NNL2JC.js → db-66E7VDNC.js} +7 -7
  51. package/dist/instrumentation.js +4 -4
  52. package/dist/nitro.js +2 -2
  53. package/dist/{oauth-callback-server-PO3M5JMG.js → oauth-callback-server-7QPD4Q7P.js} +17 -17
  54. package/dist/{runner-QHQYZYJA.js → runner-L2BKJKOD.js} +11 -11
  55. package/dist/{skills-KXMT3DRA.js → skills-HOQ2NSPW.js} +6 -6
  56. package/dist/{validation-Y42ULTT6.js → validation-ENHI7S2C.js} +6 -6
  57. package/dist/version.js +1 -1
  58. package/package.json +5 -4
@@ -11,19 +11,19 @@ import {
11
11
  getPlugins,
12
12
  setPlugins,
13
13
  validatePlugins
14
- } from "./chunk-KLBYCSLJ.js";
15
- import "./chunk-HIRIWTWD.js";
16
- import "./chunk-MW2QRPGW.js";
17
- import "./chunk-4YQ6I6VF.js";
18
- import "./chunk-XCZ6COFO.js";
14
+ } from "./chunk-WPPXIAFB.js";
15
+ import "./chunk-ZFS67WIR.js";
16
+ import "./chunk-RB4NJKEX.js";
17
+ import "./chunk-5G34IEK2.js";
18
+ import "./chunk-UG6ZYPBI.js";
19
19
  import "./chunk-VFUK3X5B.js";
20
- import "./chunk-22Z6MGMK.js";
20
+ import "./chunk-YNFERGKP.js";
21
21
  import "./chunk-HZF5P5UN.js";
22
22
  import "./chunk-F3B2YJ76.js";
23
- import "./chunk-XWPA5KZF.js";
23
+ import "./chunk-T6Z5S6PQ.js";
24
24
  import "./chunk-6GWA276C.js";
25
- import "./chunk-BG3KWWDJ.js";
26
- import "./chunk-JQRTXJHD.js";
25
+ import "./chunk-5PNJMOY5.js";
26
+ import "./chunk-XZ7NPXAB.js";
27
27
  import "./chunk-MLKGABMK.js";
28
28
  export {
29
29
  PluginHookDeniedError,
@@ -14,6 +14,7 @@ export declare function conversationSummaryFromStoredConversation(args: {
14
14
  conversation: ConversationProjectionSource;
15
15
  durationMs: number;
16
16
  locationId?: string;
17
+ teamDomainByTeamId?: ReadonlyMap<string, string>;
17
18
  usage?: ConversationUsage;
18
19
  }): ConversationSummaryReport;
19
20
  export {};
@@ -24,6 +24,7 @@ declare const _default: import("../route").ApiRoute<import("zod").ZodObject<{
24
24
  requests: import("zod").ZodNumber;
25
25
  }, import("zod/v4/core").$strict>;
26
26
  metricDays: import("zod").ZodArray<import("zod").ZodObject<{
27
+ conversations: import("zod").ZodNumber;
27
28
  costUsd: import("zod").ZodOptional<import("zod").ZodNumber>;
28
29
  date: import("zod").ZodString;
29
30
  durationMs: import("zod").ZodNumber;
@@ -1046,6 +1046,7 @@ export declare const conversationStatsItemSchema: z.ZodObject<{
1046
1046
  tokens: z.ZodOptional<z.ZodNumber>;
1047
1047
  }, z.core.$strict>;
1048
1048
  export declare const conversationMetricDaySchema: z.ZodObject<{
1049
+ conversations: z.ZodNumber;
1049
1050
  costUsd: z.ZodOptional<z.ZodNumber>;
1050
1051
  date: z.ZodString;
1051
1052
  durationMs: z.ZodNumber;
@@ -1096,6 +1097,7 @@ export declare const conversationStatsReportSchema: z.ZodObject<{
1096
1097
  requests: z.ZodNumber;
1097
1098
  }, z.core.$strict>;
1098
1099
  metricDays: z.ZodArray<z.ZodObject<{
1100
+ conversations: z.ZodNumber;
1099
1101
  costUsd: z.ZodOptional<z.ZodNumber>;
1100
1102
  date: z.ZodString;
1101
1103
  durationMs: z.ZodNumber;
@@ -37,7 +37,7 @@ import {
37
37
  taskListSchema,
38
38
  taskParamsSchema,
39
39
  taskSummarySchema
40
- } from "../chunk-TRZSM67C.js";
40
+ } from "../chunk-HCIVH3JS.js";
41
41
  import {
42
42
  healthReportSchema,
43
43
  pluginOperationalReportFeedSchema,
package/dist/api.js CHANGED
@@ -27,14 +27,14 @@ import {
27
27
  statsReportSchema,
28
28
  taskListSchema,
29
29
  taskParamsSchema
30
- } from "./chunk-TRZSM67C.js";
30
+ } from "./chunk-HCIVH3JS.js";
31
31
  import {
32
32
  formatSlackConversationRedactedLabel,
33
33
  readHealthReport,
34
34
  readTaskExecutionDays,
35
35
  readTaskExecutionSummaries,
36
36
  resolveSlackConversationContextFromThreadId
37
- } from "./chunk-3SUK3UXX.js";
37
+ } from "./chunk-6QW2RRQT.js";
38
38
  import {
39
39
  buildSentryConversationUrl
40
40
  } from "./chunk-4CODA7P5.js";
@@ -56,10 +56,10 @@ import {
56
56
  listPublicEventTasksForTeams,
57
57
  listPublicScheduledTasksForTeams,
58
58
  readStats
59
- } from "./chunk-UX2TNH5D.js";
59
+ } from "./chunk-K2NCQJKH.js";
60
60
  import {
61
61
  parseSlackThreadId
62
- } from "./chunk-TYNMSQKA.js";
62
+ } from "./chunk-YRPC6MJY.js";
63
63
  import {
64
64
  agentTurnUsageSchema,
65
65
  hasAgentTurnUsage,
@@ -69,41 +69,44 @@ import "./chunk-PDO5BLNM.js";
69
69
  import {
70
70
  createPluginLogger,
71
71
  getPlugins,
72
+ getSlackClient,
72
73
  listConversationAnnotations,
73
74
  renderPluginConversationEvent,
74
- resolveViewerUser
75
- } from "./chunk-KLBYCSLJ.js";
75
+ resolveViewerUser,
76
+ withSlackRetries
77
+ } from "./chunk-WPPXIAFB.js";
76
78
  import {
77
79
  decodeStoredConversationEvent,
78
80
  getDb,
79
81
  getSqlExecutor,
80
82
  locationFromRow,
81
83
  parseSessionSource
82
- } from "./chunk-HIRIWTWD.js";
84
+ } from "./chunk-ZFS67WIR.js";
83
85
  import {
84
86
  juniorApiTokens,
85
87
  juniorConversationEvents,
86
88
  juniorConversations,
87
89
  juniorIdentities,
88
90
  juniorUsers
89
- } from "./chunk-MW2QRPGW.js";
90
- import "./chunk-4YQ6I6VF.js";
91
- import "./chunk-XCZ6COFO.js";
91
+ } from "./chunk-RB4NJKEX.js";
92
+ import "./chunk-5G34IEK2.js";
93
+ import "./chunk-UG6ZYPBI.js";
92
94
  import {
93
95
  juniorDestinations
94
96
  } from "./chunk-VFUK3X5B.js";
95
97
  import {
96
98
  canExposeConversationPayload
97
- } from "./chunk-22Z6MGMK.js";
99
+ } from "./chunk-YNFERGKP.js";
98
100
  import "./chunk-HZF5P5UN.js";
99
101
  import {
100
102
  parseSlackChannelId,
103
+ parseSlackMessageTs,
101
104
  parseSlackTeamId
102
105
  } from "./chunk-F3B2YJ76.js";
103
- import "./chunk-XWPA5KZF.js";
106
+ import "./chunk-T6Z5S6PQ.js";
104
107
  import "./chunk-6GWA276C.js";
105
- import "./chunk-BG3KWWDJ.js";
106
- import "./chunk-JQRTXJHD.js";
108
+ import "./chunk-5PNJMOY5.js";
109
+ import "./chunk-XZ7NPXAB.js";
107
110
  import "./chunk-MLKGABMK.js";
108
111
 
109
112
  // src/api.ts
@@ -200,6 +203,120 @@ var archive_default = defineApiRoute({
200
203
  }
201
204
  });
202
205
 
206
+ // src/chat/slack/source-link.ts
207
+ function parseSlackTeamDomain(value) {
208
+ if (typeof value !== "string") return void 0;
209
+ const domain = value.trim().toLowerCase();
210
+ if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(domain)) {
211
+ return void 0;
212
+ }
213
+ return domain;
214
+ }
215
+ function archivePathFromThreadTs(threadTs) {
216
+ const [seconds, fraction = ""] = threadTs.split(".");
217
+ return `p${seconds}${(fraction ?? "").padEnd(6, "0").slice(0, 6)}`;
218
+ }
219
+ function buildSlackSourceUrl(args) {
220
+ const channelId = parseSlackChannelId(args.channelId);
221
+ const teamDomain = parseSlackTeamDomain(args.teamDomain);
222
+ const threadTs = parseSlackMessageTs(args.threadTs);
223
+ if (!channelId || !teamDomain || !threadTs) return void 0;
224
+ const url = new URL(
225
+ `https://${teamDomain}.slack.com/archives/${channelId}/${archivePathFromThreadTs(threadTs)}`
226
+ );
227
+ url.searchParams.set("thread_ts", threadTs);
228
+ url.searchParams.set("cid", channelId);
229
+ return url.toString();
230
+ }
231
+
232
+ // src/chat/slack/team-domain.ts
233
+ var TEAM_DOMAIN_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
234
+ var TEAM_DOMAIN_NEGATIVE_CACHE_TTL_MS = 60 * 1e3;
235
+ var teamDomainCache = /* @__PURE__ */ new Map();
236
+ var teamDomainInflight = /* @__PURE__ */ new Map();
237
+ function readTeamDomainCache(teamId) {
238
+ const hit = teamDomainCache.get(teamId);
239
+ if (!hit) return void 0;
240
+ if (hit.expiresAt < Date.now()) {
241
+ teamDomainCache.delete(teamId);
242
+ return void 0;
243
+ }
244
+ return hit.kind === "hit" ? hit.domain : null;
245
+ }
246
+ function writeTeamDomainCache(teamId, domain) {
247
+ if (domain) {
248
+ teamDomainCache.set(teamId, {
249
+ kind: "hit",
250
+ domain,
251
+ expiresAt: Date.now() + TEAM_DOMAIN_CACHE_TTL_MS
252
+ });
253
+ return;
254
+ }
255
+ teamDomainCache.set(teamId, {
256
+ kind: "miss",
257
+ expiresAt: Date.now() + TEAM_DOMAIN_NEGATIVE_CACHE_TTL_MS
258
+ });
259
+ }
260
+ async function fetchSlackTeamDomain(teamId) {
261
+ try {
262
+ const response = await withSlackRetries(
263
+ () => getSlackClient().team.info({ team: teamId }),
264
+ 3,
265
+ {
266
+ action: "team.info",
267
+ idempotent: true,
268
+ spanAttributes: {
269
+ "app.slack.team_id": teamId
270
+ }
271
+ }
272
+ );
273
+ const responseTeamId = parseSlackTeamId(response.team?.id);
274
+ const domain = parseSlackTeamDomain(response.team?.domain);
275
+ if (!domain || !responseTeamId || responseTeamId !== teamId) {
276
+ writeTeamDomainCache(teamId, void 0);
277
+ return void 0;
278
+ }
279
+ writeTeamDomainCache(teamId, domain);
280
+ return domain;
281
+ } catch {
282
+ writeTeamDomainCache(teamId, void 0);
283
+ return void 0;
284
+ }
285
+ }
286
+ async function resolveSlackTeamDomain(teamId) {
287
+ const parsedTeamId = parseSlackTeamId(teamId);
288
+ if (!parsedTeamId) return void 0;
289
+ const cached = readTeamDomainCache(parsedTeamId);
290
+ if (cached !== void 0) {
291
+ return cached ?? void 0;
292
+ }
293
+ const pending = teamDomainInflight.get(parsedTeamId);
294
+ if (pending) return pending;
295
+ const lookup = fetchSlackTeamDomain(parsedTeamId).finally(() => {
296
+ teamDomainInflight.delete(parsedTeamId);
297
+ });
298
+ teamDomainInflight.set(parsedTeamId, lookup);
299
+ return lookup;
300
+ }
301
+ async function resolveSlackTeamDomains(teamIds) {
302
+ const uniqueTeamIds = [
303
+ ...new Set(
304
+ [...teamIds].map((teamId) => parseSlackTeamId(teamId)).filter((teamId) => teamId !== void 0)
305
+ )
306
+ ];
307
+ const resolved = await Promise.all(
308
+ uniqueTeamIds.map(async (teamId) => {
309
+ const domain = await resolveSlackTeamDomain(teamId);
310
+ return domain ? [teamId, domain] : void 0;
311
+ })
312
+ );
313
+ return new Map(
314
+ resolved.filter(
315
+ (entry) => entry !== void 0
316
+ )
317
+ );
318
+ }
319
+
203
320
  // src/chat/pi/sql-model-usage.ts
204
321
  import { and as and2, eq as eq2, sql } from "drizzle-orm";
205
322
  var message = sql`${juniorConversationEvents.payload}`;
@@ -873,17 +990,6 @@ async function readConversationEventPage(executor, args) {
873
990
  // src/api/conversations/list.ts
874
991
  import { and as and6, asc as asc2, desc as desc2, eq as eq7, isNull as isNull3 } from "drizzle-orm";
875
992
 
876
- // src/chat/slack/source-link.ts
877
- function buildSlackSourceUrl(args) {
878
- const channelId = parseSlackChannelId(args.channelId);
879
- const teamId = parseSlackTeamId(args.teamId);
880
- if (!channelId || !teamId) return void 0;
881
- const url = new URL("https://slack.com/app_redirect");
882
- url.searchParams.set("channel", channelId);
883
- url.searchParams.set("team", teamId);
884
- return url.toString();
885
- }
886
-
887
993
  // src/api/conversations/shared.ts
888
994
  function slackStatsLocationLabel(input) {
889
995
  const channelId = input.channel;
@@ -927,11 +1033,21 @@ function surfaceFromSource(source, conversationId) {
927
1033
  }
928
1034
  return surfaceFromConversationId(conversationId);
929
1035
  }
930
- function sourceUrlFromConversation(conversation, canViewPrivateContent) {
931
- if (!canViewPrivateContent || conversation.sessionSource?.platform !== "slack") {
1036
+ function sourceUrlFromConversation(args) {
1037
+ const { conversation } = args;
1038
+ if (!args.canViewPrivateContent || conversation.sessionSource?.platform !== "slack") {
932
1039
  return void 0;
933
1040
  }
934
- return buildSlackSourceUrl(conversation.sessionSource);
1041
+ const teamDomain = args.teamDomainByTeamId?.get(
1042
+ conversation.sessionSource.teamId
1043
+ );
1044
+ const threadTs = conversation.sessionSource.threadTs;
1045
+ if (!teamDomain || !threadTs) return void 0;
1046
+ return buildSlackSourceUrl({
1047
+ channelId: conversation.sessionSource.channelId,
1048
+ teamDomain,
1049
+ threadTs
1050
+ });
935
1051
  }
936
1052
  function actorIdentityReport(actor) {
937
1053
  if (!actor) return void 0;
@@ -1009,10 +1125,11 @@ function conversationSummaryFromStoredConversation(args) {
1009
1125
  conversation.conversationId
1010
1126
  );
1011
1127
  const actorIdentity = actorIdentityReport(conversation.actor);
1012
- const sourceUrl = sourceUrlFromConversation(
1128
+ const sourceUrl = sourceUrlFromConversation({
1129
+ canViewPrivateContent,
1013
1130
  conversation,
1014
- canViewPrivateContent
1015
- );
1131
+ ...args.teamDomainByTeamId ? { teamDomainByTeamId: args.teamDomainByTeamId } : {}
1132
+ });
1016
1133
  const slackThread = parseSlackThreadId(conversation.conversationId);
1017
1134
  const channelName = channelNameFromConversation(
1018
1135
  conversation,
@@ -1420,8 +1537,16 @@ async function readConversationFeedFromSql(options = {}) {
1420
1537
  options.limit ?? CONVERSATION_FEED_LIMIT,
1421
1538
  options.actorEmail
1422
1539
  );
1423
- const conversationIds = rows.map((row) => row.conversation.conversationId);
1424
- const [accessByConversation, auxiliaryCostsByRoot, metricsByRoot] = await Promise.all([
1540
+ const conversations = rows.map((row) => conversationFromRow(row));
1541
+ const conversationIds = conversations.map(
1542
+ (conversation) => conversation.conversationId
1543
+ );
1544
+ const [
1545
+ accessByConversation,
1546
+ auxiliaryCostsByRoot,
1547
+ metricsByRoot,
1548
+ teamDomainByTeamId
1549
+ ] = await Promise.all([
1425
1550
  readConversationAccessFromSql(
1426
1551
  db,
1427
1552
  conversationIds,
@@ -1430,18 +1555,23 @@ async function readConversationFeedFromSql(options = {}) {
1430
1555
  readConversationAuxiliaryCostsFromSql(db, conversationIds, {
1431
1556
  includeDescendants: true
1432
1557
  }),
1433
- readRootConversationMetricsFromSql(db, conversationIds)
1558
+ readRootConversationMetricsFromSql(db, conversationIds),
1559
+ resolveSlackTeamDomains(
1560
+ conversations.flatMap(
1561
+ (conversation) => conversation.sessionSource?.platform === "slack" ? [conversation.sessionSource.teamId] : []
1562
+ )
1563
+ )
1434
1564
  ]);
1435
1565
  return {
1436
- conversations: rows.map((row) => {
1437
- const metrics = metricsByRoot.get(row.conversation.conversationId);
1566
+ conversations: conversations.map((conversation, index) => {
1567
+ const row = rows[index];
1568
+ const metrics = metricsByRoot.get(conversation.conversationId);
1438
1569
  return conversationSummaryFromStoredConversation({
1439
- conversation: conversationFromRow(row),
1440
- access: accessByConversation.get(row.conversation.conversationId),
1441
- auxiliaryCosts: auxiliaryCostsByRoot.get(
1442
- row.conversation.conversationId
1443
- ),
1570
+ conversation,
1571
+ access: accessByConversation.get(conversation.conversationId),
1572
+ auxiliaryCosts: auxiliaryCostsByRoot.get(conversation.conversationId),
1444
1573
  durationMs: metrics?.durationMs ?? row.conversation.durationMs,
1574
+ teamDomainByTeamId,
1445
1575
  ...row.destination?.visibility === "public" ? { locationId: row.destination.id } : {},
1446
1576
  usage: metrics?.usage ?? row.conversation.usage ?? void 0
1447
1577
  });
@@ -1487,6 +1617,7 @@ function projectConversationDetail(args) {
1487
1617
  conversation,
1488
1618
  durationMs: args.durationMs,
1489
1619
  ...args.locationId ? { locationId: args.locationId } : {},
1620
+ ...args.teamDomainByTeamId ? { teamDomainByTeamId: args.teamDomainByTeamId } : {},
1490
1621
  usage: args.usage
1491
1622
  }),
1492
1623
  annotations: canExposePayload ? args.annotations : [],
@@ -1516,7 +1647,8 @@ async function readConversationDetailFromSql(conversationId, options) {
1516
1647
  annotations,
1517
1648
  auxiliaryCostsByConversation,
1518
1649
  modelUsage,
1519
- metricsByRoot
1650
+ metricsByRoot,
1651
+ teamDomainByTeamId
1520
1652
  ] = await Promise.all([
1521
1653
  readConversationAccessFromSql(
1522
1654
  getDb(),
@@ -1534,6 +1666,9 @@ async function readConversationDetailFromSql(conversationId, options) {
1534
1666
  readRootConversationMetricsFromSql(
1535
1667
  getDb(),
1536
1668
  includeDescendantMetrics ? [conversationId] : []
1669
+ ),
1670
+ resolveSlackTeamDomains(
1671
+ record.conversation.sessionSource?.platform === "slack" ? [record.conversation.sessionSource.teamId] : []
1537
1672
  )
1538
1673
  ]);
1539
1674
  const access = accessByConversation.get(conversationId);
@@ -1551,6 +1686,7 @@ async function readConversationDetailFromSql(conversationId, options) {
1551
1686
  durationMs: metrics?.durationMs ?? record.durationMs,
1552
1687
  events: page.events,
1553
1688
  modelUsage,
1689
+ teamDomainByTeamId,
1554
1690
  ...page.previousSeq === void 0 ? {} : { previousSeq: page.previousSeq },
1555
1691
  usage: metrics?.usage ?? record.usage ?? void 0
1556
1692
  });
@@ -1803,9 +1939,10 @@ function metricDays(rows, endMs) {
1803
1939
  const date = cursor.toISOString().slice(0, 10);
1804
1940
  const row = byDate.get(date);
1805
1941
  days.push({
1942
+ conversations: row?.conversations ?? 0,
1806
1943
  date,
1807
1944
  durationMs: row?.durationMs ?? 0,
1808
- ...row?.costUsd !== null && row?.costUsd !== void 0 ? { costUsd: row.costUsd } : {},
1945
+ ...row?.costUsd !== null && row?.costUsd !== void 0 ? { costUsd: addUsd(void 0, row.costUsd) } : {},
1809
1946
  ...row?.tokens !== null && row?.tokens !== void 0 ? { tokens: row.tokens } : {}
1810
1947
  });
1811
1948
  }
@@ -1916,6 +2053,7 @@ async function aggregateStats(db, start, end) {
1916
2053
  juniorDestinations.visibility
1917
2054
  ),
1918
2055
  db.select({
2056
+ conversations: treeAggregateColumns.conversations,
1919
2057
  costUsd: treeAggregateColumns.costUsd,
1920
2058
  date: activityDate,
1921
2059
  durationMs: treeAggregateColumns.durationMs,
@@ -2029,7 +2167,7 @@ function readDescriptionText(home) {
2029
2167
  }
2030
2168
  }
2031
2169
  async function readSkillReports() {
2032
- const { discoverSkills } = await import("./skills-KXMT3DRA.js");
2170
+ const { discoverSkills } = await import("./skills-HOQ2NSPW.js");
2033
2171
  const skills = await discoverSkills();
2034
2172
  return skillReportsSchema.parse(
2035
2173
  skills.map((skill) => ({
@@ -2039,7 +2177,7 @@ async function readSkillReports() {
2039
2177
  );
2040
2178
  }
2041
2179
  async function readPlugins() {
2042
- const { pluginCatalogRuntime } = await import("./catalog-runtime-WSZQGC4D.js");
2180
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-MD66YLFV.js");
2043
2181
  return pluginsSchema.parse(
2044
2182
  pluginCatalogRuntime.getProviders().map((plugin) => ({
2045
2183
  configKeys: plugin.manifest.configKeys ?? [],
@@ -2052,7 +2190,7 @@ async function readPlugins() {
2052
2190
  async function readRuntimeInfoReport() {
2053
2191
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
2054
2192
  import("./discovery-GUFTFBTL.js"),
2055
- import("./catalog-runtime-WSZQGC4D.js"),
2193
+ import("./catalog-runtime-MD66YLFV.js"),
2056
2194
  readPlugins(),
2057
2195
  readSkillReports()
2058
2196
  ]);
@@ -2068,7 +2206,7 @@ async function readRuntimeInfoReport() {
2068
2206
  }
2069
2207
  async function readPluginOperationalReportFeed() {
2070
2208
  const nowMs = Date.now();
2071
- const { getPluginOperationalReports } = await import("./agent-hooks-2KDSPPO4.js");
2209
+ const { getPluginOperationalReports } = await import("./agent-hooks-MZOKEP3J.js");
2072
2210
  return pluginOperationalReportFeedSchema.parse({
2073
2211
  source: "plugins",
2074
2212
  generatedAt: new Date(nowMs).toISOString(),
package/dist/app.d.ts CHANGED
@@ -16,7 +16,7 @@ export interface JuniorAppOptions {
16
16
  /** Slack emoji shown after a turn completes. Defaults to `white_check_mark`. */
17
17
  completedReactionEmoji?: string;
18
18
  };
19
- /** Install-wide provider defaults (`provider.key` format). Channel overrides take precedence. */
19
+ /** Install-wide provider defaults. Unregistered `provider.key` entries warn at startup. */
20
20
  configDefaults?: Record<string, unknown>;
21
21
  /** Queue consumer wiring for the durable conversation worker. */
22
22
  conversationWork?: VercelConversationWorkCallbackOptions;