@sentry/junior-vercel 0.135.0 → 0.136.1

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
@@ -45,7 +45,13 @@ The endpoint must be publicly reachable. Subscribe it to `deployment.succeeded`,
45
45
 
46
46
  Deployment watches use Vercel's canonical `prj_...` ID. Junior resolves that ID from the project name or ID and optional team slug or ID through Vercel's authenticated project API.
47
47
 
48
- Create the conversation watch before the terminal deployment event. A valid webhook delivery does not create a watch by itself, and unmatched deliveries are not replayed later.
48
+ Supported scopes (`deployment` resource type):
49
+
50
+ - `prj_...` for every deployment in the project
51
+ - `prj_...:production` for every production deployment
52
+ - `prj_...:production:<sha>` for one commit-scoped deployment
53
+
54
+ Create the conversation watch or event task before the terminal deployment event. A valid webhook delivery does not create a watch by itself, and unmatched deliveries are not replayed later.
49
55
 
50
56
  ## Auth model
51
57
 
@@ -1,24 +1,42 @@
1
- // src/resource-events/deployment-source.ts
1
+ // src/resource-events/deployment.ts
2
2
  var VERCEL_DEPLOYMENT_EVENTS = [
3
3
  "deployment.succeeded",
4
4
  "deployment.error",
5
5
  "deployment.canceled"
6
6
  ];
7
- function vercelDeploymentSourceResource(input) {
8
- const commitSha2 = input.commitSha.toLowerCase();
7
+ var VERCEL_DEPLOYMENT_SUGGESTED_EVENTS = [
8
+ "deployment.succeeded",
9
+ "deployment.error",
10
+ "deployment.canceled"
11
+ ];
12
+ function vercelDeploymentResource(input) {
13
+ const commitSha2 = input.commitSha?.toLowerCase();
14
+ const target = input.target;
15
+ const parts = [input.projectId];
16
+ if (target) parts.push(target);
17
+ if (commitSha2) parts.push(commitSha2);
18
+ let label;
19
+ if (target && commitSha2) {
20
+ label = `Vercel ${target} deployment for ${input.projectId} at ${commitSha2.slice(0, 12)}`;
21
+ } else if (target) {
22
+ label = `Vercel ${target} deployments for ${input.projectId}`;
23
+ } else {
24
+ label = `Vercel deployments for ${input.projectId}`;
25
+ }
9
26
  return {
10
- label: `Vercel ${input.target} deployment for ${input.projectId} at ${commitSha2.slice(0, 12)}`,
27
+ label,
11
28
  namespace: "vercel",
12
- identifier: `deployment-source:${input.projectId}:${input.target}:${commitSha2}`
29
+ identifier: parts.join(":")
13
30
  };
14
31
  }
15
- function vercelDeploymentSourceSubscribable(input) {
32
+ function vercelDeploymentSubscribable(input) {
16
33
  if (!input.webhookSecret) return void 0;
34
+ if (input.commitSha && !input.target) return void 0;
17
35
  return {
18
- ...vercelDeploymentSourceResource(input),
19
- suggestedEvents: [...VERCEL_DEPLOYMENT_EVENTS],
36
+ ...vercelDeploymentResource(input),
37
+ suggestedEvents: VERCEL_DEPLOYMENT_SUGGESTED_EVENTS,
20
38
  supportedEvents: [...VERCEL_DEPLOYMENT_EVENTS],
21
- type: "deployment_source"
39
+ type: "deployment"
22
40
  };
23
41
  }
24
42
 
@@ -27,7 +45,7 @@ function vercelWebhookSecret() {
27
45
  return process.env.VERCEL_WEBHOOK_SECRET?.trim() || void 0;
28
46
  }
29
47
 
30
- // src/tools/deployment-source.ts
48
+ // src/tools/deployment.ts
31
49
  import {
32
50
  definePluginTool,
33
51
  pluginToolOutputSchema,
@@ -39,20 +57,24 @@ var commitShaSchema = z.string().regex(/^[0-9a-f]{40}$/i);
39
57
  var targetSchema = z.enum(["preview", "production", "staging"]);
40
58
  var nonEmptyStringSchema = z.string().trim().min(1);
41
59
  var inputSchema = z.object({
42
- commitSha: commitShaSchema.describe("Full 40-character Git commit SHA."),
60
+ commitSha: commitShaSchema.describe(
61
+ "Optional full 40-character Git commit SHA. Provide it to watch one deployment; omit it to watch every matching deployment for the project."
62
+ ).optional(),
43
63
  project: nonEmptyStringSchema.describe("Vercel project name or prj_ ID."),
44
- target: targetSchema.describe("Deployment target to monitor.").default("production"),
64
+ target: targetSchema.describe(
65
+ 'Optional deployment target such as "production". Omit to watch every target for the project. Defaults to "production" when commitSha is set.'
66
+ ).optional(),
45
67
  team: nonEmptyStringSchema.describe("Optional Vercel team slug or team_ ID that owns the project.").optional()
46
68
  }).strict();
47
- var deploymentSourceSchema = z.object({
48
- commitSha: commitShaSchema,
49
- deploymentTarget: targetSchema,
69
+ var deploymentSchema = z.object({
70
+ commitSha: commitShaSchema.nullable(),
71
+ deploymentTarget: targetSchema.nullable(),
50
72
  projectId: projectIdSchema,
51
73
  subscribable: subscribableResourceSchema.optional()
52
74
  });
53
75
  var outputSchema = pluginToolOutputSchema.extend({
54
- target: z.literal("deploymentSource"),
55
- ...deploymentSourceSchema.shape
76
+ target: z.literal("deployment"),
77
+ ...deploymentSchema.shape
56
78
  });
57
79
  async function readJson(response) {
58
80
  const text = await response.text();
@@ -72,7 +94,7 @@ function projectLookupUrl(project, team) {
72
94
  }
73
95
  return url.toString();
74
96
  }
75
- function createVercelDeploymentSourceTool(ctx) {
97
+ function createVercelDeploymentTool(ctx) {
76
98
  return definePluginTool({
77
99
  annotations: {
78
100
  destructiveHint: false,
@@ -80,7 +102,7 @@ function createVercelDeploymentSourceTool(ctx) {
80
102
  openWorldHint: true,
81
103
  readOnlyHint: true
82
104
  },
83
- description: "Resolve a Vercel project name or ID and describe its deployment target and full Git commit SHA as a subscribable deployment source. Use the user's explicit project and team, otherwise the vercel.project and vercel.team conversation defaults. Use this after the final deployed commit is known and before waiting for a deployment outcome.",
105
+ description: "Resolve a Vercel project name or ID and describe a subscribable deployment resource. Omit commitSha to watch every deployment for the project, optionally limited to one target (production, preview, or staging). Provide commitSha to watch one deployment; target defaults to production when omitted with commitSha. Use the user's explicit project and team, otherwise the vercel.project and vercel.team conversation defaults.",
84
106
  inputSchema,
85
107
  outputSchema,
86
108
  async execute(input) {
@@ -96,21 +118,22 @@ function createVercelDeploymentSourceTool(ctx) {
96
118
  );
97
119
  }
98
120
  const projectId = z.object({ id: projectIdSchema }).parse(parsed).id;
99
- const commitSha2 = input.commitSha.toLowerCase();
100
- const subscribable = ctx.resourceEvents.canSubscribe ? vercelDeploymentSourceSubscribable({
121
+ const commitSha2 = input.commitSha?.toLowerCase();
122
+ const deploymentTarget2 = input.target ?? (commitSha2 ? "production" : void 0);
123
+ const subscribable = ctx.resourceEvents.canSubscribe ? vercelDeploymentSubscribable({
101
124
  commitSha: commitSha2,
102
125
  projectId,
103
- target: input.target,
126
+ target: deploymentTarget2,
104
127
  webhookSecret: vercelWebhookSecret()
105
128
  }) : void 0;
106
129
  const data = {
107
- commitSha: commitSha2,
108
- deploymentTarget: input.target,
130
+ commitSha: commitSha2 ?? null,
131
+ deploymentTarget: deploymentTarget2 ?? null,
109
132
  projectId,
110
133
  ...subscribable ? { subscribable } : {}
111
134
  };
112
135
  return {
113
- target: "deploymentSource",
136
+ target: "deployment",
114
137
  ...data
115
138
  };
116
139
  }
@@ -175,32 +198,63 @@ function isDeploymentEvent(value) {
175
198
  value
176
199
  );
177
200
  }
201
+ function deploymentTargets(input) {
202
+ const targets = [
203
+ {
204
+ completeOnTerminalEvent: false,
205
+ resource: vercelDeploymentResource({
206
+ projectId: input.projectId
207
+ })
208
+ },
209
+ {
210
+ completeOnTerminalEvent: false,
211
+ resource: vercelDeploymentResource({
212
+ projectId: input.projectId,
213
+ target: input.target
214
+ })
215
+ }
216
+ ];
217
+ if (input.commitSha) {
218
+ targets.push({
219
+ completeOnTerminalEvent: true,
220
+ resource: vercelDeploymentResource({
221
+ commitSha: input.commitSha,
222
+ projectId: input.projectId,
223
+ target: input.target
224
+ })
225
+ });
226
+ }
227
+ return targets;
228
+ }
178
229
  function normalizeVercelResourceEvents(args) {
179
230
  const envelope = webhookEnvelopeSchema.safeParse(args.body);
180
231
  if (!envelope.success || !isDeploymentEvent(envelope.data.type)) return [];
181
232
  const payload = deploymentPayloadSchema.safeParse(envelope.data.payload);
182
233
  if (!payload.success) return [];
183
234
  const target = payload.data.target;
184
- const sha = payload.data.commitSha;
185
- if (!target || !sha) return [];
186
- const resource = vercelDeploymentSourceResource({
187
- commitSha: sha,
188
- projectId: payload.data.projectId,
189
- target
190
- });
235
+ if (!target) return [];
191
236
  const eventType = envelope.data.type;
192
237
  const deploymentId = payload.data.deploymentId;
193
238
  const outcome = eventType === "deployment.succeeded" ? "succeeded" : eventType === "deployment.error" ? "failed" : "was canceled";
194
- return [
195
- {
196
- eventKey: `vercel:${envelope.data.id}:${eventType}`,
197
- eventType,
198
- occurredAtMs: envelope.data.createdAt,
199
- identifier: resource.identifier,
200
- terminal: true,
201
- trustedSummary: `${resource.label} (${deploymentId}) ${outcome}.`
202
- }
203
- ];
239
+ const untrustedParts = [
240
+ `Target: ${target}`,
241
+ payload.data.commitSha ? `Commit: ${payload.data.commitSha}` : void 0,
242
+ `Deployment: ${deploymentId}`
243
+ ].filter((part) => part !== void 0);
244
+ const untrustedText = untrustedParts.join("\n");
245
+ return deploymentTargets({
246
+ commitSha: payload.data.commitSha,
247
+ projectId: payload.data.projectId,
248
+ target
249
+ }).map(({ completeOnTerminalEvent, resource }) => ({
250
+ eventKey: `vercel:${envelope.data.id}:${eventType}`,
251
+ eventType,
252
+ occurredAtMs: envelope.data.createdAt,
253
+ identifier: resource.identifier,
254
+ ...completeOnTerminalEvent ? { terminal: true } : {},
255
+ trustedSummary: `${resource.label} (${deploymentId}) ${outcome}.`,
256
+ untrustedText
257
+ }));
204
258
  }
205
259
 
206
260
  // src/webhooks/handler.ts
@@ -247,8 +301,9 @@ function createVercelWebhookRoute(args) {
247
301
 
248
302
  export {
249
303
  VERCEL_DEPLOYMENT_EVENTS,
304
+ VERCEL_DEPLOYMENT_SUGGESTED_EVENTS,
250
305
  vercelWebhookSecret,
251
- createVercelDeploymentSourceTool,
306
+ createVercelDeploymentTool,
252
307
  normalizeVercelResourceEvents,
253
308
  createVercelWebhookRoute
254
309
  };
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  * Vercel plugin runtime boundary.
3
3
  *
4
4
  * This package owns Vercel CLI setup, host-managed API authentication, signed
5
- * webhook normalization, and deployment-source tools. Junior core owns the
6
- * resulting conversation subscriptions and event delivery.
5
+ * webhook normalization, and deployment tools. Junior core owns the resulting
6
+ * conversation subscriptions and event delivery.
7
7
  */
8
8
  import { type PluginRegistration } from "@sentry/junior-plugin-api";
9
9
  /** Register Vercel runtime metadata, tools, and signed webhook ingress. */
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  VERCEL_DEPLOYMENT_EVENTS,
3
- createVercelDeploymentSourceTool,
3
+ VERCEL_DEPLOYMENT_SUGGESTED_EVENTS,
4
+ createVercelDeploymentTool,
4
5
  createVercelWebhookRoute,
5
6
  vercelWebhookSecret
6
- } from "./chunk-5ZQCPWW4.js";
7
+ } from "./chunk-JPFMGGYE.js";
7
8
 
8
9
  // src/index.ts
9
10
  import {
@@ -15,9 +16,9 @@ function vercelPlugin() {
15
16
  resourceEvents: {
16
17
  resourceTypes: [
17
18
  {
18
- type: "deployment_source",
19
+ type: "deployment",
19
20
  supportedEvents: [...VERCEL_DEPLOYMENT_EVENTS],
20
- suggestedEvents: [...VERCEL_DEPLOYMENT_EVENTS]
21
+ suggestedEvents: [...VERCEL_DEPLOYMENT_SUGGESTED_EVENTS]
21
22
  }
22
23
  ],
23
24
  isEnabled: () => Boolean(vercelWebhookSecret())
@@ -57,7 +58,7 @@ function vercelPlugin() {
57
58
  },
58
59
  tools(ctx) {
59
60
  return {
60
- deploymentSource: createVercelDeploymentSourceTool(ctx)
61
+ deployment: createVercelDeploymentTool(ctx)
61
62
  };
62
63
  }
63
64
  }
@@ -0,0 +1,17 @@
1
+ import type { SubscribableResource } from "@sentry/junior-plugin-api";
2
+ export declare const VERCEL_DEPLOYMENT_EVENTS: readonly ["deployment.succeeded", "deployment.error", "deployment.canceled"];
3
+ export declare const VERCEL_DEPLOYMENT_SUGGESTED_EVENTS: string[];
4
+ export type VercelDeploymentTarget = "preview" | "production" | "staging";
5
+ /** Build the stable deployment identity shared by tools and webhooks. */
6
+ export declare function vercelDeploymentResource(input: {
7
+ commitSha?: string;
8
+ projectId: string;
9
+ target?: VercelDeploymentTarget;
10
+ }): Pick<SubscribableResource, "label" | "namespace" | "identifier">;
11
+ /** Describe a deployment resource when signed Vercel webhooks are enabled. */
12
+ export declare function vercelDeploymentSubscribable(input: {
13
+ commitSha?: string;
14
+ projectId: string;
15
+ target?: VercelDeploymentTarget;
16
+ webhookSecret?: string;
17
+ }): SubscribableResource | undefined;
package/dist/testing.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { createVercelDeploymentSourceTool } from "./tools/deployment-source.js";
1
+ export { createVercelDeploymentTool } from "./tools/deployment.js";
2
2
  export { createVercelWebhookRoute } from "./webhooks/handler.js";
3
3
  export { normalizeVercelResourceEvents } from "./webhooks/resource-events.js";
package/dist/testing.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
- createVercelDeploymentSourceTool,
2
+ createVercelDeploymentTool,
3
3
  createVercelWebhookRoute,
4
4
  normalizeVercelResourceEvents
5
- } from "./chunk-5ZQCPWW4.js";
5
+ } from "./chunk-JPFMGGYE.js";
6
6
  export {
7
- createVercelDeploymentSourceTool,
7
+ createVercelDeploymentTool,
8
8
  createVercelWebhookRoute,
9
9
  normalizeVercelResourceEvents
10
10
  };
@@ -1,16 +1,16 @@
1
1
  import { type ToolRegistrationHookContext } from "@sentry/junior-plugin-api";
2
- /** Resolve and return the resource identity for one Vercel deployment source. */
3
- export declare function createVercelDeploymentSourceTool(ctx: ToolRegistrationHookContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
4
- commitSha: string;
2
+ /** Resolve and return the resource identity for one Vercel deployment. */
3
+ export declare function createVercelDeploymentTool(ctx: ToolRegistrationHookContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
5
4
  project: string;
6
- target: "preview" | "production" | "staging";
5
+ commitSha?: string | undefined;
6
+ target?: "preview" | "production" | "staging" | undefined;
7
7
  team?: string | undefined;
8
8
  }, {
9
9
  [x: string]: unknown;
10
- commitSha: string;
11
- deploymentTarget: "preview" | "production" | "staging";
10
+ commitSha: string | null;
11
+ deploymentTarget: "preview" | "production" | "staging" | null;
12
12
  projectId: string;
13
- target: "deploymentSource";
13
+ target: "deployment";
14
14
  truncated?: boolean | undefined;
15
15
  continuation?: {
16
16
  arguments: Record<string, unknown>;
@@ -26,10 +26,10 @@ export declare function createVercelDeploymentSourceTool(ctx: ToolRegistrationHo
26
26
  } | undefined;
27
27
  }, {
28
28
  [x: string]: unknown;
29
- commitSha: string;
30
- deploymentTarget: "preview" | "production" | "staging";
29
+ commitSha: string | null;
30
+ deploymentTarget: "preview" | "production" | "staging" | null;
31
31
  projectId: string;
32
- target: "deploymentSource";
32
+ target: "deployment";
33
33
  truncated?: boolean | undefined;
34
34
  continuation?: {
35
35
  arguments: Record<string, unknown>;
@@ -2,10 +2,10 @@
2
2
  * Owns Vercel's deployment webhook wire-format boundary.
3
3
  *
4
4
  * It validates webhook payloads, ignores unsupported or incomplete deliveries,
5
- * and emits only canonical terminal resource events.
5
+ * and emits canonical resource events for project, target, and commit watches.
6
6
  */
7
7
  import type { ResourceEventInput } from "@sentry/junior-plugin-api";
8
- /** Normalize one verified Vercel delivery into a terminal deployment event. */
8
+ /** Normalize one verified Vercel delivery into deployment resource events. */
9
9
  export declare function normalizeVercelResourceEvents(args: {
10
10
  body: unknown;
11
11
  }): ResourceEventInput[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-vercel",
3
- "version": "0.135.0",
3
+ "version": "0.136.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,7 +27,7 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "zod": "^4.4.3",
30
- "@sentry/junior-plugin-api": "0.135.0"
30
+ "@sentry/junior-plugin-api": "0.136.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^25.9.1",
@@ -37,7 +37,7 @@ Do not run `deploy`, `rollback`, `promote`, `remove`, `env`, `alias`, `dns`, `pr
37
37
  - For runtime logs, prefer `vercel logs --project <project> --since <window> --limit 20 --json` plus user-provided filters such as `--environment`, `--level`, `--status-code`, `--source`, `--query`, or `--deployment`.
38
38
  - Use `vercel inspect <deployment-id-or-url> --logs` for build logs. Add `--wait` only when the user explicitly wants to wait for an active build; also bound it with `--timeout`.
39
39
  - Use `vercel list <project>` or `vercel ls <project>` to find deployments. Prefer filters such as `--status`, `--environment`, `--prod`, or `--meta githubCommitSha=<sha>` when available.
40
- - For a deployment watch, call the `vercel_deploymentSource` plugin tool with the project name, optional team slug or ID, deployment target, and full 40-character commit SHA. The tool resolves the canonical project ID through Vercel before Junior creates the conversation subscription.
40
+ - For a deployment watch or event task, call the `vercel_deployment` plugin tool with the project name and optional team slug or ID. Omit `commitSha` to watch every deployment for the project; add `target` (`production`, `preview`, or `staging`) to limit the watch to one environment; add a full 40-character `commitSha` to watch one deployment (`target` defaults to `production` when omitted with a commit). The tool resolves the canonical project ID through Vercel before Junior creates the conversation subscription or event task.
41
41
  - Use `--follow` only when the user asks for live logs, and stop once enough evidence is captured. Do not leave a streaming command running indefinitely.
42
42
 
43
43
  3. Bound and minimize output:
@@ -1,16 +0,0 @@
1
- import type { SubscribableResource } from "@sentry/junior-plugin-api";
2
- export declare const VERCEL_DEPLOYMENT_EVENTS: readonly ["deployment.succeeded", "deployment.error", "deployment.canceled"];
3
- export type VercelDeploymentTarget = "preview" | "production" | "staging";
4
- /** Build the stable deployment-source identity shared by tools and webhooks. */
5
- export declare function vercelDeploymentSourceResource(input: {
6
- commitSha: string;
7
- projectId: string;
8
- target: VercelDeploymentTarget;
9
- }): Pick<SubscribableResource, "label" | "namespace" | "identifier">;
10
- /** Describe a deployment source when signed Vercel webhooks are enabled. */
11
- export declare function vercelDeploymentSourceSubscribable(input: {
12
- commitSha: string;
13
- projectId: string;
14
- target: VercelDeploymentTarget;
15
- webhookSecret?: string;
16
- }): SubscribableResource | undefined;