Changesetwebpatch
Drop the custom-quoted Scale offer from SoftwareApplication markup so Rich Results only reports the optional aggregateRating hint.
Changesetwebpatch
Give the Scale offer a priceSpecification so Rich Results reports no warnings on the home page.
Changesetwebpatch
Add FAQPage and SoftwareApplication structured data to the home page, and generate sitemap.xml at build time with git-derived lastmod dates.
Changesetwebpatch
Replace the placeholder hooks.dev domains with api.hooks.events and add an llms.txt link checker.
Changesetwebpatch
Route the console collection index paths to the noindex SPA shell.
Changesetwebpatch
Add crawler-visible noindex for console and auth routes and fill in full meta descriptions.
Changesetwebpatch
Run the prerender pass from a Vite plugin so alchemy deploy, which drives its own vite build, ships the prerendered marketing pages and 404 page instead of
Run the prerender pass from a Vite plugin so alchemy deploy, which drives its own vite build, ships the prerendered marketing pages and 404 page instead of only the SPA shell.
Changeset
---
--- ---
test(server): make the tampered-cookie auth test deterministic
Changeset
---
--- ---
Test-infrastructure only: run server tests with two workers instead of one so the CI step stays inside its 3 minute budget. No shipped behavior changed.
Changesetwebminor
Add standalone docs section routes:
- every documentation section now answers at
/docs/<section> (for example /docs/signatures, /docs/agents) with its own title, canonical URL and JSON-LD - each section is prerendered at build time, so
curl receives that section's HTML instead of a /docs#anchor fragment - the sitemap lists all section URLs;
/docs keeps the full single-page docs
Changesetwebminor
Prerender marketing pages so crawlers see full HTML without JavaScript:
/, /pricing, /legal, /status and /docs are rendered at build time through the router's SSR entry; curl now receives the real page head and body- unknown paths return a prerendered
404.html with a real 404 status and noindex; console and auth routes are proxied to the SPA shell via _redirects - Cloudflare asset routing uses
drop-trailing-slash (no redirects on /pricing or /docs) and 404-page for deployed stages; alchemy dev keeps the SPA fallback
Changesetserverpatch
Return 403 AUTHORIZATION_DENIED for mutating session requests that name a workspace the caller is no longer a member of, instead of silently falling back to t
Return 403 AUTHORIZATION_DENIED for mutating session requests that name a workspace the caller is no longer a member of, instead of silently falling back to their personal workspace. Reads keep the fallback so stale workspace ids can self-heal.
Changeset
---
--- ---
Changeset@hooks/apiminorserverminorwebminor
Add agent safety guards: destination sender allowlists with default-deny for agent targets, fork PR rejection, per-sender trigger frequency limits, untrusted
Add agent safety guards: destination sender allowlists with default-deny for agent targets, fork PR rejection, per-sender trigger frequency limits, untrusted template filter, and rejection reasons in the event routing view.
Changesetserverminor@hooks/apiminorwebminor
Add bulk replay: POST /v1/replays previews or creates a job that re-delivers up to 1000 historical events to an existing or inline destination, with per-event
Add bulk replay: POST /v1/replays previews or creates a job that re-delivers up to 1000 historical events to an existing or inline destination, with per-event destination filtering, pause/resume/cancel, progress counters and replayId on deliveries. GET /v1/deliveries?replayId= filters the delivery log, and the console marks replayed deliveries.
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor
Record agent run IDs end to end:
TargetAdapter.interpretResponse returns an optional structured run ({ id, url?, status? }), validated by targetRunSchema; Grok Bot, Paseo and T3 Code parse it from their response body- successful deliveries and attempts store
target_run_id / target_run_url (both indexed; new migration 20261031160000_agent_run_ids leaves existing rows null) - run URLs are redacted before storage: token-like query parameters become
redacted and basic-auth userinfo is stripped GET /v1/runs/:runId returns the source event and its deliveries (404 RUN_NOT_FOUND when unknown or from another workspace)- the event drawer lists the runs the event started, the delivery page keeps showing the run id/link, and event search falls back to the run lookup endpoint so a run id copied from the agent platform locates its event
Changesetserverminor@hooks/apiminor
Add a Discord source adapter: Ed25519 verification with the application public key, PING handshake answered only after verification (invalid signatures get 401)
Add a Discord source adapter: Ed25519 verification with the application public key, PING handshake answered only after verification (invalid signatures get 401), deferred interaction responses for the 3-second limit, and normalization for commands, components, modals and Webhook Events.
Changeset@hooks/apiminorserverminorwebminor
Add the Svix source adapter (svix): verifies svix-id / svix-timestamp / svix-signature by reusing the Standard Webhooks core (HMAC-SHA256 over `<id>.<ti
Add the Svix source adapter (svix): verifies svix-id / svix-timestamp / svix-signature by reusing the Standard Webhooks core (HMAC-SHA256 over <id>.<timestamp>.<body>, multiple signatures for rotation, 5-minute replay window, v1a ignored), decodes whsec_ secrets, dedupes on svix-id, and normalizes sender-defined body types with sourceConfig.eventType overrides. Clerk, Resend, Brex and Autumn webhooks can use it directly. The provider is selectable in the API and the console.
Changesetserverminor@hooks/apiminor
Add a Twilio source adapter: HMAC-SHA1 verification over the full request URL plus sorted form parameters (and bodySHA256 for JSON posts), SMS/WhatsApp/voice
Add a Twilio source adapter: HMAC-SHA1 verification over the full request URL plus sorted form parameters (and bodySHA256 for JSON posts), SMS/WhatsApp/voice normalization, and status-aware delivery ids so repeated status callbacks dedupe while distinct statuses stay separate.
Changesetserverminor@hooks/apiminor
Add a zendesk source adapter for Zendesk webhooks:
- verifies
X-Zendesk-Webhook-Signature as base64 HMAC-SHA256 over timestamp + raw body (no separator) with the timestamp header inside a 5-minute replay window and constant-time comparison; missing headers, expired timestamps and reversed concatenation all fail - uses
X-Zendesk-Webhook-Invocation-Id (falling back to detail.id) as the delivery id so retries dedupe, and strips the zen:event-type: prefix from the body type - normalizes event-subscription
ticket.* events with ticket id, subject title, comment plain text, tags labels, status and an /agent/tickets/<id> URL converted from the API URL - reads trigger/automation webhook types through
sourceConfig.eventType and leaves custom bodies unnormalized, and documents the fixed static signing secret used by Zendesk test webhooks
Changesetserverminor@hooks/apiminor
Add an intercom source adapter for Intercom notification webhooks:
- verifies
X-Hub-Signature: sha1=<hex> as HMAC-SHA1 of the raw body with constant-time comparison; only the sha1 method passes, and missing or sha256=-prefixed values are rejected - maps three-segment topics onto the unified
<resource>.<action> shape (conversation.user.created → conversation.user_created), keeps the raw topic in raw, and uses the notification id (notif_...) as the delivery id so retries dedupe - normalizes conversations with id, subject title, HTML-stripped message text, source URL, state and author actor, falling back to
data.item.type for other resources - filters
conversation.operator_replied and conversation.admin_replied by default so an agent's own replies do not trigger it, and documents that Intercom sends no timestamp header
Changesetserverminor@hooks/apiminor
Add a shopify source adapter for Shopify webhooks:
- verifies
X-Shopify-Hmac-Sha256 as a base64 HMAC-SHA256 of the raw body in constant time, rejecting missing or mismatched values; documents that Shopify sends no timestamp header, so replay protection is dedupe by the webhook id - derives the event type from
X-Shopify-Topic (orders/create → orders.create) and uses X-Shopify-Webhook-Id (falling back to X-Shopify-Event-Id) as the delivery id, with X-Shopify-Triggered-At as occurredAt and the shop domain as repo - normalizes orders (id, name, admin URL, financial status,
total_price in minor units, currency, customer), refunds (refund or first transaction amount/currency, note body), customers, products and abandoned checkouts
Changesetserverminor@hooks/apiminor
Add a gitlab source adapter for GitLab project webhooks:
- verifies the recommended GitLab 19+ signing token (
webhook-id, webhook-timestamp, webhook-signature) with the shared Standard Webhooks verifier and a 5-minute window, and falls back to a constant-time X-Gitlab-Token comparison when no signature header is present; a request carrying webhook-signature never falls back, so a bad signature cannot pass through a configured secret token - normalizes
<object_kind>.<action> types for merge requests (iid, title, description, URL, labels, merge → merged), notes (note text as subject.body, parent MR/issue title and labels), issues and pipelines (ref title, status state, URL built from the project when absent), plus push/release/job subjects - uses
webhook-id (or Idempotency-Key) as the delivery id so retries dedupe, and reads labels from both object_attributes.labels and the top-level labels array, deduplicated - documents that secret-token mode has no replay protection and signing token is recommended, and that GitLab test deliveries have no reliable filter marker
Changesetserverminor@hooks/apiminor
Add a vercel source adapter for Vercel webhooks:
- verifies
x-vercel-signature as a bare lowercase-hex HMAC-SHA1 of the raw body with constant-time comparison, rejecting missing values and sha1=-prefixed values; SHA-1 is kept only because Vercel signs that way - normalizes
deployment.* (deployment.error, deployment.succeeded, ...) with a deployment subject (id, name, links.deployment, event suffix as state, error level for failures) and alerts.triggered with an alert subject (id, title, severity as level, status, links.observability) - uses body
id as the delivery id so retries dedupe, and keeps payload.target (production/staging) in raw - documents that Vercel sends no timestamp header, so replay protection is dedupe by
id
Changesetserverminorwebminor
Add agent-aware retry and failure handling:
- target adapters can set
retryDefaults; agent targets (Grok Bot, T3 Code, Paseo) now default to 3 attempts with a 15s initial delay, and an explicit destination retryPolicy still wins - exhausted retryable failures enter a new
dead (dead-letter) status instead of failed; the console has a Dead letter filter and retries them the same way - destinations auto-pause after 5 consecutive failed deliveries, with the reason shown on the destination page
- optional dead-letter email notifications, off by default (
notifyOnDeadLetter project setting) docs/agent-gateway/delivery-semantics.md documents at-least-once delivery and duplicate-run risk
Changesetwebminor
Add AI agent use-case and target guides: /use-cases/ai-agents overview (receive, filter, template, retry, protect) plus /targets/{grok-bot,t3code,paseo} per
Add AI agent use-case and target guides: /use-cases/ai-agents overview (receive, filter, template, retry, protect) plus /targets/{grok-bot,t3code,paseo} per-target setup guides and a /targets index, each with per-page head tags, TechArticle + FAQPage JSON-LD, and sitemap entries. Ships the agent skill as docs/agent-gateway/skill.md until the public docs repository exists.
Changesetserverminor
Use auth.api.getSession in the server auth middleware: session cookies are signature-verified again, the 5 minute cookie cache now serves /v1/* requests (on
Use auth.api.getSession in the server auth middleware: session cookies are signature-verified again, the 5 minute cookie cache now serves /v1/* requests (one D1 query instead of two), session-only write endpoints force a database read, and /api/auth/get-session no longer consumes the auth rate limit.
Changesetwebminor
Add /compare/* and /alternatives/* pages: four head-to-head comparisons (Hookdeck, Svix Ingest, Convoy, DIY Cloudflare Worker) and three tool alternatives (
Add /compare/* and /alternatives/* pages: four head-to-head comparisons (Hookdeck, Svix Ingest, Convoy, DIY Cloudflare Worker) and three tool alternatives (webhook.site, smee.io, ngrok), each with per-page title/description/canonical, Article + FAQPage JSON-LD, source links with check dates, sitemap entries, and homepage/docs entry points.
Changesetwebpatch
Give delivered and succeeded items their own success color ramp on the console Overview so published work scans faster than queued or pending work. Successful d
Give delivered and succeeded items their own success color ramp on the console Overview so published work scans faster than queued or pending work. Successful deliveries now reads as the headline stat tile, the Delivered funnel value is tinted, and succeeded delivery rows carry a green inset edge. Failure states keep priority, and the brand indigo stays reserved for navigation and primary actions.
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor
业务去重与投递幂等:endpoint 的 sourceConfig.dedupe 可配置去重键模板和窗口(默认 60 秒),窗口内重复事件仍入库但标记 duplicate、通过 duplicate_of_event_id 链接首条,且不产生投递;控制台事件列表显示 Duplicate 徽标并可跳回首条。没有
业务去重与投递幂等:endpoint 的 sourceConfig.dedupe 可配置去重键模板和窗口(默认 60 秒),窗口内重复事件仍入库但标记 duplicate、通过 duplicate_of_event_id 链接首条,且不产生投递;控制台事件列表显示 Duplicate 徽标并可跳回首条。没有 delivery id 的来源改用 source + type + subject.id + payloadHash 的哈希兜底。所有出站请求新增 Idempotency-Key(等于 deliveryId,重试不变)与 X-Hooks-Event-Id。event_dedupe_keys 表随 cron 清理过期窗口。
Changesetwebpatchserverpatch
Fix duplicate outbound Content-Type header. Destination header merging is now case-insensitive, so a custom Content-Type no longer joins with the forwarded in
Fix duplicate outbound Content-Type header. Destination header merging is now case-insensitive, so a custom Content-Type no longer joins with the forwarded inbound content-type into application/json, application/json (which destinations rejected with 415). Raw payload passthrough keeps the inbound content type; templated bodies set it from the body mode. Create-flow headers with {{event.*}} tokens are no longer dropped.
Changesetserverminorwebminor
Surface routing decisions and the rendered outbound request in the console:
- the event drawer gains Normalized and Routing tabs: the stored normalized JSON plus why the event was forwarded, filtered, or treated as a duplicate
- the Events list can filter by Filtered and Duplicate in addition to Delivered and Failed; the API accepts
status=filtered|duplicate|failed|delivered with cursor pagination - the delivery page shows the rendered request (method, target host, masked headers, body) before the response
- filtered and duplicate events use a shorter retention window (7 days by default,
FILTERED_RETENTION_DAYS)
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor
destination 级事件过滤:allow/deny 规则对 NormalizedEvent 点路径求值(equals/not_equals/in/contains/matches/exists,支持 all/any/not 嵌套与正则长度/复杂度限制),可忽略 bot 作者和指定账号;被拒绝的 destina
destination 级事件过滤:allow/deny 规则对 NormalizedEvent 点路径求值(equals/not_equals/in/contains/matches/exists,支持 all/any/not 嵌套与正则长度/复杂度限制),可忽略 bot 作者和指定账号;被拒绝的 destination 不产生投递,事件以 destination_rules 入库并记录 filter_detail。新增 POST /v1/destinations/filter-preview 试运行,控制台 destination 编辑页新增 Filters 标签页。
Changeset
---
--- ---
Documentation-only change to the server test config: record why isolate must stay enabled so the next person does not trade correctness for the 7x speedup. No shipped behavior changed.
Changesetwebpatch
Endpoint editing now covers inbound and outbound: the edit dialog adds an Outbound tab to add, edit and remove destinations (URL, method, headers, params, auth,
Endpoint editing now covers inbound and outbound: the edit dialog adds an Outbound tab to add, edit and remove destinations (URL, method, headers, params, auth, body, retry, timeout). The create flow now sends the full destination config — previously auth, method, params and body were dropped, so a configured Bearer token never reached the destination ("Missing Authorization header"). "Save & continue" now advances the step instead of doing nothing.
Changesetserverpatch
Decode application/x-www-form-urlencoded payloads (payload=<json>, as GitHub sends) when a destination's json-mode body is a raw passthrough. Previously the
Decode application/x-www-form-urlencoded payloads (payload=<json>, as GitHub sends) when a destination's json-mode body is a raw passthrough. Previously the raw bytes were forwarded and JSON destinations rejected them with 400 (Unexpected token 'p', "payload=%7"...). Raw and form body modes still forward the original bytes.
Changesetserverminor
把通用 HTTP destination 的构建逻辑整理为 HttpTargetAdapter(实现 TargetAdapter 接口,行为不变),并导出可复用的 buildRequestAuth,供 Grok Bot、t3code、Paseo、Slack 等 target 复用 bearer/basic/
把通用 HTTP destination 的构建逻辑整理为 HttpTargetAdapter(实现 TargetAdapter 接口,行为不变),并导出可复用的 buildRequestAuth,供 Grok Bot、t3code、Paseo、Slack 等 target 复用 bearer/basic/apikey/oauth2/hmac 鉴权构建;响应分类继续使用现有重试规则(classifyHttpResponse 纯函数)。
Changeset@hooks/apiminorserverminorwebpatch
Generic source adapter learns endpoint-level extraction config (sourceConfig, stored in endpoints.config_json): event type and delivery-id can come from con
Generic source adapter learns endpoint-level extraction config (sourceConfig, stored in endpoints.config_json): event type and delivery-id can come from configured $.a.b JSON paths or header:X-Name headers, and actor/subject.title map into the normalized event. Form-encoded bodies (including GitHub-style payload=<json>) now normalize alongside JSON and plain text. New shared-secret verification mode compares a shared token header (default x-webhook-token, name configurable) in constant time; a wrong token records the event unverified and returns 401, same as HMAC failures. Endpoints without config keep their exact previous behavior. The console endpoint edit dialog gained the config fields, and a pre-existing endpoints.tsx import cycle is broken via a shared types module.
Changeset@hooks/dbminorserverminorwebpatch
GitHub 来源归一化:<event>.<action> 事件类型、repo/actor/subject 映射、issue_comment 区分 issue 与 PR 评论、表单 payload= 投递解包。ping 默认过滤——事件照常入库(新增 events.filter_reason 列)但
GitHub 来源归一化:<event>.<action> 事件类型、repo/actor/subject 映射、issue_comment 区分 issue 与 PR 评论、表单 payload= 投递解包。ping 默认过滤——事件照常入库(新增 events.filter_reason 列)但不创建 delivery,控制台事件列表标记 Filtered: ping。
Changesetserverminorwebminor
新增 grokbot target:routine URL + {{secret.NAME}} 形式的 Bearer key,body 固定为 JSON {task, repo?, ...extra},task/repo/extra 用现有模板引擎渲染;task 渲染为空时以 `EMPTY_
新增 grokbot target:routine URL + {{secret.NAME}} 形式的 Bearer key,body 固定为 JSON {task, repo?, ...extra},task/repo/extra 用现有模板引擎渲染;task 渲染为空时以 EMPTY_TARGET_TASK 失败且不发送,缺 key secret 时以 MISSING_TARGET_SECRET 失败。2xx 视为已接收,429/5xx 重试,其他 4xx 永久失败,Authorization 始终以 [redacted] 记录。destination 的 config 在 API 返回时隐藏 key 字段(PATCH 留空则保留原值)。控制台 Target 标签新增「Send test task」按钮,调用 POST /v1/destinations/:id/test-task 立即发送示例任务并显示状态与脱敏后的响应。
Changesetwebpatchserverpatch
Add "Clear events" / "Clear deliveries" actions to the console, backed by DELETE /v1/events and DELETE /v1/deliveries (new history:purge scope). Purging r
Add "Clear events" / "Clear deliveries" actions to the console, backed by DELETE /v1/events and DELETE /v1/deliveries (new history:purge scope). Purging removes the workspace's payload objects, events, deliveries, attempts, replays and queued outbox rows, so history no longer piles up.
Changesetserverminor@hooks/apiminor
Add a jira source adapter for Jira Cloud admin webhooks:
- verifies
X-Hub-Signature: sha256=<hex> (WebSub HMAC over the raw body) and rejects other methods; Jira sends no timestamp, so replay protection is the X-Atlassian-Webhook-Identifier dedupe id - normalizes
jira:issue_* / comment_* events into issue.created, issue.updated, comment.created, ... with actor, project, issue/comment subject, labels, status and priority; ADF descriptions are flattened to text - changelog updates keep
raw.issue.changelog and expose the latest state/labels to destination filters - documents that the Jira secret is optional and that unsigned admin webhooks cannot be verified
Changeset@hooks/apiminorserverminorwebminor
Add the Linear source adapter: Linear-Signature HMAC verification with the 60-second webhookTimestamp replay window, Linear-Delivery-based dedupe for retr
Add the Linear source adapter: Linear-Signature HMAC verification with the 60-second webhookTimestamp replay window, Linear-Delivery-based dedupe for retries, normalization of issue/comment/label events (issue.create, comment.create, ...), and label names exposed as subject.labels for destination filters. Linear is now a selectable provider in the API and the console.
Changesetwebminor
Publish Markdown versions of every docs page (/docs/*.md), a generated /llms-full.txt, and a rewritten /llms.txt with a definition sentence, supported and
Publish Markdown versions of every docs page (/docs/*.md), a generated /llms-full.txt, and a rewritten /llms.txt with a definition sentence, supported and planned sources/targets, quick start, and a comparison with Hookdeck and Svix. Corrects the API and ingress base URLs to api.hooks.events and serves the Markdown files with explicit content types.
Changesetwebminorserverminor@hooks/apiminor@hooks/dbminor
Support multiple workspaces per account: create, switch and delete workspaces from the console, with per-workspace data isolation and an X-Workspace-Id header
Support multiple workspaces per account: create, switch and delete workspaces from the console, with per-workspace data isolation and an X-Workspace-Id header for session requests.
Changeset@hooks/apipatch@hooks/dbpatchserverpatch
Define the unified internal event format (NormalizedEvent Zod schema in @hooks/api), add a nullable normalized_json column to events (old rows unaffecte
Define the unified internal event format (NormalizedEvent Zod schema in @hooks/api), add a nullable normalized_json column to events (old rows unaffected), and let destination templates resolve {{event.<path>}} against the normalized event when present. Existing {{event.payload}} / {{event.id}} / {{event.type}} tokens behave exactly as before. Source adapters that fill the column land in follow-up issues (#16-#22).
Changesetserverpatchwebpatch
Harden the outbound delivery pipeline: attempt records now keep a truncated copy of the sent request body, header redaction only hides credential-bearing names,
Harden the outbound delivery pipeline: attempt records now keep a truncated copy of the sent request body, header redaction only hides credential-bearing names, JSON body templates are validated (with {{event.payload.json}} for safe string embedding) and destination saves dry-run the request builder. The queue consumer loads a delivery with one JOIN instead of five queries, and the console's three destination builders share one payload-mapping module.
Changesetserverpatchwebpatch
Outbound P1/P2: structured form-body entries (KV editor + entry-array templates), a server-backed destination preview endpoint, client types derived from the zo
Outbound P1/P2: structured form-body entries (KV editor + entry-array templates), a server-backed destination preview endpoint, client types derived from the zod contracts, table-driven auth/body/header test matrices, new binary and multipart body modes, OAuth2 client-credentials auth with a cached token fetched by the worker, and a consumer pipeline split into load/build/assemble/send stages.
Changesetserverpatch
Align outbound request building with established API-client semantics (Hoppscotch reference): repeated query keys are appended instead of collapsed, auth fields
Align outbound request building with established API-client semantics (Hoppscotch reference): repeated query keys are appended instead of collapsed, auth fields resolve {{event.*}} templates like headers/params/body, form-mode array values expand to repeated keys, and raw custom bodies default to text/plain when no destination content type is pinned.
Changesetserverminorwebminor
Add the Paseo target adapter (paseo): dispatches a Paseo Hub manual run (POST /api/v1/manual-runs) with projectSlug, trigger, actor, the Hooks deliver
Add the Paseo target adapter (paseo): dispatches a Paseo Hub manual run (POST /api/v1/manual-runs) with projectSlug, trigger, actor, the Hooks delivery id as deliveryKey, and a templated input. The API key must be a {{secret.NAME}} reference. Successful responses record Hub's triggerRunId, which the console now shows as the delivery's agent run in a new deliveries.target_run_id / target_run_url column pair.
Changesetwebpatchserverpatch
Fix production latency, the workspace lockout, and missing endpoint edit/delete actions.
Server: treat placeholder email credentials as unconfigured so sign-ups are not locked out by email verification they can never complete, and fall back to the caller's own workspace when a stale requested workspace is not theirs. Enable D1 read replication to cut cross-region query latency.
Web: cache content-hashed assets as immutable, dedupe session fetches across navigations, share one react-query cache between the console shell and pages, seed the created endpoint into the cache, and add Edit and Delete actions to every row of the endpoints list.
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor
项目级 secret 管理:secrets 表按 project 加密存储命名凭据(AES-GCM,只写不读,GET 仅返回名称与元数据),destination 的 headers/params/auth 可用 {{secret.NAME}} 引用并在投递时解析,缺失引用会让投递以 `OUTBOUND_REQ
项目级 secret 管理:secrets 表按 project 加密存储命名凭据(AES-GCM,只写不读,GET 仅返回名称与元数据),destination 的 headers/params/auth 可用 {{secret.NAME}} 引用并在投递时解析,缺失引用会让投递以 OUTBOUND_REQUEST_BLOCKED 失败而不发出请求;解析出的明文会从记录的请求头中抹去。新增 POST /v1/secrets/migrate 把既有明文 auth_json 凭据迁移为 DEST_ 引用(幂等、可回滚,旧投递继续可用)。来源签名密钥轮换改为双密钥过渡:rotate-secret 保留旧密钥,rotate-secret/complete 才让它失效。secret 的创建/替换/删除仅限 workspace owner/admin,审计日志不含明文。控制台 Settings 的 Security 标签新增 Project secrets 面板(新增/替换/删除,永不回显值)。
Changesetserverminorwebminor@hooks/apiminor
Add source→target quick-setup templates:
GET /v1/templates lists five ready-made flows (GitHub issue/comment → Grok Bot, Sentry issue → Grok Bot, Linear issue → T3 Code, Stripe failed payment → Slack)POST /v1/templates/:id/apply validates the user-filled values, creates project secrets for target keys, renders the filter and target config, and creates the endpoint plus destination in one call- the console gains a Quick setup page that picks a template, fills password-style fields, shows the upstream webhook URL and signing instructions, and can send a test event
Changesetserverminorwebminor
Add inbound and outbound rate limits:
- endpoints accept
rateLimitPerMinute (default 600) and rateLimitAction (store keeps a rate_limited audit event, drop discards it); over-limit webhooks get 429 with Retry-After - destinations accept
rateLimitPerMinute and maxConcurrency; agent targets default to 30/min and 3 concurrent sends, HTTP to 600/min and 10 - over-limit deliveries are deferred to
retry_wait without consuming an attempt and are re-enqueued by the cron, so nothing is lost - destination API responses include a
usage block and the destination page shows limits and current usage docs/agent-gateway/rate-limits.md documents the behavior
Changeset@hooks/apiminorserverminorwebminor
Add the Sentry source adapter: Sentry-Hook-Signature HMAC verification, Request-ID-based dedupe for retries, and normalization of issue and alert webhooks (
Add the Sentry source adapter: Sentry-Hook-Signature HMAC verification, Request-ID-based dedupe for retries, and normalization of issue and alert webhooks (issue.created, event_alert.triggered) including title, URL, status and severity. NormalizedEvent.subject gains an optional level field, and Sentry is now a selectable provider in the API and the console.
Changesetserverpatch
Share one buildSimpleHttpRequest helper between the generic HTTP target and agent targets. Grok Bot now uses it, so every target produces the same request con
Share one buildSimpleHttpRequest helper between the generic HTTP target and agent targets. Grok Bot now uses it, so every target produces the same request contract and redaction rules; behavior is unchanged.
Changeset@hooks/apiminorserverminorwebminor
Add the Slack source adapter: X-Slack-Signature verification, url_verification challenge handshake, event_id-based dedupe for Slack retries, normalization
Add the Slack source adapter: X-Slack-Signature verification, url_verification challenge handshake, event_id-based dedupe for Slack retries, normalization of app_mention and message events, and default filtering of bot messages. Slack is now a selectable provider in the API and the console.
Changesetserverminorwebpatch
Add the Slack target adapter (slack) with two modes: an Incoming Webhook URL, or a bot token plus channel for chat.postMessage. Both render text and Block
Add the Slack target adapter (slack) with two modes: an Incoming Webhook URL, or a bot token plus channel for chat.postMessage. Both render text and Block Kit blocks with the event template engine, read ok: false in HTTP 200 responses as failures with Slack's error, and retry 429 responses honoring Retry-After. Webhook URLs and bot tokens must be {{secret.NAME}} references and are redacted from attempt records and previews.
Changeset@hooks/apipatchserverpatchwebpatch
Introduce the source adapter framework: a SourceAdapter interface and registry (apps/server/src/sources/) that owns per-provider signature verification, del
Introduce the source adapter framework: a SourceAdapter interface and registry (apps/server/src/sources/) that owns per-provider signature verification, delivery-id/event-type extraction, normalization into the unified event format, and optional protocol handshakes. GitHub, Stripe and the generic x-hooks-* HMAC scheme migrate onto it with unchanged behavior, and ingest-service no longer branches on provider names. Provider ids now come from one shared SOURCE_PROVIDERS list in @hooks/api used by API validation, the console picker and the server registry. Generic-source events get a normalized_json payload from day one; GitHub/Stripe mapping lands with their adapter issues (#18/#19). Full normalization format: docs/agent-gateway/event-format.md; adapter how-to: docs/agent-gateway/source-adapters.md.
Changeset@hooks/apiminorserverminorwebminor
Add the Standard Webhooks source adapter (standard-webhooks): verifies webhook-id / webhook-timestamp / webhook-signature (v1, base64 HMAC-SHA256 over
Add the Standard Webhooks source adapter (standard-webhooks): verifies webhook-id / webhook-timestamp / webhook-signature (v1, base64 HMAC-SHA256 over <id>.<timestamp>.<body>, multiple signatures for rotation, 5-minute replay window, v1a ignored), decodes whsec_ secrets, dedupes on webhook-id, and normalizes sender-defined body types with sourceConfig.eventType overrides. OpenAI, Replicate, Recall.ai, Composio, Loops, Granola and GitLab 19+ signing tokens can use it directly. The provider is selectable in the API and the console.
Changeset@hooks/apiminorserverminor
Normalize Stripe webhooks: the adapter uses the event id (evt_...) as the delivery id so resends dedupe, maps <resource>.<action> types (`checkout.session
Normalize Stripe webhooks: the adapter uses the event id (evt_...) as the delivery id so resends dedupe, maps <resource>.<action> types (checkout.session.completed becomes checkout_session.completed), and fills the unified subject with id, status, amount, currency and customer. The subject schema gains optional amount, currency and customer fields.
Changesetserverminor
Add the T3 Code target adapter (t3code): triggers an "On a webhook" scheduled task with a JSON body of title, body, url, repo, actor and type (tem
Add the T3 Code target adapter (t3code): triggers an "On a webhook" scheduled task with a JSON body of title, body, url, repo, actor and type (templates overridable), optional HMAC-SHA256 signing over the raw body with configurable header/encoding/prefix, and T3 Code's response semantics (202 accepted, 429/5xx retryable, 401/404/409/410 permanent). The webhook URL and signing key must be {{secret.NAME}} references; resolved values are redacted from the destination preview and delivery records.
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor
新增 target adapter 层:TargetAdapter 接口(id、configSchema、buildRequest、interpretResponse、describe)+ 注册表,endpoint_destinations 新增 type(默认 http,旧记录行为不变)和 `conf
新增 target adapter 层:TargetAdapter 接口(id、configSchema、buildRequest、interpretResponse、describe)+ 注册表,endpoint_destinations 新增 type(默认 http,旧记录行为不变)和 config_json;interpretResponse 的成功/可重试/永久失败分类接入重试策略(429/503 保留 Retry-After,4xx 默认不重试)。SSRF 与密钥脱敏对所有 target 类型生效。新增 GET /v1/targets 供控制台按 type 渲染配置表单,文档见 docs/agent-gateway/target-adapters.md。
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor
请求模板引擎:destination 的 body/URL/header/query/auth 统一支持 {{event.<路径>}}(含数组下标与 event.raw.*)、default / json / truncate / lower / upper / join 过滤器;JSO
请求模板引擎:destination 的 body/URL/header/query/auth 统一支持 {{event.<路径>}}(含数组下标与 event.raw.*)、default / json / truncate / lower / upper / join 过滤器;JSON body 自动转义字符串值。新增 templateStrict(endpoint_destinations.template_strict):路径缺失时默认渲染为空,严格模式让投递失败并列出缺失路径。/v1/destinations/preview 接受 eventId,控制台可用历史事件预览渲染结果。
Changesetserverpatch
Migrate the server test setup from the deprecated @cloudflare/vitest-pool-workers to @cloudflare/vitest-plugin. The old package prints a deprecation warning
Migrate the server test setup from the deprecated @cloudflare/vitest-pool-workers to @cloudflare/vitest-plugin. The old package prints a deprecation warning on every run and warns it will not receive updates; the new one is the same API under a new name. Test-only change with no runtime behavior affected.
Changeset@hooks/apiminorwebminorserverpatch
Add free browser-only webhook tools: a payload-to-agent-task previewer and a signature verifier, and move the template renderer and destination filter evaluator
Add free browser-only webhook tools: a payload-to-agent-task previewer and a signature verifier, and move the template renderer and destination filter evaluator into the shared API package.