Changelog · 95 entries

What shipped in Hooks.

Short answer: Every release note on this page comes from the repository's changesets: a change cannot ship without an entry, and the page is regenerated at build time from the same files maintainers commit.

New sources, targets, task-engine features, console changes, and fixes, newest first. The page is generated by a local script from .changeset/*.md and each workspace CHANGELOG.md; there is no post-deploy editorial step.

November 1, 2026

Changeset@hooks/dbminorserverminorwebminor

Add Slack agent sessions (issue #95, stage 1):

  • the per-run callback accepts event types status, delta, step, approval_request, final and failed; the token stays run-scoped, is never logged, and terminal events reuse the #141 PR-requirement/idempotency path
  • a new GET /callbacks/tasks/:engineId/:runId/events endpoint lets the agent poll approval decisions, thread follow-ups and the stop flag with the same token
  • the Slack target gains mode: "agentSession": thread_ts is the session key, progress streams through chat.startStream/appendStream/stopStream with 750 ms batching and a chat.postMessage fallback, and Approve/Deny Block Kit cards carry the run id and call id in their action_id and collapse after the first decision
  • the Slack source accepts Interactivity (block_actions, form-encoded payload=) with signature and timestamp verification, retry dedupe, the #41 sender allowlist (default deny), and routes follow-ups/stop in the session thread to the same run
  • task_runs mirrors the agent session id/status (migration 20261101170000_agent_sessions) and the run detail page shows the session, steps and approvals
  • Slack write-back is advisory: a missing secret, outage or timeout never fails or blocks an agent callback
  • docs: Slack target scopes/Interactivity/manifest and the callback event contract
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor

Add sandboxed JavaScript transforms for destinations (QuickJS WASM, 50 ms CPU / 16 MB heap / 256 KB output limits), gated by the JS_TRANSFORM_ENABLED flag (de

Add sandboxed JavaScript transforms for destinations (QuickJS WASM, 50 ms CPU / 16 MB heap / 256 KB output limits), gated by the JS_TRANSFORM_ENABLED flag (default off). Includes a Transform tab with dry run in the destination editor and the new migration 20261101160000_destination_js_transform (adds a nullable column).

Changeset@hooks/apiminor@hooks/climinor@hooks/dbminorserverminor

Add hooks listen, a local relay for webhooks:

  • packages/cli (private, not published) logs in with an API key and stores a revocable hkc_ CLI token with config mode 600
  • hooks listen <endpointId> --forward http://localhost:3000/... receives events over a hibernating Durable Object WebSocket and falls back to 1.5s polling when WebSockets are unavailable
  • events missed while offline are replayed from a stored cursor within a configurable 24h buffer (later reconnects can extend --buffer-hours)
  • forwarding runs on the user's machine, so localhost targets bypass the server-side SSRF check; results are recorded in the delivery log with via: cli
  • hooks events list|get and hooks replay inspect and re-deliver historical events; hooks logout revokes the device token
  • new cli_tokens table and deliveries.via column in migration 20261101150000_cli_relay
  • docs/agent-gateway/cli.md documents setup, the WebSocket/polling design, the offline buffer and the security model
Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor

Add alert rules and delivery metrics:

  • alert rules (failure rate, latency, no-delivery) evaluated on a schedule, with email and webhook channels and per-rule error isolation
  • new migration 20261101140000_alerting_metrics adds the alert tables; existing rows are untouched
  • metrics endpoints and an Alerts page in the console
Changeset@hooks/apiminorserverminorwebminor

Add declarative Typeform and Calendly sources and document the remaining #94 providers.

  • Add typeform (HMAC-SHA256, base64 with sha256= prefix) and calendly (t=...,v1=..., HMAC-SHA256 over <t>.<body>, 3-minute window) as fully declarative providers, including sample event types and subject mappings.
  • Fix the Bitbucket declaration to require the documented sha256= prefix on X-Hub-Signature, and map Bitbucket issue events onto the normalized subject.
  • Extend the declarative signature engine with keyed signature headers (engine.params) and declarative subject paths.
  • Document Datadog and Grafana as generic + shared-secret guides, and record why HubSpot v3 and Notion remain unsupported.
Changesetwebminor

Add a public /changelog generated from the repository's changesets and the public payload/template sample library:

  • apps/web/scripts/build-changelog.mjs reads .changeset/*.md and each workspace CHANGELOG.md before the build and writes apps/web/src/generated/changelog.json; the page renders the timeline, is prerendered, and is listed in the sitemap
  • apps/web/scripts/build-samples.mjs reads public-repo/samples/<source>/<event>.json plus the matching templates/ file and powers the new /samples page, covering GitHub, Stripe, Slack, Linear, and Sentry with sanitized fictional payloads
  • source pages link to the matching sample section, and the home footer links to both new pages
Changesetserverminor

Add an opt-in Tasks engine send path for legacy deliveries (#148):

  • DELIVERY_TASKS_ENABLED (default false) routes the outbound HTTP send through a (project, destination) Tasks engine shard; lifecycle hooks, admission, attempt rows, retry/DLQ classification and destination health stay in the queue consumer
  • the task builder references destination credentials through run-scoped, memory-only secrets, and the persisted task/DO state contains neither plaintext credentials, the callback token nor the raw event
  • multipart forms and bodies over 16 KiB keep using the inline path; the flag can be rolled back by configuration alone
  • docs/legacy-delivery-tasks.md documents the switch, sharding, limits and rollout verification
Changesetserverminor

Harden the Tasks engine against unbounded concurrency, storage, retries and request bodies (issue #156):

  • centralize every engine limit in apps/server/src/tasks/limits.ts and document the defaults in docs/tasks-engine-limits.md
  • default concurrency.max_machines to the account's five-machine quota and use the same constant in the built-in issue-to-pr template
  • prune terminal runs after 30 days or beyond 1000 per engine and delete their dashboard index rows
  • cap stored step inputs/outputs at 64 KiB and a whole run at 1 MiB, trimming storage-only data with a warning event
  • make enqueue idempotent per event id; duplicates return the existing run
  • reject request bodies over 256 KiB and truncate response bodies over 64 KiB
  • cap the computed retry backoff at one hour and definition values for step count, timeout, retry delay and max_machines
  • compare callback tokens in constant time and report background persist/alarm failures instead of leaking unhandled rejections
Changesetserverpatch

Harden Tasks engine credential handling (issue #156): persist only a hash of the run callback token, redact credential-bearing event data before storage and in

Harden Tasks engine credential handling (issue #156): persist only a hash of the run callback token, redact credential-bearing event data before storage and in API responses, validate GitHub repo/issue inputs before building URLs, and add a minimum length for substring secret redaction.

Changesetserverpatch

Read the dashboard task pulse from the task_runs index instead of one Durable Object call per run. The engine mirrors status, start and finish times into D1 o

Read the dashboard task pulse from the task_runs index instead of one Durable Object call per run. The engine mirrors status, start and finish times into D1 on status changes, and the summary is one bounded GROUP BY status query over the last 7 days. Runs created before this change have a null mirrored status and are left out of the pulse; run lists and detail views keep reading the Durable Object.

Changesetserverminorwebminor

Add isolated post-run actions to the Tasks engine:

  • task definitions accept after_deliver (success) and on_dead (failure/timeout/cancel; on_failure stays as an alias); each action is isolated and recorded on the run
  • the issue-to-pr built-in task comments the result (PR URL on success, reason and redacted log tail on failure), switches in-progress to agent:pr-opened/agent:failed, clears the assignee, notifies Slack and retires the machine
  • new steps github.assignee, instabox.suspend and configurable instabox.cleanup (delete/suspend/none); github.label removal tolerates a missing label
  • instabox target config gains cleanupAction, and {{run.log_tail}} is available to post-run templates
  • the run detail page shows the post-run and cleanup timelines separately
Changeset

---

--- ---

Changesetserverminorwebminor

Add the Tasks editor: YAML validation with line-level errors, autocomplete, a read-only flow preview, and a no-side-effect dry run (POST /tasks/dry-run, `GET

Add the Tasks editor: YAML validation with line-level errors, autocomplete, a read-only flow preview, and a no-side-effect dry run (POST /tasks/dry-run, GET /tasks/catalog) that renders step inputs and never calls a step handler.

Changesetserverminor

Add trigger conditions and budgets for label-driven agent tasks:

  • opt-in agent block on task definitions gates github.issues.labeled events on the configured label, a collaborator sender and a configurable skip-label list (blocked, in-progress by default)
  • per-issue frequency windows and a per-task UTC-day run cap, both configurable with defaults (1/60 minutes and 10/day)
  • max_run_minutes, max_rounds and max_runs_per_day budgets, with an agent-task watchdog default and dispatch logging a machine-readable reason for every skipped trigger
  • --dangerously-skip-permissions stays off by default and is only emitted when agent.permissions.allowed_domains is non-empty
  • the issue-to-PR template writes a static run-agent.sh, passes the prompt through AGENT_PROMPT, and marks the issue title and body as untrusted content
Changesetserverminorwebminor

Harden GitHub credential injection for agent task runs (issue #143):

  • instabox-agent and the built-in issue-to-pr task inject GITHUB_TOKEN only through exec envs; cmd, argv and stdin containing a rendered credential now fail with SECRET_IN_COMMAND
  • default identity isolation sets a per-run GH_CONFIG_DIR, GIT_CONFIG_GLOBAL, GIT_CONFIG_NOSYSTEM and a neutral commit identity through GIT_CONFIG_*; useMachineLogin opts out and sets none of GH_TOKEN, GH_CONFIG_DIR or GIT_CONFIG_*
  • a read-only github.token_check step (GET /user, GET /repos/{repo}) records a warning when the token has admin or broad classic scopes; failures never block the run and the run detail page shows the warning
  • docs/agent-gateway/targets/instabox.md documents fine-grained PAT scopes and the isolation model
  • tests assert that run records, step inputs/outputs and callback log tails never contain injected secret values
Changesetserverminor

Add the run-agent callback contract and InstaBox error fallback:

  • callbacks accept status (success / skipped / failed), prUrl (or a pr number plus repo), and a log tail; success without a PR link fails the run, skipped / failed fail it with the reported reason
  • callbacks are idempotent: the first accepted payload is recorded on the run, retries return the current state, and a token stops working after the run ends or its wait.callback deadline passes
  • log tails and callback messages are truncated and redacted (known secret values plus credential-like patterns) before storage
  • POST /callbacks/tasks/:engineId/:runId/instabox verifies Standard Webhooks signatures with the project INSTABOX_WEBHOOK_SECRET and fails the matching run on a signed sandbox.error
  • docs/agent-gateway/callbacks.md documents the payload, idempotency, response codes, run-agent.sh convention, and webhook fallback
Changesetserverminorwebminor

Add a tasks console with a run list and dashboard pulse:

  • GET /v1/tasks lists saved tasks with a 7-day run count, success rate and latest status; PATCH /v1/tasks/:name toggles a task without deleting its history
  • GET /v1/tasks/runs lists runs across every saved task with status, task, since and limit filters, using the same status groups as the summary (running includes waiting)
  • GET /v1/tasks/summary returns running, queued and failed-today counts plus InstaBox machine usage (used/limit, unavailable when the account is not configured)
  • /tasks lists tasks with trigger, enable switch and stats, and creates a task from the built-in issue-to-pr template; /tasks/runs is the filtered run list
  • the dashboard adds cards for running, queued and failed-today runs and InstaBox machine usage, each count linking to the matching filtered run list
  • events no longer start runs for disabled tasks, while in-flight runs continue unaffected
Changesetserverminorwebminor@hooks/dbminor

Add a run detail page and a unified runs API:

  • GET /v1/tasks/runs/:runId returns task runs (live state from their Durable Object) and legacy deliveries (synthesised as metadata-only single-step runs)
  • GET /v1/tasks/runs?eventId= lists every run triggered by an event, merging task runs with legacy deliveries
  • new POST /v1/tasks/runs/:runId/rerun (optionally from_step) creates a new run that re-executes only that step and later ones, while POST .../complete records the operator who marked a waiting run done
  • POST /v1/tasks/runs/:runId/cancel unifies cancellation for indexed task runs; cancellation still runs the task's on_failure cleanup steps
  • a task_runs index table in D1 maps run ids to their engine and event without writing run status outside the engine
  • the console run detail page shows trigger/status/duration/PR/machine metadata, an expandable step timeline with redacted input/output/log tail and retry counts, a live timeout countdown for waiting steps, and rerun/cancel/mark-done actions; event details now list every triggered run
Changesetserverminor

Add a durable run state machine, serial queue, and watchdog to task runs:

  • runs move through queued -> starting -> running -> done/failed (plus waiting for callbacks), and illegal transitions such as done -> running now throw
  • concurrency.max_machines caps how many runs execute at once across all concurrency keys (default 5); excess runs wait in queued and are admitted automatically in FIFO order
  • concurrency.dedupe drops a trigger while a run with the same key is active and records a deduplicated event on the active run
  • max_run_minutes arms a Durable Object alarm that fails overdue runs with a timeout reason and still runs on_failure cleanup
  • the tasks API exposes run events and a derived deliveryStatus where waiting is dispatched (not success); GET /tasks/:engineId/runs lists runs, optionally filtered by status
  • the built-in issue-to-pr task dedupes per repository+issue, caps at five machines, and has a 60-minute watchdog
Changesetserverminor

Add the InstaBox agent target as a Tasks-engine template (issue #139): buildInstaboxTask() compiles snapshot, repo, agent, script, maxRunMinutes and `delete

Add the InstaBox agent target as a Tasks-engine template (issue #139): buildInstaboxTask() compiles snapshot, repo, agent, script, maxRunMinutes and deleteAfterSeconds into an ordered run that ensures or creates the machine, writes run-agent.sh through exec stdin, launches it with setsid nohup, waits for the callback and cleans up. New instabox.ensure, instabox.write_script and instabox.launch steps expose the machine id to later steps, and task runs now record the platform run id (targetRunId, the machine id for InstaBox) and the step that failed (failedStep).

Changesetserverminor

Add the Tasks engine for multi-step runs:

  • Task definitions (YAML/JSON) are validated at save time: unknown step ids, unknown uses, invalid durations, and references to missing or not-yet-completed steps are rejected with their JSON path
  • a new Durable Object per task stores runs and per-step status/input/output; execution supports per-step timeout, retry, wait.callback, on_failure, configurable concurrency queues, and cancellation with cleanup
  • strict templating resolves {{event.*}}, {{steps.<id>.<field>}}, {{secret.*}} and {{run.*}}; missing fields fail the run instead of rendering empty strings
  • step library v1: http, instabox.create, instabox.exec, instabox.delete, github.comment, github.label, slack.post, grokbot, wait.callback; additional registries can expose the #134 lifecycle actions as steps
  • built-in issue-to-pr task and a legacy delivery adapter that expresses an existing HTTP delivery as a one-step run
  • task API routes (/v1/tasks/validate, /v1/tasks/runs, run read/cancel) plus a per-run token-protected /callbacks/tasks/:engineId/:runId endpoint
  • secrets resolved from project secrets are redacted from persisted step inputs, outputs, errors, and run records
Changeset@hooks/apiminorserverminorwebminor

Add declarative lifecycle hooks. Endpoints and destinations can configure actions for received, before_transform, before_deliver, after_deliver, `on_fai

Add declarative lifecycle hooks. Endpoints and destinations can configure actions for received, before_transform, before_deliver, after_deliver, on_failure and on_dead: drop, set_field, add_tag, route_to, notify and forward. The executor isolates failing actions, enforces per-stage/per-event caps and route-hop limits, rejects route_to cycles at save time, and runs forward through the SSRF guard. Built-in verification, dedupe, filtering, templating and retry steps now write entries to a per-delivery lifecycle trace shown on the delivery page.

Changeset@hooks/apiminorserverminorwebminor

Add declarative provider definitions and a generic signature engine: one shared definition now describes each provider's signature scheme, event-type and delive

Add declarative provider definitions and a generic signature engine: one shared definition now describes each provider's signature scheme, event-type and delivery-id headers, and docs. Purely declarative providers get an adapter from the definition alone, and /sources/<id> pages plus sitemap entries are generated from the same list. Adds Bitbucket as the first fully declarative provider.

Changeset@hooks/apiminor@hooks/dbminorserverminorwebminor

Add an anonymous temporary webhook inspector: /tools/inspect hands out a 24-hour receiving address that captures the newest 100 requests over SSE, detects the

Add an anonymous temporary webhook inspector: /tools/inspect hands out a 24-hour receiving address that captures the newest 100 requests over SSE, detects the provider and event type, verifies signatures in the browser, replays to a visitor URL behind the SSRF guard, previews the normalized agent task, and can be claimed into a real endpoint after sign-in.

Changesetwebpatch

Add source pages, a Slack target page, and source-to-target guides with HowTo and TechArticle structured data.

Changesetwebpatch

Add definition-first webhook concept articles with Article and FAQPage structured data.

Changesetwebpatch

Prerender every sitemap route so comparison, alternatives, target, use-case, and tool pages ship real HTML.

October 31, 2026

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.

Changesetwebpatch

Paginate the Events and Deliveries console lists with cursor-based "Load more" (50-row pages) instead of a fixed latest-100 window. Events older than the loaded

Paginate the Events and Deliveries console lists with cursor-based "Load more" (50-row pages) instead of a fixed latest-100 window. Events older than the loaded delivery window now show a neutral placeholder instead of a misleading 0/0 delivery summary.

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.

Changesetserverminor@hooks/apiminor

Add a pagerduty source adapter for PagerDuty v3 webhooks:

  • verifies X-PagerDuty-Signature with one or more comma-separated v1=<hex> HMAC-SHA256 signatures over the raw body (any match passes, so secret rotation works); unknown schemes are ignored
  • normalizes event.event_type (incident.triggered, incident.resolved, incident.annotated, incident.priority_updated, ...) with actor, incident subject (title, html_url, status, priority/urgency) and the parent incident for annotations, whose note body becomes subject.body
  • maps non-incident resources (e.g. service.created) by resource_type, and leaves unnormalizable payloads without normalized_json
  • documents that PagerDuty sends no timestamp header, so replay protection is dedupe by event.id
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.