Workflow contract reference
The ActionDefinition, TriggerDefinition, and ConditionDefinition interfaces published by @donmai/core, and the workflow YAML grammar.
The @donmai/core package publishes the interface contracts for the
workflow engine: type definitions that describe what a node action, trigger,
and condition must look like, plus a Zod-validated YAML grammar for writing
workflow definitions.
Important: @donmai/core does not ship a concrete workflow runtime or
any built-in node implementations. Concrete execution (the actual node
catalog, OAuth handling, dispatch, Redis pubsub) lives in the closed
platform layer. OSS consumers can use these contracts to author plugins or
build their own execution engine against the grammar.
Provider plugin contracts
The ProviderPlugin interface bundles actions, triggers, and conditions for a
single integration (e.g. Slack, GitHub, Jira):
import type {
ActionDefinition,
TriggerDefinition,
ConditionDefinition,
ProviderPlugin,
} from '@donmai/core'ActionDefinition
An operation that can be performed against a provider.
export interface ActionDefinition {
/** Unique action identifier within the provider */
id: string
/** Human-readable action name */
displayName: string
description?: string
/** Grouping category for UI organization */
category?: string
/** JSON Schema describing the action's input parameters */
inputSchema: JSONSchema7
/** JSON Schema describing the action's output shape */
outputSchema: JSONSchema7
/** Execute the action with resolved inputs */
execute(
input: Record<string, unknown>,
context: ProviderExecutionContext,
): Promise<ActionResult>
}TriggerDefinition
An event source that initiates workflow execution.
export interface TriggerDefinition {
id: string
displayName: string
description?: string
/** The normalized event type this trigger emits */
eventType: string
/** JSON Schema for filtering which events match */
filterSchema: JSONSchema7
/** Normalize a raw provider event */
normalizeEvent(rawEvent: unknown): NormalizedEvent
/** Register a webhook with the provider */
registerWebhook(config: WebhookConfig): Promise<WebhookRegistration>
/** Remove a previously registered webhook */
deregisterWebhook(registration: WebhookRegistration): Promise<void>
}ConditionDefinition
A boolean predicate used for conditional branching.
export interface ConditionDefinition {
id: string
displayName: string
description?: string
/** JSON Schema for evaluation parameters */
evaluationSchema: JSONSchema7
/** Evaluate the condition */
evaluate(
params: Record<string, unknown>,
context: ConditionContext,
): Promise<boolean>
}ProviderPlugin
The top-level type that bundles everything:
export interface ProviderPlugin {
id: string
displayName: string
description?: string
version: string
icon?: string
actions: ActionDefinition[]
triggers: TriggerDefinition[]
conditions: ConditionDefinition[]
credentials: CredentialDefinition[]
}Workflow YAML grammar
Workflow definitions use a versioned YAML schema. @donmai/core publishes
Zod schemas for both grammars (WorkflowDefinitionSchema for v1.1,
WorkflowDefinitionV2Schema for v2) and two validators:
validateWorkflowDefinition accepts v1.1 documents only;
validateAnyWorkflowDefinition dispatches on the apiVersion field
('v1.1' or 'v2'). Both throw on an invalid document:
import { validateAnyWorkflowDefinition } from '@donmai/core'
try {
const workflow = validateAnyWorkflowDefinition(yamlObject, 'my-workflow.yaml')
// workflow is typed AnyWorkflowDefinition (v1.1 or v2 by apiVersion)
} catch (error) {
console.error(error)
}A minimal v2 workflow YAML (CI validates this example against the published
@donmai/core package on every build):
apiVersion: v2
kind: WorkflowDefinition
metadata:
name: my-workflow
description: Dispatch an agent session when a Linear issue is created.
triggers:
- name: on-issue-created
type: webhook
source: linear
event: issue.created
providers:
- name: claude
type: claude
nodes:
- name: dispatch-agent
description: Run an agent session against the new issue
provider: claude
steps:
- id: spawn
action: spawn-session
with:
workType: developmentThe grammar enforces document structure and referential integrity: node
names must be unique, node.provider must name an entry in providers,
and {{ steps.<id>.output.<key> }} interpolations must reference step IDs
declared in the same node. Provider and action identifiers are resolved by
the execution engine at runtime - the grammar itself does not constrain
which providers or actions exist.
Node type registry
@donmai/core also exports a NodeTypeRegistry class and loadProviderPlugins
helper for building a registry of known ProviderPlugin instances:
import { NodeTypeRegistry, loadProviderPlugins } from '@donmai/core'
const registry = new NodeTypeRegistry()
await loadProviderPlugins(registry, [myPlugin])
const action = registry.getAction('my-provider', 'my-action')This is useful if you are building your own execution engine that consumes the same contract surface.
What the platform layer adds
OSS boundary
@donmai/core publishes the contracts - interfaces and the YAML grammar.
Concrete node implementations, OAuth flows, and the durable executor live in
the closed platform layer and are not part of the OSS release.
The closed platform layer provides:
- ~60 concrete node implementations (actions, triggers, conditions) that implement the interfaces above
- OAuth token management and provider credential flows
- Durable execution with Redis pubsub and step retries
- The workflow editor UI that populates the node palette
OSS consumers see the contract boundary (the interfaces and grammar above). The concrete nodes are not extractable to OSS because they depend deeply on the platform DB, OAuth flows, and A2A dispatch layer.
ProviderPlugin field reference
Prop
Type