feat(sdk,cli,core): webhook() with typed provider sources, filters, and indexing - #4923
feat(sdk,cli,core): webhook() with typed provider sources, filters, and indexing#4923ericallam wants to merge 1 commit into
Conversation
…nd indexing The public SDK half of hosted webhooks: `webhook()` declares an endpoint that routes a verified, typed event to `onEvent`, with provider presets (`webhooks.stripe()`, `webhooks.github()`, `webhooks.svix()`, and the rest of the config-table producers) or `webhooks.custom<T>()`, and an optional type-checked `filter`. The CLI indexes declared webhooks into the worker manifest and fails indexing on duplicate webhook ids. Docs cover sources, connecting a provider, deliveries, and filters. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PPzBQgFgqD8aPQcEYZXty
🦋 Changeset detectedLatest commit: a46f330 The changes in this PR will be included in the next version bump. This PR includes changesets to release 27 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughAdds hosted webhook declarations with typed provider sources, custom verification, filters, event handlers, and webhook metadata. Extends worker indexing and deployment manifests with webhook data and duplicate-ID detection. Adds documentation for webhook sources, provider connection, deliveries, filters, and lifecycle behavior. Adds release metadata for the webhook packages. Priority: ➖ Normal Merge Risk: 🟠 High · up to Manual webhook triggers can invoke handlers without event data, while duplicate webhook IDs can cause indexing to time out instead of reporting the collision. Fix these paths before merge. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 9 files. (7 skipped: 7 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
docs/webhooks/sources.mdx (1)
15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse
typescriptfor all TypeScript fences.The documentation guide specifies
typescriptas the TypeScript fence tag. Change the fivetsfences in this page totypescript.packages/trigger-sdk/src/v3/webhooks.ts (1)
294-307: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse a type alias for
Webhooks.This follows the repository’s TypeScript convention. The change is type-only and has no runtime effect.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Advanced
Run ID: 120ae2de-2a9b-46a2-9c92-c795719cbbb8
📒 Files selected for processing (16)
.changeset/hosted-webhook-ingress.mddocs/docs.jsondocs/webhooks/connect.mdxdocs/webhooks/deliveries.mdxdocs/webhooks/filters.mdxdocs/webhooks/overview.mdxdocs/webhooks/sources.mdxpackages/cli-v3/src/dev/devSupervisor.tspackages/cli-v3/src/entryPoints/dev-index-worker.tspackages/cli-v3/src/entryPoints/managed-index-controller.tspackages/cli-v3/src/entryPoints/managed-index-worker.tspackages/cli-v3/src/indexing/indexWorkerManifest.tspackages/cli-v3/src/indexing/reportWebhookIdCollisions.tspackages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.tspackages/trigger-sdk/src/v3/webhooks.ts
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
📜 Review details
⏰ Context from checks skipped due to timeout. (46)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (18, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (16, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (23, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (21, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (24, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (22, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (1, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (10, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (19, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (3, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (7, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (14, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (5, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (4, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (17, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (20, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (12, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (2, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (13, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (9, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (8, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (6, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (15, 24)
- GitHub Check: webapp / 🧪 Unit Tests: Webapp (11, 24)
- GitHub Check: e2e / 🧪 CLI v3 tests (warp-windows-latest-x64-8x - pnpm)
- GitHub Check: sdk-compat / Node.js 26.4 (warp-ubuntu-latest-x64-4x)
- GitHub Check: e2e / 🧪 CLI v3 tests (warp-windows-latest-x64-8x - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (warp-ubuntu-latest-x64-4x - npm)
- GitHub Check: e2e / 🧪 CLI v3 tests (warp-ubuntu-latest-x64-4x - pnpm)
- GitHub Check: sdk-compat / Node.js 22.23 (warp-ubuntu-latest-x64-4x)
- GitHub Check: sdk-compat / Node.js 24.18 (warp-ubuntu-latest-x64-4x)
- GitHub Check: sdk-compat / Node.js 20.20 (warp-ubuntu-latest-x64-4x)
- GitHub Check: packages / 🧪 Unit Tests: Packages (2, 3)
- GitHub Check: sdk-compat / Deno Runtime
- GitHub Check: runops-guard / runops-guard
- GitHub Check: sdk-compat / Bun Runtime
- GitHub Check: packages / 🧪 Unit Tests: Packages (3, 3)
- GitHub Check: packages / 🧪 Unit Tests: Packages (1, 3)
- GitHub Check: sdk-compat / Cloudflare Workers
- GitHub Check: fk-cascade-guard / fk-cascade-guard
- GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (2, 2)
- GitHub Check: typecheck / typecheck
- GitHub Check: internal / 🧪 Unit Tests: Internal
- GitHub Check: e2e-webapp / 🧪 E2E Tests: Webapp (1, 2)
- GitHub Check: code-quality / code-quality
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (12)
**Public packages** (`packages/*`): Use `build`.
📄 CodeRabbit inference engine (AGENTS.md)
Files:
packages/cli-v3/src/entryPoints/managed-index-controller.tspackages/cli-v3/src/entryPoints/dev-index-worker.tspackages/cli-v3/src/dev/devSupervisor.tspackages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.tspackages/cli-v3/src/indexing/indexWorkerManifest.tspackages/cli-v3/src/entryPoints/managed-index-worker.tspackages/cli-v3/src/indexing/reportWebhookIdCollisions.tspackages/trigger-sdk/src/v3/webhooks.ts
Code in `src/entryPoints/` runs inside customer containers and is a different runtime environment from the CLI - changes affect deployed task execution directly
📄 CodeRabbit inference engine (packages/cli-v3/CLAUDE.md)
Files:
packages/cli-v3/src/entryPoints/managed-index-controller.tspackages/cli-v3/src/entryPoints/dev-index-worker.tspackages/cli-v3/src/entryPoints/managed-index-worker.ts
Always import from `@trigger.dev/sdk`.
📄 CodeRabbit inference engine (packages/trigger-sdk/CLAUDE.md)
Files:
packages/trigger-sdk/src/v3/webhooks.ts
Use zod for validation in packages/core and apps/webapp
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
packages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.ts
In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
packages/trigger-sdk/src/v3/webhooks.ts
Never import the root package (`@trigger.dev/core`).
📄 CodeRabbit inference engine (packages/core/CLAUDE.md)
Files:
packages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.ts
Dev mode code should be located in `src/dev/` and runs tasks locally in the user's Node.js process without containers
📄 CodeRabbit inference engine (packages/cli-v3/CLAUDE.md)
Files:
packages/cli-v3/src/dev/devSupervisor.ts
Main documentation config must be defined in `docs.json` which includes navigation structure, theme, and metadata Navigation structure in `docs.json` should be organized using `navigation.dropdowns` with groups and pages
📄 CodeRabbit inference engine (docs/CLAUDE.md)
Files:
docs/docs.json
Use function declarations instead of default exports
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
packages/cli-v3/src/entryPoints/managed-index-controller.tspackages/cli-v3/src/entryPoints/dev-index-worker.tspackages/cli-v3/src/dev/devSupervisor.tspackages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.tspackages/cli-v3/src/indexing/indexWorkerManifest.tspackages/cli-v3/src/entryPoints/managed-index-worker.tspackages/cli-v3/src/indexing/reportWebhookIdCollisions.tspackages/trigger-sdk/src/v3/webhooks.ts
MDX documentation pages must include frontmatter with title (required), description (required), and sidebarTitle (optional) in YAML format Use Mintlify components for structured content: , , , , ,
📄 CodeRabbit inference engine (docs/CLAUDE.md)
Files:
docs/webhooks/connect.mdx
docs/webhooks/sources.mdx
docs/webhooks/overview.mdx
docs/webhooks/filters.mdx
docs/webhooks/deliveries.mdx
docs/webhooks/connect.mdxdocs/webhooks/sources.mdxdocs/webhooks/overview.mdxdocs/webhooks/filters.mdxdocs/webhooks/deliveries.mdxUse types over interfaces for TypeScript Avoid using enums; prefer string unions or const objects instead
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
packages/cli-v3/src/entryPoints/managed-index-controller.tspackages/cli-v3/src/entryPoints/dev-index-worker.tspackages/cli-v3/src/dev/devSupervisor.tspackages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.tspackages/cli-v3/src/indexing/indexWorkerManifest.tspackages/cli-v3/src/entryPoints/managed-index-worker.tspackages/cli-v3/src/indexing/reportWebhookIdCollisions.tspackages/trigger-sdk/src/v3/webhooks.ts
When creating or editing OTEL metrics (counters, histograms, gauges), ensure metric attributes have low cardinality by using only enums, booleans, bounded error codes, or bounded shard IDs Do not use high-cardinality attributes in OTEL metr...
📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)
Files:
packages/cli-v3/src/entryPoints/managed-index-controller.tspackages/cli-v3/src/entryPoints/dev-index-worker.tspackages/cli-v3/src/dev/devSupervisor.tspackages/core/src/v3/errors.tspackages/core/src/v3/schemas/messages.tspackages/cli-v3/src/indexing/indexWorkerManifest.tspackages/cli-v3/src/entryPoints/managed-index-worker.tspackages/cli-v3/src/indexing/reportWebhookIdCollisions.tspackages/trigger-sdk/src/v3/webhooks.ts
🧠 Learnings (1)
📚 Learning: 2026-04-30T20:30:29.458Z
Learnt from: ericallam
Repo: triggerdotdev/trigger.dev PR: 3226
File: docs/ai-chat/quick-start.mdx:13-13
Timestamp: 2026-04-30T20:30:29.458Z
Learning: In this repo’s documentation MDX files (`docs/**/*.mdx`), use `ts` and `tsx` (not `typescript`) as the code-fence language tags for TypeScript/TSX snippets. Do not flag `ts`/`tsx` code-fence language tags as incorrect in any docs MDX file, since this is the site-wide Mintlify-compatible convention.
Applied to files:
docs/webhooks/sources.mdxdocs/webhooks/overview.mdxdocs/webhooks/filters.mdx
🪛 LanguageTool
.changeset/hosted-webhook-ingress.md
[uncategorized] ~9-~9: The official name of this software platform is spelled with a capital “H”.
Context: ...rce with a preset (webhooks.stripe(), webhooks.github(), and others) or `webhooks.custom(...
(GITHUB)
[grammar] ~10-~10: Ensure spelling is correct
Context: ... hosted URL on deploy. - filter gates which deliveries run, using a type-safe expre...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
docs/webhooks/sources.mdx
[uncategorized] ~57-~57: The official name of this software platform is spelled with a capital “H”.
Context: ... The available presets are stripe(), github(), svix(), square(), and `discord(...
(GITHUB)
🔇 Additional comments (10)
docs/webhooks/connect.mdx (1)
1-35: LGTM!packages/trigger-sdk/src/v3/webhooks.ts (1)
1-23: LGTM!Also applies to: 48-200, 203-232, 252-263, 265-267, 313-330
packages/cli-v3/src/indexing/reportWebhookIdCollisions.ts (1)
1-21: LGTM!Also applies to: 25-28
packages/cli-v3/src/entryPoints/dev-index-worker.ts (1)
20-20: LGTM!Also applies to: 204-204
packages/cli-v3/src/entryPoints/managed-index-worker.ts (1)
20-20: LGTM!Also applies to: 200-200
packages/cli-v3/src/dev/devSupervisor.ts (1)
394-394: LGTM!packages/core/src/v3/schemas/messages.ts (1)
47-50: LGTM!packages/core/src/v3/errors.ts (1)
610-639: LGTM!packages/cli-v3/src/indexing/indexWorkerManifest.ts (1)
4-4: LGTM!Also applies to: 98-104
packages/cli-v3/src/entryPoints/managed-index-controller.ts (1)
106-106: LGTM!
| Duplicate deliveries are deduplicated automatically. The idempotency key is the provider's event id | ||
| (e.g. the Stripe event id, or GitHub's `X-GitHub-Delivery`), so a provider retry of the same event | ||
| resolves to the original delivery and won't trigger a second run. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Qualify the duplicate-delivery guarantee.
If a source has no configured idempotency field and a provider retry has a new timestamp or signature, the fallback key changes. internal-packages/webhook-engine/src/engine/verification/derive.ts:3-25 hashes the raw body, timestamp, and signature in that case. The retry can create another delivery and run.
State that automatic retry deduplication requires a stable provider event ID. Tell custom-source users to configure idempotencyField when the provider supplies one.
| async (msg) => { | ||
| send(msg); | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Await the IPC send completion before exiting.
sendMessageInCatalog awaits its sender, but both callbacks call safeSend(msg) without returning its result. safeSend can skip the send or swallow a synchronous process.send error, so reportWebhookIdCollisions still returns true and the worker exits after 10 ms. The parent can then wait for the 20-second timeout instead of receiving WEBHOOKS_FAILED_TO_INDEX.
Make safeSend return a promise backed by the process.send callback. Reject when the channel is unavailable, process.send throws, or the callback receives an error, and return that promise from both reporter callbacks. The callback confirms that Node wrote to the IPC channel; it does not confirm that the parent processed the message. Add an acknowledgement protocol if that stronger guarantee is required.
| const task = createTask<TIdentifier, InferWebhookEvent<TSource>, void>({ | ||
| id, | ||
| triggerSource: "webhook", | ||
| run: async (payload, runOptions) => { | ||
| const envelope = payload as unknown as WebhookRunPayload<InferWebhookEvent<TSource>>; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
Do not expose event-only trigger methods for this task.
WebhookHandle accepts TEvent through methods such as trigger(). The runner then casts that event to WebhookRunPayload<TEvent> and reads envelope.event.
A call such as handle.trigger(event) therefore type-checks, but onEvent receives undefined. Use the envelope as the internal task input. Return a webhook-specific handle that omits manual trigger methods, or implement manual event handling explicitly.
|
Closing; this work is being reorganised and will be re-opened separately. |
Summary
The public SDK half of hosted webhooks, split out of #4537 so the webhook API can ship on its own.
webhook()declares an endpoint that routes a verified, typed event to anonEventhandler, with provider presets (webhooks.stripe(),webhooks.github(),webhooks.svix(), and the rest of the config-table producers) orwebhooks.custom<T>(), plus an optionalfilterchecked against the event type at author time.The CLI indexes declared webhooks into the worker manifest and fails indexing on duplicate webhook ids with a
DuplicateWebhookIdsError. Docs add the Webhooks section: overview, sources, connecting a provider, deliveries, and filters.Stack
This is the bottom of a two-PR stack. #4537 (chat.event, session routing, channels, human-in-the-loop,
@trigger.dev/slack) is retargeted onto this branch and merges after it. The server half (#4344) is already on main behind a flag.Testing
tsc --noEmitclean for@trigger.dev/sdkandtrigger.dev(CLI).@trigger.dev/sdkvitest suite passes with the stacked branch applied on top.Changelog
Adds
webhook()andwebhooks.*provider sources to@trigger.dev/sdk, webhook indexing and duplicate-id detection to the CLI, and the webhooks docs section. One changeset bumps core, sdk, and the CLI together.🤖 Generated with Claude Code
https://claude.ai/code/session_016PPzBQgFgqD8aPQcEYZXty