@sentry/junior-plugin-api 0.189.0 → 0.190.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/README.md CHANGED
@@ -42,6 +42,9 @@ reports, and other typed hook surfaces exported by this package.
42
42
 
43
43
  - Hook context carries the active source, actor, conversation, plugin metadata,
44
44
  database, logging, and only the host capabilities required by that hook.
45
+ - Source uses `kind` to state what produced the input, including input such as
46
+ a Resource event that has no provider platform. Actor and Destination keep
47
+ `platform` for their provider scope.
45
48
  - Prompt hooks return bounded structured prompt messages rather than mutate the
46
49
  core prompt.
47
50
  - `formatMarkdown` is a pure text rewrite into ordinary Markdown before delivery.
package/dist/context.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import type { ZodTypeAny } from "zod";
3
- import { destinationSchema, identitySchema, locationSchema, webActorSchema, localActorSchema, platformSchema, actorSchema, slackActorSchema, systemActorSchema, sourceSchema, slackLocationSchema, userSchema } from "./schemas";
3
+ import { destinationSchema, identitySchema, locationSchema, webActorSchema, localActorSchema, platformSchema, actorSchema, slackActorSchema, systemActorSchema, sourceSchema, sourceVisibilitySchema, slackLocationSchema, userSchema } from "./schemas";
4
4
  /** Runtime platform name without source or destination coordinates. */
5
5
  export type Platform = z.output<typeof platformSchema>;
6
6
  export type Actor = z.output<typeof actorSchema>;
@@ -16,15 +16,18 @@ export type Location = z.output<typeof locationSchema>;
16
16
  /** Complete Slack Location associated with a Conversation. */
17
17
  export type SlackLocation = z.output<typeof slackLocationSchema>;
18
18
  export type SlackSource = Extract<Source, {
19
- platform: "slack";
19
+ kind: "slack";
20
20
  }>;
21
21
  export type LocalSource = Extract<Source, {
22
- platform: "local";
22
+ kind: "local";
23
23
  }>;
24
24
  export type WebSource = Extract<Source, {
25
- platform: "web";
25
+ kind: "web";
26
+ }>;
27
+ export type ResourceEventSource = Extract<Source, {
28
+ kind: "resource_event";
26
29
  }>;
27
- export type SourceVisibility = Source["visibility"];
30
+ export type SourceVisibility = z.output<typeof sourceVisibilitySchema>;
28
31
  export type Destination = z.output<typeof destinationSchema>;
29
32
  export type SlackDestination = Extract<Destination, {
30
33
  platform: "slack";
@@ -102,7 +105,14 @@ export interface WebInvocationContext extends BaseInvocationContext {
102
105
  /** Runtime-owned dashboard/web source for this invocation. */
103
106
  source: WebSource;
104
107
  }
105
- export type InvocationContext = LocalInvocationContext | SlackInvocationContext | WebInvocationContext;
108
+ export interface ResourceEventInvocationContext extends BaseInvocationContext {
109
+ /** Existing conversation destination used for tool context. */
110
+ destination: Destination;
111
+ actor?: SystemActor;
112
+ /** Runtime-owned Resource event Source for this invocation. */
113
+ source: ResourceEventSource;
114
+ }
115
+ export type InvocationContext = LocalInvocationContext | ResourceEventInvocationContext | SlackInvocationContext | WebInvocationContext;
106
116
  /** Build a normalized Slack source from runtime-owned Slack coordinates. */
107
117
  export declare function createSlackSource(input: {
108
118
  channelId: string;
@@ -116,6 +126,13 @@ export declare function createSlackSource(input: {
116
126
  export declare function createLocalSource(conversationId: string): LocalSource;
117
127
  /** Build a normalized web/dashboard source from a conversation id. */
118
128
  export declare function createWebSource(conversationId: string, visibility?: SourceVisibility): WebSource;
129
+ /** Build a normalized Resource event Source from one matched event. */
130
+ export declare function createResourceEventSource(input: {
131
+ eventKey: string;
132
+ eventType: string;
133
+ identifier: string;
134
+ namespace: string;
135
+ }): ResourceEventSource;
119
136
  /** Return whether a source is private to a person or restricted group. */
120
137
  export declare function isPrivateSource(source: Source): boolean;
121
138
  /** Return the stable source identity used for idempotency and attribution. */
package/dist/index.js CHANGED
@@ -150,29 +150,55 @@ var destinationSchema = z4.discriminatedUnion("platform", [
150
150
  slackDestinationSchema,
151
151
  localDestinationSchema
152
152
  ]);
153
- var slackSourceSchema = slackAddressSchema.extend({
153
+ var slackSourceSchema = z4.object({
154
+ kind: z4.literal("slack"),
155
+ teamId: slackTeamIdSchema,
156
+ channelId: slackConversationIdSchema,
154
157
  visibility: sourceVisibilitySchema,
155
158
  messageTs: nonBlankStringSchema.optional(),
156
159
  threadTs: nonBlankStringSchema.optional()
157
160
  }).strict();
158
161
  var localSourceSchema = z4.object({
159
- platform: z4.literal("local"),
162
+ kind: z4.literal("local"),
160
163
  visibility: z4.literal("private"),
161
164
  conversationId: localConversationIdSchema
162
165
  }).strict();
163
166
  var webSourceSchema = z4.object({
164
- platform: z4.literal("web"),
167
+ kind: z4.literal("web"),
165
168
  visibility: sourceVisibilitySchema,
166
169
  // Web can continue any existing conversation id, including Slack roots.
167
170
  conversationId: exactNonBlankStringSchema
168
171
  }).strict();
169
- var sourceWithLegacyLocationSchema = z4.discriminatedUnion("platform", [
170
- slackSourceSchema.extend({ location: locationSchema.optional() }).strict(),
171
- localSourceSchema.extend({ location: locationSchema.optional() }).strict(),
172
- webSourceSchema.extend({ location: locationSchema.optional() }).strict()
172
+ var resourceEventSourceSchema = z4.object({
173
+ kind: z4.literal("resource_event"),
174
+ eventKey: exactNonBlankStringSchema,
175
+ eventType: exactNonBlankStringSchema,
176
+ identifier: exactNonBlankStringSchema,
177
+ namespace: exactNonBlankStringSchema
178
+ }).strict();
179
+ var currentSourceSchema = z4.discriminatedUnion("kind", [
180
+ slackSourceSchema,
181
+ localSourceSchema,
182
+ webSourceSchema,
183
+ resourceEventSourceSchema
173
184
  ]);
174
- var sourceSchema = sourceWithLegacyLocationSchema.transform(
175
- ({ location: _legacyLocation, ...source }) => source
185
+ function normalizeStoredSource(value) {
186
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
187
+ return value;
188
+ }
189
+ const source = value;
190
+ if ("kind" in source || !("platform" in source)) {
191
+ return value;
192
+ }
193
+ if (source.platform !== "slack" && source.platform !== "local" && source.platform !== "web") {
194
+ return value;
195
+ }
196
+ const { location: _location, platform: kind, ...fields } = source;
197
+ return { ...fields, kind };
198
+ }
199
+ var sourceSchema = z4.preprocess(
200
+ normalizeStoredSource,
201
+ currentSourceSchema
176
202
  );
177
203
  var pluginCredentialSubjectSchema = z4.discriminatedUnion(
178
204
  "allowedWhen",
@@ -299,7 +325,7 @@ var dispatchOptionsSchema = z4.object({
299
325
  // src/context.ts
300
326
  function createSlackSource(input) {
301
327
  return {
302
- platform: "slack",
328
+ kind: "slack",
303
329
  visibility: input.visibility,
304
330
  teamId: input.teamId,
305
331
  channelId: input.channelId,
@@ -309,23 +335,32 @@ function createSlackSource(input) {
309
335
  }
310
336
  function createLocalSource(conversationId) {
311
337
  return {
312
- platform: "local",
338
+ kind: "local",
313
339
  visibility: "private",
314
340
  conversationId
315
341
  };
316
342
  }
317
343
  function createWebSource(conversationId, visibility = "public") {
318
344
  return {
319
- platform: "web",
345
+ kind: "web",
320
346
  visibility,
321
347
  conversationId
322
348
  };
323
349
  }
350
+ function createResourceEventSource(input) {
351
+ return {
352
+ kind: "resource_event",
353
+ eventKey: input.eventKey,
354
+ eventType: input.eventType,
355
+ identifier: input.identifier,
356
+ namespace: input.namespace
357
+ };
358
+ }
324
359
  function isPrivateSource(source) {
325
- return source.visibility === "private";
360
+ return "visibility" in source && source.visibility === "private";
326
361
  }
327
362
  function getSourceKey(source) {
328
- switch (source.platform) {
363
+ switch (source.kind) {
329
364
  case "web":
330
365
  case "local":
331
366
  return source.conversationId;
@@ -336,6 +371,8 @@ function getSourceKey(source) {
336
371
  }
337
372
  return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
338
373
  }
374
+ case "resource_event":
375
+ return `resource-event:${source.namespace}:${source.eventKey}`;
339
376
  }
340
377
  }
341
378
  function isSlackDestination(destination) {
@@ -1015,6 +1052,7 @@ export {
1015
1052
  conversationSidebarAnnotationSchema,
1016
1053
  conversationSidebarIconSchema,
1017
1054
  createLocalSource,
1055
+ createResourceEventSource,
1018
1056
  createSlackSource,
1019
1057
  createWebSource,
1020
1058
  defineConversationEvent,
@@ -1071,6 +1109,7 @@ export {
1071
1109
  resourceEventMatchSchema,
1072
1110
  resourceEventMatches,
1073
1111
  resourceEventSchema,
1112
+ resourceEventSourceSchema,
1074
1113
  resourceEventSubscriptionResultSchema,
1075
1114
  resourceEventTypeSchema,
1076
1115
  resourceLinkAnnotationSchema,
package/dist/schemas.d.ts CHANGED
@@ -53,9 +53,9 @@ export declare const destinationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
53
53
  platform: z.ZodLiteral<"local">;
54
54
  conversationId: z.ZodString;
55
55
  }, z.core.$strict>], "platform">;
56
- /** Runtime-owned Slack coordinates for the inbound invocation. */
56
+ /** Runtime-owned Slack input Source. */
57
57
  export declare const slackSourceSchema: z.ZodObject<{
58
- platform: z.ZodLiteral<"slack">;
58
+ kind: z.ZodLiteral<"slack">;
59
59
  teamId: z.ZodString;
60
60
  channelId: z.ZodString;
61
61
  visibility: z.ZodEnum<{
@@ -65,24 +65,32 @@ export declare const slackSourceSchema: z.ZodObject<{
65
65
  messageTs: z.ZodOptional<z.ZodString>;
66
66
  threadTs: z.ZodOptional<z.ZodString>;
67
67
  }, z.core.$strict>;
68
- /** Runtime-owned local CLI coordinates for the inbound invocation. */
68
+ /** Runtime-owned local CLI input Source. */
69
69
  export declare const localSourceSchema: z.ZodObject<{
70
- platform: z.ZodLiteral<"local">;
70
+ kind: z.ZodLiteral<"local">;
71
71
  visibility: z.ZodLiteral<"private">;
72
72
  conversationId: z.ZodString;
73
73
  }, z.core.$strict>;
74
- /** Runtime-owned dashboard/web coordinates for the inbound invocation. */
74
+ /** Runtime-owned dashboard input Source. */
75
75
  export declare const webSourceSchema: z.ZodObject<{
76
- platform: z.ZodLiteral<"web">;
76
+ kind: z.ZodLiteral<"web">;
77
77
  visibility: z.ZodEnum<{
78
78
  public: "public";
79
79
  private: "private";
80
80
  }>;
81
81
  conversationId: z.ZodString;
82
82
  }, z.core.$strict>;
83
- /** Runtime-owned input Source. Legacy stored Location is accepted and removed. */
84
- export declare const sourceSchema: z.ZodPipe<z.ZodDiscriminatedUnion<[z.ZodObject<{
85
- platform: z.ZodLiteral<"slack">;
83
+ /** Runtime-owned Resource event input Source. */
84
+ export declare const resourceEventSourceSchema: z.ZodObject<{
85
+ kind: z.ZodLiteral<"resource_event">;
86
+ eventKey: z.ZodString;
87
+ eventType: z.ZodString;
88
+ identifier: z.ZodString;
89
+ namespace: z.ZodString;
90
+ }, z.core.$strict>;
91
+ /** Runtime-owned input Source. Stored `platform` and Location fields normalize on read. */
92
+ export declare const sourceSchema: z.ZodPreprocess<z.ZodDiscriminatedUnion<[z.ZodObject<{
93
+ kind: z.ZodLiteral<"slack">;
86
94
  teamId: z.ZodString;
87
95
  channelId: z.ZodString;
88
96
  visibility: z.ZodEnum<{
@@ -91,90 +99,24 @@ export declare const sourceSchema: z.ZodPipe<z.ZodDiscriminatedUnion<[z.ZodObjec
91
99
  }>;
92
100
  messageTs: z.ZodOptional<z.ZodString>;
93
101
  threadTs: z.ZodOptional<z.ZodString>;
94
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
95
- id: z.ZodString;
96
- provider: z.ZodLiteral<"slack">;
97
- teamId: z.ZodString;
98
- channelId: z.ZodString;
99
- threadTs: z.ZodOptional<z.ZodString>;
100
- }, z.core.$strict>], "provider">>;
101
102
  }, z.core.$strict>, z.ZodObject<{
102
- platform: z.ZodLiteral<"local">;
103
+ kind: z.ZodLiteral<"local">;
103
104
  visibility: z.ZodLiteral<"private">;
104
105
  conversationId: z.ZodString;
105
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
106
- id: z.ZodString;
107
- provider: z.ZodLiteral<"slack">;
108
- teamId: z.ZodString;
109
- channelId: z.ZodString;
110
- threadTs: z.ZodOptional<z.ZodString>;
111
- }, z.core.$strict>], "provider">>;
112
106
  }, z.core.$strict>, z.ZodObject<{
113
- platform: z.ZodLiteral<"web">;
107
+ kind: z.ZodLiteral<"web">;
114
108
  visibility: z.ZodEnum<{
115
109
  public: "public";
116
110
  private: "private";
117
111
  }>;
118
112
  conversationId: z.ZodString;
119
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
120
- id: z.ZodString;
121
- provider: z.ZodLiteral<"slack">;
122
- teamId: z.ZodString;
123
- channelId: z.ZodString;
124
- threadTs: z.ZodOptional<z.ZodString>;
125
- }, z.core.$strict>], "provider">>;
126
- }, z.core.$strict>], "platform">, z.ZodTransform<{
127
- platform: "slack";
128
- teamId: string;
129
- channelId: string;
130
- visibility: "public" | "private";
131
- messageTs?: string | undefined;
132
- threadTs?: string | undefined;
133
- } | {
134
- platform: "local";
135
- visibility: "private";
136
- conversationId: string;
137
- } | {
138
- platform: "web";
139
- visibility: "public" | "private";
140
- conversationId: string;
141
- }, {
142
- platform: "slack";
143
- teamId: string;
144
- channelId: string;
145
- visibility: "public" | "private";
146
- messageTs?: string | undefined;
147
- threadTs?: string | undefined;
148
- location?: {
149
- id: string;
150
- provider: "slack";
151
- teamId: string;
152
- channelId: string;
153
- threadTs?: string | undefined;
154
- } | undefined;
155
- } | {
156
- platform: "local";
157
- visibility: "private";
158
- conversationId: string;
159
- location?: {
160
- id: string;
161
- provider: "slack";
162
- teamId: string;
163
- channelId: string;
164
- threadTs?: string | undefined;
165
- } | undefined;
166
- } | {
167
- platform: "web";
168
- visibility: "public" | "private";
169
- conversationId: string;
170
- location?: {
171
- id: string;
172
- provider: "slack";
173
- teamId: string;
174
- channelId: string;
175
- threadTs?: string | undefined;
176
- } | undefined;
177
- }>>;
113
+ }, z.core.$strict>, z.ZodObject<{
114
+ kind: z.ZodLiteral<"resource_event">;
115
+ eventKey: z.ZodString;
116
+ eventType: z.ZodString;
117
+ identifier: z.ZodString;
118
+ namespace: z.ZodString;
119
+ }, z.core.$strict>], "kind">>;
178
120
  /** Stable user credential subject shape accepted from plugins. */
179
121
  export declare const pluginCredentialSubjectSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
180
122
  type: z.ZodLiteral<"user">;
@@ -292,8 +234,8 @@ export declare const dispatchOptionsSchema: z.ZodObject<{
292
234
  label: z.ZodPipe<z.ZodString, z.ZodString>;
293
235
  detail: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodString>>;
294
236
  }, z.core.$strict>>;
295
- source: z.ZodPipe<z.ZodDiscriminatedUnion<[z.ZodObject<{
296
- platform: z.ZodLiteral<"slack">;
237
+ source: z.ZodPreprocess<z.ZodDiscriminatedUnion<[z.ZodObject<{
238
+ kind: z.ZodLiteral<"slack">;
297
239
  teamId: z.ZodString;
298
240
  channelId: z.ZodString;
299
241
  visibility: z.ZodEnum<{
@@ -302,88 +244,22 @@ export declare const dispatchOptionsSchema: z.ZodObject<{
302
244
  }>;
303
245
  messageTs: z.ZodOptional<z.ZodString>;
304
246
  threadTs: z.ZodOptional<z.ZodString>;
305
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
306
- id: z.ZodString;
307
- provider: z.ZodLiteral<"slack">;
308
- teamId: z.ZodString;
309
- channelId: z.ZodString;
310
- threadTs: z.ZodOptional<z.ZodString>;
311
- }, z.core.$strict>], "provider">>;
312
247
  }, z.core.$strict>, z.ZodObject<{
313
- platform: z.ZodLiteral<"local">;
248
+ kind: z.ZodLiteral<"local">;
314
249
  visibility: z.ZodLiteral<"private">;
315
250
  conversationId: z.ZodString;
316
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
317
- id: z.ZodString;
318
- provider: z.ZodLiteral<"slack">;
319
- teamId: z.ZodString;
320
- channelId: z.ZodString;
321
- threadTs: z.ZodOptional<z.ZodString>;
322
- }, z.core.$strict>], "provider">>;
323
251
  }, z.core.$strict>, z.ZodObject<{
324
- platform: z.ZodLiteral<"web">;
252
+ kind: z.ZodLiteral<"web">;
325
253
  visibility: z.ZodEnum<{
326
254
  public: "public";
327
255
  private: "private";
328
256
  }>;
329
257
  conversationId: z.ZodString;
330
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
331
- id: z.ZodString;
332
- provider: z.ZodLiteral<"slack">;
333
- teamId: z.ZodString;
334
- channelId: z.ZodString;
335
- threadTs: z.ZodOptional<z.ZodString>;
336
- }, z.core.$strict>], "provider">>;
337
- }, z.core.$strict>], "platform">, z.ZodTransform<{
338
- platform: "slack";
339
- teamId: string;
340
- channelId: string;
341
- visibility: "public" | "private";
342
- messageTs?: string | undefined;
343
- threadTs?: string | undefined;
344
- } | {
345
- platform: "local";
346
- visibility: "private";
347
- conversationId: string;
348
- } | {
349
- platform: "web";
350
- visibility: "public" | "private";
351
- conversationId: string;
352
- }, {
353
- platform: "slack";
354
- teamId: string;
355
- channelId: string;
356
- visibility: "public" | "private";
357
- messageTs?: string | undefined;
358
- threadTs?: string | undefined;
359
- location?: {
360
- id: string;
361
- provider: "slack";
362
- teamId: string;
363
- channelId: string;
364
- threadTs?: string | undefined;
365
- } | undefined;
366
- } | {
367
- platform: "local";
368
- visibility: "private";
369
- conversationId: string;
370
- location?: {
371
- id: string;
372
- provider: "slack";
373
- teamId: string;
374
- channelId: string;
375
- threadTs?: string | undefined;
376
- } | undefined;
377
- } | {
378
- platform: "web";
379
- visibility: "public" | "private";
380
- conversationId: string;
381
- location?: {
382
- id: string;
383
- provider: "slack";
384
- teamId: string;
385
- channelId: string;
386
- threadTs?: string | undefined;
387
- } | undefined;
388
- }>>;
258
+ }, z.core.$strict>, z.ZodObject<{
259
+ kind: z.ZodLiteral<"resource_event">;
260
+ eventKey: z.ZodString;
261
+ eventType: z.ZodString;
262
+ identifier: z.ZodString;
263
+ namespace: z.ZodString;
264
+ }, z.core.$strict>], "kind">>;
389
265
  }, z.core.$strict>;
package/dist/tasks.d.ts CHANGED
@@ -148,8 +148,8 @@ export declare const pluginRunContextSchema: z.ZodObject<{
148
148
  name: z.ZodString;
149
149
  }, z.core.$strict>], "platform">>;
150
150
  runId: z.ZodString;
151
- source: z.ZodPipe<z.ZodDiscriminatedUnion<[z.ZodObject<{
152
- platform: z.ZodLiteral<"slack">;
151
+ source: z.ZodPreprocess<z.ZodDiscriminatedUnion<[z.ZodObject<{
152
+ kind: z.ZodLiteral<"slack">;
153
153
  teamId: z.ZodString;
154
154
  channelId: z.ZodString;
155
155
  visibility: z.ZodEnum<{
@@ -158,90 +158,24 @@ export declare const pluginRunContextSchema: z.ZodObject<{
158
158
  }>;
159
159
  messageTs: z.ZodOptional<z.ZodString>;
160
160
  threadTs: z.ZodOptional<z.ZodString>;
161
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
162
- id: z.ZodString;
163
- provider: z.ZodLiteral<"slack">;
164
- teamId: z.ZodString;
165
- channelId: z.ZodString;
166
- threadTs: z.ZodOptional<z.ZodString>;
167
- }, z.core.$strict>], "provider">>;
168
161
  }, z.core.$strict>, z.ZodObject<{
169
- platform: z.ZodLiteral<"local">;
162
+ kind: z.ZodLiteral<"local">;
170
163
  visibility: z.ZodLiteral<"private">;
171
164
  conversationId: z.ZodString;
172
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
173
- id: z.ZodString;
174
- provider: z.ZodLiteral<"slack">;
175
- teamId: z.ZodString;
176
- channelId: z.ZodString;
177
- threadTs: z.ZodOptional<z.ZodString>;
178
- }, z.core.$strict>], "provider">>;
179
165
  }, z.core.$strict>, z.ZodObject<{
180
- platform: z.ZodLiteral<"web">;
166
+ kind: z.ZodLiteral<"web">;
181
167
  visibility: z.ZodEnum<{
182
168
  public: "public";
183
169
  private: "private";
184
170
  }>;
185
171
  conversationId: z.ZodString;
186
- location: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
187
- id: z.ZodString;
188
- provider: z.ZodLiteral<"slack">;
189
- teamId: z.ZodString;
190
- channelId: z.ZodString;
191
- threadTs: z.ZodOptional<z.ZodString>;
192
- }, z.core.$strict>], "provider">>;
193
- }, z.core.$strict>], "platform">, z.ZodTransform<{
194
- platform: "slack";
195
- teamId: string;
196
- channelId: string;
197
- visibility: "public" | "private";
198
- messageTs?: string | undefined;
199
- threadTs?: string | undefined;
200
- } | {
201
- platform: "local";
202
- visibility: "private";
203
- conversationId: string;
204
- } | {
205
- platform: "web";
206
- visibility: "public" | "private";
207
- conversationId: string;
208
- }, {
209
- platform: "slack";
210
- teamId: string;
211
- channelId: string;
212
- visibility: "public" | "private";
213
- messageTs?: string | undefined;
214
- threadTs?: string | undefined;
215
- location?: {
216
- id: string;
217
- provider: "slack";
218
- teamId: string;
219
- channelId: string;
220
- threadTs?: string | undefined;
221
- } | undefined;
222
- } | {
223
- platform: "local";
224
- visibility: "private";
225
- conversationId: string;
226
- location?: {
227
- id: string;
228
- provider: "slack";
229
- teamId: string;
230
- channelId: string;
231
- threadTs?: string | undefined;
232
- } | undefined;
233
- } | {
234
- platform: "web";
235
- visibility: "public" | "private";
236
- conversationId: string;
237
- location?: {
238
- id: string;
239
- provider: "slack";
240
- teamId: string;
241
- channelId: string;
242
- threadTs?: string | undefined;
243
- } | undefined;
244
- }>>;
172
+ }, z.core.$strict>, z.ZodObject<{
173
+ kind: z.ZodLiteral<"resource_event">;
174
+ eventKey: z.ZodString;
175
+ eventType: z.ZodString;
176
+ identifier: z.ZodString;
177
+ namespace: z.ZodString;
178
+ }, z.core.$strict>], "kind">>;
245
179
  transcript: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
246
180
  type: z.ZodLiteral<"message">;
247
181
  role: z.ZodEnum<{
package/dist/tools.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Actor, Identity, LocalInvocationContext, PluginContext, PluginEmbedder, PluginModel, SlackInvocationContext, User, WebInvocationContext } from "./context";
1
+ import type { Actor, Identity, LocalInvocationContext, ResourceEventInvocationContext, PluginContext, PluginEmbedder, PluginModel, SlackInvocationContext, User, WebInvocationContext } from "./context";
2
2
  import type { PluginCredentialSubject } from "./credentials";
3
3
  import type { PluginAnnotations } from "./annotations";
4
4
  import type { SlackConversationLink } from "./operations";
@@ -343,5 +343,8 @@ interface LocalToolRegistrationContext extends BaseToolRegistrationHookContext,
343
343
  interface WebToolRegistrationContext extends BaseToolRegistrationHookContext, WebInvocationContext {
344
344
  slack?: never;
345
345
  }
346
- export type ToolRegistrationHookContext = LocalToolRegistrationContext | SlackToolRegistrationContext | WebToolRegistrationContext;
346
+ interface ResourceEventToolRegistrationContext extends BaseToolRegistrationHookContext, ResourceEventInvocationContext {
347
+ slack?: never;
348
+ }
349
+ export type ToolRegistrationHookContext = LocalToolRegistrationContext | ResourceEventToolRegistrationContext | SlackToolRegistrationContext | WebToolRegistrationContext;
347
350
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-plugin-api",
3
- "version": "0.189.0",
3
+ "version": "0.190.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/context.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  slackActorSchema,
12
12
  systemActorSchema,
13
13
  sourceSchema,
14
+ sourceVisibilitySchema,
14
15
  slackLocationSchema,
15
16
  userSchema,
16
17
  } from "./schemas";
@@ -29,10 +30,11 @@ export type Source = z.output<typeof sourceSchema>;
29
30
  export type Location = z.output<typeof locationSchema>;
30
31
  /** Complete Slack Location associated with a Conversation. */
31
32
  export type SlackLocation = z.output<typeof slackLocationSchema>;
32
- export type SlackSource = Extract<Source, { platform: "slack" }>;
33
- export type LocalSource = Extract<Source, { platform: "local" }>;
34
- export type WebSource = Extract<Source, { platform: "web" }>;
35
- export type SourceVisibility = Source["visibility"];
33
+ export type SlackSource = Extract<Source, { kind: "slack" }>;
34
+ export type LocalSource = Extract<Source, { kind: "local" }>;
35
+ export type WebSource = Extract<Source, { kind: "web" }>;
36
+ export type ResourceEventSource = Extract<Source, { kind: "resource_event" }>;
37
+ export type SourceVisibility = z.output<typeof sourceVisibilitySchema>;
36
38
 
37
39
  export type Destination = z.output<typeof destinationSchema>;
38
40
 
@@ -117,8 +119,17 @@ export interface WebInvocationContext extends BaseInvocationContext {
117
119
  source: WebSource;
118
120
  }
119
121
 
122
+ export interface ResourceEventInvocationContext extends BaseInvocationContext {
123
+ /** Existing conversation destination used for tool context. */
124
+ destination: Destination;
125
+ actor?: SystemActor;
126
+ /** Runtime-owned Resource event Source for this invocation. */
127
+ source: ResourceEventSource;
128
+ }
129
+
120
130
  export type InvocationContext =
121
131
  | LocalInvocationContext
132
+ | ResourceEventInvocationContext
122
133
  | SlackInvocationContext
123
134
  | WebInvocationContext;
124
135
 
@@ -132,7 +143,7 @@ export function createSlackSource(input: {
132
143
  visibility: SourceVisibility;
133
144
  }): SlackSource {
134
145
  return {
135
- platform: "slack",
146
+ kind: "slack",
136
147
  visibility: input.visibility,
137
148
  teamId: input.teamId,
138
149
  channelId: input.channelId,
@@ -144,7 +155,7 @@ export function createSlackSource(input: {
144
155
  /** Build a normalized local source from a local conversation id. */
145
156
  export function createLocalSource(conversationId: string): LocalSource {
146
157
  return {
147
- platform: "local",
158
+ kind: "local",
148
159
  visibility: "private",
149
160
  conversationId,
150
161
  };
@@ -156,20 +167,36 @@ export function createWebSource(
156
167
  visibility: SourceVisibility = "public",
157
168
  ): WebSource {
158
169
  return {
159
- platform: "web",
170
+ kind: "web",
160
171
  visibility,
161
172
  conversationId,
162
173
  };
163
174
  }
164
175
 
176
+ /** Build a normalized Resource event Source from one matched event. */
177
+ export function createResourceEventSource(input: {
178
+ eventKey: string;
179
+ eventType: string;
180
+ identifier: string;
181
+ namespace: string;
182
+ }): ResourceEventSource {
183
+ return {
184
+ kind: "resource_event",
185
+ eventKey: input.eventKey,
186
+ eventType: input.eventType,
187
+ identifier: input.identifier,
188
+ namespace: input.namespace,
189
+ };
190
+ }
191
+
165
192
  /** Return whether a source is private to a person or restricted group. */
166
193
  export function isPrivateSource(source: Source): boolean {
167
- return source.visibility === "private";
194
+ return "visibility" in source && source.visibility === "private";
168
195
  }
169
196
 
170
197
  /** Return the stable source identity used for idempotency and attribution. */
171
198
  export function getSourceKey(source: Source): string | undefined {
172
- switch (source.platform) {
199
+ switch (source.kind) {
173
200
  case "web":
174
201
  case "local":
175
202
  return source.conversationId;
@@ -180,6 +207,8 @@ export function getSourceKey(source: Source): string | undefined {
180
207
  }
181
208
  return `slack:${source.teamId}:${source.channelId}:${messageKey}`;
182
209
  }
210
+ case "resource_event":
211
+ return `resource-event:${source.namespace}:${source.eventKey}`;
183
212
  }
184
213
  }
185
214
 
package/src/schemas.ts CHANGED
@@ -79,47 +79,80 @@ export const destinationSchema = z.discriminatedUnion("platform", [
79
79
  localDestinationSchema,
80
80
  ]);
81
81
 
82
- /** Runtime-owned Slack coordinates for the inbound invocation. */
83
- export const slackSourceSchema = slackAddressSchema
84
- .extend({
82
+ /** Runtime-owned Slack input Source. */
83
+ export const slackSourceSchema = z
84
+ .object({
85
+ kind: z.literal("slack"),
86
+ teamId: slackTeamIdSchema,
87
+ channelId: slackConversationIdSchema,
85
88
  visibility: sourceVisibilitySchema,
86
89
  messageTs: nonBlankStringSchema.optional(),
87
90
  threadTs: nonBlankStringSchema.optional(),
88
91
  })
89
92
  .strict();
90
93
 
91
- /** Runtime-owned local CLI coordinates for the inbound invocation. */
94
+ /** Runtime-owned local CLI input Source. */
92
95
  export const localSourceSchema = z
93
96
  .object({
94
- platform: z.literal("local"),
97
+ kind: z.literal("local"),
95
98
  visibility: z.literal("private"),
96
99
  conversationId: localConversationIdSchema,
97
100
  })
98
101
  .strict();
99
102
 
100
- /** Runtime-owned dashboard/web coordinates for the inbound invocation. */
103
+ /** Runtime-owned dashboard input Source. */
101
104
  export const webSourceSchema = z
102
105
  .object({
103
- platform: z.literal("web"),
106
+ kind: z.literal("web"),
104
107
  visibility: sourceVisibilitySchema,
105
108
  // Web can continue any existing conversation id, including Slack roots.
106
109
  conversationId: exactNonBlankStringSchema,
107
110
  })
108
111
  .strict();
109
112
 
110
- // TODO(dcramer): Replace Source.platform with Source.kind after every input
111
- // owner emits a first-class Source kind and deployed readers accept it.
112
- const sourceWithLegacyLocationSchema = z.discriminatedUnion("platform", [
113
- slackSourceSchema.extend({ location: locationSchema.optional() }).strict(),
114
- localSourceSchema.extend({ location: locationSchema.optional() }).strict(),
115
- webSourceSchema.extend({ location: locationSchema.optional() }).strict(),
113
+ /** Runtime-owned Resource event input Source. */
114
+ export const resourceEventSourceSchema = z
115
+ .object({
116
+ kind: z.literal("resource_event"),
117
+ eventKey: exactNonBlankStringSchema,
118
+ eventType: exactNonBlankStringSchema,
119
+ identifier: exactNonBlankStringSchema,
120
+ namespace: exactNonBlankStringSchema,
121
+ })
122
+ .strict();
123
+
124
+ const currentSourceSchema = z.discriminatedUnion("kind", [
125
+ slackSourceSchema,
126
+ localSourceSchema,
127
+ webSourceSchema,
128
+ resourceEventSourceSchema,
116
129
  ]);
117
130
 
118
- /** Runtime-owned input Source. Legacy stored Location is accepted and removed. */
119
- // TODO(dcramer): Parse sourceSchema directly from the three Source schemas after
120
- // no stored SQL, Redis, queue, or public Source can contain Location.
121
- export const sourceSchema = sourceWithLegacyLocationSchema.transform(
122
- ({ location: _legacyLocation, ...source }) => source,
131
+ function normalizeStoredSource(value: unknown): unknown {
132
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
133
+ return value;
134
+ }
135
+ const source = value as Record<string, unknown>;
136
+ if ("kind" in source || !("platform" in source)) {
137
+ return value;
138
+ }
139
+ if (
140
+ source.platform !== "slack" &&
141
+ source.platform !== "local" &&
142
+ source.platform !== "web"
143
+ ) {
144
+ return value;
145
+ }
146
+ const { location: _location, platform: kind, ...fields } = source;
147
+ return { ...fields, kind };
148
+ }
149
+
150
+ /** Runtime-owned input Source. Stored `platform` and Location fields normalize on read. */
151
+ // TODO(dcramer): Remove stored Source normalization after deployed SQL, Redis,
152
+ // queue, and OAuth values can only contain `kind` and no Location copy.
153
+ export const sourceSchema = z.preprocess(
154
+ normalizeStoredSource,
155
+ currentSourceSchema,
123
156
  );
124
157
 
125
158
  /** Stable user credential subject shape accepted from plugins. */
package/src/tools.ts CHANGED
@@ -2,6 +2,7 @@ import type {
2
2
  Actor,
3
3
  Identity,
4
4
  LocalInvocationContext,
5
+ ResourceEventInvocationContext,
5
6
  PluginContext,
6
7
  PluginEmbedder,
7
8
  PluginModel,
@@ -582,7 +583,13 @@ interface WebToolRegistrationContext
582
583
  slack?: never;
583
584
  }
584
585
 
586
+ interface ResourceEventToolRegistrationContext
587
+ extends BaseToolRegistrationHookContext, ResourceEventInvocationContext {
588
+ slack?: never;
589
+ }
590
+
585
591
  export type ToolRegistrationHookContext =
586
592
  | LocalToolRegistrationContext
593
+ | ResourceEventToolRegistrationContext
587
594
  | SlackToolRegistrationContext
588
595
  | WebToolRegistrationContext;