Generic platform
Minion exposes generic primitives. Vendors and frameworks are configuration or ordinary dependencies, not platform branches.
Minion's platform code exposes generic primitives: webhooks, jobs, events, secrets, storage. A provider is a set of settings for one of those primitives. It doesn't get its own code path, its own handler or its own type.
When a new provider needs something the primitive can't express, widen the primitive. Don't add an if (provider === ...).
Example
Webhook ownership checks are one type. Slack's URL verification, WebSub hub challenges and X's CRC check are presets that expand into it before anything runs:
/** Expands the preset types into subscription-challenge knobs. */
export function normalizeChallenge(c: WebhookChallenge): SubscriptionChallenge {
switch (c.type) {
case 'subscription-challenge':
return c
case 'slack-url-verification':
return {
type: 'subscription-challenge',
method: 'POST',
challenge: { in: 'json', key: 'challenge' },
when: { json: { type: 'url_verification' } }, The webhook endpoint only ever runs the generic path. A provider that isn't a preset still works: describe its challenge with subscription-challenge knobs. See Webhooks .
The sandbox treats npm the same way. There is one allowlist and one error, not per-package rules:
npm package "lodash" isn't on the sandbox allowlist (zod, hono) In your packages
Write a package against Minion's primitives, not against one caller. A package that reads input.webhook and the request works for any provider you point at it. Keep the provider-specific parts (header names, payload shapes) in one small function at the edge.