@sentry/junior 0.203.0 → 0.204.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.
- package/dist/agent-CMyTD4DD.js +17509 -0
- package/dist/agent-hooks-Bbcp9e33.js +4040 -0
- package/dist/agent-runner-DNb1A49M.js +678 -0
- package/dist/api/schema.d.ts +2728 -2639
- package/dist/api/schema.js +4 -169
- package/dist/api.d.ts +23 -17
- package/dist/api.js +3881 -5326
- package/dist/app-B1TOqBI8.d.ts +246 -0
- package/dist/app.d.ts +4 -520
- package/dist/app.js +9522 -11875
- package/dist/auth-pause-state-DosEalIG.js +168 -0
- package/dist/catalog-runtime-BReos-D4.js +7 -0
- package/dist/checkpoint-CNrPyRJN.js +2450 -0
- package/dist/cli/chat.d.ts +20 -0
- package/dist/cli/chat.js +229 -336
- package/dist/cli/check.d.ts +8 -0
- package/dist/cli/check.js +513 -806
- package/dist/cli/env.d.ts +13 -0
- package/dist/cli/env.js +63 -12
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.js +90 -159
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +43 -64
- package/dist/cli/plugins.d.ts +13 -0
- package/dist/cli/plugins.js +148 -227
- package/dist/cli/run.d.ts +16 -0
- package/dist/cli/run.js +52 -8
- package/dist/cli/snapshot-create.d.ts +4 -0
- package/dist/cli/snapshot-create.js +71 -125
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +232 -335
- package/dist/config-nGCW1OTG.js +941 -0
- package/dist/context-B45_WqVX.js +298 -0
- package/dist/conversation-privacy-B4voFRSm.js +182 -0
- package/dist/conversation-work-C6y3T5Hx.js +51 -0
- package/dist/credential-sync-kXr1hvO1.js +2660 -0
- package/dist/db-BeyXKJOI.d.ts +5 -0
- package/dist/destinations-BeBiJeEM.js +29 -0
- package/dist/execution-stats-DWfSihcH.js +373 -0
- package/dist/executor-DcMSlI5c.js +721 -0
- package/dist/experimental-CIXf7Uye.js +46 -0
- package/dist/history-ClE4toxe.d.ts +32 -0
- package/dist/history-CqTuSAdI.js +441 -0
- package/dist/instrumentation.d.ts +3 -3
- package/dist/instrumentation.js +130 -176
- package/dist/job-queue-Drn_LXlM.js +63 -0
- package/dist/logging-BzAk1S_s.js +1210 -0
- package/dist/model-profile-CZmVoGdX.js +49 -0
- package/dist/nitro.d.ts +31 -36
- package/dist/nitro.js +275 -456
- package/dist/oauth-callback-server-JiftokvA.js +130 -0
- package/dist/oauth-relay-CdCnu80W.js +62 -0
- package/dist/package-discovery-7a9YqLhE.js +455 -0
- package/dist/pending-auth-CWmSdZVg.js +185 -0
- package/dist/plugin-module-BKGOXca2.js +81 -0
- package/dist/plugins-BI9A1vKA.d.ts +95 -0
- package/dist/plugins-egKWjgue.js +99 -0
- package/dist/private-trace-result-BLvBjy_e.js +16 -0
- package/dist/profile-CrT5nXbw.js +861 -0
- package/dist/registry-DH1xUo2N.js +1419 -0
- package/dist/reporting-schema-DosTN__Q.js +105 -0
- package/dist/resolve-CZHnfxaS.js +546 -0
- package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
- package/dist/runner-CZV2sC46.js +392 -0
- package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
- package/dist/schema-Rn8-XEaN.js +1140 -0
- package/dist/sentry-CD3SdJl-.js +26 -0
- package/dist/skills-CIcDQSgM.js +316 -0
- package/dist/spawn-DdkUFRmq.js +29 -0
- package/dist/stats-DTUbAb88.js +2634 -0
- package/dist/store-C5qxF2ac.d.ts +208 -0
- package/dist/task-queue-CJIR4RF7.js +136 -0
- package/dist/task-runner-D-O3A-Cp.js +639 -0
- package/dist/thread-state-CRc9jTJS.js +431 -0
- package/dist/turn-execution-BkinIdJF.js +47 -0
- package/dist/turn-lifecycle-DQV19VTW.js +54 -0
- package/dist/usage-D3EbSO7w.js +296 -0
- package/dist/usage-schema-CKaDkH_j.js +20 -0
- package/dist/validation-C2CR-OX3.js +40 -0
- package/dist/vercel-queue-DIkVcfK4.js +167 -0
- package/dist/vercel.d.ts +6 -6
- package/dist/vercel.js +14 -6
- package/dist/version-CnXZ614E.d.ts +5 -0
- package/dist/version-DxcWdoKa.js +8 -0
- package/dist/version.d.ts +2 -4
- package/dist/version.js +2 -6
- package/dist/web-authorization-RMBxAR_t.js +76 -0
- package/dist/web-input-3EPfpf55.js +494 -0
- package/dist/work-fGofI7Op.js +509 -0
- package/dist/worker-CsOLq-mR.js +625 -0
- package/package.json +8 -8
- package/dist/agent-hooks-GB2VPTNA.js +0 -51
- package/dist/catalog-runtime-UBLIWD3O.js +0 -14
- package/dist/chunk-2LYHWMR4.js +0 -46
- package/dist/chunk-352OWAZH.js +0 -320
- package/dist/chunk-3Y47VMHV.js +0 -6
- package/dist/chunk-3YJSKOWF.js +0 -164
- package/dist/chunk-4KSSKTQ5.js +0 -229
- package/dist/chunk-4UO6FK4G.js +0 -64
- package/dist/chunk-5AHX53NQ.js +0 -717
- package/dist/chunk-5J3E5FWA.js +0 -700
- package/dist/chunk-5PDAG6O3.js +0 -206
- package/dist/chunk-6Y5B5PEX.js +0 -80
- package/dist/chunk-7GWQ5S5R.js +0 -2086
- package/dist/chunk-7H2VZTWN.js +0 -103
- package/dist/chunk-7NL7T6VU.js +0 -406
- package/dist/chunk-A5L27LE4.js +0 -387
- package/dist/chunk-ADIAWL34.js +0 -81
- package/dist/chunk-ASTEMBKJ.js +0 -519
- package/dist/chunk-CEMMLV5L.js +0 -98
- package/dist/chunk-CM5HNV2W.js +0 -131
- package/dist/chunk-CRTRBBRI.js +0 -105
- package/dist/chunk-DA2KGZZI.js +0 -13
- package/dist/chunk-DIB4GX3G.js +0 -8
- package/dist/chunk-DKIJ2RP5.js +0 -68
- package/dist/chunk-DWPN6SCH.js +0 -172
- package/dist/chunk-EDKUFGPL.js +0 -64
- package/dist/chunk-ENY6SKIU.js +0 -1228
- package/dist/chunk-F4MGCZOX.js +0 -2943
- package/dist/chunk-FA6POGLH.js +0 -70
- package/dist/chunk-FSUR7GTG.js +0 -20475
- package/dist/chunk-GKEOHJL5.js +0 -1856
- package/dist/chunk-GMCB6W5Y.js +0 -333
- package/dist/chunk-IE2VPG7O.js +0 -1135
- package/dist/chunk-IZ5B5IHQ.js +0 -3656
- package/dist/chunk-JAL3CH4G.js +0 -27
- package/dist/chunk-KIIEUXD3.js +0 -1764
- package/dist/chunk-KXU4NIL7.js +0 -692
- package/dist/chunk-MTM5IFCY.js +0 -1190
- package/dist/chunk-N7TMSOZH.js +0 -235
- package/dist/chunk-NCEBK6PH.js +0 -36
- package/dist/chunk-NHJU2ZAL.js +0 -56
- package/dist/chunk-P6KTRNVC.js +0 -321
- package/dist/chunk-PDO5BLNM.js +0 -22
- package/dist/chunk-PDRNLLFT.js +0 -3295
- package/dist/chunk-PEQXYSSE.js +0 -45
- package/dist/chunk-PKEX2AQX.js +0 -198
- package/dist/chunk-PSJCGIGO.js +0 -1163
- package/dist/chunk-PZUSUL55.js +0 -506
- package/dist/chunk-R45M4TUS.js +0 -37
- package/dist/chunk-RC745GGZ.js +0 -122
- package/dist/chunk-SP3QKZXJ.js +0 -820
- package/dist/chunk-TXKUKMVO.js +0 -417
- package/dist/chunk-UE4GPWSD.js +0 -931
- package/dist/chunk-UIE3R5XU.js +0 -17
- package/dist/chunk-UXPG6ZIN.js +0 -84
- package/dist/chunk-VFUK3X5B.js +0 -50
- package/dist/chunk-VNMJWREK.js +0 -787
- package/dist/chunk-VZ7CSOX2.js +0 -706
- package/dist/chunk-WCNQJKFT.js +0 -10
- package/dist/chunk-WDZR3QQM.js +0 -135
- package/dist/chunk-WLYVJCHV.js +0 -1433
- package/dist/chunk-WS7NAFTM.js +0 -1520
- package/dist/chunk-X6GDDWQH.js +0 -60
- package/dist/chunk-XPDEYNQI.js +0 -102
- package/dist/chunk-XRW44VGM.js +0 -58
- package/dist/chunk-Y2CM7HXH.js +0 -111
- package/dist/chunk-Y7X25LFY.js +0 -15
- package/dist/conversation-work-VIOQ5ZF3.js +0 -54
- package/dist/db-NGDJV7YH.js +0 -26
- package/dist/discovery-DWVDM7UK.js +0 -44
- package/dist/experimental-P5FZM4CU.js +0 -12
- package/dist/oauth-callback-server-YFY7YEGK.js +0 -243
- package/dist/oauth-relay-5XPVRPYB.js +0 -8
- package/dist/plugins-YTYJMMJF.js +0 -14
- package/dist/runner-ORTNSB2Q.js +0 -522
- package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
- package/dist/sentry-MB3NL3IR.js +0 -42
- package/dist/skills-H376WQOH.js +0 -27
- package/dist/spawn-T43WHLOS.js +0 -42
- package/dist/task-runner-LBZWF32V.js +0 -36
- package/dist/validation-REJLRKI6.js +0 -17
- package/dist/work-3KJ3RE76.js +0 -51
- package/dist/worker-QFEBU72E.js +0 -24
package/dist/chunk-5J3E5FWA.js
DELETED
|
@@ -1,700 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
healthReportSchema
|
|
3
|
-
} from "./chunk-RC745GGZ.js";
|
|
4
|
-
import {
|
|
5
|
-
parseSlackThreadId
|
|
6
|
-
} from "./chunk-XPDEYNQI.js";
|
|
7
|
-
import {
|
|
8
|
-
appendAndEnqueueExclusiveInboundMessage,
|
|
9
|
-
appendAndEnqueueInboundMessage
|
|
10
|
-
} from "./chunk-KIIEUXD3.js";
|
|
11
|
-
import {
|
|
12
|
-
buildDeterministicTurnId
|
|
13
|
-
} from "./chunk-DA2KGZZI.js";
|
|
14
|
-
import {
|
|
15
|
-
normalizeSlackConversationId
|
|
16
|
-
} from "./chunk-IZ5B5IHQ.js";
|
|
17
|
-
import {
|
|
18
|
-
getConversationStore,
|
|
19
|
-
getDb
|
|
20
|
-
} from "./chunk-GKEOHJL5.js";
|
|
21
|
-
import {
|
|
22
|
-
juniorConversationParticipants,
|
|
23
|
-
juniorConversations,
|
|
24
|
-
juniorIdentities,
|
|
25
|
-
juniorUsers
|
|
26
|
-
} from "./chunk-IE2VPG7O.js";
|
|
27
|
-
import {
|
|
28
|
-
juniorDestinations
|
|
29
|
-
} from "./chunk-VFUK3X5B.js";
|
|
30
|
-
import {
|
|
31
|
-
getSlackBotToken
|
|
32
|
-
} from "./chunk-ENY6SKIU.js";
|
|
33
|
-
import {
|
|
34
|
-
canExposeConversationPayload
|
|
35
|
-
} from "./chunk-PKEX2AQX.js";
|
|
36
|
-
import {
|
|
37
|
-
logWarn
|
|
38
|
-
} from "./chunk-WS7NAFTM.js";
|
|
39
|
-
|
|
40
|
-
// src/handlers/health.ts
|
|
41
|
-
function readHealthReport() {
|
|
42
|
-
return healthReportSchema.parse({
|
|
43
|
-
status: "ok",
|
|
44
|
-
service: "junior",
|
|
45
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
function GET() {
|
|
49
|
-
return Response.json(readHealthReport());
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// src/chat/attachments/vercel.ts
|
|
53
|
-
import { del, get, put } from "@vercel/blob";
|
|
54
|
-
function createVercelAttachmentStorage() {
|
|
55
|
-
return {
|
|
56
|
-
provider: "vercel-blob",
|
|
57
|
-
async put(input) {
|
|
58
|
-
await put(input.key, input.body, {
|
|
59
|
-
access: "private",
|
|
60
|
-
addRandomSuffix: false,
|
|
61
|
-
allowOverwrite: true,
|
|
62
|
-
contentType: input.contentType
|
|
63
|
-
});
|
|
64
|
-
},
|
|
65
|
-
async get(key) {
|
|
66
|
-
const result = await get(key, { access: "private", useCache: false });
|
|
67
|
-
return result?.statusCode === 200 ? result.stream : null;
|
|
68
|
-
},
|
|
69
|
-
async delete(keys) {
|
|
70
|
-
if (keys.length === 0) return;
|
|
71
|
-
await del(keys);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// src/api/conversations/access.ts
|
|
77
|
-
import { eq as eq2, inArray as inArray2 } from "drizzle-orm";
|
|
78
|
-
import { alias } from "drizzle-orm/pg-core";
|
|
79
|
-
|
|
80
|
-
// src/api/conversations/membership.ts
|
|
81
|
-
import {
|
|
82
|
-
and,
|
|
83
|
-
eq,
|
|
84
|
-
exists,
|
|
85
|
-
inArray,
|
|
86
|
-
isNotNull,
|
|
87
|
-
notExists,
|
|
88
|
-
or
|
|
89
|
-
} from "drizzle-orm";
|
|
90
|
-
function conversationHasParticipantUser(userId) {
|
|
91
|
-
const participant = getDb().select({
|
|
92
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
93
|
-
}).from(juniorConversationParticipants).where(
|
|
94
|
-
and(
|
|
95
|
-
eq(
|
|
96
|
-
juniorConversationParticipants.rootConversationId,
|
|
97
|
-
juniorConversations.conversationId
|
|
98
|
-
),
|
|
99
|
-
eq(juniorConversationParticipants.userId, userId)
|
|
100
|
-
)
|
|
101
|
-
);
|
|
102
|
-
return exists(participant);
|
|
103
|
-
}
|
|
104
|
-
function conversationHasParticipantEmail(email) {
|
|
105
|
-
const participant = getDb().select({
|
|
106
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
107
|
-
}).from(juniorConversationParticipants).innerJoin(
|
|
108
|
-
juniorUsers,
|
|
109
|
-
eq(juniorUsers.id, juniorConversationParticipants.userId)
|
|
110
|
-
).where(
|
|
111
|
-
and(
|
|
112
|
-
eq(
|
|
113
|
-
juniorConversationParticipants.rootConversationId,
|
|
114
|
-
juniorConversations.conversationId
|
|
115
|
-
),
|
|
116
|
-
eq(juniorUsers.primaryEmailNormalized, email)
|
|
117
|
-
)
|
|
118
|
-
);
|
|
119
|
-
return exists(participant);
|
|
120
|
-
}
|
|
121
|
-
function conversationArchivedForUser(userId) {
|
|
122
|
-
const archive = getDb().select({
|
|
123
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
124
|
-
}).from(juniorConversationParticipants).where(
|
|
125
|
-
and(
|
|
126
|
-
eq(
|
|
127
|
-
juniorConversationParticipants.rootConversationId,
|
|
128
|
-
juniorConversations.conversationId
|
|
129
|
-
),
|
|
130
|
-
eq(juniorConversationParticipants.userId, userId),
|
|
131
|
-
isNotNull(juniorConversationParticipants.archivedAt)
|
|
132
|
-
)
|
|
133
|
-
);
|
|
134
|
-
return exists(archive);
|
|
135
|
-
}
|
|
136
|
-
function conversationNotArchivedForUser(userId) {
|
|
137
|
-
const archive = getDb().select({
|
|
138
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
139
|
-
}).from(juniorConversationParticipants).where(
|
|
140
|
-
and(
|
|
141
|
-
eq(
|
|
142
|
-
juniorConversationParticipants.rootConversationId,
|
|
143
|
-
juniorConversations.conversationId
|
|
144
|
-
),
|
|
145
|
-
eq(juniorConversationParticipants.userId, userId),
|
|
146
|
-
isNotNull(juniorConversationParticipants.archivedAt)
|
|
147
|
-
)
|
|
148
|
-
);
|
|
149
|
-
return notExists(archive);
|
|
150
|
-
}
|
|
151
|
-
function conversationArchivedForEmail(email) {
|
|
152
|
-
const archive = getDb().select({
|
|
153
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
154
|
-
}).from(juniorConversationParticipants).innerJoin(
|
|
155
|
-
juniorUsers,
|
|
156
|
-
eq(juniorUsers.id, juniorConversationParticipants.userId)
|
|
157
|
-
).where(
|
|
158
|
-
and(
|
|
159
|
-
eq(
|
|
160
|
-
juniorConversationParticipants.rootConversationId,
|
|
161
|
-
juniorConversations.conversationId
|
|
162
|
-
),
|
|
163
|
-
eq(juniorUsers.primaryEmailNormalized, email),
|
|
164
|
-
isNotNull(juniorConversationParticipants.archivedAt)
|
|
165
|
-
)
|
|
166
|
-
);
|
|
167
|
-
return exists(archive);
|
|
168
|
-
}
|
|
169
|
-
function conversationNotArchivedForEmail(email) {
|
|
170
|
-
const archive = getDb().select({
|
|
171
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
172
|
-
}).from(juniorConversationParticipants).innerJoin(
|
|
173
|
-
juniorUsers,
|
|
174
|
-
eq(juniorUsers.id, juniorConversationParticipants.userId)
|
|
175
|
-
).where(
|
|
176
|
-
and(
|
|
177
|
-
eq(
|
|
178
|
-
juniorConversationParticipants.rootConversationId,
|
|
179
|
-
juniorConversations.conversationId
|
|
180
|
-
),
|
|
181
|
-
eq(juniorUsers.primaryEmailNormalized, email),
|
|
182
|
-
isNotNull(juniorConversationParticipants.archivedAt)
|
|
183
|
-
)
|
|
184
|
-
);
|
|
185
|
-
return notExists(archive);
|
|
186
|
-
}
|
|
187
|
-
function viewerConversationMembership(args) {
|
|
188
|
-
if (args.actorMatch && args.participantMatch) {
|
|
189
|
-
return or(args.actorMatch, args.participantMatch);
|
|
190
|
-
}
|
|
191
|
-
return args.actorMatch ?? args.participantMatch;
|
|
192
|
-
}
|
|
193
|
-
async function conversationArchiveTimes(db, conversationIds, subject) {
|
|
194
|
-
if (!subject || conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
195
|
-
const query = db.select({
|
|
196
|
-
archivedAt: juniorConversationParticipants.archivedAt,
|
|
197
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
198
|
-
}).from(juniorConversationParticipants);
|
|
199
|
-
const rows = "userId" in subject ? await query.where(
|
|
200
|
-
and(
|
|
201
|
-
eq(juniorConversationParticipants.userId, subject.userId),
|
|
202
|
-
inArray(juniorConversationParticipants.rootConversationId, [
|
|
203
|
-
...conversationIds
|
|
204
|
-
]),
|
|
205
|
-
isNotNull(juniorConversationParticipants.archivedAt)
|
|
206
|
-
)
|
|
207
|
-
) : await query.innerJoin(
|
|
208
|
-
juniorUsers,
|
|
209
|
-
eq(juniorUsers.id, juniorConversationParticipants.userId)
|
|
210
|
-
).where(
|
|
211
|
-
and(
|
|
212
|
-
eq(juniorUsers.primaryEmailNormalized, subject.email),
|
|
213
|
-
inArray(juniorConversationParticipants.rootConversationId, [
|
|
214
|
-
...conversationIds
|
|
215
|
-
]),
|
|
216
|
-
isNotNull(juniorConversationParticipants.archivedAt)
|
|
217
|
-
)
|
|
218
|
-
);
|
|
219
|
-
return new Map(
|
|
220
|
-
rows.flatMap(
|
|
221
|
-
(row) => row.archivedAt ? [[row.rootConversationId, row.archivedAt.getTime()]] : []
|
|
222
|
-
)
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
async function conversationIdsWithParticipantUser(db, conversationIds, userId) {
|
|
226
|
-
if (conversationIds.length === 0) {
|
|
227
|
-
return /* @__PURE__ */ new Set();
|
|
228
|
-
}
|
|
229
|
-
const rows = await db.select({
|
|
230
|
-
rootConversationId: juniorConversationParticipants.rootConversationId
|
|
231
|
-
}).from(juniorConversationParticipants).where(
|
|
232
|
-
and(
|
|
233
|
-
eq(juniorConversationParticipants.userId, userId),
|
|
234
|
-
inArray(juniorConversationParticipants.rootConversationId, [
|
|
235
|
-
...conversationIds
|
|
236
|
-
])
|
|
237
|
-
)
|
|
238
|
-
);
|
|
239
|
-
return new Set(rows.map((row) => row.rootConversationId));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// src/api/conversations/access.ts
|
|
243
|
-
var rootConversation = alias(juniorConversations, "access_root_conversation");
|
|
244
|
-
var rootDestination = alias(juniorDestinations, "access_root_destination");
|
|
245
|
-
var rootIdentity = alias(juniorIdentities, "access_root_identity");
|
|
246
|
-
async function readConversationAccessFromSql(db, conversationIds, viewer) {
|
|
247
|
-
if (conversationIds.length === 0) return /* @__PURE__ */ new Map();
|
|
248
|
-
const normalizedViewerEmail = viewer?.email.trim().toLowerCase() || void 0;
|
|
249
|
-
const rows = await db.select({
|
|
250
|
-
conversationId: juniorConversations.conversationId,
|
|
251
|
-
parentConversationId: juniorConversations.parentConversationId,
|
|
252
|
-
storedRootConversationId: juniorConversations.rootConversationId,
|
|
253
|
-
rootConversationId: rootConversation.conversationId,
|
|
254
|
-
rootParentConversationId: rootConversation.parentConversationId,
|
|
255
|
-
rootRootConversationId: rootConversation.rootConversationId,
|
|
256
|
-
visibility: rootDestination.visibility,
|
|
257
|
-
rootEmailNormalized: rootIdentity.emailNormalized,
|
|
258
|
-
rootEmailVerified: rootIdentity.emailVerified,
|
|
259
|
-
rootUserId: rootIdentity.userId
|
|
260
|
-
}).from(juniorConversations).leftJoin(
|
|
261
|
-
rootConversation,
|
|
262
|
-
eq2(
|
|
263
|
-
rootConversation.conversationId,
|
|
264
|
-
juniorConversations.rootConversationId
|
|
265
|
-
)
|
|
266
|
-
).leftJoin(
|
|
267
|
-
rootDestination,
|
|
268
|
-
eq2(rootDestination.id, rootConversation.destinationId)
|
|
269
|
-
).leftJoin(
|
|
270
|
-
rootIdentity,
|
|
271
|
-
eq2(rootIdentity.id, rootConversation.actorIdentityId)
|
|
272
|
-
).where(inArray2(juniorConversations.conversationId, [...conversationIds]));
|
|
273
|
-
const membershipConversationIds = /* @__PURE__ */ new Set();
|
|
274
|
-
for (const row of rows) {
|
|
275
|
-
membershipConversationIds.add(row.conversationId);
|
|
276
|
-
if (row.storedRootConversationId) {
|
|
277
|
-
membershipConversationIds.add(row.storedRootConversationId);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
const participantRootIds = viewer !== void 0 ? await conversationIdsWithParticipantUser(
|
|
281
|
-
db,
|
|
282
|
-
[...membershipConversationIds],
|
|
283
|
-
viewer.id
|
|
284
|
-
) : /* @__PURE__ */ new Set();
|
|
285
|
-
return new Map(
|
|
286
|
-
rows.map((row) => {
|
|
287
|
-
const hasValidRoot = row.rootConversationId !== null && row.rootConversationId === row.storedRootConversationId && row.rootRootConversationId === row.rootConversationId && row.rootParentConversationId === null && (row.parentConversationId !== null || row.storedRootConversationId === row.conversationId);
|
|
288
|
-
const validRootConversationId = hasValidRoot ? row.rootConversationId ?? void 0 : void 0;
|
|
289
|
-
const visibility = validRootConversationId === void 0 ? null : row.visibility;
|
|
290
|
-
const isRootActor = validRootConversationId !== void 0 && viewer !== void 0 && (row.rootUserId === viewer.id || normalizedViewerEmail !== void 0 && row.rootEmailVerified === true && row.rootEmailNormalized === normalizedViewerEmail);
|
|
291
|
-
const isMaterializedParticipant = participantRootIds.has(row.conversationId) || validRootConversationId !== void 0 && participantRootIds.has(validRootConversationId);
|
|
292
|
-
const isParticipant = isRootActor || isMaterializedParticipant;
|
|
293
|
-
const canViewPrivateContent = isParticipant || validRootConversationId !== void 0 && canExposeConversationPayload({
|
|
294
|
-
visibility: visibility ?? void 0
|
|
295
|
-
});
|
|
296
|
-
return [
|
|
297
|
-
row.conversationId,
|
|
298
|
-
{
|
|
299
|
-
canViewPrivateContent,
|
|
300
|
-
isParticipant,
|
|
301
|
-
visibility
|
|
302
|
-
}
|
|
303
|
-
];
|
|
304
|
-
})
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// src/chat/conversations/web-input.ts
|
|
309
|
-
import { createHash } from "crypto";
|
|
310
|
-
import { createWebSource } from "@sentry/junior-plugin-api";
|
|
311
|
-
|
|
312
|
-
// src/chat/conversations/destination.ts
|
|
313
|
-
import {
|
|
314
|
-
localDestinationSchema
|
|
315
|
-
} from "@sentry/junior-plugin-api";
|
|
316
|
-
function requireLocalDestination(conversationId) {
|
|
317
|
-
const parsed = localDestinationSchema.safeParse({
|
|
318
|
-
platform: "local",
|
|
319
|
-
conversationId
|
|
320
|
-
});
|
|
321
|
-
if (!parsed.success) {
|
|
322
|
-
throw new Error(`Invalid local conversation id: ${conversationId}`);
|
|
323
|
-
}
|
|
324
|
-
return parsed.data;
|
|
325
|
-
}
|
|
326
|
-
function resolveConversationDestination(args) {
|
|
327
|
-
return args.existing ?? requireLocalDestination(args.conversationId);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// src/chat/conversations/web-input.ts
|
|
331
|
-
function normalizeEmail(email) {
|
|
332
|
-
return email.trim().toLowerCase();
|
|
333
|
-
}
|
|
334
|
-
function stableHex(...parts) {
|
|
335
|
-
return createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 24);
|
|
336
|
-
}
|
|
337
|
-
function createConversationId(args) {
|
|
338
|
-
return `local:web:${stableHex(
|
|
339
|
-
normalizeEmail(args.actorEmail),
|
|
340
|
-
args.idempotencyKey
|
|
341
|
-
)}`;
|
|
342
|
-
}
|
|
343
|
-
function webMessageId(args) {
|
|
344
|
-
return `api-msg:${stableHex(args.conversationId, args.idempotencyKey)}`;
|
|
345
|
-
}
|
|
346
|
-
function conversationTurnIdForMessage(messageId) {
|
|
347
|
-
return buildDeterministicTurnId(messageId);
|
|
348
|
-
}
|
|
349
|
-
function storedActorFromWeb(actor) {
|
|
350
|
-
return {
|
|
351
|
-
...actor.email ? { email: normalizeEmail(actor.email) } : void 0,
|
|
352
|
-
...actor.fullName ? { fullName: actor.fullName } : void 0
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
function webActorFromEmail(email, profile) {
|
|
356
|
-
const normalized = normalizeEmail(email);
|
|
357
|
-
return {
|
|
358
|
-
platform: "web",
|
|
359
|
-
userId: `dashboard:${stableHex(normalized)}`,
|
|
360
|
-
email: normalized,
|
|
361
|
-
...profile?.fullName ? { fullName: profile.fullName } : void 0,
|
|
362
|
-
...profile?.userName ? { userName: profile.userName } : void 0
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
function buildWebInboundMessage(args) {
|
|
366
|
-
const text = args.message.trim();
|
|
367
|
-
if (!text) {
|
|
368
|
-
throw new Error("Web Message must not be empty");
|
|
369
|
-
}
|
|
370
|
-
if (!args.actor.email) {
|
|
371
|
-
throw new Error("Web Actor requires a verified email");
|
|
372
|
-
}
|
|
373
|
-
const destination = resolveConversationDestination({
|
|
374
|
-
conversationId: args.conversationId,
|
|
375
|
-
existing: args.destination
|
|
376
|
-
});
|
|
377
|
-
const nowMs = args.nowMs ?? Date.now();
|
|
378
|
-
return {
|
|
379
|
-
conversationId: args.conversationId,
|
|
380
|
-
createdAtMs: args.createdAtMs ?? nowMs,
|
|
381
|
-
delivery: "defer",
|
|
382
|
-
// TODO(dcramer): Remove InboundMessage.destination after workers read the
|
|
383
|
-
// Conversation Location and no mailbox reader requires Destination.
|
|
384
|
-
destination,
|
|
385
|
-
inboundMessageId: args.messageId,
|
|
386
|
-
input: {
|
|
387
|
-
authorId: args.actor.userId,
|
|
388
|
-
text,
|
|
389
|
-
metadata: {
|
|
390
|
-
authorEmail: normalizeEmail(args.actor.email),
|
|
391
|
-
...args.actor.fullName && { authorFullName: args.actor.fullName },
|
|
392
|
-
authorUserId: args.actor.userId,
|
|
393
|
-
...args.actor.userName && { authorUserName: args.actor.userName },
|
|
394
|
-
// TODO(dcramer): Remove api_turn after deployed mailbox readers use
|
|
395
|
-
// Inbound message Source.kind to identify web input.
|
|
396
|
-
kind: "api_turn",
|
|
397
|
-
messageId: args.messageId
|
|
398
|
-
}
|
|
399
|
-
},
|
|
400
|
-
receivedAtMs: nowMs,
|
|
401
|
-
// TODO(dcramer): Replace this string after deployed mailbox readers and
|
|
402
|
-
// writers use a complete web Source.
|
|
403
|
-
source: "web"
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
async function recordWebConversationActivity(args) {
|
|
407
|
-
const store = args.conversationStore ?? getConversationStore();
|
|
408
|
-
const existing = await store.get({ conversationId: args.conversationId });
|
|
409
|
-
const destination = resolveConversationDestination({
|
|
410
|
-
conversationId: args.conversationId,
|
|
411
|
-
existing: existing?.destination
|
|
412
|
-
});
|
|
413
|
-
const isNewRoot = !existing;
|
|
414
|
-
const visibility = args.rootVisibility === "private" ? "private" : "public";
|
|
415
|
-
const source = isNewRoot ? createWebSource(args.conversationId, visibility) : void 0;
|
|
416
|
-
await store.recordActivity({
|
|
417
|
-
conversationId: args.conversationId,
|
|
418
|
-
// TODO(dcramer): Remove the Conversation destination write after all
|
|
419
|
-
// readers use its stored Location.
|
|
420
|
-
destination,
|
|
421
|
-
nowMs: args.nowMs,
|
|
422
|
-
actor: storedActorFromWeb(args.actor),
|
|
423
|
-
// A dashboard continuation does not replace the root Source.
|
|
424
|
-
// TODO(dcramer): Remove the Conversation source and sessionSource writes
|
|
425
|
-
// after every Turn stores Source and all resume readers use that Turn fact.
|
|
426
|
-
...isNewRoot ? { source: "web" } : void 0,
|
|
427
|
-
...source ? { sessionSource: source } : void 0,
|
|
428
|
-
...isNewRoot ? { visibility } : void 0
|
|
429
|
-
});
|
|
430
|
-
return destination;
|
|
431
|
-
}
|
|
432
|
-
async function createAndEnqueueConversation(input, options) {
|
|
433
|
-
if (!input.actor.email) {
|
|
434
|
-
throw new Error("Web Actor requires a verified email");
|
|
435
|
-
}
|
|
436
|
-
const conversationId = createConversationId({
|
|
437
|
-
actorEmail: input.actor.email,
|
|
438
|
-
idempotencyKey: input.idempotencyKey
|
|
439
|
-
});
|
|
440
|
-
return await appendAndEnqueueWebMessage(
|
|
441
|
-
{
|
|
442
|
-
actor: input.actor,
|
|
443
|
-
conversationId,
|
|
444
|
-
idempotencyKey: input.idempotencyKey,
|
|
445
|
-
message: input.message,
|
|
446
|
-
rootVisibility: input.visibility === "private" ? "private" : "public"
|
|
447
|
-
},
|
|
448
|
-
options
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
async function appendAndEnqueueWebMessage(input, options) {
|
|
452
|
-
const text = input.message.trim();
|
|
453
|
-
if (!text) {
|
|
454
|
-
throw new Error("Web Message must not be empty");
|
|
455
|
-
}
|
|
456
|
-
if (!input.actor.email) {
|
|
457
|
-
throw new Error("Web Actor requires a verified email");
|
|
458
|
-
}
|
|
459
|
-
const nowMs = options.nowMs ?? Date.now();
|
|
460
|
-
const messageId = webMessageId({
|
|
461
|
-
conversationId: input.conversationId,
|
|
462
|
-
idempotencyKey: input.idempotencyKey
|
|
463
|
-
});
|
|
464
|
-
const destination = await recordWebConversationActivity({
|
|
465
|
-
actor: input.actor,
|
|
466
|
-
conversationId: input.conversationId,
|
|
467
|
-
conversationStore: options.conversationStore,
|
|
468
|
-
nowMs,
|
|
469
|
-
...input.rootVisibility && { rootVisibility: input.rootVisibility }
|
|
470
|
-
});
|
|
471
|
-
const enqueue = options.exclusive ? appendAndEnqueueExclusiveInboundMessage : appendAndEnqueueInboundMessage;
|
|
472
|
-
const result = await enqueue({
|
|
473
|
-
message: buildWebInboundMessage({
|
|
474
|
-
actor: input.actor,
|
|
475
|
-
conversationId: input.conversationId,
|
|
476
|
-
destination,
|
|
477
|
-
message: text,
|
|
478
|
-
messageId,
|
|
479
|
-
nowMs
|
|
480
|
-
}),
|
|
481
|
-
conversationStore: options.conversationStore,
|
|
482
|
-
nowMs,
|
|
483
|
-
queue: options.queue,
|
|
484
|
-
state: options.state
|
|
485
|
-
});
|
|
486
|
-
const status = result.status === "appended" ? "accepted" : result.status;
|
|
487
|
-
return {
|
|
488
|
-
conversationId: input.conversationId,
|
|
489
|
-
messageId,
|
|
490
|
-
status
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// src/chat/conversations/web-mailbox.ts
|
|
495
|
-
import { z } from "zod";
|
|
496
|
-
var legacyWebMailboxMetadataSchema = z.object({
|
|
497
|
-
authorEmail: z.string().email(),
|
|
498
|
-
authorFullName: z.string().min(1).optional(),
|
|
499
|
-
authorUserId: z.string().min(1),
|
|
500
|
-
authorUserName: z.string().min(1).optional(),
|
|
501
|
-
kind: z.literal("api_turn"),
|
|
502
|
-
messageId: z.string().min(1)
|
|
503
|
-
}).strict();
|
|
504
|
-
|
|
505
|
-
// src/chat/slack/user.ts
|
|
506
|
-
import { z as z2 } from "zod";
|
|
507
|
-
var slackUserInfoSchema = z2.object({
|
|
508
|
-
ok: z2.literal(true),
|
|
509
|
-
user: z2.object({
|
|
510
|
-
name: z2.string().nullish(),
|
|
511
|
-
profile: z2.object({
|
|
512
|
-
email: z2.string().nullish(),
|
|
513
|
-
real_name: z2.string().nullish()
|
|
514
|
-
}).optional()
|
|
515
|
-
})
|
|
516
|
-
});
|
|
517
|
-
var USER_CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
518
|
-
var userCache = /* @__PURE__ */ new Map();
|
|
519
|
-
function userCacheKey(teamId, userId) {
|
|
520
|
-
return `${teamId}:${userId}`;
|
|
521
|
-
}
|
|
522
|
-
function readFromCache(teamId, userId) {
|
|
523
|
-
const hit = userCache.get(userCacheKey(teamId, userId));
|
|
524
|
-
if (!hit) return null;
|
|
525
|
-
if (hit.expiresAt < Date.now()) {
|
|
526
|
-
userCache.delete(userCacheKey(teamId, userId));
|
|
527
|
-
return null;
|
|
528
|
-
}
|
|
529
|
-
return hit.value;
|
|
530
|
-
}
|
|
531
|
-
function writeToCache(teamId, userId, value) {
|
|
532
|
-
userCache.set(userCacheKey(teamId, userId), {
|
|
533
|
-
value,
|
|
534
|
-
expiresAt: Date.now() + USER_CACHE_TTL_MS
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
async function lookupSlackUser(teamId, userId) {
|
|
538
|
-
if (!teamId || !userId) {
|
|
539
|
-
return null;
|
|
540
|
-
}
|
|
541
|
-
const cached = readFromCache(teamId, userId);
|
|
542
|
-
if (cached) {
|
|
543
|
-
return cached;
|
|
544
|
-
}
|
|
545
|
-
const token = getSlackBotToken();
|
|
546
|
-
if (!token) {
|
|
547
|
-
return null;
|
|
548
|
-
}
|
|
549
|
-
try {
|
|
550
|
-
const response = await fetch(
|
|
551
|
-
`https://slack.com/api/users.info?user=${encodeURIComponent(userId)}`,
|
|
552
|
-
{
|
|
553
|
-
headers: {
|
|
554
|
-
authorization: `Bearer ${token}`
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
);
|
|
558
|
-
if (!response.ok) {
|
|
559
|
-
logWarn("slack.user.lookup.failed", {
|
|
560
|
-
"enduser.id": userId,
|
|
561
|
-
"app.slack.team_id": teamId,
|
|
562
|
-
"http.response.status_code": response.status
|
|
563
|
-
});
|
|
564
|
-
return null;
|
|
565
|
-
}
|
|
566
|
-
const parsed = slackUserInfoSchema.safeParse(await response.json());
|
|
567
|
-
if (!parsed.success) {
|
|
568
|
-
return null;
|
|
569
|
-
}
|
|
570
|
-
const payload = parsed.data;
|
|
571
|
-
const userName = payload.user.name?.trim() || void 0;
|
|
572
|
-
const fullName = payload.user.profile?.real_name?.trim() || void 0;
|
|
573
|
-
const result = {
|
|
574
|
-
userName,
|
|
575
|
-
fullName,
|
|
576
|
-
email: payload.user.profile?.email?.trim() || void 0
|
|
577
|
-
};
|
|
578
|
-
writeToCache(teamId, userId, result);
|
|
579
|
-
return result;
|
|
580
|
-
} catch (error) {
|
|
581
|
-
logWarn("slack.user.lookup.failed", {
|
|
582
|
-
"enduser.id": userId,
|
|
583
|
-
"app.slack.team_id": teamId,
|
|
584
|
-
"exception.message": error instanceof Error ? error.message : String(error)
|
|
585
|
-
});
|
|
586
|
-
return null;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// src/chat/slack/conversation-context.ts
|
|
591
|
-
function normalizeConversationName(type, channelName) {
|
|
592
|
-
const trimmed = channelName?.trim();
|
|
593
|
-
if (!trimmed) return void 0;
|
|
594
|
-
if (type === "public_channel" || type === "private_channel" || type === "private_channel_or_group_dm") {
|
|
595
|
-
return trimmed.startsWith("#") ? trimmed : `#${trimmed}`;
|
|
596
|
-
}
|
|
597
|
-
return trimmed;
|
|
598
|
-
}
|
|
599
|
-
function typeFromSlackChannelType(channelType) {
|
|
600
|
-
if (channelType === "channel") return "public_channel";
|
|
601
|
-
if (channelType === "group") return "private_channel";
|
|
602
|
-
if (channelType === "mpim") return "group_dm";
|
|
603
|
-
if (channelType === "im") return "direct_message";
|
|
604
|
-
return void 0;
|
|
605
|
-
}
|
|
606
|
-
function typeFromChannelId(channelId, channelName) {
|
|
607
|
-
const normalized = normalizeSlackConversationId(channelId);
|
|
608
|
-
if (!normalized) return void 0;
|
|
609
|
-
if (normalized.startsWith("C")) return "public_channel";
|
|
610
|
-
if (normalized.startsWith("D")) return "direct_message";
|
|
611
|
-
if (normalized.startsWith("G")) {
|
|
612
|
-
return channelName?.trim().startsWith("mpdm-") ? "group_dm" : "private_channel_or_group_dm";
|
|
613
|
-
}
|
|
614
|
-
return void 0;
|
|
615
|
-
}
|
|
616
|
-
function toSlackEventChannelType(channelType) {
|
|
617
|
-
if (channelType === "channel" || channelType === "group" || channelType === "mpim" || channelType === "im") {
|
|
618
|
-
return channelType;
|
|
619
|
-
}
|
|
620
|
-
return void 0;
|
|
621
|
-
}
|
|
622
|
-
function conversationVisibilityFromSlackChannelType(channelType) {
|
|
623
|
-
if (!channelType) return void 0;
|
|
624
|
-
return channelType === "channel" ? "public" : "private";
|
|
625
|
-
}
|
|
626
|
-
function resolveSlackChannelTypeFromMessage(message) {
|
|
627
|
-
const raw = message.raw;
|
|
628
|
-
if (!raw || typeof raw !== "object") {
|
|
629
|
-
return void 0;
|
|
630
|
-
}
|
|
631
|
-
const channelType = raw.channel_type;
|
|
632
|
-
return typeof channelType === "string" ? toSlackEventChannelType(channelType.trim()) : void 0;
|
|
633
|
-
}
|
|
634
|
-
function resolveSlackConversationContext(input) {
|
|
635
|
-
const type = typeFromSlackChannelType(input.channelType) ?? typeFromChannelId(input.channelId, input.channelName);
|
|
636
|
-
if (!type) return void 0;
|
|
637
|
-
const name = normalizeConversationName(type, input.channelName);
|
|
638
|
-
const visibility = conversationVisibilityFromSlackChannelType(
|
|
639
|
-
input.channelType
|
|
640
|
-
);
|
|
641
|
-
return {
|
|
642
|
-
type,
|
|
643
|
-
...name ? { name } : void 0,
|
|
644
|
-
...visibility ? { visibility } : void 0
|
|
645
|
-
};
|
|
646
|
-
}
|
|
647
|
-
function resolveSlackConversationContextFromThreadId(input) {
|
|
648
|
-
const slackThread = parseSlackThreadId(input.threadId);
|
|
649
|
-
const context = resolveSlackConversationContext({
|
|
650
|
-
channelId: slackThread?.channelId,
|
|
651
|
-
channelName: input.channelName
|
|
652
|
-
});
|
|
653
|
-
if (!context || !input.visibility) {
|
|
654
|
-
return context;
|
|
655
|
-
}
|
|
656
|
-
return {
|
|
657
|
-
...context,
|
|
658
|
-
type: input.visibility === "private" && context.type === "public_channel" ? "private_channel" : context.type,
|
|
659
|
-
visibility: input.visibility
|
|
660
|
-
};
|
|
661
|
-
}
|
|
662
|
-
function formatSlackConversationTypeLabel(type) {
|
|
663
|
-
if (type === "public_channel") return "Public Channel";
|
|
664
|
-
if (type === "private_channel") return "Private Channel";
|
|
665
|
-
if (type === "group_dm") return "Group DM";
|
|
666
|
-
if (type === "direct_message") return "Direct Message";
|
|
667
|
-
return "Private Channel or Group DM";
|
|
668
|
-
}
|
|
669
|
-
function formatSlackConversationRedactedLabel(context) {
|
|
670
|
-
if (!context) return void 0;
|
|
671
|
-
return formatSlackConversationTypeLabel(context.type);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
export {
|
|
675
|
-
readHealthReport,
|
|
676
|
-
GET,
|
|
677
|
-
createVercelAttachmentStorage,
|
|
678
|
-
legacyWebMailboxMetadataSchema,
|
|
679
|
-
lookupSlackUser,
|
|
680
|
-
conversationVisibilityFromSlackChannelType,
|
|
681
|
-
resolveSlackChannelTypeFromMessage,
|
|
682
|
-
resolveSlackConversationContext,
|
|
683
|
-
resolveSlackConversationContextFromThreadId,
|
|
684
|
-
formatSlackConversationRedactedLabel,
|
|
685
|
-
resolveConversationDestination,
|
|
686
|
-
conversationHasParticipantUser,
|
|
687
|
-
conversationHasParticipantEmail,
|
|
688
|
-
conversationArchivedForUser,
|
|
689
|
-
conversationNotArchivedForUser,
|
|
690
|
-
conversationArchivedForEmail,
|
|
691
|
-
conversationNotArchivedForEmail,
|
|
692
|
-
viewerConversationMembership,
|
|
693
|
-
conversationArchiveTimes,
|
|
694
|
-
readConversationAccessFromSql,
|
|
695
|
-
conversationTurnIdForMessage,
|
|
696
|
-
webActorFromEmail,
|
|
697
|
-
recordWebConversationActivity,
|
|
698
|
-
createAndEnqueueConversation,
|
|
699
|
-
appendAndEnqueueWebMessage
|
|
700
|
-
};
|