donmai is in 0.x preview. APIs may change between minor releases. See the changelog.

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 v2 YAML schema validated by validateWorkflowDefinition from @donmai/core:

import { validateWorkflowDefinition } from '@donmai/core'

const result = validateWorkflowDefinition(yamlObject)
if (!result.success) {
  console.error(result.error)
}

A minimal workflow YAML:

apiVersion: v1
kind: WorkflowDefinition
metadata:
  name: my-workflow
  version: "1.0.0"

nodes:
  - id: start-node
    type: trigger
    data:
      config:
        nodeId: linear.issue-created
        filters: {}

  - id: action-node
    type: action
    data:
      config:
        nodeId: agent.dispatch
        inputs:
          workType: development

The grammar enforces node structure, edge references, and metadata shape. Node type identifiers (nodeId) are resolved by the execution engine at runtime — the grammar itself does not constrain which node IDs are valid.

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