@orbytautomation/engine 0.1.1 → 0.2.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/README.md +607 -34
- package/dist/core/EngineConfig.d.ts +5 -0
- package/dist/core/EngineConfig.d.ts.map +1 -1
- package/dist/core/EngineConfig.js +4 -0
- package/dist/core/EngineConfig.js.map +1 -1
- package/dist/core/OrbytEngine.d.ts +207 -76
- package/dist/core/OrbytEngine.d.ts.map +1 -1
- package/dist/core/OrbytEngine.js +395 -63
- package/dist/core/OrbytEngine.js.map +1 -1
- package/dist/errors/SecurityErrors.d.ts +75 -0
- package/dist/errors/SecurityErrors.d.ts.map +1 -0
- package/dist/errors/SecurityErrors.js +145 -0
- package/dist/errors/SecurityErrors.js.map +1 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +1 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/execution/ExecutionLimits.d.ts +116 -0
- package/dist/execution/ExecutionLimits.d.ts.map +1 -0
- package/dist/execution/ExecutionLimits.js +280 -0
- package/dist/execution/ExecutionLimits.js.map +1 -0
- package/dist/execution/ExecutionStrategyResolver.d.ts +140 -0
- package/dist/execution/ExecutionStrategyResolver.d.ts.map +1 -0
- package/dist/execution/ExecutionStrategyResolver.js +332 -0
- package/dist/execution/ExecutionStrategyResolver.js.map +1 -0
- package/dist/execution/IntentAnalyzer.d.ts +101 -0
- package/dist/execution/IntentAnalyzer.d.ts.map +1 -0
- package/dist/execution/IntentAnalyzer.js +348 -0
- package/dist/execution/IntentAnalyzer.js.map +1 -0
- package/dist/execution/InternalExecutionContext.d.ts +255 -0
- package/dist/execution/InternalExecutionContext.d.ts.map +1 -0
- package/dist/execution/InternalExecutionContext.js +175 -0
- package/dist/execution/InternalExecutionContext.js.map +1 -0
- package/dist/execution/index.d.ts +5 -0
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +6 -0
- package/dist/execution/index.js.map +1 -1
- package/dist/index.d.ts +5 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/loader/WorkflowLoader.d.ts +154 -0
- package/dist/loader/WorkflowLoader.d.ts.map +1 -0
- package/dist/loader/WorkflowLoader.js +239 -0
- package/dist/loader/WorkflowLoader.js.map +1 -0
- package/dist/loader/index.d.ts +10 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/index.js +10 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/parser/WorkflowParser.d.ts +8 -0
- package/dist/parser/WorkflowParser.d.ts.map +1 -1
- package/dist/parser/WorkflowParser.js +6 -0
- package/dist/parser/WorkflowParser.js.map +1 -1
- package/dist/security/ReservedFields.d.ts +64 -0
- package/dist/security/ReservedFields.d.ts.map +1 -0
- package/dist/security/ReservedFields.js +253 -0
- package/dist/security/ReservedFields.js.map +1 -0
- package/dist/security/index.d.ts +1 -0
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1 -0
- package/dist/security/index.js.map +1 -1
- package/dist/types/core-types.d.ts +59 -0
- package/dist/types/core-types.d.ts.map +1 -0
- package/dist/types/core-types.js +2 -0
- package/dist/types/core-types.js.map +1 -0
- package/package.json +2 -2
- package/test-security-annotations.yaml +20 -0
- package/test-security-context.yaml +21 -0
- package/test-security.mjs +148 -0
- package/test-security.yaml +19 -0
- package/test-valid-workflow.yaml +26 -0
package/README.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# @orbytautomation/engine
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Execution runtime for the Orbyt automation framework** — Run workflows defined in Orbyt's YAML-based workflow language with adapters, lifecycle hooks, and powerful state management.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@orbytautomation/engine` is the execution engine for the **Orbyt automation framework**. It provides the runtime environment for executing workflow definitions written in Orbyt's workflow language.
|
|
8
|
+
|
|
9
|
+
Orbyt is a **complete automation framework and language** that includes:
|
|
10
|
+
|
|
11
|
+
- **Workflow Language** — YAML-based workflow definitions
|
|
12
|
+
- **Execution Engine** — This package (runtime orchestration)
|
|
13
|
+
- **CLI Tooling** — Command-line interface for workflow execution
|
|
14
|
+
- **Adapter Framework** — Extensible adapter system
|
|
15
|
+
|
|
16
|
+
This package provides the core execution engine that powers all workflow orchestration.
|
|
4
17
|
|
|
5
18
|
## Installation
|
|
6
19
|
|
|
@@ -11,57 +24,617 @@ npm install @orbytautomation/engine
|
|
|
11
24
|
## Quick Start
|
|
12
25
|
|
|
13
26
|
```typescript
|
|
14
|
-
import { OrbytEngine } from
|
|
27
|
+
import { OrbytEngine } from "@orbytautomation/engine";
|
|
15
28
|
|
|
16
|
-
// Create engine instance
|
|
17
29
|
const engine = new OrbytEngine();
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
|
|
31
|
+
const result = await engine.run("./workflow.yaml", {
|
|
32
|
+
vars: { environment: "production" },
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
console.log(result.status); // 'completed', 'failed', 'timeout', etc.
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Core Features
|
|
39
|
+
|
|
40
|
+
- 🔗 **Adapter-based architecture** — Extensible integrations (CLI, HTTP, Shell, FS)
|
|
41
|
+
- 🔁 **Retry strategies** — Exponential backoff, linear, constant
|
|
42
|
+
- ⏰ **Timeout management** — Step and workflow-level timeouts
|
|
43
|
+
- 📡 **Event system** — Real-time workflow execution events
|
|
44
|
+
- 🖇️ **Step dependencies** — Sequential and parallel step execution
|
|
45
|
+
- 🪝 **Lifecycle hooks** — Before/after workflow, before/after step
|
|
46
|
+
- 🔐 **State isolation** — Each execution has independent state
|
|
47
|
+
- 🎯 **Variable interpolation** — Use `${{ vars.name }}`, `${{ env.KEY }}`, `${{ steps.step1.output }}`
|
|
48
|
+
- 🛑 **Exit codes** — Workflow-level exit code support
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## API Reference
|
|
53
|
+
|
|
54
|
+
### OrbytEngine
|
|
55
|
+
|
|
56
|
+
Primary class for workflow execution.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { OrbytEngine } from "@orbytautomation/engine";
|
|
60
|
+
|
|
61
|
+
const engine = new OrbytEngine(config);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### Configuration Options
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
interface OrbytEngineConfig {
|
|
68
|
+
// Maximum number of steps to run concurrently
|
|
69
|
+
maxConcurrentSteps?: number; // default: 10
|
|
70
|
+
|
|
71
|
+
// Default timeout for steps (ms)
|
|
72
|
+
defaultStepTimeout?: number; // default: 300000 (5 minutes)
|
|
73
|
+
|
|
74
|
+
// Continue executing even if a step fails
|
|
75
|
+
continueOnError?: boolean; // default: false
|
|
76
|
+
|
|
77
|
+
// Enable detailed logging
|
|
78
|
+
verbose?: boolean; // default: false
|
|
79
|
+
|
|
80
|
+
// Dry run mode (no adapters execute)
|
|
81
|
+
dryRun?: boolean; // default: false
|
|
82
|
+
|
|
83
|
+
// Custom adapter registry
|
|
84
|
+
adapters?: Record<string, Adapter>;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Methods
|
|
89
|
+
|
|
90
|
+
##### `run(workflowPath, options)`
|
|
91
|
+
|
|
92
|
+
Execute a workflow from a file.
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
const result = await engine.run("./workflow.yaml", {
|
|
96
|
+
// Variables passed to workflow
|
|
97
|
+
vars: {
|
|
98
|
+
environment: "production",
|
|
99
|
+
version: "1.2.3",
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// Environment variables to inject
|
|
103
|
+
env: {
|
|
104
|
+
API_KEY: process.env.API_KEY,
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// Execution timeout (ms)
|
|
108
|
+
timeout: 600000,
|
|
109
|
+
|
|
110
|
+
// Continue on errors
|
|
111
|
+
continueOnError: false,
|
|
112
|
+
|
|
113
|
+
// Dry run mode
|
|
114
|
+
dryRun: false,
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Returns**: `WorkflowResult`
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
interface WorkflowResult {
|
|
122
|
+
status: "completed" | "failed" | "timeout" | "cancelled" | "validation_error";
|
|
123
|
+
exitCode: number;
|
|
124
|
+
duration: number;
|
|
125
|
+
steps: StepResult[];
|
|
126
|
+
metadata: {
|
|
127
|
+
startTime: Date;
|
|
128
|
+
endTime: Date;
|
|
129
|
+
workflowName: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
##### `runWorkflow(workflowDef, options)`
|
|
135
|
+
|
|
136
|
+
Execute a workflow from a definition object.
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const workflowDef = {
|
|
140
|
+
name: "my-workflow",
|
|
141
|
+
steps: [
|
|
142
|
+
{
|
|
143
|
+
id: "hello",
|
|
144
|
+
adapter: "cli",
|
|
145
|
+
params: { command: 'echo "Hello"' },
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const result = await engine.runWorkflow(workflowDef, options);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
##### `on(event, handler)`
|
|
154
|
+
|
|
155
|
+
Subscribe to workflow execution events.
|
|
21
156
|
|
|
22
|
-
|
|
157
|
+
```typescript
|
|
158
|
+
engine.on("workflow.started", (event) => {
|
|
159
|
+
console.log(`Workflow ${event.workflowId} started`);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
engine.on("step.completed", (event) => {
|
|
163
|
+
console.log(`Step ${event.stepId} completed: ${event.status}`);
|
|
164
|
+
});
|
|
23
165
|
```
|
|
24
166
|
|
|
25
|
-
|
|
167
|
+
**Available Events**:
|
|
168
|
+
|
|
169
|
+
- `workflow.started`
|
|
170
|
+
- `workflow.completed`
|
|
171
|
+
- `workflow.failed`
|
|
172
|
+
- `workflow.timeout`
|
|
173
|
+
- `workflow.cancelled`
|
|
174
|
+
- `step.started`
|
|
175
|
+
- `step.completed`
|
|
176
|
+
- `step.failed`
|
|
177
|
+
- `step.retrying`
|
|
178
|
+
- `step.skipped`
|
|
179
|
+
- `step.timeout`
|
|
26
180
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
181
|
+
##### `validate(workflowPath)`
|
|
182
|
+
|
|
183
|
+
Validate a workflow without executing it.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const validation = await engine.validate("./workflow.yaml");
|
|
187
|
+
|
|
188
|
+
if (!validation.valid) {
|
|
189
|
+
console.error("Validation errors:", validation.errors);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
36
192
|
|
|
37
|
-
|
|
193
|
+
##### `registerAdapter(name, adapter)`
|
|
38
194
|
|
|
39
|
-
|
|
195
|
+
Register a custom adapter.
|
|
40
196
|
|
|
41
197
|
```typescript
|
|
42
|
-
import {
|
|
198
|
+
import { createAdapter } from "@orbytautomation/engine";
|
|
43
199
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
200
|
+
const myAdapter = createAdapter({
|
|
201
|
+
name: "my-adapter",
|
|
202
|
+
execute: async (params, context) => {
|
|
203
|
+
// Implementation
|
|
204
|
+
return { success: true, output: "result" };
|
|
205
|
+
},
|
|
47
206
|
});
|
|
48
207
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
208
|
+
engine.registerAdapter("my-adapter", myAdapter);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Workflow Language Reference
|
|
214
|
+
|
|
215
|
+
Orbyt workflows are defined in YAML with the following structure:
|
|
216
|
+
|
|
217
|
+
### Basic Structure
|
|
218
|
+
|
|
219
|
+
```yaml
|
|
220
|
+
name: my-workflow
|
|
221
|
+
description: Example workflow
|
|
222
|
+
|
|
223
|
+
# Global configuration
|
|
224
|
+
config:
|
|
225
|
+
timeout: 300000
|
|
226
|
+
continueOnError: false
|
|
227
|
+
exitCode: 0
|
|
228
|
+
|
|
229
|
+
# Variables
|
|
230
|
+
vars:
|
|
231
|
+
environment: production
|
|
232
|
+
version: 1.0.0
|
|
233
|
+
|
|
234
|
+
# Steps
|
|
235
|
+
steps:
|
|
236
|
+
- id: step1
|
|
237
|
+
adapter: cli
|
|
238
|
+
params:
|
|
239
|
+
command: echo "Hello ${{ vars.environment }}"
|
|
240
|
+
|
|
241
|
+
- id: step2
|
|
242
|
+
adapter: http
|
|
243
|
+
depends_on: [step1]
|
|
244
|
+
params:
|
|
245
|
+
url: https://api.example.com
|
|
246
|
+
method: GET
|
|
247
|
+
retry:
|
|
248
|
+
maxAttempts: 3
|
|
249
|
+
strategy: exponential
|
|
250
|
+
initialDelay: 1000
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Variable Interpolation
|
|
254
|
+
|
|
255
|
+
Access variables using `${{ expression }}` syntax:
|
|
256
|
+
|
|
257
|
+
```yaml
|
|
258
|
+
steps:
|
|
259
|
+
- id: deploy
|
|
260
|
+
adapter: cli
|
|
261
|
+
params:
|
|
262
|
+
# Variables
|
|
263
|
+
command: deploy --env=${{ vars.environment }}
|
|
264
|
+
|
|
265
|
+
# Environment variables
|
|
266
|
+
api_key: ${{ env.API_KEY }}
|
|
267
|
+
|
|
268
|
+
# Previous step outputs
|
|
269
|
+
version: ${{ steps.build.output.version }}
|
|
270
|
+
|
|
271
|
+
# Context variables
|
|
272
|
+
workflow: ${{ workflow.name }}
|
|
273
|
+
timestamp: ${{ workflow.startTime }}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Available Contexts**:
|
|
277
|
+
|
|
278
|
+
- `vars.*` — User-defined variables
|
|
279
|
+
- `env.*` — Environment variables
|
|
280
|
+
- `steps.<id>.output.*` — Output from previous steps
|
|
281
|
+
- `workflow.*` — Workflow metadata (name, startTime, etc.)
|
|
282
|
+
|
|
283
|
+
### Step Configuration
|
|
284
|
+
|
|
285
|
+
```yaml
|
|
286
|
+
steps:
|
|
287
|
+
- id: step-id # Required: Unique identifier
|
|
288
|
+
adapter: adapter-name # Required: Adapter to use
|
|
289
|
+
|
|
290
|
+
# Optional: Description
|
|
291
|
+
description: What this step does
|
|
292
|
+
|
|
293
|
+
# Optional: Dependencies (wait for these steps)
|
|
294
|
+
depends_on: [step1, step2]
|
|
295
|
+
|
|
296
|
+
# Optional: Conditional execution
|
|
297
|
+
if: ${{ vars.deploy == true }}
|
|
298
|
+
|
|
299
|
+
# Optional: Timeout (ms)
|
|
300
|
+
timeout: 30000
|
|
301
|
+
|
|
302
|
+
# Optional: Continue on failure
|
|
303
|
+
continueOnError: false
|
|
304
|
+
|
|
305
|
+
# Optional: Retry strategy
|
|
306
|
+
retry:
|
|
307
|
+
maxAttempts: 3
|
|
308
|
+
strategy: exponential # exponential, linear, constant
|
|
309
|
+
initialDelay: 1000
|
|
310
|
+
maxDelay: 30000
|
|
311
|
+
backoffMultiplier: 2
|
|
312
|
+
|
|
313
|
+
# Required: Adapter-specific parameters
|
|
314
|
+
params:
|
|
315
|
+
# ... adapter params
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Retry Strategies
|
|
319
|
+
|
|
320
|
+
**Exponential Backoff**:
|
|
321
|
+
|
|
322
|
+
```yaml
|
|
323
|
+
retry:
|
|
324
|
+
maxAttempts: 5
|
|
325
|
+
strategy: exponential
|
|
326
|
+
initialDelay: 1000 # 1s
|
|
327
|
+
maxDelay: 60000 # 60s max
|
|
328
|
+
backoffMultiplier: 2 # 1s, 2s, 4s, 8s, 16s
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Linear Backoff**:
|
|
332
|
+
|
|
333
|
+
```yaml
|
|
334
|
+
retry:
|
|
335
|
+
maxAttempts: 3
|
|
336
|
+
strategy: linear
|
|
337
|
+
initialDelay: 2000 # 2s, 4s, 6s
|
|
338
|
+
backoffMultiplier: 1
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
**Constant Delay**:
|
|
342
|
+
|
|
343
|
+
```yaml
|
|
344
|
+
retry:
|
|
345
|
+
maxAttempts: 3
|
|
346
|
+
strategy: constant
|
|
347
|
+
initialDelay: 5000 # 5s, 5s, 5s
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Step Dependencies
|
|
351
|
+
|
|
352
|
+
**Sequential Execution**:
|
|
353
|
+
|
|
354
|
+
```yaml
|
|
355
|
+
steps:
|
|
356
|
+
- id: build
|
|
357
|
+
adapter: cli
|
|
358
|
+
params: { command: npm run build }
|
|
359
|
+
|
|
360
|
+
- id: test
|
|
361
|
+
adapter: cli
|
|
362
|
+
depends_on: [build]
|
|
363
|
+
params: { command: npm test }
|
|
364
|
+
|
|
365
|
+
- id: deploy
|
|
366
|
+
adapter: cli
|
|
367
|
+
depends_on: [test]
|
|
368
|
+
params: { command: npm run deploy }
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Parallel Execution**:
|
|
372
|
+
|
|
373
|
+
```yaml
|
|
374
|
+
steps:
|
|
375
|
+
# These run in parallel
|
|
376
|
+
- id: lint
|
|
377
|
+
adapter: cli
|
|
378
|
+
params: { command: npm run lint }
|
|
379
|
+
|
|
380
|
+
- id: typecheck
|
|
381
|
+
adapter: cli
|
|
382
|
+
params: { command: npm run typecheck }
|
|
383
|
+
|
|
384
|
+
# This waits for both
|
|
385
|
+
- id: build
|
|
386
|
+
adapter: cli
|
|
387
|
+
depends_on: [lint, typecheck]
|
|
388
|
+
params: { command: npm run build }
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## Built-in Adapters
|
|
394
|
+
|
|
395
|
+
### CLI Adapter
|
|
396
|
+
|
|
397
|
+
Execute shell commands.
|
|
398
|
+
|
|
399
|
+
```yaml
|
|
400
|
+
- id: run-script
|
|
401
|
+
adapter: cli
|
|
402
|
+
params:
|
|
403
|
+
command: npm run build
|
|
404
|
+
cwd: ./project
|
|
405
|
+
env:
|
|
406
|
+
NODE_ENV: production
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Shell Adapter
|
|
410
|
+
|
|
411
|
+
Execute shell commands with streaming output.
|
|
412
|
+
|
|
413
|
+
```yaml
|
|
414
|
+
- id: deploy
|
|
415
|
+
adapter: shell
|
|
416
|
+
params:
|
|
417
|
+
script: |
|
|
418
|
+
set -e
|
|
419
|
+
npm install
|
|
420
|
+
npm run build
|
|
421
|
+
npm run deploy
|
|
422
|
+
shell: bash
|
|
423
|
+
cwd: ./app
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### HTTP Adapter
|
|
427
|
+
|
|
428
|
+
Make HTTP requests.
|
|
429
|
+
|
|
430
|
+
```yaml
|
|
431
|
+
- id: api-call
|
|
432
|
+
adapter: http
|
|
433
|
+
params:
|
|
434
|
+
url: https://api.example.com/deploy
|
|
435
|
+
method: POST
|
|
436
|
+
headers:
|
|
437
|
+
Authorization: Bearer ${{ env.API_TOKEN }}
|
|
438
|
+
body:
|
|
439
|
+
version: ${{ vars.version }}
|
|
440
|
+
timeout: 30000
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### FS Adapter
|
|
444
|
+
|
|
445
|
+
File system operations.
|
|
446
|
+
|
|
447
|
+
```yaml
|
|
448
|
+
- id: write-config
|
|
449
|
+
adapter: fs
|
|
450
|
+
params:
|
|
451
|
+
operation: writeFile
|
|
452
|
+
path: ./config.json
|
|
453
|
+
content: ${{ steps.generate.output.config }}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## Custom Adapters
|
|
459
|
+
|
|
460
|
+
Create custom adapters to integrate with any system.
|
|
461
|
+
|
|
462
|
+
### Basic Adapter
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
import { createAdapter, AdapterResultBuilder } from "@orbytautomation/engine";
|
|
466
|
+
|
|
467
|
+
const slackAdapter = createAdapter({
|
|
468
|
+
name: "slack",
|
|
469
|
+
|
|
470
|
+
execute: async (params, context) => {
|
|
471
|
+
const { message, channel } = params;
|
|
472
|
+
|
|
473
|
+
// Send message to Slack
|
|
474
|
+
const response = await sendSlackMessage(channel, message);
|
|
475
|
+
|
|
476
|
+
return new AdapterResultBuilder()
|
|
477
|
+
.success()
|
|
478
|
+
.withOutput({ messageId: response.ts })
|
|
479
|
+
.build();
|
|
480
|
+
},
|
|
54
481
|
});
|
|
55
482
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
483
|
+
// Register with engine
|
|
484
|
+
engine.registerAdapter("slack", slackAdapter);
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Usage in Workflow
|
|
488
|
+
|
|
489
|
+
```yaml
|
|
490
|
+
steps:
|
|
491
|
+
- id: notify
|
|
492
|
+
adapter: slack
|
|
493
|
+
params:
|
|
494
|
+
channel: "#deployments"
|
|
495
|
+
message: Deployment completed successfully!
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Adapter API
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
interface Adapter {
|
|
502
|
+
name: string;
|
|
503
|
+
execute: (
|
|
504
|
+
params: Record<string, any>,
|
|
505
|
+
context: AdapterContext,
|
|
506
|
+
) => Promise<AdapterResult>;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
interface AdapterContext {
|
|
510
|
+
workflowId: string;
|
|
511
|
+
stepId: string;
|
|
512
|
+
vars: Record<string, any>;
|
|
513
|
+
env: Record<string, any>;
|
|
514
|
+
stepOutputs: Record<string, any>;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
interface AdapterResult {
|
|
518
|
+
success: boolean;
|
|
519
|
+
output?: any;
|
|
520
|
+
error?: string;
|
|
521
|
+
metadata?: Record<string, any>;
|
|
60
522
|
}
|
|
61
523
|
```
|
|
62
524
|
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## Event System
|
|
528
|
+
|
|
529
|
+
Subscribe to real-time workflow execution events:
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
// Workflow events
|
|
533
|
+
engine.on("workflow.started", (event) => {
|
|
534
|
+
console.log(`Workflow ${event.workflowId} started`);
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
engine.on("workflow.completed", (event) => {
|
|
538
|
+
console.log(`Workflow completed in ${event.duration}ms`);
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
engine.on("workflow.failed", (event) => {
|
|
542
|
+
console.error(`Workflow failed: ${event.error}`);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// Step events
|
|
546
|
+
engine.on("step.started", (event) => {
|
|
547
|
+
console.log(`Step ${event.stepId} started`);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
engine.on("step.completed", (event) => {
|
|
551
|
+
console.log(`Step ${event.stepId} completed`);
|
|
552
|
+
console.log("Output:", event.output);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
engine.on("step.failed", (event) => {
|
|
556
|
+
console.error(`Step ${event.stepId} failed: ${event.error}`);
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
engine.on("step.retrying", (event) => {
|
|
560
|
+
console.log(`Retrying step ${event.stepId} (attempt ${event.attempt})`);
|
|
561
|
+
});
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
## Lifecycle Hooks
|
|
567
|
+
|
|
568
|
+
Execute custom logic at key points in workflow execution:
|
|
569
|
+
|
|
570
|
+
```typescript
|
|
571
|
+
engine.beforeWorkflow(async (workflow, context) => {
|
|
572
|
+
console.log(`Starting workflow: ${workflow.name}`);
|
|
573
|
+
// Setup, validation, logging, etc.
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
engine.afterWorkflow(async (result, context) => {
|
|
577
|
+
console.log(`Workflow ${result.status} in ${result.duration}ms`);
|
|
578
|
+
// Cleanup, notifications, etc.
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
engine.beforeStep(async (step, context) => {
|
|
582
|
+
console.log(`Starting step: ${step.id}`);
|
|
583
|
+
// Pre-step setup
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
engine.afterStep(async (step, result, context) => {
|
|
587
|
+
console.log(`Step ${step.id}: ${result.success ? "success" : "failed"}`);
|
|
588
|
+
// Post-step processing
|
|
589
|
+
});
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## Exit Codes
|
|
595
|
+
|
|
596
|
+
Workflows can specify exit codes for different scenarios:
|
|
597
|
+
|
|
598
|
+
```yaml
|
|
599
|
+
name: deployment
|
|
600
|
+
config:
|
|
601
|
+
exitCode: 0 # Success
|
|
602
|
+
|
|
603
|
+
steps:
|
|
604
|
+
- id: deploy
|
|
605
|
+
adapter: cli
|
|
606
|
+
params:
|
|
607
|
+
command: deploy.sh
|
|
608
|
+
exitCode: 1 # Failure exit code
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
**Standard Exit Codes**:
|
|
612
|
+
|
|
613
|
+
- `0` — Success
|
|
614
|
+
- `1` — Validation error
|
|
615
|
+
- `2` — Step failure
|
|
616
|
+
- `3` — Timeout
|
|
617
|
+
- `4` — Internal error
|
|
618
|
+
- `5` — Cancelled
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
## Related Packages
|
|
623
|
+
|
|
624
|
+
- **[@orbytautomation/cli](https://www.npmjs.com/package/@orbytautomation/cli)** — Command-line interface for Orbyt
|
|
625
|
+
- **[@dev-ecosystem/core](https://www.npmjs.com/package/@dev-ecosystem/core)** — Shared types and utilities
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
63
629
|
## Links
|
|
64
630
|
|
|
65
|
-
- [GitHub
|
|
66
|
-
- [
|
|
67
|
-
- [Issues](https://github.com/0xshariq/orbyt/issues)
|
|
631
|
+
- **Repository**: [GitHub](https://github.com/0xshariq/orbyt)
|
|
632
|
+
- **Documentation**: [GitHub README](https://github.com/0xshariq/orbyt#readme)
|
|
633
|
+
- **Issues**: [GitHub Issues](https://github.com/0xshariq/orbyt/issues)
|
|
634
|
+
- **npm**: [@orbytautomation/engine](https://www.npmjs.com/package/@orbytautomation/engine)
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## License
|
|
639
|
+
|
|
640
|
+
MIT
|
|
@@ -44,6 +44,11 @@ export interface OrbytEngineConfig {
|
|
|
44
44
|
* @default 10
|
|
45
45
|
*/
|
|
46
46
|
maxConcurrentWorkflows?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Maximum number of steps that can execute concurrently within a workflow
|
|
49
|
+
* @default 10
|
|
50
|
+
*/
|
|
51
|
+
maxConcurrentSteps?: number;
|
|
47
52
|
/**
|
|
48
53
|
* Default timeout for workflows (milliseconds)
|
|
49
54
|
* @default 300000 (5 minutes)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EngineConfig.d.ts","sourceRoot":"","sources":["../../src/core/EngineConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,SAAS,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IAGhC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IAIrB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAI1B;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IAIjB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAIhC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAIrB;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IAIxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAIvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAE1C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAI1B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,iBAAsB,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,aAAa,GAAG,gBAAgB,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,aAAa,GAAG,gBAAgB,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"EngineConfig.d.ts","sourceRoot":"","sources":["../../src/core/EngineConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,aAAa,GAAG,SAAS,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IAGhC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IAIrB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAI1B;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IAIjB;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAIhC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAIrB;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IAIxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAIvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAIhB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAE1C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAI1B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,iBAAsB,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,aAAa,GAAG,gBAAgB,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,iBAAiB,EAAE,OAAO,GAAG,aAAa,GAAG,gBAAgB,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC,CAuB/R;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAwB9D"}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
export function applyConfigDefaults(config = {}) {
|
|
16
16
|
return {
|
|
17
17
|
maxConcurrentWorkflows: config.maxConcurrentWorkflows ?? 10,
|
|
18
|
+
maxConcurrentSteps: config.maxConcurrentSteps ?? 10,
|
|
18
19
|
defaultTimeout: config.defaultTimeout ?? 300000, // 5 minutes
|
|
19
20
|
mode: config.mode ?? 'local',
|
|
20
21
|
enableScheduler: config.enableScheduler ?? true,
|
|
@@ -45,6 +46,9 @@ export function validateConfig(config) {
|
|
|
45
46
|
if (config.maxConcurrentWorkflows !== undefined && config.maxConcurrentWorkflows < 1) {
|
|
46
47
|
throw new Error('maxConcurrentWorkflows must be at least 1');
|
|
47
48
|
}
|
|
49
|
+
if (config.maxConcurrentSteps !== undefined && config.maxConcurrentSteps < 1) {
|
|
50
|
+
throw new Error('maxConcurrentSteps must be at least 1');
|
|
51
|
+
}
|
|
48
52
|
if (config.defaultTimeout !== undefined && config.defaultTimeout < 1) {
|
|
49
53
|
throw new Error('defaultTimeout must be positive');
|
|
50
54
|
}
|