src/platform/plugins/shared/workflows_extensions/README.md
Extension point registry for workflow extensions. This plugin provides a centralized location for registering custom workflow extensions, including step types.
The workflows_extensions plugin serves as the home for workflow extension points. It provides:
External teams must implement steps and triggers in their own plugins and register via the plugin contract; see Custom step types and Event-driven triggers for details.
The step type registry provides a clean separation between:
This separation ensures that:
Async registration (public only): The public step registry accepts either a definition or a loader function () => Promise<PublicStepDefinition>. Using a loader (e.g. () => import('./my_step').then(m => m.myStepDefinition)) allows step modules—and heavy dependencies like zod—to be loaded asynchronously, keeping them out of your plugin’s main bundle. The registry resolves loaders in the background; the workflows app awaits workflowsExtensions.isReady() before rendering so definitions are ready when needed.
The trigger registry follows the same pattern as steps:
eventSchema for payload validation). Other plugins register during setup().Async registration (public only): The public trigger registry accepts either a definition or a loader function () => Promise<PublicTriggerDefinition>. Using a loader (e.g. () => import('./my_trigger').then(m => m.myTriggerDefinition)) keeps trigger modules and heavy deps out of your plugin's main bundle. Loaders are resolved in the background; workflowsExtensions.isReady() waits for both step and trigger loaders before the workflows UI renders.
To run workflows when something happens, your plugin calls emitEvent (via the request-scoped client or the start contract). The platform validates the payload against the trigger's eventSchema, then invokes the registered trigger event handler (e.g. workflows_management), which finds subscribed workflows and runs them in the request's space.
┌─────────────────────────────────────────────────────────────────────────┐
│ Other Plugins │
│ ┌────────────────────────┐ ┌────────────────────────┐ │
│ │ Server Setup │ │ Public Setup │ │
│ │ registerStep() │ │ registerStep() │ │
│ │ registerTriggerDef() │ │ registerTriggerDef() │ │
│ └────────────────────────┘ └────────────────────────┘ │
│ ┌────────────────────────┐ │
│ │ Runtime: emitEvent() │ (when something happens) │
│ └────────────────────────┘ │
└────────────────────┬──────────────────┬────────────────┬────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ Server Registry │ │ Public Registry │ │ Trigger event │
│ Step handlers │ │ Step/Trigger │ │ handler │
│ Trigger defs │ │ UI definitions │ │ (e.g. workflows_ │
│ (id+eventSchema) │ │ │ │ management) │
└─────────┬─────────┘ └─────────┬────────┘ └──────────┬──────────┘
│ │ │
│ │ │
┌─────────▼──────────┐ ┌────────▼──────────┐ ┌────────▼───────────┐
│ Execution Engine │ │ Workflows UI │ │ Resolve subscribed │
│ (Uses step │ │ (Uses step/trigger│ │ workflows, run │
│ handlers) │ │ definitions) │ │ via engine │
└────────────────────┘ └───────────────────┘ └────────────────────┘
Event-driven flow: When a plugin calls emitEvent(triggerId, payload), the trigger event handler (e.g. workflows_management) validates the payload, resolves workflows subscribed to that trigger in the space, and runs them via the Execution Engine.
@elastic/eui for icon componentsThe workflows_extensions plugin is automatically integrated with:
workflows_execution_engine: Uses server registry to resolve custom steps during workflow executionworkflows_management: Uses public registry to display step definitions in the UINo additional configuration is required.