@sentry/junior 0.98.0 → 0.100.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 (82) hide show
  1. package/dist/{agent-hooks-OSW6C3CJ.js → agent-hooks-V6KU7PQN.js} +6 -5
  2. package/dist/api/activity.d.ts +14 -0
  3. package/dist/api/conversations/aggregate.d.ts +16 -0
  4. package/dist/api/conversations/detail-projection.d.ts +1 -0
  5. package/dist/api/conversations/list.d.ts +7 -2
  6. package/dist/api/conversations/list.query.d.ts +12 -3
  7. package/dist/api/conversations/projection.d.ts +1 -0
  8. package/dist/api/conversations/reporting.d.ts +42 -0
  9. package/dist/api/conversations/schema.d.ts +7 -7
  10. package/dist/api/conversations/stats.query.d.ts +1 -1
  11. package/dist/api/locations/detail.d.ts +81 -0
  12. package/dist/api/locations/list.d.ts +30 -0
  13. package/dist/api/locations/query.d.ts +5 -0
  14. package/dist/api/locations/schema.d.ts +175 -0
  15. package/dist/api/people/list.query.d.ts +1 -1
  16. package/dist/api/people/profile.query.d.ts +1 -1
  17. package/dist/api/people/schema.d.ts +10 -14
  18. package/dist/api/people/shared.d.ts +38 -78
  19. package/dist/api/schema.d.ts +11 -0
  20. package/dist/api/schema.js +16 -3
  21. package/dist/api-reference.d.ts +1 -1
  22. package/dist/api.js +41 -13
  23. package/dist/app.js +35 -27
  24. package/dist/chat/agent/request.d.ts +3 -0
  25. package/dist/chat/config.d.ts +2 -0
  26. package/dist/chat/reasoning-level.d.ts +4 -0
  27. package/dist/chat/services/context-compaction.d.ts +1 -0
  28. package/dist/chat/services/{turn-thinking-level.d.ts → turn-reasoning-level.d.ts} +11 -10
  29. package/dist/chat/services/turn-result.d.ts +3 -3
  30. package/dist/chat/tools/search-tools.d.ts +2 -2
  31. package/dist/{chunk-UAMKJPDF.js → chunk-2RNOB32R.js} +7 -1
  32. package/dist/{chunk-NJEDJFK4.js → chunk-2T7DCRAW.js} +1 -1
  33. package/dist/{chunk-DPHWDS6I.js → chunk-45DMFMY2.js} +81 -69
  34. package/dist/chunk-4AQUWWEM.js +75 -0
  35. package/dist/{chunk-EEZCY5WX.js → chunk-A7X2FDUO.js} +18 -2
  36. package/dist/{chunk-WTYEKPXU.js → chunk-FP5N5OWZ.js} +1 -1
  37. package/dist/chunk-FXFQNHRU.js +48 -0
  38. package/dist/chunk-GEUUJRQF.js +102 -0
  39. package/dist/{chunk-CRQVIHDI.js → chunk-IDZBM3NW.js} +2 -8
  40. package/dist/{chunk-DHHU2WSG.js → chunk-IQIBZXGB.js} +2 -2
  41. package/dist/{chunk-OL6XQ23W.js → chunk-IVXL57YF.js} +3 -3
  42. package/dist/{chunk-IO65E4ZD.js → chunk-JPQISMMJ.js} +3 -3
  43. package/dist/{chunk-KJHAW6VE.js → chunk-JSAANELJ.js} +28 -9
  44. package/dist/{chunk-EUZ44ROE.js → chunk-MM5UFDAC.js} +1 -3
  45. package/dist/{chunk-WJ7STXT6.js → chunk-NSOCZGOH.js} +3 -3
  46. package/dist/chunk-PGGEOCQY.js +77 -0
  47. package/dist/{chunk-EOWXRY5E.js → chunk-PWC24W5F.js} +1 -1
  48. package/dist/chunk-QOZOJNSE.js +96 -0
  49. package/dist/chunk-QSBQJ3PA.js +275 -0
  50. package/dist/{chunk-FTTFV6DC.js → chunk-TPTJEHUE.js} +4 -4
  51. package/dist/{chunk-OGHXZ4KQ.js → chunk-VHRM6GNH.js} +88 -122
  52. package/dist/{chunk-NG2AV7IB.js → chunk-VVIXK2BX.js} +1 -1
  53. package/dist/{chunk-6HHEZENZ.js → chunk-VY7BT4SM.js} +16 -7
  54. package/dist/{chunk-H66UCBPW.js → chunk-XJA7BPHS.js} +1 -1
  55. package/dist/{chunk-ER45IV77.js → chunk-XSBIISXS.js} +9 -9
  56. package/dist/cli/chat.js +15 -14
  57. package/dist/cli/plugins.js +6 -5
  58. package/dist/cli/snapshot-warmup.js +2 -2
  59. package/dist/cli/upgrade.js +8 -7
  60. package/dist/db/schema/conversations.d.ts +17 -0
  61. package/dist/db/schema/destinations.d.ts +12 -3
  62. package/dist/db/schema.d.ts +19 -2
  63. package/dist/{db-GFSCDAHS.js → db-RCZB7KNM.js} +3 -2
  64. package/dist/detail-5SLCGT6J.js +29 -0
  65. package/dist/{detail-W4ZSD45K.js → detail-LU6COZO6.js} +11 -10
  66. package/dist/{legacy-import-6WWXMALY.js → legacy-import-VCYLWT2V.js} +4 -3
  67. package/dist/list-2FI5SFV7.js +80 -0
  68. package/dist/list-4ALSU6ZW.js +30 -0
  69. package/dist/{list-3KZNG3SJ.js → list-KHRAWZWU.js} +11 -8
  70. package/dist/{plugin-conversations-ZYRWZYEA.js → plugin-conversations-JANXC4GA.js} +7 -6
  71. package/dist/profile-3O3OVENT.js +212 -0
  72. package/dist/{runner-267ZRLZD.js → runner-BM7D35YW.js} +12 -11
  73. package/dist/stats-J3YGCYDF.js +174 -0
  74. package/dist/{subagent-5HZPQC7V.js → subagent-P7HOSMVC.js} +10 -9
  75. package/migrations/0003_peaceful_scalphunter.sql +4 -0
  76. package/migrations/meta/0003_snapshot.json +1035 -0
  77. package/migrations/meta/_journal.json +8 -1
  78. package/package.json +5 -5
  79. package/dist/chunk-CV22LUIV.js +0 -261
  80. package/dist/list-M5BRWW3D.js +0 -92
  81. package/dist/profile-UEIRSVT3.js +0 -146
  82. package/dist/stats-L62E4O4U.js +0 -207
@@ -22,6 +22,13 @@
22
22
  "when": 1783870609225,
23
23
  "tag": "0002_conversation_message_search",
24
24
  "breakpoints": true
25
+ },
26
+ {
27
+ "idx": 3,
28
+ "version": "7",
29
+ "when": 1783915376595,
30
+ "tag": "0003_peaceful_scalphunter",
31
+ "breakpoints": true
25
32
  }
26
33
  ]
27
- }
34
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior",
3
- "version": "0.98.0",
3
+ "version": "0.100.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -75,7 +75,7 @@
75
75
  "pg": "^8.16.3",
76
76
  "yaml": "^2.9.0",
77
77
  "zod": "^4.4.3",
78
- "@sentry/junior-plugin-api": "0.98.0"
78
+ "@sentry/junior-plugin-api": "0.100.0"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@emnapi/core": "^1.10.0",
@@ -92,10 +92,10 @@
92
92
  "typescript": "^6.0.3",
93
93
  "vercel": "^54.4.0",
94
94
  "vitest": "^4.1.7",
95
- "@sentry/junior-github": "0.98.0",
96
- "@sentry/junior-memory": "0.98.0",
95
+ "@sentry/junior-github": "0.100.0",
96
+ "@sentry/junior-scheduler": "0.100.0",
97
97
  "@sentry/junior-testing": "0.0.0",
98
- "@sentry/junior-scheduler": "0.98.0"
98
+ "@sentry/junior-memory": "0.100.0"
99
99
  },
100
100
  "scripts": {
101
101
  "build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",
@@ -1,261 +0,0 @@
1
- import {
2
- getDb,
3
- juniorConversations,
4
- juniorDestinations,
5
- juniorIdentities,
6
- juniorUsers
7
- } from "./chunk-OGHXZ4KQ.js";
8
-
9
- // src/api/people/shared.ts
10
- import { and, asc, desc, eq, sql } from "drizzle-orm";
11
- var PRIVATE_CONVERSATION_LABEL = "Private Conversation";
12
- var SAMPLE_LIMIT = 5e3;
13
- var RECENT_LIMIT = 25;
14
- var ACTIVITY_DAYS = 366;
15
- function normalizeEmail(email) {
16
- const normalized = email?.trim().toLowerCase();
17
- return normalized || void 0;
18
- }
19
- function reportTime(value) {
20
- const time = Date.parse(value);
21
- return Number.isFinite(time) ? time : void 0;
22
- }
23
- function reportDate(value) {
24
- const time = reportTime(value);
25
- return time === void 0 ? void 0 : new Date(time).toISOString().slice(0, 10);
26
- }
27
- function channelFromConversationId(conversationId) {
28
- const [provider, channel] = conversationId.split(":");
29
- return provider === "slack" && channel ? channel : void 0;
30
- }
31
- function surfaceFromRow(row) {
32
- const source = row.source;
33
- if (source === "api" || source === "scheduler" || source === "slack") {
34
- return source;
35
- }
36
- if (row.conversationId.startsWith("slack:")) return "slack";
37
- if (row.conversationId.startsWith("scheduler:")) return "scheduler";
38
- if (row.conversationId.startsWith("api:")) return "api";
39
- return "internal";
40
- }
41
- function statusFromRow(row) {
42
- if (row.executionStatus === "failed") {
43
- return "failed";
44
- }
45
- if (row.executionStatus === "idle") {
46
- return "completed";
47
- }
48
- return "active";
49
- }
50
- function surfaceLabel(surface) {
51
- if (surface === "scheduler") return "Scheduler";
52
- if (surface === "api") return "API";
53
- if (surface === "internal") return "Internal";
54
- return "Conversation";
55
- }
56
- function slackLocationLabel(args) {
57
- const channelId = args.channel;
58
- if (!channelId) return void 0;
59
- if (args.channelNameRedacted && args.channelName) {
60
- return args.channelName;
61
- }
62
- const name = args.channelName?.replace(/^#/, "");
63
- if (channelId.startsWith("D")) return "Direct Message";
64
- if (channelId.startsWith("C")) return name ? `#${name}` : "Public Channel";
65
- if (channelId.startsWith("G")) {
66
- if (name?.startsWith("mpdm-")) return "Group DM";
67
- return "Private Channel";
68
- }
69
- return name || channelId;
70
- }
71
- function channelNameFromRow(row) {
72
- if (row.destinationVisibility && row.destinationVisibility !== "public") {
73
- return PRIVATE_CONVERSATION_LABEL;
74
- }
75
- return row.channelName ?? void 0;
76
- }
77
- function titleFromRow(row, surface) {
78
- if (row.destinationVisibility && row.destinationVisibility !== "public") {
79
- return PRIVATE_CONVERSATION_LABEL;
80
- }
81
- const channel = channelFromConversationId(row.conversationId);
82
- return row.title ?? slackLocationLabel({
83
- channel,
84
- channelName: row.channelName ?? void 0
85
- }) ?? surfaceLabel(surface);
86
- }
87
- function summaryFromRow(row) {
88
- const surface = surfaceFromRow(row);
89
- const channel = channelFromConversationId(row.conversationId);
90
- const channelName = channelNameFromRow(row);
91
- const channelNameRedacted = Boolean(row.destinationVisibility) && row.destinationVisibility !== "public";
92
- return {
93
- conversationId: row.conversationId,
94
- cumulativeDurationMs: row.durationMs,
95
- displayTitle: titleFromRow(row, surface),
96
- lastProgressAt: new Date(
97
- row.executionUpdatedAt ?? row.updatedAt
98
- ).toISOString(),
99
- lastSeenAt: row.lastActivityAt.toISOString(),
100
- startedAt: row.createdAt.toISOString(),
101
- status: statusFromRow(row),
102
- surface,
103
- actorIdentity: {
104
- email: row.email,
105
- ...row.fullName ? { fullName: row.fullName } : {},
106
- slackUserId: row.providerSubjectId,
107
- ...row.handle ? { slackUserName: row.handle } : {}
108
- },
109
- ...channel ? { channel } : {},
110
- ...channelName ? { channelName } : {},
111
- ...channelNameRedacted ? { channelNameRedacted: true } : {}
112
- };
113
- }
114
- function usageTokens(row) {
115
- const usage = row.usage;
116
- if (!usage) return void 0;
117
- if (usage.totalTokens !== void 0) return usage.totalTokens;
118
- const values = [
119
- usage.inputTokens,
120
- usage.outputTokens,
121
- usage.cachedInputTokens,
122
- usage.cacheCreationTokens
123
- ].filter((value) => value !== void 0);
124
- return values.length > 0 ? values.reduce((sum, value) => sum + value, 0) : void 0;
125
- }
126
- function emptyTotals() {
127
- return {
128
- active: 0,
129
- activeDays: 0,
130
- conversations: 0,
131
- durationMs: 0,
132
- failed: 0
133
- };
134
- }
135
- function emptyStatsItem(label) {
136
- return {
137
- active: 0,
138
- conversations: 0,
139
- durationMs: 0,
140
- failed: 0,
141
- label
142
- };
143
- }
144
- function emptyActivityDay(date) {
145
- return {
146
- active: 0,
147
- conversations: 0,
148
- date,
149
- durationMs: 0,
150
- failed: 0
151
- };
152
- }
153
- function signals(summary) {
154
- return {
155
- active: summary.status === "active",
156
- failed: summary.status === "failed"
157
- };
158
- }
159
- function addSignals(target, value) {
160
- target.active += value.active ? 1 : 0;
161
- target.failed += value.failed ? 1 : 0;
162
- }
163
- function identityWithEmail(actor) {
164
- const email = normalizeEmail(actor?.email);
165
- if (!email) return void 0;
166
- return {
167
- email,
168
- ...actor?.fullName ? { fullName: actor.fullName } : {},
169
- ...actor?.slackUserId ? { slackUserId: actor.slackUserId } : {},
170
- ...actor?.slackUserName ? { slackUserName: actor.slackUserName } : {}
171
- };
172
- }
173
- function mergeIdentity(current, next) {
174
- return {
175
- email: current.email,
176
- ...current.fullName ?? next.fullName ? { fullName: current.fullName ?? next.fullName } : {},
177
- ...current.slackUserId ?? next.slackUserId ? { slackUserId: current.slackUserId ?? next.slackUserId } : {},
178
- ...current.slackUserName ?? next.slackUserName ? { slackUserName: current.slackUserName ?? next.slackUserName } : {}
179
- };
180
- }
181
- function activityDays(days, nowMs) {
182
- const items = [];
183
- const end = new Date(nowMs);
184
- end.setUTCHours(0, 0, 0, 0);
185
- const start = new Date(end);
186
- start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
187
- for (const cursor = new Date(start); cursor.getTime() <= end.getTime(); cursor.setUTCDate(cursor.getUTCDate() + 1)) {
188
- const date = cursor.toISOString().slice(0, 10);
189
- items.push(days.get(date) ?? emptyActivityDay(date));
190
- }
191
- return items;
192
- }
193
- function statsItems(map) {
194
- return [...map.values()].sort(
195
- (left, right) => right.conversations - left.conversations || right.durationMs - left.durationMs || left.label.localeCompare(right.label)
196
- );
197
- }
198
- async function actorRows(email) {
199
- const normalizedEmail = normalizeEmail(email);
200
- const rows = await getDb().select({
201
- channelName: juniorConversations.channelName,
202
- conversationId: juniorConversations.conversationId,
203
- createdAt: juniorConversations.createdAt,
204
- destinationVisibility: juniorDestinations.visibility,
205
- durationMs: juniorConversations.durationMs,
206
- email: juniorUsers.primaryEmailNormalized,
207
- executionStatus: juniorConversations.executionStatus,
208
- executionUpdatedAt: juniorConversations.executionUpdatedAt,
209
- fullName: juniorUsers.displayName,
210
- handle: juniorIdentities.handle,
211
- lastActivityAt: juniorConversations.lastActivityAt,
212
- providerSubjectId: juniorIdentities.providerSubjectId,
213
- source: juniorConversations.source,
214
- title: juniorConversations.title,
215
- updatedAt: juniorConversations.updatedAt,
216
- usage: juniorConversations.usage
217
- }).from(juniorConversations).innerJoin(
218
- juniorIdentities,
219
- eq(juniorIdentities.id, juniorConversations.actorIdentityId)
220
- ).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).leftJoin(
221
- juniorDestinations,
222
- eq(juniorDestinations.id, juniorConversations.destinationId)
223
- ).where(
224
- and(
225
- eq(juniorIdentities.provider, "slack"),
226
- eq(juniorIdentities.emailVerified, true),
227
- sql`${juniorUsers.primaryEmailNormalized} IS NOT NULL`,
228
- normalizedEmail ? eq(juniorUsers.primaryEmailNormalized, normalizedEmail) : void 0
229
- )
230
- ).orderBy(
231
- desc(juniorConversations.lastActivityAt),
232
- asc(juniorConversations.conversationId)
233
- ).limit(SAMPLE_LIMIT + 1);
234
- return {
235
- rows: rows.slice(0, SAMPLE_LIMIT),
236
- truncated: rows.length > SAMPLE_LIMIT
237
- };
238
- }
239
-
240
- export {
241
- SAMPLE_LIMIT,
242
- RECENT_LIMIT,
243
- ACTIVITY_DAYS,
244
- normalizeEmail,
245
- reportTime,
246
- reportDate,
247
- surfaceLabel,
248
- slackLocationLabel,
249
- summaryFromRow,
250
- usageTokens,
251
- emptyTotals,
252
- emptyStatsItem,
253
- emptyActivityDay,
254
- signals,
255
- addSignals,
256
- identityWithEmail,
257
- mergeIdentity,
258
- activityDays,
259
- statsItems,
260
- actorRows
261
- };
@@ -1,92 +0,0 @@
1
- import {
2
- SAMPLE_LIMIT,
3
- actorRows,
4
- addSignals,
5
- emptyTotals,
6
- identityWithEmail,
7
- mergeIdentity,
8
- reportDate,
9
- reportTime,
10
- signals,
11
- summaryFromRow,
12
- usageTokens
13
- } from "./chunk-CV22LUIV.js";
14
- import {
15
- actorDirectoryReportSchema
16
- } from "./chunk-CRQVIHDI.js";
17
- import "./chunk-EUZ44ROE.js";
18
- import "./chunk-PDO5BLNM.js";
19
- import "./chunk-OGHXZ4KQ.js";
20
- import "./chunk-EEZCY5WX.js";
21
- import "./chunk-LVA4I4H7.js";
22
- import "./chunk-B7PUBQQM.js";
23
- import "./chunk-I35CTGPO.js";
24
- import "./chunk-OB42YVAE.js";
25
- import "./chunk-6GWA276C.js";
26
- import "./chunk-7FBGKXPE.js";
27
- import "./chunk-MLKGABMK.js";
28
-
29
- // src/api/people/list.query.ts
30
- function directoryItem(accumulator) {
31
- return {
32
- active: accumulator.active,
33
- activeDays: accumulator.activeDates.size,
34
- conversations: accumulator.conversations,
35
- durationMs: accumulator.durationMs,
36
- failed: accumulator.failed,
37
- firstSeenAt: new Date(accumulator.firstSeenMs).toISOString(),
38
- lastSeenAt: new Date(accumulator.lastSeenMs).toISOString(),
39
- actor: accumulator.actor,
40
- ...accumulator.tokens !== void 0 ? { tokens: accumulator.tokens } : {}
41
- };
42
- }
43
- async function readPeopleListFromSql() {
44
- const nowMs = Date.now();
45
- const { rows, truncated } = await actorRows();
46
- const people = /* @__PURE__ */ new Map();
47
- for (const row of rows) {
48
- const summary = summaryFromRow(row);
49
- const actor = identityWithEmail(summary.actorIdentity);
50
- if (!actor) continue;
51
- const firstSeenMs = reportTime(summary.startedAt) ?? row.createdAt.getTime();
52
- const lastSeenMs = reportTime(summary.lastSeenAt) ?? row.lastActivityAt.getTime();
53
- const date = reportDate(summary.lastSeenAt);
54
- const accumulator = people.get(actor.email) ?? {
55
- ...emptyTotals(),
56
- activeDates: /* @__PURE__ */ new Set(),
57
- firstSeenMs,
58
- lastSeenMs,
59
- actor
60
- };
61
- accumulator.actor = mergeIdentity(accumulator.actor, actor);
62
- accumulator.conversations += 1;
63
- accumulator.durationMs += summary.cumulativeDurationMs;
64
- const tokens = usageTokens(row);
65
- if (tokens !== void 0) {
66
- accumulator.tokens = (accumulator.tokens ?? 0) + tokens;
67
- }
68
- addSignals(accumulator, signals(summary));
69
- accumulator.firstSeenMs = Math.min(accumulator.firstSeenMs, firstSeenMs);
70
- accumulator.lastSeenMs = Math.max(accumulator.lastSeenMs, lastSeenMs);
71
- if (date) accumulator.activeDates.add(date);
72
- people.set(actor.email, accumulator);
73
- }
74
- return {
75
- generatedAt: new Date(nowMs).toISOString(),
76
- people: [...people.values()].map(directoryItem).sort(
77
- (left, right) => (reportTime(right.lastSeenAt) ?? 0) - (reportTime(left.lastSeenAt) ?? 0) || right.conversations - left.conversations || left.actor.email.localeCompare(right.actor.email)
78
- ),
79
- sampleLimit: SAMPLE_LIMIT,
80
- sampleSize: rows.length,
81
- source: "conversation_index",
82
- truncated
83
- };
84
- }
85
-
86
- // src/api/people/list.ts
87
- async function readPeopleList() {
88
- return actorDirectoryReportSchema.parse(await readPeopleListFromSql());
89
- }
90
- export {
91
- readPeopleList
92
- };
@@ -1,146 +0,0 @@
1
- import {
2
- ACTIVITY_DAYS,
3
- RECENT_LIMIT,
4
- SAMPLE_LIMIT,
5
- activityDays,
6
- actorRows,
7
- addSignals,
8
- emptyActivityDay,
9
- emptyStatsItem,
10
- emptyTotals,
11
- identityWithEmail,
12
- mergeIdentity,
13
- normalizeEmail,
14
- reportDate,
15
- reportTime,
16
- signals,
17
- slackLocationLabel,
18
- statsItems,
19
- summaryFromRow,
20
- surfaceLabel,
21
- usageTokens
22
- } from "./chunk-CV22LUIV.js";
23
- import {
24
- actorProfileReportSchema
25
- } from "./chunk-CRQVIHDI.js";
26
- import "./chunk-EUZ44ROE.js";
27
- import "./chunk-PDO5BLNM.js";
28
- import "./chunk-OGHXZ4KQ.js";
29
- import "./chunk-EEZCY5WX.js";
30
- import "./chunk-LVA4I4H7.js";
31
- import "./chunk-B7PUBQQM.js";
32
- import "./chunk-I35CTGPO.js";
33
- import "./chunk-OB42YVAE.js";
34
- import "./chunk-6GWA276C.js";
35
- import "./chunk-7FBGKXPE.js";
36
- import "./chunk-MLKGABMK.js";
37
-
38
- // src/api/people/profile.query.ts
39
- function emptyProfile(email, nowMs) {
40
- const end = new Date(nowMs);
41
- end.setUTCHours(0, 0, 0, 0);
42
- const start = new Date(end);
43
- start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
44
- return {
45
- activityDays: activityDays(/* @__PURE__ */ new Map(), nowMs),
46
- generatedAt: new Date(nowMs).toISOString(),
47
- locations: [],
48
- recentConversations: [],
49
- actor: { email },
50
- sampleLimit: SAMPLE_LIMIT,
51
- sampleSize: 0,
52
- source: "conversation_index",
53
- surfaces: [],
54
- totals: emptyTotals(),
55
- truncated: false,
56
- windowEnd: end.toISOString(),
57
- windowStart: start.toISOString()
58
- };
59
- }
60
- async function readPeopleProfileFromSql(email) {
61
- const nowMs = Date.now();
62
- const normalizedEmail = normalizeEmail(email);
63
- if (!normalizedEmail) {
64
- return emptyProfile("", nowMs);
65
- }
66
- const { rows, truncated } = await actorRows(normalizedEmail);
67
- let actor;
68
- const totals = emptyTotals();
69
- const activeDates = /* @__PURE__ */ new Set();
70
- const days = /* @__PURE__ */ new Map();
71
- const locations = /* @__PURE__ */ new Map();
72
- const surfaces = /* @__PURE__ */ new Map();
73
- const recentConversations = [];
74
- for (const row of rows) {
75
- const summary = summaryFromRow(row);
76
- const identity = identityWithEmail(summary.actorIdentity);
77
- if (identity) {
78
- actor = actor ? mergeIdentity(actor, identity) : identity;
79
- }
80
- recentConversations.push(summary);
81
- const value = signals(summary);
82
- const date = reportDate(summary.lastSeenAt);
83
- totals.conversations += 1;
84
- totals.durationMs += summary.cumulativeDurationMs;
85
- const tokens = usageTokens(row);
86
- if (tokens !== void 0) totals.tokens = (totals.tokens ?? 0) + tokens;
87
- addSignals(totals, value);
88
- if (date) {
89
- activeDates.add(date);
90
- const day = days.get(date) ?? emptyActivityDay(date);
91
- day.conversations += 1;
92
- day.durationMs += summary.cumulativeDurationMs;
93
- if (tokens !== void 0) day.tokens = (day.tokens ?? 0) + tokens;
94
- addSignals(day, value);
95
- days.set(date, day);
96
- }
97
- const location = slackLocationLabel(summary) ?? surfaceLabel(summary.surface);
98
- const locationItem = locations.get(location) ?? emptyStatsItem(location);
99
- locationItem.conversations += 1;
100
- locationItem.durationMs += summary.cumulativeDurationMs;
101
- if (tokens !== void 0) {
102
- locationItem.tokens = (locationItem.tokens ?? 0) + tokens;
103
- }
104
- addSignals(locationItem, value);
105
- locations.set(location, locationItem);
106
- const surface = surfaceLabel(summary.surface);
107
- const surfaceItem = surfaces.get(surface) ?? emptyStatsItem(surface);
108
- surfaceItem.conversations += 1;
109
- surfaceItem.durationMs += summary.cumulativeDurationMs;
110
- if (tokens !== void 0) {
111
- surfaceItem.tokens = (surfaceItem.tokens ?? 0) + tokens;
112
- }
113
- addSignals(surfaceItem, value);
114
- surfaces.set(surface, surfaceItem);
115
- }
116
- totals.activeDays = activeDates.size;
117
- const end = new Date(nowMs);
118
- end.setUTCHours(0, 0, 0, 0);
119
- const start = new Date(end);
120
- start.setUTCDate(start.getUTCDate() - (ACTIVITY_DAYS - 1));
121
- return {
122
- activityDays: activityDays(days, nowMs),
123
- generatedAt: new Date(nowMs).toISOString(),
124
- locations: statsItems(locations),
125
- recentConversations: recentConversations.sort(
126
- (left, right) => (reportTime(right.lastSeenAt) ?? 0) - (reportTime(left.lastSeenAt) ?? 0) || right.conversationId.localeCompare(left.conversationId)
127
- ).slice(0, RECENT_LIMIT),
128
- actor: actor ?? { email: normalizedEmail },
129
- sampleLimit: SAMPLE_LIMIT,
130
- sampleSize: rows.length,
131
- source: "conversation_index",
132
- surfaces: statsItems(surfaces),
133
- totals,
134
- truncated,
135
- windowEnd: end.toISOString(),
136
- windowStart: start.toISOString()
137
- };
138
- }
139
-
140
- // src/api/people/profile.ts
141
- async function readPeopleProfile(email) {
142
- return actorProfileReportSchema.parse(await readPeopleProfileFromSql(email));
143
- }
144
- export {
145
- readPeopleProfile
146
- };