@sentry/junior 0.126.1 → 0.128.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-hooks-U5YGLX6Y.js → agent-hooks-F75ANGBV.js} +9 -9
- package/dist/api/people/spend.d.ts +4 -0
- package/dist/api/people/spend.query.d.ts +3 -0
- package/dist/api/schema/person.d.ts +9 -0
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +3 -1
- package/dist/api.js +141 -40
- package/dist/app.js +289 -146
- package/dist/{catalog-runtime-OUPLWD7F.js → catalog-runtime-ZPSA5QM2.js} +6 -6
- package/dist/chat/agent-dispatch/context.d.ts +17 -0
- package/dist/chat/agent-dispatch/store.d.ts +1 -1
- package/dist/chat/agent-dispatch/work.d.ts +1 -1
- package/dist/chat/credentials/context.d.ts +27 -0
- package/dist/chat/credentials/subject.d.ts +15 -0
- package/dist/chat/event-tasks/ingest.d.ts +9 -0
- package/dist/chat/event-tasks/store.d.ts +15 -0
- package/dist/chat/event-tasks/tool-support.d.ts +140 -0
- package/dist/chat/event-tasks/types.d.ts +44 -0
- package/dist/chat/plugins/agent-hooks.d.ts +4 -2
- package/dist/chat/plugins/viewer.d.ts +16 -0
- package/dist/chat/resource-events/catalog.d.ts +21 -0
- package/dist/chat/resource-events/ingest.d.ts +2 -1
- package/dist/chat/resource-events/notification.d.ts +2 -2
- package/dist/chat/resource-events/store.d.ts +11 -9
- package/dist/chat/resource-events/tool-support.d.ts +10 -0
- package/dist/chat/resource-events/workspace.d.ts +4 -0
- package/dist/chat/sandbox/command-result.d.ts +3 -22
- package/dist/chat/sandbox/egress/schemas.d.ts +11 -0
- package/dist/chat/services/guardian-action-policy.d.ts +1 -1
- package/dist/chat/slack/dispatch-turn.d.ts +1 -1
- package/dist/chat/slack/tools/canvas/create.d.ts +0 -16
- package/dist/chat/slack/tools/canvas/edit.d.ts +0 -16
- package/dist/chat/slack/tools/canvas/read.d.ts +0 -16
- package/dist/chat/slack/tools/canvas/write.d.ts +0 -16
- package/dist/chat/slack/tools/channel-list-messages.d.ts +0 -16
- package/dist/chat/slack/tools/conversation-search.d.ts +0 -16
- package/dist/chat/slack/tools/list/add-items.d.ts +0 -16
- package/dist/chat/slack/tools/list/create.d.ts +0 -16
- package/dist/chat/slack/tools/list/get-items.d.ts +0 -16
- package/dist/chat/slack/tools/list/update-item.d.ts +0 -16
- package/dist/chat/slack/tools/message-add-reaction.d.ts +0 -16
- package/dist/chat/slack/tools/public-search.d.ts +0 -16
- package/dist/chat/slack/tools/send-files.d.ts +10 -28
- package/dist/chat/slack/tools/thread-read.d.ts +0 -16
- package/dist/chat/slack/tools/user-lookup.d.ts +0 -16
- package/dist/chat/task-execution/slack-work.d.ts +4 -4
- package/dist/chat/tool-support/action-review.d.ts +1 -1
- package/dist/chat/tool-support/structured-result.d.ts +17 -46
- package/dist/chat/tool-support/text-range-result.d.ts +8 -32
- package/dist/chat/tool-support/zod-tool.d.ts +6 -7
- package/dist/chat/tools/create-event-task.d.ts +65 -0
- package/dist/chat/tools/definition.d.ts +4 -0
- package/dist/chat/tools/delete-event-task.d.ts +57 -0
- package/dist/chat/tools/event-tasks.d.ts +5 -0
- package/dist/chat/tools/handoff/tool.d.ts +0 -16
- package/dist/chat/tools/list-event-tasks.d.ts +55 -0
- package/dist/chat/tools/list-resource-event-subscriptions.d.ts +42 -0
- package/dist/chat/tools/query-conversation-events.d.ts +0 -16
- package/dist/chat/tools/resource-events.d.ts +2 -1
- package/dist/chat/tools/runtime/report-progress.d.ts +0 -16
- package/dist/chat/tools/sandbox/edit-file.d.ts +0 -23
- package/dist/chat/tools/sandbox/file-utils.d.ts +2 -17
- package/dist/chat/tools/sandbox/find-files.d.ts +5 -8
- package/dist/chat/tools/sandbox/grep.d.ts +1 -4
- package/dist/chat/tools/sandbox/list-dir.d.ts +1 -4
- package/dist/chat/tools/search-resource-event-types.d.ts +44 -0
- package/dist/chat/tools/search-tools.d.ts +0 -16
- package/dist/chat/tools/skill/load-skill.d.ts +0 -20
- package/dist/chat/tools/skill/search-mcp-tools.d.ts +0 -16
- package/dist/chat/tools/stop-watching-resources.d.ts +28 -0
- package/dist/chat/tools/system-time.d.ts +0 -16
- package/dist/chat/tools/types.d.ts +8 -4
- package/dist/chat/tools/update-event-task.d.ts +66 -0
- package/dist/chat/tools/watch-resource-events.d.ts +59 -0
- package/dist/chat/tools/web/fetch-content.d.ts +0 -2
- package/dist/chat/tools/web/fetch-tool.d.ts +0 -16
- package/dist/chat/tools/web/image-generate.d.ts +0 -16
- package/dist/chat/tools/web/search.d.ts +0 -16
- package/dist/{chunk-QVSYR5CV.js → chunk-2HTHX6XV.js} +4 -4
- package/dist/{chunk-Y2QRKPI7.js → chunk-3PKF6YNU.js} +1 -1
- package/dist/{chunk-GLNB2R42.js → chunk-5KKIBIIP.js} +12 -12
- package/dist/{chunk-W3U3YQYI.js → chunk-77VDLF3Z.js} +18 -1
- package/dist/{chunk-YZHA2L7P.js → chunk-A76LKS5W.js} +230 -102
- package/dist/{chunk-6ZBSTNYN.js → chunk-AFJF3RGU.js} +9 -0
- package/dist/{chunk-PD6J33TO.js → chunk-B6E3YA2H.js} +1 -1
- package/dist/{chunk-S4LM6UB7.js → chunk-B7FPRGUJ.js} +3 -3
- package/dist/{chunk-R3GXQJEE.js → chunk-BY43CEXN.js} +2 -2
- package/dist/{chunk-HDSDCEPK.js → chunk-EPBBYMNE.js} +1 -1
- package/dist/{chunk-YFE6VNHU.js → chunk-FJEIX3AH.js} +2 -2
- package/dist/{chunk-F2ARYRKC.js → chunk-G6XQODHM.js} +1 -1
- package/dist/{chunk-KBW6J5GA.js → chunk-HBFQLSGV.js} +4 -4
- package/dist/{chunk-YUPNY2HZ.js → chunk-JDCPDJ54.js} +2 -2
- package/dist/{chunk-WIIPHGJY.js → chunk-K5ZB3WWH.js} +2 -2
- package/dist/{chunk-OG6E44DH.js → chunk-KNRODVH2.js} +6 -6
- package/dist/{chunk-W3JHZHAN.js → chunk-KTGJAWRO.js} +1 -1
- package/dist/{chunk-7VF3JAVF.js → chunk-NHWE6Y7G.js} +7 -7
- package/dist/{chunk-HXWOZ4HG.js → chunk-OLGB5Y7R.js} +2 -2
- package/dist/{chunk-QMK2VF6K.js → chunk-PBWUUVVG.js} +1 -1
- package/dist/{chunk-7ZMY4GCG.js → chunk-RYWMDDWK.js} +1 -1
- package/dist/{chunk-S4PUICSB.js → chunk-SHMHHXD5.js} +34 -5
- package/dist/{chunk-JKV244BI.js → chunk-WZ365SQC.js} +1 -1
- package/dist/{chunk-SD2VFSN6.js → chunk-YY6CVET7.js} +1428 -1116
- package/dist/{chunk-U36WL4OL.js → chunk-Z4KTQMWW.js} +1 -1
- package/dist/cli/chat.js +27 -27
- package/dist/cli/check.js +7 -7
- package/dist/cli/plugins.js +13 -13
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +8 -8
- package/dist/db/schema/event-tasks.d.ts +161 -0
- package/dist/db/schema.d.ts +163 -1
- package/dist/{db-FQID26JW.js → db-FYJYPAKG.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-Z5MHHKFD.js → oauth-callback-server-W3PPIHCS.js} +18 -18
- package/dist/{runner-PGPGKYSF.js → runner-5NOFUYKR.js} +11 -11
- package/dist/{sandbox-egress-signals-CDFAP67O.js → sandbox-egress-signals-A5HWIQH4.js} +2 -2
- package/dist/{skills-BCQHR636.js → skills-ENIBKF5V.js} +7 -7
- package/dist/{validation-QP3FYBLZ.js → validation-BHLBOO6K.js} +7 -7
- package/dist/version.js +1 -1
- package/migrations/0015_magical_ezekiel_stane.sql +11 -0
- package/migrations/meta/0015_snapshot.json +1360 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +5 -5
- package/dist/chat/plugins/viewer-actors.d.ts +0 -6
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
persistAuthPauseTurnState,
|
|
14
14
|
requireTurnFailureEventId,
|
|
15
15
|
scheduleSessionCompletedPluginTasks
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-KNRODVH2.js";
|
|
17
17
|
import {
|
|
18
18
|
buildSentryConversationUrl
|
|
19
19
|
} from "./chunk-4CODA7P5.js";
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
resolveBaseUrl,
|
|
41
41
|
resolvePluginOAuthAccount,
|
|
42
42
|
truncateStatusText
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-NHWE6Y7G.js";
|
|
44
44
|
import {
|
|
45
45
|
JUNIOR_THREAD_STATE_TTL_MS,
|
|
46
46
|
TurnSliceLimitExceededError,
|
|
@@ -73,13 +73,13 @@ import {
|
|
|
73
73
|
recordDeliveredAssistantMessage,
|
|
74
74
|
turnHasReply,
|
|
75
75
|
updateConversationStats
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-HBFQLSGV.js";
|
|
77
77
|
import {
|
|
78
78
|
parseSlackThreadId,
|
|
79
79
|
readSlackRawMessageContext,
|
|
80
80
|
resolveSlackChannelIdFromMessage,
|
|
81
81
|
resolveSlackChannelIdFromThreadId
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-PBWUUVVG.js";
|
|
83
83
|
import {
|
|
84
84
|
SlackActionError,
|
|
85
85
|
getDashboardConversationLink,
|
|
@@ -88,19 +88,19 @@ import {
|
|
|
88
88
|
getSlackClient,
|
|
89
89
|
isDmChannel,
|
|
90
90
|
normalizeSlackConversationId
|
|
91
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-A76LKS5W.js";
|
|
92
92
|
import {
|
|
93
93
|
getConversationEventStore,
|
|
94
94
|
getConversationStore,
|
|
95
95
|
parseDestination,
|
|
96
96
|
requireSlackDestination,
|
|
97
97
|
sameDestination
|
|
98
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-B7FPRGUJ.js";
|
|
99
99
|
import {
|
|
100
100
|
acquireActiveLock,
|
|
101
101
|
getDefaultRedisStateAdapterFor,
|
|
102
102
|
getStateAdapter
|
|
103
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-G6XQODHM.js";
|
|
104
104
|
import {
|
|
105
105
|
FUNCTION_TIMEOUT_BUFFER_SECONDS,
|
|
106
106
|
botConfig,
|
|
@@ -109,18 +109,18 @@ import {
|
|
|
109
109
|
getRuntimeMetadata,
|
|
110
110
|
normalizeSlackEmojiName,
|
|
111
111
|
standardModelId
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-K5ZB3WWH.js";
|
|
113
113
|
import {
|
|
114
114
|
discoverSkills
|
|
115
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-BY43CEXN.js";
|
|
116
116
|
import {
|
|
117
117
|
pluginCatalogRuntime
|
|
118
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-WZ365SQC.js";
|
|
119
119
|
import {
|
|
120
120
|
buildOAuthTokenRequest,
|
|
121
121
|
hasRequiredOAuthScope,
|
|
122
122
|
parseOAuthTokenResponse
|
|
123
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-OLGB5Y7R.js";
|
|
124
124
|
import {
|
|
125
125
|
createSlackResumeActor,
|
|
126
126
|
isUserActor,
|
|
@@ -139,7 +139,7 @@ import {
|
|
|
139
139
|
toOptionalNumber,
|
|
140
140
|
toOptionalString,
|
|
141
141
|
withLogContext
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-B6E3YA2H.js";
|
|
143
143
|
import {
|
|
144
144
|
homeDir
|
|
145
145
|
} from "./chunk-H4HBKISO.js";
|
|
@@ -18,9 +18,16 @@ var scheduledTaskCredentialSubjectBindingSchema = z.object({
|
|
|
18
18
|
taskId: exactNonBlankStringSchema,
|
|
19
19
|
signature: z.string().min(1)
|
|
20
20
|
}).strict();
|
|
21
|
+
var eventTaskCredentialSubjectBindingSchema = z.object({
|
|
22
|
+
type: z.literal("event-task"),
|
|
23
|
+
plugin: z.string().min(1),
|
|
24
|
+
taskId: exactNonBlankStringSchema,
|
|
25
|
+
signature: z.string().min(1)
|
|
26
|
+
}).strict();
|
|
21
27
|
var credentialSubjectBindingSchema = z.discriminatedUnion("type", [
|
|
22
28
|
slackDirectCredentialSubjectBindingSchema,
|
|
23
|
-
scheduledTaskCredentialSubjectBindingSchema
|
|
29
|
+
scheduledTaskCredentialSubjectBindingSchema,
|
|
30
|
+
eventTaskCredentialSubjectBindingSchema
|
|
24
31
|
]);
|
|
25
32
|
var credentialUserActorSchema = z.object({
|
|
26
33
|
type: z.literal("user"),
|
|
@@ -46,6 +53,16 @@ var credentialSubjectSchema = z.discriminatedUnion("allowedWhen", [
|
|
|
46
53
|
}).strict().refine((subject) => subject.binding.taskId === subject.taskId, {
|
|
47
54
|
message: "Scheduled task credential subject requires task binding",
|
|
48
55
|
path: ["binding"]
|
|
56
|
+
}),
|
|
57
|
+
z.object({
|
|
58
|
+
type: z.literal("user"),
|
|
59
|
+
userId: exactActorIdSchema,
|
|
60
|
+
allowedWhen: z.literal("event-task"),
|
|
61
|
+
taskId: exactNonBlankStringSchema,
|
|
62
|
+
binding: eventTaskCredentialSubjectBindingSchema
|
|
63
|
+
}).strict().refine((subject) => subject.binding.taskId === subject.taskId, {
|
|
64
|
+
message: "Event task credential subject requires task binding",
|
|
65
|
+
path: ["binding"]
|
|
49
66
|
})
|
|
50
67
|
]);
|
|
51
68
|
var credentialContextSchema = z.union([
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getConversationEventStore,
|
|
3
3
|
getDb
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-B7FPRGUJ.js";
|
|
5
5
|
import {
|
|
6
6
|
juniorConversationAnnotations,
|
|
7
7
|
juniorConversationEvents,
|
|
8
8
|
juniorIdentities,
|
|
9
9
|
juniorUsers
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SHMHHXD5.js";
|
|
11
11
|
import {
|
|
12
12
|
SANDBOX_WORKSPACE_ROOT,
|
|
13
13
|
getStateAdapter,
|
|
14
14
|
sleep
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-G6XQODHM.js";
|
|
16
16
|
import {
|
|
17
17
|
botConfig,
|
|
18
18
|
completeObject,
|
|
19
19
|
embedTexts,
|
|
20
20
|
getSlackBotToken,
|
|
21
21
|
standardModelId
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-K5ZB3WWH.js";
|
|
23
23
|
import {
|
|
24
24
|
isActorUserId,
|
|
25
25
|
parseActorUserId
|
|
@@ -37,14 +37,16 @@ import {
|
|
|
37
37
|
setSpanAttributes,
|
|
38
38
|
setSpanStatus,
|
|
39
39
|
withSpan
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-B6E3YA2H.js";
|
|
41
41
|
|
|
42
42
|
// src/chat/plugins/agent-hooks.ts
|
|
43
43
|
import {
|
|
44
44
|
missingToolAnnotationKeys,
|
|
45
|
+
normalizeResourceEventIdentifier,
|
|
45
46
|
promptContextSchema,
|
|
46
47
|
promptMessageSchema,
|
|
47
|
-
|
|
48
|
+
pluginResourceEventsSchema,
|
|
49
|
+
resourceEventInputSchema
|
|
48
50
|
} from "@sentry/junior-plugin-api";
|
|
49
51
|
|
|
50
52
|
// src/chat/plugins/annotations.ts
|
|
@@ -422,88 +424,6 @@ function getDashboardConversationLink(conversationId) {
|
|
|
422
424
|
return `${baseURL}${path}`;
|
|
423
425
|
}
|
|
424
426
|
|
|
425
|
-
// src/chat/slack/tools/context.ts
|
|
426
|
-
function getSlackToolContext(context) {
|
|
427
|
-
if (context.source.platform !== "slack") {
|
|
428
|
-
return void 0;
|
|
429
|
-
}
|
|
430
|
-
if (context.destination.platform !== "slack") {
|
|
431
|
-
throw new TypeError("Slack source requires a Slack destination");
|
|
432
|
-
}
|
|
433
|
-
const destinationChannelId = parseSlackChannelReferenceId(
|
|
434
|
-
context.destination.channelId
|
|
435
|
-
);
|
|
436
|
-
const sourceChannelId = parseSlackChannelReferenceId(
|
|
437
|
-
context.source.channelId
|
|
438
|
-
);
|
|
439
|
-
const teamId = parseSlackTeamId(context.source.teamId);
|
|
440
|
-
if (!destinationChannelId || !sourceChannelId || !teamId) {
|
|
441
|
-
return void 0;
|
|
442
|
-
}
|
|
443
|
-
return {
|
|
444
|
-
destination: context.destination,
|
|
445
|
-
source: context.source,
|
|
446
|
-
actor: context.actor?.platform === "slack" ? context.actor : void 0,
|
|
447
|
-
destinationChannelId,
|
|
448
|
-
messageTs: parseSlackMessageTs(context.source.messageTs),
|
|
449
|
-
sourceChannelId,
|
|
450
|
-
teamId,
|
|
451
|
-
threadTs: parseSlackMessageTs(context.source.threadTs)
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
// src/chat/plugins/viewer-actors.ts
|
|
456
|
-
import { and as and3, eq as eq3 } from "drizzle-orm";
|
|
457
|
-
import {
|
|
458
|
-
actorSchema
|
|
459
|
-
} from "@sentry/junior-plugin-api";
|
|
460
|
-
async function readViewerActorsFromSql(db, email) {
|
|
461
|
-
const normalizedEmail = normalizeIdentityEmail(email);
|
|
462
|
-
if (!normalizedEmail) return [];
|
|
463
|
-
const rows = await db.select({
|
|
464
|
-
displayName: juniorIdentities.displayName,
|
|
465
|
-
email: juniorUsers.primaryEmail,
|
|
466
|
-
handle: juniorIdentities.handle,
|
|
467
|
-
provider: juniorIdentities.provider,
|
|
468
|
-
providerSubjectId: juniorIdentities.providerSubjectId,
|
|
469
|
-
providerTenantId: juniorIdentities.providerTenantId
|
|
470
|
-
}).from(juniorIdentities).innerJoin(juniorUsers, eq3(juniorUsers.id, juniorIdentities.userId)).where(
|
|
471
|
-
and3(
|
|
472
|
-
eq3(juniorUsers.primaryEmailNormalized, normalizedEmail),
|
|
473
|
-
eq3(juniorIdentities.kind, "user")
|
|
474
|
-
)
|
|
475
|
-
);
|
|
476
|
-
const actors = [];
|
|
477
|
-
for (const row of rows) {
|
|
478
|
-
const candidate = row.provider === "slack" ? {
|
|
479
|
-
platform: "slack",
|
|
480
|
-
teamId: row.providerTenantId,
|
|
481
|
-
userId: row.providerSubjectId,
|
|
482
|
-
email: row.email,
|
|
483
|
-
...row.displayName ? { fullName: row.displayName } : {},
|
|
484
|
-
...row.handle ? { userName: row.handle } : {}
|
|
485
|
-
} : row.provider === "local" ? {
|
|
486
|
-
platform: "local",
|
|
487
|
-
userId: row.providerSubjectId,
|
|
488
|
-
email: row.email,
|
|
489
|
-
...row.displayName ? { fullName: row.displayName } : {},
|
|
490
|
-
...row.handle ? { userName: row.handle } : {}
|
|
491
|
-
} : void 0;
|
|
492
|
-
if (!candidate) continue;
|
|
493
|
-
const parsed = actorSchema.safeParse(candidate);
|
|
494
|
-
if (parsed.success && parsed.data.platform !== "system") {
|
|
495
|
-
actors.push(parsed.data);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
return actors;
|
|
499
|
-
}
|
|
500
|
-
async function readViewerActors(email) {
|
|
501
|
-
return await readViewerActorsFromSql(getDb(), email);
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// src/chat/credentials/subject.ts
|
|
505
|
-
import { createHmac, timingSafeEqual } from "crypto";
|
|
506
|
-
|
|
507
427
|
// src/chat/slack/client.ts
|
|
508
428
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
509
429
|
import { WebClient } from "@slack/web-api";
|
|
@@ -914,7 +834,138 @@ async function downloadPrivateSlackFile(url) {
|
|
|
914
834
|
);
|
|
915
835
|
}
|
|
916
836
|
|
|
837
|
+
// src/chat/resource-events/workspace.ts
|
|
838
|
+
function canRouteResourceEvents() {
|
|
839
|
+
return Boolean(getSlackBotToken());
|
|
840
|
+
}
|
|
841
|
+
function createResourceEventTeamIdResolver() {
|
|
842
|
+
let pending;
|
|
843
|
+
return async () => {
|
|
844
|
+
if (!canRouteResourceEvents()) return void 0;
|
|
845
|
+
pending ??= getSlackClient().auth.test().then((result) => {
|
|
846
|
+
const teamId = result.team_id?.trim();
|
|
847
|
+
if (!teamId) {
|
|
848
|
+
throw new Error("Slack auth.test did not return a workspace team id");
|
|
849
|
+
}
|
|
850
|
+
return teamId;
|
|
851
|
+
}).catch((error) => {
|
|
852
|
+
pending = void 0;
|
|
853
|
+
throw error;
|
|
854
|
+
});
|
|
855
|
+
return await pending;
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// src/chat/slack/tools/context.ts
|
|
860
|
+
function getSlackToolContext(context) {
|
|
861
|
+
if (context.source.platform !== "slack") {
|
|
862
|
+
return void 0;
|
|
863
|
+
}
|
|
864
|
+
if (context.destination.platform !== "slack") {
|
|
865
|
+
throw new TypeError("Slack source requires a Slack destination");
|
|
866
|
+
}
|
|
867
|
+
const destinationChannelId = parseSlackChannelReferenceId(
|
|
868
|
+
context.destination.channelId
|
|
869
|
+
);
|
|
870
|
+
const sourceChannelId = parseSlackChannelReferenceId(
|
|
871
|
+
context.source.channelId
|
|
872
|
+
);
|
|
873
|
+
const teamId = parseSlackTeamId(context.source.teamId);
|
|
874
|
+
if (!destinationChannelId || !sourceChannelId || !teamId) {
|
|
875
|
+
return void 0;
|
|
876
|
+
}
|
|
877
|
+
return {
|
|
878
|
+
destination: context.destination,
|
|
879
|
+
source: context.source,
|
|
880
|
+
actor: context.actor?.platform === "slack" ? context.actor : void 0,
|
|
881
|
+
destinationChannelId,
|
|
882
|
+
messageTs: parseSlackMessageTs(context.source.messageTs),
|
|
883
|
+
sourceChannelId,
|
|
884
|
+
teamId,
|
|
885
|
+
threadTs: parseSlackMessageTs(context.source.threadTs)
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// src/chat/plugins/viewer.ts
|
|
890
|
+
import { randomUUID } from "crypto";
|
|
891
|
+
import { and as and3, asc, eq as eq3 } from "drizzle-orm";
|
|
892
|
+
import {
|
|
893
|
+
identitySchema,
|
|
894
|
+
userSchema
|
|
895
|
+
} from "@sentry/junior-plugin-api";
|
|
896
|
+
function identityFromRow(row) {
|
|
897
|
+
return identitySchema.parse({
|
|
898
|
+
id: row.id,
|
|
899
|
+
provider: row.provider,
|
|
900
|
+
providerSubjectId: row.providerSubjectId,
|
|
901
|
+
...row.providerTenantId ? { providerTenantId: row.providerTenantId } : {},
|
|
902
|
+
...row.displayName ? { displayName: row.displayName } : {},
|
|
903
|
+
...row.handle ? { handle: row.handle } : {}
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
async function readUserById(db, userRow) {
|
|
907
|
+
const identityRows = await db.select().from(juniorIdentities).where(
|
|
908
|
+
and3(
|
|
909
|
+
eq3(juniorIdentities.userId, userRow.id),
|
|
910
|
+
eq3(juniorIdentities.kind, "user")
|
|
911
|
+
)
|
|
912
|
+
).orderBy(
|
|
913
|
+
asc(juniorIdentities.provider),
|
|
914
|
+
asc(juniorIdentities.providerTenantId),
|
|
915
|
+
asc(juniorIdentities.providerSubjectId)
|
|
916
|
+
);
|
|
917
|
+
return userSchema.parse({
|
|
918
|
+
email: userRow.primaryEmail,
|
|
919
|
+
id: userRow.id,
|
|
920
|
+
identities: identityRows.map(identityFromRow),
|
|
921
|
+
...userRow.displayName ? { displayName: userRow.displayName } : {}
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
async function resolveViewerUserFromSql(db, email) {
|
|
925
|
+
const normalizedEmail = normalizeIdentityEmail(email);
|
|
926
|
+
if (!normalizedEmail) return void 0;
|
|
927
|
+
const now = /* @__PURE__ */ new Date();
|
|
928
|
+
const rows = await db.insert(juniorUsers).values({
|
|
929
|
+
id: randomUUID(),
|
|
930
|
+
primaryEmail: email.trim(),
|
|
931
|
+
primaryEmailNormalized: normalizedEmail,
|
|
932
|
+
displayName: null,
|
|
933
|
+
createdAt: now,
|
|
934
|
+
updatedAt: now
|
|
935
|
+
}).onConflictDoNothing({ target: juniorUsers.primaryEmailNormalized }).returning();
|
|
936
|
+
const userRow = rows[0] ?? (await db.select().from(juniorUsers).where(eq3(juniorUsers.primaryEmailNormalized, normalizedEmail)).limit(1))[0];
|
|
937
|
+
return userRow ? await readUserById(db, userRow) : void 0;
|
|
938
|
+
}
|
|
939
|
+
async function resolveViewerUser(email) {
|
|
940
|
+
return await resolveViewerUserFromSql(getDb(), email);
|
|
941
|
+
}
|
|
942
|
+
async function readActorIdentityFromSql(db, actor) {
|
|
943
|
+
if (actor.platform === "system") return void 0;
|
|
944
|
+
const providerTenantId = actor.platform === "slack" ? actor.teamId : "";
|
|
945
|
+
const rows = await db.select({
|
|
946
|
+
identity: juniorIdentities,
|
|
947
|
+
user: juniorUsers
|
|
948
|
+
}).from(juniorIdentities).leftJoin(juniorUsers, eq3(juniorUsers.id, juniorIdentities.userId)).where(
|
|
949
|
+
and3(
|
|
950
|
+
eq3(juniorIdentities.kind, "user"),
|
|
951
|
+
eq3(juniorIdentities.provider, actor.platform),
|
|
952
|
+
eq3(juniorIdentities.providerTenantId, providerTenantId),
|
|
953
|
+
eq3(juniorIdentities.providerSubjectId, actor.userId)
|
|
954
|
+
)
|
|
955
|
+
).limit(1);
|
|
956
|
+
const row = rows[0];
|
|
957
|
+
if (!row) return void 0;
|
|
958
|
+
return {
|
|
959
|
+
identity: identityFromRow(row.identity),
|
|
960
|
+
...row.user ? { user: await readUserById(db, row.user) } : {}
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
async function readActorIdentity(actor) {
|
|
964
|
+
return await readActorIdentityFromSql(getDb(), actor);
|
|
965
|
+
}
|
|
966
|
+
|
|
917
967
|
// src/chat/credentials/subject.ts
|
|
968
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
918
969
|
var CREDENTIAL_SUBJECT_HMAC_CONTEXT = "junior.credential_subject.v1";
|
|
919
970
|
var CREDENTIAL_SUBJECT_SIGNATURE_VERSION = "v1";
|
|
920
971
|
function getCredentialSubjectSecret() {
|
|
@@ -1039,6 +1090,51 @@ function verifyScheduledTaskCredentialSubject(input) {
|
|
|
1039
1090
|
);
|
|
1040
1091
|
return timingSafeMatch(expected, binding.signature);
|
|
1041
1092
|
}
|
|
1093
|
+
function bindEventTaskCredentialSubject(input) {
|
|
1094
|
+
const secret = getCredentialSubjectSecret();
|
|
1095
|
+
const plugin = input.plugin.trim();
|
|
1096
|
+
const userId = parseActorUserId(input.subject.userId);
|
|
1097
|
+
if (!secret || plugin !== "junior" || !userId || input.subject.allowedWhen !== "event-task") {
|
|
1098
|
+
return void 0;
|
|
1099
|
+
}
|
|
1100
|
+
const taskId = input.subject.taskId;
|
|
1101
|
+
if (!taskId || taskId !== taskId.trim()) {
|
|
1102
|
+
return void 0;
|
|
1103
|
+
}
|
|
1104
|
+
return {
|
|
1105
|
+
type: "user",
|
|
1106
|
+
userId,
|
|
1107
|
+
allowedWhen: "event-task",
|
|
1108
|
+
taskId,
|
|
1109
|
+
binding: {
|
|
1110
|
+
type: "event-task",
|
|
1111
|
+
plugin,
|
|
1112
|
+
taskId,
|
|
1113
|
+
signature: signPayload(
|
|
1114
|
+
secret,
|
|
1115
|
+
buildPayload(["event-task", plugin, taskId, userId])
|
|
1116
|
+
)
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
function verifyEventTaskCredentialSubject(input) {
|
|
1121
|
+
const secret = getCredentialSubjectSecret();
|
|
1122
|
+
const { subject } = input;
|
|
1123
|
+
const binding = subject.binding;
|
|
1124
|
+
if (!secret || input.plugin !== "junior" || subject.type !== "user" || !isActorUserId(subject.userId) || subject.allowedWhen !== "event-task" || !subject.taskId || binding.type !== "event-task" || binding.plugin !== input.plugin || binding.taskId !== subject.taskId) {
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
const expected = signPayload(
|
|
1128
|
+
secret,
|
|
1129
|
+
buildPayload([
|
|
1130
|
+
"event-task",
|
|
1131
|
+
binding.plugin,
|
|
1132
|
+
binding.taskId,
|
|
1133
|
+
subject.userId
|
|
1134
|
+
])
|
|
1135
|
+
);
|
|
1136
|
+
return timingSafeMatch(expected, binding.signature);
|
|
1137
|
+
}
|
|
1042
1138
|
|
|
1043
1139
|
// src/chat/slack/tools/channel-capabilities.ts
|
|
1044
1140
|
function resolveChannelCapabilities(channelId) {
|
|
@@ -1249,6 +1345,9 @@ function validatePlugins(plugins) {
|
|
|
1249
1345
|
if (seen.has(name)) {
|
|
1250
1346
|
throw new Error(`Duplicate plugin name "${name}"`);
|
|
1251
1347
|
}
|
|
1348
|
+
if (plugin.resourceEvents !== void 0 && !pluginResourceEventsSchema.safeParse(plugin.resourceEvents).success) {
|
|
1349
|
+
throw new Error(`Plugin "${name}" resourceEvents is invalid`);
|
|
1350
|
+
}
|
|
1252
1351
|
for (const [taskName, task] of Object.entries(plugin.tasks ?? {})) {
|
|
1253
1352
|
if (!PLUGIN_TOOL_NAME_RE.test(taskName)) {
|
|
1254
1353
|
throw new Error(
|
|
@@ -1420,6 +1519,10 @@ function getPluginTools(context) {
|
|
|
1420
1519
|
plugin: pluginName
|
|
1421
1520
|
}) : void 0;
|
|
1422
1521
|
const mcp = pluginMcpContext(plugin, context);
|
|
1522
|
+
const resourceEvents = {
|
|
1523
|
+
canSubscribe: context.source.platform === "slack" && canRouteResourceEvents()
|
|
1524
|
+
};
|
|
1525
|
+
const resolveActor = context.resolveActorIdentity ?? (async () => void 0);
|
|
1423
1526
|
let pluginContext;
|
|
1424
1527
|
if (context.source.platform === "slack") {
|
|
1425
1528
|
if (context.destination.platform !== "slack") {
|
|
@@ -1440,7 +1543,9 @@ function getPluginTools(context) {
|
|
|
1440
1543
|
egress: context.egress,
|
|
1441
1544
|
...mcp ? { mcp } : {},
|
|
1442
1545
|
model: createPluginModel(pluginName, plugin.model),
|
|
1443
|
-
|
|
1546
|
+
resourceEvents,
|
|
1547
|
+
state: createPluginState(pluginName),
|
|
1548
|
+
users: { resolveActor }
|
|
1444
1549
|
};
|
|
1445
1550
|
} else {
|
|
1446
1551
|
if (context.destination.platform !== "local") {
|
|
@@ -1460,7 +1565,9 @@ function getPluginTools(context) {
|
|
|
1460
1565
|
egress: context.egress,
|
|
1461
1566
|
...mcp ? { mcp } : {},
|
|
1462
1567
|
model: createPluginModel(pluginName, plugin.model),
|
|
1463
|
-
|
|
1568
|
+
resourceEvents,
|
|
1569
|
+
state: createPluginState(pluginName),
|
|
1570
|
+
users: { resolveActor }
|
|
1464
1571
|
};
|
|
1465
1572
|
}
|
|
1466
1573
|
const pluginTools = hook(pluginContext);
|
|
@@ -1525,6 +1632,21 @@ function routeMethods(route, pluginName) {
|
|
|
1525
1632
|
}
|
|
1526
1633
|
return methods;
|
|
1527
1634
|
}
|
|
1635
|
+
function requirePublishedResourceEvent(plugin, eventType) {
|
|
1636
|
+
const registration = plugin.resourceEvents;
|
|
1637
|
+
if (!registration || registration.isEnabled?.() === false) {
|
|
1638
|
+
throw new Error(
|
|
1639
|
+
`Plugin "${plugin.manifest.name}" cannot publish resource events without an active registration`
|
|
1640
|
+
);
|
|
1641
|
+
}
|
|
1642
|
+
if (!registration.resourceTypes.some(
|
|
1643
|
+
(resourceType) => resourceType.supportedEvents.includes(eventType)
|
|
1644
|
+
)) {
|
|
1645
|
+
throw new Error(
|
|
1646
|
+
`Plugin "${plugin.manifest.name}" did not register resource event "${eventType}"`
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1528
1650
|
function getPluginRoutes(options) {
|
|
1529
1651
|
const routes = [];
|
|
1530
1652
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1546,13 +1668,16 @@ function getPluginRoutes(options) {
|
|
|
1546
1668
|
},
|
|
1547
1669
|
resourceEvents: {
|
|
1548
1670
|
async publish(event) {
|
|
1549
|
-
const parsed =
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1671
|
+
const parsed = resourceEventInputSchema.parse(event);
|
|
1672
|
+
requirePublishedResourceEvent(plugin, parsed.eventType);
|
|
1673
|
+
await options.resourceEvents.publish({
|
|
1674
|
+
...parsed,
|
|
1675
|
+
identifier: normalizeResourceEventIdentifier(
|
|
1676
|
+
plugin.resourceEvents,
|
|
1677
|
+
parsed.identifier
|
|
1678
|
+
),
|
|
1679
|
+
namespace: pluginName
|
|
1680
|
+
});
|
|
1556
1681
|
}
|
|
1557
1682
|
}
|
|
1558
1683
|
});
|
|
@@ -1612,9 +1737,7 @@ function getPluginApiRoutes() {
|
|
|
1612
1737
|
const app = hook({
|
|
1613
1738
|
...basePluginContext(plugin),
|
|
1614
1739
|
eventStats: createPluginConversationEventStats(plugin),
|
|
1615
|
-
|
|
1616
|
-
actors: readViewerActors
|
|
1617
|
-
}
|
|
1740
|
+
users: { resolve: resolveViewerUser }
|
|
1618
1741
|
});
|
|
1619
1742
|
if (app === void 0) {
|
|
1620
1743
|
continue;
|
|
@@ -2083,8 +2206,6 @@ export {
|
|
|
2083
2206
|
createPluginState,
|
|
2084
2207
|
setDashboardConversationLinkOptions,
|
|
2085
2208
|
getDashboardConversationLink,
|
|
2086
|
-
getSlackToolContext,
|
|
2087
|
-
readViewerActors,
|
|
2088
2209
|
runWithWorkspaceTeamId,
|
|
2089
2210
|
getWorkspaceTeamId,
|
|
2090
2211
|
SlackActionError,
|
|
@@ -2097,10 +2218,17 @@ export {
|
|
|
2097
2218
|
isConversationScopedChannel,
|
|
2098
2219
|
getFilePermalink,
|
|
2099
2220
|
downloadPrivateSlackFile,
|
|
2221
|
+
canRouteResourceEvents,
|
|
2222
|
+
createResourceEventTeamIdResolver,
|
|
2223
|
+
getSlackToolContext,
|
|
2224
|
+
resolveViewerUser,
|
|
2225
|
+
readActorIdentity,
|
|
2100
2226
|
bindSlackDirectCredentialSubject,
|
|
2101
2227
|
verifySlackDirectCredentialSubject,
|
|
2102
2228
|
bindScheduledTaskCredentialSubject,
|
|
2103
2229
|
verifyScheduledTaskCredentialSubject,
|
|
2230
|
+
bindEventTaskCredentialSubject,
|
|
2231
|
+
verifyEventTaskCredentialSubject,
|
|
2104
2232
|
resolveChannelCapabilities,
|
|
2105
2233
|
PluginHookDeniedError,
|
|
2106
2234
|
validatePlugins,
|
|
@@ -523,6 +523,14 @@ var actorProfileReportSchema = z3.object({
|
|
|
523
523
|
windowEnd: z3.string(),
|
|
524
524
|
windowStart: z3.string()
|
|
525
525
|
}).strict();
|
|
526
|
+
var personalSpendReportSchema = z3.object({
|
|
527
|
+
generatedAt: z3.string(),
|
|
528
|
+
sevenDaysUsd: z3.number().finite().nonnegative(),
|
|
529
|
+
source: z3.literal("conversation_index"),
|
|
530
|
+
thirtyDaysUsd: z3.number().finite().nonnegative(),
|
|
531
|
+
windowEnd: z3.string(),
|
|
532
|
+
windowStart: z3.string()
|
|
533
|
+
}).strict();
|
|
526
534
|
|
|
527
535
|
// src/api/schema/location.ts
|
|
528
536
|
import { z as z4 } from "zod";
|
|
@@ -619,6 +627,7 @@ export {
|
|
|
619
627
|
personParamsSchema,
|
|
620
628
|
actorDirectoryReportSchema,
|
|
621
629
|
actorProfileReportSchema,
|
|
630
|
+
personalSpendReportSchema,
|
|
622
631
|
locationParamsSchema,
|
|
623
632
|
locationActivityDayReportSchema,
|
|
624
633
|
locationDirectoryReportSchema,
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
juniorConversations,
|
|
5
5
|
juniorIdentities,
|
|
6
6
|
juniorUsers
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-SHMHHXD5.js";
|
|
8
8
|
import {
|
|
9
9
|
TURN_REASONING_LEVELS,
|
|
10
10
|
getChatConfig,
|
|
11
11
|
modelProfileSchema
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-K5ZB3WWH.js";
|
|
13
13
|
import {
|
|
14
14
|
juniorDestinations
|
|
15
15
|
} from "./chunk-VFUK3X5B.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "./chunk-F3B2YJ76.js";
|
|
20
20
|
import {
|
|
21
21
|
normalizeIdentityEmail
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-B6E3YA2H.js";
|
|
23
23
|
|
|
24
24
|
// src/chat/conversations/sql/store.ts
|
|
25
25
|
import { randomUUID as randomUUID2 } from "crypto";
|