Skip to content

feat(surface): trigger namespaces for every relayfile adapter with webhooks - #456

Merged
khaliqgant merged 8 commits into
mainfrom
feat/all-provider-triggers
Sep 18, 2026
Merged

khaliqgant merged 8 commits into
mainfrom
feat/all-provider-triggers

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Sep 17, 2026 •

Copy link
Copy Markdown
Member

Stacked on #446 (feat/github-trigger-vocabulary); rebase onto main once it merges. Draft until the merge condition below is met.

Why

flow().on(...) could subscribe to Slack and GitHub only. scripts/generate-triggers.mjs read the mapping YAML bundled in @relayfile/adapter-core, and that was the two core fallbacks — while relayfile ingests events from 47 providers (linear 33, gitlab 47, ramp 47, notion 13, cloudflare 8, …).

What

The generator applies three sources per provider, in order:

  1. core fallback mappings (mappings/*.mapping.yaml);
  2. each adapter's own mapping — mappings/adapters/*.mapping.yaml in the package once relayfile-adapters#280 ships, packages/<adapter>/ in a checkout — superseding the fallback as a whole;
  3. the trigger catalog @relayfile/adapter-core/triggers (KNOWN_TRIGGER_CATALOG, fed by every adapter's supportedEvents()) for providers with no webhooks: block.

Mapping-backed providers keep payload-aware signatures (github.pull_request(action?)); catalog-backed ones get (filter?). 47 namespaces, 570 events (catalog events unioned into every provider; a mapping only adds payload shape) — full table in the generated packages/surface/src/triggers/PROVIDERS.md (covered by --check). github/slack are strict supersets of #446's output (6 fallback GitHub events and their signatures unchanged), so flows deploy --on github:events=… is unaffected. Hyphenated ids become identifiers (azure_blob.file_created() lowers to { provider: 'azure-blob', type: 'file.created' }); a reserved-namespace guard refuses a provider named like a surface export (webhook, flow, schedule, …).

flows check's provider-event refusal (provider-trigger-contract.ts) reads providerEventTypes, so it now covers all 47 with no change of its own.

Merge condition

  • relayfile-adapters#280 published as @relayfile/adapter-core ≥ 0.5.26, then bump the pin in packages/sdk/package.json, run node scripts/generate-triggers.mjs --check, un-draft.
  • Until then --check (and tests/generate-triggers.test.ts "reproduces all checked-in modules") reports drift on github.ts, gitlab.ts, index.ts, PROVIDERS.md only — 45 of 47 providers already generate identically from the catalog 0.5.25 ships.

Tests

  • surface: triggers-all-providers.test.ts (≥40 providers present; every registry event has a frozen namespace method lowering to {provider,type}; hyphenated ids; catalog-only signature), triggers-github-events.test.ts relaxed to a superset.
  • sdk: generator fixture with a catalog JSON (catalog-only providers added with (filter?), mapping-backed never overridden, PROVIDERS.md generated and drift-checked, reserved namespaces refused); provider-trigger-contract.test.ts accepts one subscription from each of github/slack/linear/notion/gitlab, refuses no.such.event on five providers, and flows check passes a five-provider flow.
  • Full SDK suite on a built kernel: 1796 passed, 1 failed (the pin-drift check above), Bun-version skip.

What Cloud still gates (not implemented here)

Local ingress delivers any of these providers today (flows serve-webhook → POST /providers/<name> → providerInboxEvent). Hosted deployments do not: cloud/packages/web/lib/flows/flow-trigger-sources.ts (FLOW_TRIGGER_PROVIDERS = ["github","linear","jira","shortcut","slack"], flowIssueFromEvent → per-provider *IssueFromEvent) and launch-flow-deployment.ts (skipped: "not_a_ticket", inputs: { approver, issue, event }) admit only ticket-shaped events from those five, plus PR events after cloud#3772; prepare-flow-deploy.ts builds watch rules from the same list (buildFlowWatchRules, flowSourceTriggers).

Proposed generalisation: at deploy time, derive the deployment's subscriptions from the flow's declared sources — each .on(<provider>.<event>(filter)) is { provider, eventType, filter } (already what providerDeclaration() extracts in the SDK) — persist them on the deployment record (flow-deployment-store.ts), build one watch rule per (provider, eventType) on that provider's relayfile projection (the rule paths per provider come from each adapter's inbound.ts / path-mapper, not a hand-kept table), and in launch-flow-deployment.ts admit any delivered event whose (provider, eventType) the deployment declared, passing the raw record as inputs.event and dispatching the matching handler body (the #301 handler-dispatch work) — with issue/pullRequest projections kept as conveniences for the five ticket providers. Until #301 lands, the default body runs with inputs.event only.

🤖 Generated with Claude Code


Summary by cubic

Adds trigger namespaces for every relayfile adapter provider, so flow().on(...) can subscribe to all 47 providers (570 events) instead of only GitHub and Slack. The generator now merges core fallback mappings, adapter-local mappings, and the trigger catalog, and unions catalog events into every provider so a webhooks: block can no longer hide events ingress actually delivers. Mapping-backed providers keep payload-aware signatures like github.pull_request(action?), while catalog-only events take (filter?); GitHub and Slack are strict supersets, so existing subscriptions keep their signatures.

Details

  • Bumps @relayfile/adapter-core to 0.5.26, which bundles adapter-local mappings, and regenerates all trigger modules from the installed tarball; generate-triggers.mjs --check now passes.
  • Hyphenated provider ids become identifiers (azure_blob) but keep their upstream spelling when lowered.
  • The generated PROVIDERS.md is covered by the generator's drift check, and flows check now admits events from all 47 providers.
  • A reserved-namespace guard refuses provider names like webhook, flow, and schedule.
  • The GitHub vocabulary gains github.check_run(action?) and github.issue_comment(action?), and flows deploy --on github:events=pull_request now selects PR events for hosted GitHub listeners.
  • Action-qualified events like pull_request_edited now take a plain (filter?); only aggregate events (pull_request, check_run, issue_comment) still accept an action, and both spellings stay because two ingresses deliver them.
  • Where two upstream names mangle to one identifier (slack publishes both reaction.added and reaction_added), the mapping-declared event owns the method and the other stays in providerEventTypes, subscribable via webhook(...).

Not included

  • Hosted Cloud deployments still gate on the existing five providers; local ingress already delivers all 47, but the new namespaces aren't wired into hosted triggers yet.

Written for commit 179fb09. Summary will update on new commits.

Review in cubic


Note

Medium Risk
Large generated public API surface and expanded providerEventTypes affect flows check and all provider subscriptions; backward compatibility relies on GitHub/Slack remaining supersets of prior exports.

Overview
Expands flow trigger authoring from GitHub and Slack only to 47 providers and 570 events by regenerating @relayflows/surface trigger modules from an upgraded generator and @relayfile/adapter-core 0.5.26.

generate-triggers.mjs now merges three inputs per provider: core fallback mappings, adapter-local mappings (new in adapter-core), and KNOWN_TRIGGER_CATALOG (unioned so catalog events are always present; mapping YAML only shapes signatures for events it declares). It emits per-provider TypeScript namespaces, an expanded providerEventTypes registry, and a drift-checked PROVIDERS.md. Mapping-backed events keep payload-aware APIs (e.g. github.pull_request(action?)); catalog-only events use (filter?). Action-qualified names like pull_request.edited stay filter-only even when the mapping extracts action. Colliding identifiers favor mapping-declared events; registry-only duplicates remain valid via webhook(provider, { provider, type }). Reserved surface names (webhook, flow, schedule, …) are rejected as provider namespaces.

GitHub and Slack are strict supersets of the prior vocabulary (existing six GitHub mapping events and signatures preserved). Tests cover catalog union, drift on PROVIDERS.md, multi-provider flows check, and namespace coverage across providers.

Reviewed by Cursor Bugbot for commit 179fb09. Bugbot is set up for automated code reviews on this repo. Configure here.

Relayflow Lead and others added 4 commits September 17, 2026 14:55
Regenerated `packages/surface/src/triggers/github.ts` from the core GitHub
mapping in AgentWorkforce/relayfile-adapters#279, which declares `check_run`
and `issue_comment` as action-bearing webhook keys. The surface gains
`github.check_run(action?)` and `github.issue_comment(action?)` — the two
events a PR reviewer needs for merge-on-green and comment-driven directives —
and `providerEventTypes.github` lists them, so `flows check` admits a
subscription to either instead of refusing it as unpublished.

Generated with the adapters checkout's `packages/core/mappings` alone, which is
byte-for-byte what the published `@relayfile/adapter-core` tarball will carry,
so `generate-triggers.mjs --check` reproduces these files once the SDK's pinned
adapter-core is bumped to the release that contains #279. Until that bump the
check refuses, by design.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The GitHub source setting `events` (AgentWorkforce/cloud#3772) selects
which records wake a listener: `issues` (default) or `pull_request`. The
CLI validates it client-side like the other settings and the doc describes
the pull-request run's input.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The release carrying relayfile-adapters#279 (`check_run` and
`issue_comment` webhook keys). `generate-triggers.mjs` against the
installed tarball reproduces the committed trigger modules byte for byte,
and `--check` passes again.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…bhooks

`scripts/generate-triggers.mjs` read only the mapping YAML that
@relayfile/adapter-core bundles, and that was the two core fallbacks, so
`flow().on(...)` could subscribe to Slack and GitHub and nothing else,
although relayfile ingests events from 47 providers.

The generator now applies three sources per provider: the core fallback
mappings, each adapter's own mapping (`mappings/adapters/` in the package
since relayfile-adapters#280, or `packages/<adapter>/` in a checkout) which
supersedes the fallback as a whole, and the trigger catalog
(`@relayfile/adapter-core/triggers`, fed by every adapter's
`supportedEvents()`) for providers with no `webhooks:` block. Mapping-backed
providers keep payload-aware signatures (`github.pull_request(action?)`);
catalog-backed ones get `(filter?)`. Result: 47 namespaces, 502 events;
`github` and `slack` are supersets of what #446 generated, so
`--on github:events=` and the six fallback GitHub events are unchanged.

Also: a reserved-namespace guard (`webhook`, `flow`, `schedule`, …), a
generated `PROVIDERS.md` table covered by `--check`, and hyphenated ids
mapped to identifiers (`azure_blob`, `google_drive`) with upstream spelling
kept in the lowered filter.

Merge condition: adapter-core published with relayfile-adapters#280 and the
SDK pin bumped; until then `generate-triggers.mjs --check` (and its test)
report github.ts/gitlab.ts/index.ts/PROVIDERS.md drift against 0.5.25 — 45
of the 47 providers already generate identically from the catalog it ships.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 16 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: fb8953ac-e29b-4246-b147-e38d06731071

📥 Commits

Reviewing files that changed from the base of the PR and between c73f670 and 179fb09.

⛔ Files ignored due to path filters (1)
  • packages/sdk/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (56)
  • packages/sdk/package.json
  • packages/sdk/tests/generate-triggers.test.ts
  • packages/sdk/tests/provider-trigger-contract.test.ts
  • packages/surface/src/triggers/PROVIDERS.md
  • packages/surface/src/triggers/README.md
  • packages/surface/src/triggers/airtable.ts
  • packages/surface/src/triggers/asana.ts
  • packages/surface/src/triggers/azure-blob.ts
  • packages/surface/src/triggers/box.ts
  • packages/surface/src/triggers/calendly.ts
  • packages/surface/src/triggers/clickup.ts
  • packages/surface/src/triggers/cloudflare.ts
  • packages/surface/src/triggers/confluence.ts
  • packages/surface/src/triggers/daytona.ts
  • packages/surface/src/triggers/docker-hub.ts
  • packages/surface/src/triggers/dropbox.ts
  • packages/surface/src/triggers/fathom.ts
  • packages/surface/src/triggers/gcp.ts
  • packages/surface/src/triggers/gcs.ts
  • packages/surface/src/triggers/github.ts
  • packages/surface/src/triggers/gitlab.ts
  • packages/surface/src/triggers/gmail.ts
  • packages/surface/src/triggers/google-calendar.ts
  • packages/surface/src/triggers/google-drive.ts
  • packages/surface/src/triggers/granola.ts
  • packages/surface/src/triggers/hubspot.ts
  • packages/surface/src/triggers/index.ts
  • packages/surface/src/triggers/intercom.ts
  • packages/surface/src/triggers/jira.ts
  • packages/surface/src/triggers/linear.ts
  • packages/surface/src/triggers/mailgun.ts
  • packages/surface/src/triggers/mixpanel.ts
  • packages/surface/src/triggers/neon.ts
  • packages/surface/src/triggers/notion.ts
  • packages/surface/src/triggers/onedrive.ts
  • packages/surface/src/triggers/pipedrive.ts
  • packages/surface/src/triggers/postgres.ts
  • packages/surface/src/triggers/posthog.ts
  • packages/surface/src/triggers/ramp.ts
  • packages/surface/src/triggers/recall.ts
  • packages/surface/src/triggers/redis.ts
  • packages/surface/src/triggers/s3.ts
  • packages/surface/src/triggers/salesforce.ts
  • packages/surface/src/triggers/segment.ts
  • packages/surface/src/triggers/sendgrid.ts
  • packages/surface/src/triggers/sharepoint.ts
  • packages/surface/src/triggers/shopify.ts
  • packages/surface/src/triggers/shortcut.ts
  • packages/surface/src/triggers/slack.ts
  • packages/surface/src/triggers/stripe.ts
  • packages/surface/src/triggers/teams.ts
  • packages/surface/src/triggers/telegram.ts
  • packages/surface/src/triggers/zendesk.ts
  • packages/surface/tests/triggers-all-providers.test.ts
  • packages/surface/tests/triggers-github-events.test.ts
  • scripts/generate-triggers.mjs

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…trigger test

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review swarm: maintainability

No fresh transcript was produced for run 7bb02788-3453-4e7e-bddd-5d8a93e31491 (MISSING).

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review swarm: history

No fresh transcript was produced for run 7bb02788-3453-4e7e-bddd-5d8a93e31491 (MISSING).

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review swarm: structure

No fresh transcript was produced for run 7bb02788-3453-4e7e-bddd-5d8a93e31491 (MISSING).

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Review swarm: FAILED

  • maintainability: MISSING
  • history: MISSING
  • structure: MISSING

Cloud run: 7bb02788-3453-4e7e-bddd-5d8a93e31491

…rovider trigger namespace

Merges origin/main (#446) and moves the pin to 0.5.26, the first release
that bundles every adapter's own mapping under mappings/adapters/
(relayfile-adapters#280). Triggers are regenerated from the installed
tarball alone — no --adapters-dir — and `generate-triggers.mjs --check`
passes: 47 providers, 502 events, PROVIDERS.md in sync. Conflicts resolved
by taking main's cloud-deploy.* (untouched here) and this branch's
superset github-events test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@khaliqgant
khaliqgant marked this pull request as ready for review September 17, 2026 23:46
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Devin Review

Comment thread scripts/generate-triggers.mjs Outdated
Comment on lines +70 to +74
// A provider with a `webhooks:` block keeps its mapping-defined vocabulary.
if (mappings.has(provider) && Object.keys(mappings.get(provider)).length) continue;
if (!events.length) continue;
mappings.set(provider, Object.fromEntries([...new Set(events)].sort().map(event => [event, {}])));
catalogProviders.add(provider);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Mapping providers lose supported events

For providers with any mapping webhook, readCatalog drops every catalog-only event. GitLab loses 39 delivered event types, so ingress rejects them.

Learn more

The trigger catalog records the event types emitted by each adapter's supportedEvents(). Adapter mappings carry richer definitions for some events, but they are not a complete replacement vocabulary. The upstream catalog generator explicitly unions supported events with mapping webhook keys for this reason. Here, the provider-level early return keeps only mapping keys whenever one exists. This affects GitHub, GitLab, and Slack; GitLab's generated registry has 8 entries while its pinned catalog has 47.

Example: The pinned GitLab catalog includes merge_request.open, but its mapping has only merge_request. Generation omits merge_request.open. A flow cannot use gitlab.merge_request_open(), and providerInboxEvent('gitlab', { type: 'merge_request.open', payload: {} }) rejects a real adapter event.

Recommended fix: Merge catalog events into each provider's mapping vocabulary. Preserve each mapping definition for matching event names, and add catalog-only names with {} so they receive the plain filter signature. Keep collision validation after the union.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in eb5640c: catalog events are unioned into every provider (mapping-declared events keep their signature), so gitlab now has all 53, github 26, slack 21 — 570 events across 47 providers. One wrinkle surfaced: slack publishes both reaction.added and reaction_added, which mangle to one identifier; the mapping-declared one owns the method and the other stays in providerEventTypes (accepted by flows check/ingress via webhook('slack', { provider, type })), listed in PROVIDERS.md. Generator test added for both rules; full SDK suite 1861 passed.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bf3929e. Configure here.

Comment thread packages/surface/src/triggers/github.ts
Relayflow Lead and others added 2 commits September 17, 2026 16:55
Devin on #456: a provider with any `webhooks:` block lost every event the
catalog listed but the mapping did not — gitlab kept 8 of the 53 it
delivers, so ingress would refuse the other 45 and `flows check` had no
namespace for them. The mapping describes payload shape for some events,
never the delivered set; `supportedEvents()` does.

Catalog events are now unioned into every provider with the plain
`(filter?)` signature; a mapping-declared event keeps its signature. Where
two upstream names mangle to one identifier (slack publishes both
`reaction.added` and `reaction_added`) the mapping-declared event owns the
method and the other remains in `providerEventTypes`, subscribable via
`webhook(provider, { provider, type })` and listed in PROVIDERS.md.
47 providers, 570 events (was 502): gitlab 53, github 26, slack 21.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…cond action

Cursor on #456: `pull_request_edited(action?)` pinned the type to
`pull_request.edited` and still accepted an action, a dual vocabulary that
is easy to misuse. Only an aggregate event whose mapping extracts `action`
takes one now (`pull_request`, `check_run`, `issue_comment`). Both
spellings stay, because two ingresses deliver them: the aggregate form is
what raw GitHub and the local receiver carry, the action-qualified form is
what relayfile's Cloud ingress normalizes to; the README says which to use.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@khaliqgant
khaliqgant merged commit df3a525 into main Sep 18, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant