@objectstack/service-automation 7.3.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
- import { FlowNodeParsed, FlowParsed, ExecutionLog } from '@objectstack/spec/automation';
2
- import { IAutomationService, Logger, AutomationContext, AutomationResult } from '@objectstack/spec/contracts';
1
+ import { ActionDescriptor, FlowNodeParsed, FlowParsed, ExecutionLog } from '@objectstack/spec/automation';
2
+ import { IAutomationService, Logger, AutomationContext, ScreenSpec, AutomationResult, ResumeSignal } from '@objectstack/spec/contracts';
3
+ import { Connector } from '@objectstack/spec/integration';
3
4
  import { Plugin, PluginContext } from '@objectstack/core';
4
5
 
5
6
  /**
@@ -8,8 +9,15 @@ import { Plugin, PluginContext } from '@objectstack/core';
8
9
  * it with the engine to extend automation capabilities.
9
10
  */
10
11
  interface NodeExecutor {
11
- /** Corresponds to FlowNodeAction enum value */
12
+ /** Registry node type (built-in id or plugin-defined) */
12
13
  readonly type: string;
14
+ /**
15
+ * Optional ADR-0018 action descriptor. When present, it is published into
16
+ * the engine's action registry and surfaced via {@link AutomationEngine.getActionDescriptors}
17
+ * — feeding flow validation and the designer palette. Plugins SHOULD publish
18
+ * one so their node appears in the palette and validates as a legal flow node.
19
+ */
20
+ readonly descriptor?: ActionDescriptor;
13
21
  /**
14
22
  * Execute a node
15
23
  * @param node - Current node definition
@@ -25,15 +33,127 @@ interface NodeExecutionResult {
25
33
  error?: string;
26
34
  /** Used by decision nodes — returns the selected branch label */
27
35
  branchLabel?: string;
36
+ /**
37
+ * ADR-0019 durable pause. When `true`, the node has done its on-entry work
38
+ * (e.g. opened an approval request) and the run should **suspend** here: the
39
+ * engine persists a continuation, stops traversal, and `execute()` returns
40
+ * `{ status: 'paused', runId }`. The run is continued later via
41
+ * {@link AutomationEngine.resume}. Any `output` is written to variables
42
+ * before suspending. The node reads its own run id from the `$runId`
43
+ * flow variable so it can map the run to external state.
44
+ */
45
+ suspend?: boolean;
46
+ /**
47
+ * Optional correlation key surfaced on the suspended-run record (e.g. an
48
+ * approval request id). For observability / lookup; not required to resume.
49
+ */
50
+ correlation?: string;
51
+ /**
52
+ * Screen to render — set by a `screen` node that suspends to collect input.
53
+ * Surfaced on the paused {@link AutomationResult} so a UI runner can render
54
+ * the form and `resume()` with the values.
55
+ */
56
+ screen?: ScreenSpec;
57
+ }
58
+ /**
59
+ * A normalized description of *what* fires a flow, derived by the engine from
60
+ * the flow's `start` node and handed to the matching {@link FlowTrigger} when a
61
+ * flow is activated. Concrete triggers (record-change, schedule, …) read the
62
+ * fields they care about and ignore the rest.
63
+ *
64
+ * The engine — not the trigger — owns parsing the start node, so trigger
65
+ * plugins stay decoupled from flow-definition internals (mirrors how
66
+ * `connector_action` keeps connectors decoupled from node config).
67
+ */
68
+ interface FlowTriggerBinding {
69
+ /** Flow this binding activates. */
70
+ readonly flowName: string;
71
+ /** record-change: the object whose mutations fire the flow. */
72
+ readonly object?: string;
73
+ /** record-change: the start node's `triggerType` (e.g. 'record-after-update'). */
74
+ readonly event?: string;
75
+ /**
76
+ * Optional trigger predicate copied from the start node's `condition`. The
77
+ * engine evaluates it before running the flow; triggers may ignore it.
78
+ */
79
+ readonly condition?: string | {
80
+ dialect?: string;
81
+ source?: string;
82
+ ast?: unknown;
83
+ };
84
+ /** schedule: cron/interval descriptor (parsed but not yet acted on here). */
85
+ readonly schedule?: unknown;
86
+ /** The raw start-node `config`, for trigger-specific fields not modeled above. */
87
+ readonly config?: Record<string, unknown>;
28
88
  }
29
89
  /**
30
90
  * Trigger interface. Schedule/Event/API triggers are registered via plugins.
91
+ *
92
+ * The engine completes the wiring: when a flow whose start node maps to this
93
+ * trigger's {@link type} is registered (or when this trigger is registered
94
+ * after such flows already exist), the engine calls {@link start} with the
95
+ * parsed {@link FlowTriggerBinding} and a `callback` that runs the flow. The
96
+ * trigger subscribes to its event source (e.g. an ObjectQL lifecycle hook) and
97
+ * invokes `callback(ctx)` when it fires. {@link stop} tears that subscription
98
+ * down when the flow is unregistered/disabled or the trigger is removed.
31
99
  */
32
100
  interface FlowTrigger {
33
101
  readonly type: string;
34
- start(flowName: string, callback: (ctx: AutomationContext) => Promise<void>): void;
102
+ start(binding: FlowTriggerBinding, callback: (ctx: AutomationContext) => Promise<void>): void;
35
103
  stop(flowName: string): void;
36
104
  }
105
+ /**
106
+ * Context handed to a connector action handler. Carries the live flow variable
107
+ * map and the trigger context so a handler can read prior-node output, plus a
108
+ * logger. The platform ships the registry + the `connector_action` dispatch
109
+ * node (baseline, ADR-0018 §Addendum); *concrete* connectors — `connector-rest`,
110
+ * `connector-slack`, … — are plugins that register handlers here.
111
+ */
112
+ interface ConnectorActionContext {
113
+ readonly variables: Map<string, unknown>;
114
+ readonly automation: AutomationContext;
115
+ readonly logger: Logger;
116
+ }
117
+ /**
118
+ * A handler for one connector action. Receives the (already-resolved) input
119
+ * mapped from the flow node and returns the action's output, which the
120
+ * `connector_action` node writes back into flow variables.
121
+ */
122
+ type ConnectorActionHandler = (input: Record<string, unknown>, ctx: ConnectorActionContext) => Promise<Record<string, unknown>>;
123
+ /**
124
+ * A connector registered on the engine: its validated {@link Connector}
125
+ * definition plus the handler for each action it declares.
126
+ */
127
+ interface RegisteredConnector {
128
+ readonly def: Connector;
129
+ readonly handlers: Record<string, ConnectorActionHandler>;
130
+ }
131
+ /**
132
+ * A designer-facing view of one connector action — identity + its JSON-Schema
133
+ * input/output. The runtime handler is intentionally omitted; this is metadata.
134
+ */
135
+ interface ConnectorActionDescriptor {
136
+ readonly key: string;
137
+ readonly label: string;
138
+ readonly description?: string;
139
+ readonly inputSchema?: Record<string, unknown>;
140
+ readonly outputSchema?: Record<string, unknown>;
141
+ }
142
+ /**
143
+ * A designer-facing descriptor for a registered connector: its identity plus
144
+ * the actions it exposes. Served by `GET /api/v1/automation/connectors` so the
145
+ * flow designer can populate the `connector_action` node's connector → action
146
+ * → input pickers (ADR-0018 §Addendum, ADR-0022). Mirrors `ActionDescriptor`'s
147
+ * role for node types, but for the connector registry.
148
+ */
149
+ interface ConnectorDescriptor {
150
+ readonly name: string;
151
+ readonly label: string;
152
+ readonly type: string;
153
+ readonly description?: string;
154
+ readonly icon?: string;
155
+ readonly actions: ConnectorActionDescriptor[];
156
+ }
37
157
  /**
38
158
  * Internal execution step log entry.
39
159
  */
@@ -78,11 +198,22 @@ declare class AutomationEngine implements IAutomationService {
78
198
  private flowEnabled;
79
199
  private flowVersionHistory;
80
200
  private nodeExecutors;
201
+ private actionDescriptors;
81
202
  private triggers;
203
+ /**
204
+ * Flows currently wired to a trigger, keyed by flow name → the trigger
205
+ * `type` that owns the binding. Used to avoid double-binding and to know
206
+ * which trigger to `stop()` when a flow is unregistered/disabled.
207
+ */
208
+ private boundFlowTriggers;
209
+ /** Connectors registered by integration plugins, keyed by connector name (ADR-0018 §Addendum). */
210
+ private connectors;
82
211
  private executionLogs;
83
212
  private maxLogSize;
84
213
  private logger;
85
214
  private runCounter;
215
+ /** Runs paused at a node, keyed by runId (ADR-0019). In-memory, see {@link SuspendedRun}. */
216
+ private suspendedRuns;
86
217
  constructor(logger: Logger);
87
218
  /** Register a node executor (called by plugins) */
88
219
  registerNodeExecutor(executor: NodeExecutor): void;
@@ -92,8 +223,63 @@ declare class AutomationEngine implements IAutomationService {
92
223
  registerTrigger(trigger: FlowTrigger): void;
93
224
  /** Unregister a trigger (hot-unplug) */
94
225
  unregisterTrigger(type: string): void;
226
+ /**
227
+ * Derive a flow's trigger binding from its `start` node, or `undefined` if
228
+ * the flow has no auto-trigger (manual / screen / api). The convention —
229
+ * established by the showcase flows — is that the start node carries the
230
+ * trigger details in its `config`: `{ objectName, triggerType, condition }`
231
+ * for record-change, or a `schedule` descriptor for time-based flows.
232
+ */
233
+ private resolveTriggerBinding;
234
+ /**
235
+ * Bind a flow to its matching registered trigger (idempotent). No-op when
236
+ * the flow has no trigger binding or no trigger is registered for its type
237
+ * yet — {@link registerTrigger} re-attempts activation when one arrives.
238
+ */
239
+ private activateFlowTrigger;
240
+ /** Unbind a flow from its trigger, if bound. */
241
+ private deactivateFlowTrigger;
242
+ /** Active flow→trigger bindings (observability / tests). */
243
+ getActiveTriggerBindings(): Array<{
244
+ flowName: string;
245
+ triggerType: string;
246
+ }>;
247
+ /**
248
+ * Register a connector (called by integration plugins, ADR-0018 §Addendum).
249
+ * Validates the definition against {@link ConnectorSchema} and asserts every
250
+ * declared action has a handler, so a half-wired connector fails loudly at
251
+ * registration rather than silently at dispatch. Re-registering the same
252
+ * name replaces (mirrors {@link registerNodeExecutor}).
253
+ */
254
+ registerConnector(def: Connector, handlers: Record<string, ConnectorActionHandler>): void;
255
+ /** Unregister a connector (hot-unplug). */
256
+ unregisterConnector(name: string): void;
257
+ /**
258
+ * Resolve the handler for a connector action, used by the baseline
259
+ * `connector_action` node. Returns `undefined` when the connector or action
260
+ * is not registered, so the node can fail the step with a clear error.
261
+ */
262
+ resolveConnectorAction(connectorId: string, actionId: string): ConnectorActionHandler | undefined;
263
+ /** Get all registered connector names. */
264
+ getRegisteredConnectors(): string[];
265
+ /**
266
+ * Get a designer-facing descriptor for every registered connector — its
267
+ * identity plus the actions it exposes (input/output JSON Schema). Backs
268
+ * `GET /api/v1/automation/connectors` so the designer can fill the
269
+ * `connector_action` node's connector / action / input pickers (ADR-0022).
270
+ * Handlers are omitted — they are runtime code, not metadata.
271
+ */
272
+ getConnectorDescriptors(): ConnectorDescriptor[];
95
273
  /** Get all registered node types */
96
274
  getRegisteredNodeTypes(): string[];
275
+ /**
276
+ * Get all published action descriptors (ADR-0018). Backs both flow
277
+ * validation and the designer palette (`GET /api/v1/automation/actions`).
278
+ * Only executors that published a descriptor appear here.
279
+ */
280
+ getActionDescriptors(): ActionDescriptor[];
281
+ /** Get the action descriptor for a single node type, if published. */
282
+ getActionDescriptor(type: string): ActionDescriptor | undefined;
97
283
  /** Get all registered trigger types */
98
284
  getRegisteredTriggerTypes(): string[];
99
285
  registerFlow(name: string, definition: unknown): void;
@@ -115,7 +301,41 @@ declare class AutomationEngine implements IAutomationService {
115
301
  }): Promise<ExecutionLogEntry[]>;
116
302
  getRun(runId: string): Promise<ExecutionLogEntry | null>;
117
303
  execute(flowName: string, context?: AutomationContext): Promise<AutomationResult>;
304
+ /**
305
+ * Resume a run suspended at a node (ADR-0019 durable pause). Restores the
306
+ * snapshotted variables, merges `signal.output` under the suspended node's
307
+ * id, and continues traversal from that node's out-edges — optionally
308
+ * restricted to the edge labelled `signal.branchLabel` (e.g. the approval
309
+ * decision). The continuation may itself suspend again, in which case this
310
+ * returns `{ status: 'paused', runId }` afresh.
311
+ */
312
+ resume(runId: string, signal?: ResumeSignal): Promise<AutomationResult>;
313
+ /**
314
+ * List the runs currently suspended awaiting {@link resume} (ADR-0019).
315
+ * Backs operability surfaces such as a "pending approvals" view.
316
+ */
317
+ listSuspendedRuns(): Array<{
318
+ runId: string;
319
+ flowName: string;
320
+ nodeId: string;
321
+ correlation?: string;
322
+ }>;
323
+ /**
324
+ * The screen a paused run is currently waiting on (screen-flow runtime), or
325
+ * `null` if the run isn't suspended / didn't pause at a screen node. Lets a
326
+ * UI flow-runner re-fetch the form after a refresh.
327
+ */
328
+ getSuspendedScreen(runId: string): ScreenSpec | null;
118
329
  private recordLog;
330
+ /**
331
+ * Validate each node's `type` against the live action registry (ADR-0018).
332
+ * A type is known if it is structural (start/end), has a registered
333
+ * executor, or has a published action descriptor. Unknown types are
334
+ * warned about (not rejected) so flows authored against a temporarily
335
+ * absent plugin still register; the runtime surfaces a hard NO_EXECUTOR
336
+ * error if such a node is actually executed.
337
+ */
338
+ private validateNodeTypes;
119
339
  /**
120
340
  * Detect cycles in the flow graph (DAG validation).
121
341
  * Uses DFS with coloring (white/gray/black) to detect back edges.
@@ -135,6 +355,17 @@ declare class AutomationEngine implements IAutomationService {
135
355
  * Execute a node with timeout support, fault edge handling, and step logging.
136
356
  */
137
357
  private executeNode;
358
+ /**
359
+ * Traverse a node's out-edges and execute its successors. Split out of
360
+ * {@link executeNode} so {@link resume} can re-enter traversal from a
361
+ * suspended node without re-running the node body.
362
+ *
363
+ * @param branchLabel - When set (e.g. from a resume signal), restrict
364
+ * traversal to out-edges whose `label` matches — this is how an Approval
365
+ * node's `approve`/`reject` decision selects its downstream branch. When
366
+ * no edge carries the label, traversal falls back to the normal edge set.
367
+ */
368
+ private traverseNext;
138
369
  /**
139
370
  * Execute a promise with timeout using Promise.race.
140
371
  */
@@ -176,14 +407,17 @@ interface AutomationServicePluginOptions {
176
407
  * AutomationServicePlugin — Core engine plugin
177
408
  *
178
409
  * Responsibilities:
179
- * 1. init phase: Create engine instance, register as 'automation' service
180
- * 2. start phase: Trigger 'automation:ready' hook for node plugin registration,
181
- * then pull flow definitions from the ObjectQL schema registry and register
182
- * them with the engine.
410
+ * 1. init phase: Create engine instance, register as 'automation' service, and
411
+ * seed the platform's built-in node executors (logic / CRUD / screen-script /
412
+ * http_request) via {@link installBuiltinNodes}. Per ADR-0018, foundational
413
+ * capabilities are built into the core, not packaged as optional plugins.
414
+ * 2. start phase: Trigger 'automation:ready' hook so third-party plugins can
415
+ * register additional node types, then pull flow definitions from the
416
+ * ObjectQL schema registry and register them with the engine.
183
417
  * 3. destroy phase: Clean up resources
184
418
  *
185
- * Does NOT implement any specific nodes nodes are registered by other plugins
186
- * via the engine's extension API.
419
+ * The engine's `registerNodeExecutor()` stays open so plugins extend the
420
+ * node/action vocabulary at runtime — the marketplace-extensibility contract.
187
421
  *
188
422
  * @example
189
423
  * ```ts
@@ -211,8 +445,21 @@ declare class AutomationServicePlugin implements Plugin {
211
445
  }
212
446
 
213
447
  /**
214
- * CRUD Node Pluginwires `get_record` / `create_record` / `update_record` /
215
- * `delete_record` flow nodes to the runtime data layer (ObjectQL / IDataEngine).
448
+ * Logic built-in nodesdecision / assignment / loop.
449
+ *
450
+ * Part of the automation engine's foundational vocabulary, so the core
451
+ * {@link AutomationServicePlugin} seeds them directly (ADR-0018). These are NOT
452
+ * shipped as a separately installable plugin — "plugins are plugins; the
453
+ * platform's foundational capabilities are built in." Third-party node types
454
+ * are still registered via `engine.registerNodeExecutor()`.
455
+ */
456
+ declare function registerLogicNodes(engine: AutomationEngine, ctx: PluginContext): void;
457
+
458
+ /**
459
+ * CRUD built-in nodes — `get_record` / `create_record` / `update_record` /
460
+ * `delete_record`, wired to the runtime data layer (ObjectQL / IDataEngine).
461
+ * Part of the platform baseline, so the core {@link AutomationServicePlugin}
462
+ * seeds them directly (ADR-0018) rather than shipping a separate plugin.
216
463
  *
217
464
  * Each executor:
218
465
  * 1. Interpolates `{var}` / `{var.path}` / `{$User.*}` / `{NOW()}` tokens in
@@ -225,59 +472,88 @@ declare class AutomationServicePlugin implements Plugin {
225
472
  * If no data engine is registered, executors degrade to a no-op success so
226
473
  * test environments without ObjectQL still complete the flow without errors.
227
474
  */
228
- declare class CrudNodesPlugin implements Plugin {
229
- name: string;
230
- version: string;
231
- type: "standard";
232
- dependencies: string[];
233
- init(ctx: PluginContext): Promise<void>;
234
- }
475
+ declare function registerCrudNodes(engine: AutomationEngine, ctx: PluginContext): void;
235
476
 
236
477
  /**
237
- * Logic Node Plugin Provides decision / assignment / loop nodes
478
+ * Screen / Script built-in nodes 'screen' and 'script' executors.
479
+ * Part of the core flow capability, so the {@link AutomationServicePlugin}
480
+ * seeds them directly (ADR-0018) rather than shipping a separate plugin.
238
481
  *
239
- * Dependencies: service-automation (engine)
482
+ * - 'screen' nodes collect user input. A screen that declares `config.fields`
483
+ * (or sets `config.waitForInput === true`) suspends the run on entry via the
484
+ * engine's durable pause (ADR-0019), surfacing a `ScreenSpec` for the client
485
+ * to render; the run continues via `resume()` with the collected values (set
486
+ * as bare flow variables). A field-less screen — or one with
487
+ * `waitForInput === false` — stays a server pass-through (input vars, if any,
488
+ * are already injected from `context.params`).
489
+ * - 'script' nodes dispatch by `config.actionType`. Currently only 'email'
490
+ * has a (logger-backed) implementation; unknown action types still succeed
491
+ * so flows can continue and downstream nodes can react.
240
492
  */
241
- declare class LogicNodesPlugin implements Plugin {
242
- name: string;
243
- version: string;
244
- type: "standard";
245
- dependencies: string[];
246
- init(ctx: PluginContext): Promise<void>;
247
- }
493
+ declare function registerScreenNodes(engine: AutomationEngine, ctx: PluginContext): void;
248
494
 
249
495
  /**
250
- * HTTP + Connector Node Plugin Provides http_request / connector_action nodes
496
+ * HTTP built-in node`http_request` (foundational outbound I/O).
497
+ *
498
+ * Part of the platform baseline, so the core {@link AutomationServicePlugin}
499
+ * seeds it directly (ADR-0018). Its generic-dispatch sibling `connector_action`
500
+ * (see {@link ./connector-nodes.ts}) is now also baseline: where `http_request`
501
+ * calls a raw URL, `connector_action` invokes a registered connector's action,
502
+ * with concrete connectors contributed by plugins via `engine.registerConnector()`
503
+ * (ADR-0018 §Addendum).
251
504
  *
252
- * Dependencies: service-automation (engine)
505
+ * ADR-0018 §M3 target: route `http_request` through the service-messaging
506
+ * outbox (retry / idempotency / dead-letter) under the canonical `http` type.
507
+ * Today it is a bare `fetch()`.
253
508
  */
254
- declare class HttpConnectorPlugin implements Plugin {
255
- name: string;
256
- version: string;
257
- type: "standard";
258
- dependencies: string[];
259
- init(ctx: PluginContext): Promise<void>;
260
- }
509
+ declare function registerHttpNodes(engine: AutomationEngine, ctx: PluginContext): void;
261
510
 
262
511
  /**
263
- * Screen / Script Node Plugin Provides 'screen' and 'script' executors.
512
+ * Connector built-in node`connector_action` (generic integration dispatch).
264
513
  *
265
- * - 'screen' nodes are pass-through on the server. The engine already injects
266
- * `isInput: true` flow variables from `context.params` into the top-level
267
- * variables map before execution begins, so screen nodes have no remaining
268
- * server-side work.
269
- * - 'script' nodes dispatch by `config.actionType`. Currently only 'email'
270
- * has a (logger-backed) implementation; unknown action types still succeed
271
- * so flows can continue and downstream nodes can react.
514
+ * Part of the platform baseline alongside `http_request` (ADR-0018 §Addendum):
515
+ * where `http_request` calls *any raw URL*, `connector_action` invokes *any
516
+ * registered connector's action*. The platform ships the generic dispatch node
517
+ * + an (initially empty) connector registry on the engine; concrete connectors
518
+ * — `connector-rest`, `connector-slack`, `connector-salesforce`, populate
519
+ * the registry at runtime via `engine.registerConnector()`.
272
520
  *
273
- * Dependencies: service-automation (engine)
521
+ * Because the registry starts empty, a flow referencing a connector that no
522
+ * plugin has registered fails the *step* with a clear error rather than failing
523
+ * to register — graceful degradation matching `http_request`'s fail-soft style.
274
524
  */
275
- declare class ScreenNodesPlugin implements Plugin {
276
- name: string;
277
- version: string;
278
- type: "standard";
279
- dependencies: string[];
280
- init(ctx: PluginContext): Promise<void>;
281
- }
525
+ declare function registerConnectorNodes(engine: AutomationEngine, ctx: PluginContext): void;
526
+
527
+ /**
528
+ * Built-in node executors — the automation engine's foundational vocabulary.
529
+ *
530
+ * Per ADR-0018 and the platform principle "plugins are plugins; the platform's
531
+ * foundational capabilities are built in," these node packs are seeded directly
532
+ * by the core {@link AutomationServicePlugin} rather than shipped as separately
533
+ * installable plugins. Each `register*Nodes(engine, ctx)` publishes its
534
+ * descriptors with `source: 'builtin'`.
535
+ *
536
+ * Scope (built-in baseline):
537
+ * - logic — decision / assignment / loop (engine core)
538
+ * - data — get/create/update/delete_record (platform CRUD baseline)
539
+ * - human — screen / script (core flow capability)
540
+ * - io — http_request (foundational outbound I/O)
541
+ * - io — connector_action (generic integration dispatch)
542
+ * - io — notify (outbound notification via messaging service)
543
+ *
544
+ * `connector_action` is the *generic dispatch* counterpart to `http_request`
545
+ * (ADR-0018 §Addendum): the platform ships the node + an (initially empty)
546
+ * connector registry on the engine, and *concrete* connectors populate it at
547
+ * runtime via `engine.registerConnector()`. Third-party node types continue to
548
+ * extend the vocabulary via `engine.registerNodeExecutor()`, keeping the action
549
+ * list open and marketplace-extensible.
550
+ */
551
+
552
+ /**
553
+ * Seed every built-in node executor into the engine. Called by
554
+ * {@link AutomationServicePlugin.init} so a bare `new AutomationServicePlugin()`
555
+ * yields a fully-functional automation capability with no companion plugins.
556
+ */
557
+ declare function installBuiltinNodes(engine: AutomationEngine, ctx: PluginContext): void;
282
558
 
283
- export { AutomationEngine, AutomationServicePlugin, type AutomationServicePluginOptions, CrudNodesPlugin, type FlowTrigger, HttpConnectorPlugin, LogicNodesPlugin, type NodeExecutionResult, type NodeExecutor, ScreenNodesPlugin };
559
+ export { AutomationEngine, AutomationServicePlugin, type AutomationServicePluginOptions, type ConnectorActionContext, type ConnectorActionDescriptor, type ConnectorActionHandler, type ConnectorDescriptor, type FlowTrigger, type FlowTriggerBinding, type NodeExecutionResult, type NodeExecutor, type RegisteredConnector, installBuiltinNodes, registerConnectorNodes, registerCrudNodes, registerHttpNodes, registerLogicNodes, registerScreenNodes };