@orbytautomation/engine 0.8.0 → 0.8.2

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 CHANGED
@@ -1,640 +1,192 @@
1
1
  # @orbytautomation/engine
2
2
 
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.
3
+ Execution runtime for Orbyt workflows.
4
4
 
5
- ## Overview
5
+ ## Package Info
6
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.
7
+ - Name: @orbytautomation/engine
8
+ - Version: 0.8.0
9
+ - Node: >= 22
8
10
 
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.
17
-
18
- ## Installation
11
+ ## Install
19
12
 
20
13
  ```bash
21
14
  npm install @orbytautomation/engine
22
15
  ```
23
16
 
24
- ## Quick Start
25
-
26
- ```typescript
27
- import { OrbytEngine } from "@orbytautomation/engine";
28
-
29
- const engine = new OrbytEngine();
30
-
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
17
+ ## Core Concepts
53
18
 
54
- ### OrbytEngine
19
+ - OrbytEngine: primary runtime class
20
+ - WorkflowLoader: load and validate workflow inputs
21
+ - run: execute one workflow
22
+ - runMany: preload, resolve mode, then execute many workflows
23
+ - validate: verify workflow correctness without execution
24
+ - explain: build and return execution plan without running steps
55
25
 
56
- Primary class for workflow execution.
26
+ Built-in adapters are registered by default:
57
27
 
58
- ```typescript
59
- import { OrbytEngine } from "@orbytautomation/engine";
28
+ - cli
29
+ - shell
30
+ - http
31
+ - fs
60
32
 
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)
33
+ ## Quick Start
73
34
 
74
- // Continue executing even if a step fails
75
- continueOnError?: boolean; // default: false
35
+ ```ts
36
+ import { OrbytEngine, WorkflowLoader } from "@orbytautomation/engine";
76
37
 
77
- // Enable detailed logging
78
- verbose?: boolean; // default: false
38
+ const engine = new OrbytEngine({ logLevel: "info" });
39
+ const workflow = await WorkflowLoader.fromFile("./workflow.yaml");
79
40
 
80
- // Dry run mode (no adapters execute)
81
- dryRun?: boolean; // default: false
41
+ const result = await engine.run(workflow, {
42
+ variables: { target: "prod" },
43
+ timeout: 300000,
44
+ });
82
45
 
83
- // Custom adapter registry
84
- adapters?: Record<string, Adapter>;
85
- }
46
+ console.log(result.status);
86
47
  ```
87
48
 
88
- #### Methods
49
+ ## Single Workflow API
89
50
 
90
- ##### `run(workflowPath, options)`
51
+ Accepted workflow inputs:
91
52
 
92
- Execute a workflow from a file.
53
+ - file path string
54
+ - YAML string
55
+ - JSON string
56
+ - parsed workflow object
93
57
 
94
- ```typescript
58
+ ```ts
95
59
  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
60
+ variables: { region: "us-east-1" },
61
+ env: { NODE_ENV: "production" },
62
+ secrets: { TOKEN: process.env.TOKEN },
111
63
  continueOnError: false,
112
-
113
- // Dry run mode
114
64
  dryRun: false,
115
65
  });
116
66
  ```
117
67
 
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
- ```
68
+ ## Batch Execution API (runMany)
133
69
 
134
- ##### `runWorkflow(workflowDef, options)`
70
+ runMany behavior:
135
71
 
136
- Execute a workflow from a definition object.
72
+ 1. Preload and validate all workflows first
73
+ 2. Resolve execution mode
74
+ 3. Execute in sequential, parallel, or mixed orchestration
75
+ 4. Return per-workflow and aggregate result data
137
76
 
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.
156
-
157
- ```typescript
158
- engine.on("workflow.started", (event) => {
159
- console.log(`Workflow ${event.workflowId} started`);
77
+ ```ts
78
+ const batch = await engine.runMany([
79
+ "./w1.yaml",
80
+ "./w2.yaml",
81
+ "./w3.yaml",
82
+ ], {
83
+ executionMode: "parallel", // sequential | parallel | mixed
84
+ maxParallelWorkflows: 3,
85
+ mixedBatchSize: 2,
86
+ failFast: false,
160
87
  });
161
88
 
162
- engine.on("step.completed", (event) => {
163
- console.log(`Step ${event.stepId} completed: ${event.status}`);
164
- });
89
+ console.log(batch.mode);
90
+ console.log(batch.totalWorkflows, batch.successfulWorkflows, batch.failedWorkflows);
165
91
  ```
166
92
 
167
- **Available Events**:
93
+ Mode resolution precedence:
168
94
 
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`
95
+ 1. Explicit executionMode option
96
+ 2. Workflow strategy.type declaration
97
+ 3. Default sequential
180
98
 
181
- ##### `validate(workflowPath)`
99
+ For details see:
182
100
 
183
- Validate a workflow without executing it.
101
+ - ../docs/execution-modes.md
184
102
 
185
- ```typescript
186
- const validation = await engine.validate("./workflow.yaml");
103
+ ## validate and explain
187
104
 
188
- if (!validation.valid) {
189
- console.error("Validation errors:", validation.errors);
190
- }
105
+ ```ts
106
+ const ok = await engine.validate("./workflow.yaml");
107
+ const plan = await engine.explain("./workflow.yaml");
191
108
  ```
192
109
 
193
- ##### `registerAdapter(name, adapter)`
194
-
195
- Register a custom adapter.
110
+ - validate returns true or throws on invalid input
111
+ - explain returns an execution explanation object
196
112
 
197
- ```typescript
198
- import { createAdapter } from "@orbytautomation/engine";
113
+ ## Configuration (OrbytEngineConfig)
199
114
 
200
- const myAdapter = createAdapter({
201
- name: "my-adapter",
202
- execute: async (params, context) => {
203
- // Implementation
204
- return { success: true, output: "result" };
205
- },
206
- });
207
-
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
- ```
115
+ Common options:
349
116
 
350
- ### Step Dependencies
117
+ - maxConcurrentWorkflows
118
+ - maxConcurrentSteps
119
+ - defaultTimeout
120
+ - mode (local | distributed | dry-run)
121
+ - enableScheduler
122
+ - adapters
123
+ - hooks
124
+ - logLevel
125
+ - verbose
126
+ - stateDir
127
+ - logDir
128
+ - cacheDir
129
+ - runtimeDir
130
+ - workingDirectory
351
131
 
352
- **Sequential Execution**:
132
+ Example:
353
133
 
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
- },
134
+ ```ts
135
+ const engine = new OrbytEngine({
136
+ mode: "local",
137
+ logLevel: "info",
138
+ maxConcurrentWorkflows: 10,
139
+ maxConcurrentSteps: 10,
140
+ defaultTimeout: 300000,
141
+ enableScheduler: true,
481
142
  });
482
-
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
143
  ```
497
144
 
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>;
522
- }
523
- ```
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
- });
145
+ ## Events and Hooks
554
146
 
555
- engine.on("step.failed", (event) => {
556
- console.error(`Step ${event.stepId} failed: ${event.error}`);
557
- });
147
+ Event bus:
558
148
 
559
- engine.on("step.retrying", (event) => {
560
- console.log(`Retrying step ${event.stepId} (attempt ${event.attempt})`);
149
+ ```ts
150
+ const events = engine.getEventBus();
151
+ events.on("workflow.completed", (event) => {
152
+ console.log(event.workflowName, event.executionId);
561
153
  });
562
154
  ```
563
155
 
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
- });
156
+ Hooks:
580
157
 
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
158
+ ```ts
159
+ engine.registerHook({
160
+ name: "audit-hook",
161
+ beforeStep: async (ctx) => {
162
+ // custom behavior
163
+ },
589
164
  });
590
165
  ```
591
166
 
592
- ---
593
-
594
- ## Exit Codes
595
-
596
- Workflows can specify exit codes for different scenarios:
167
+ ## Minimal Workflow Example
597
168
 
598
169
  ```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
170
+ version: "1.0"
171
+ kind: workflow
619
172
 
620
- ---
173
+ metadata:
174
+ name: simple-shell
621
175
 
622
- ## Related Packages
623
-
624
- - **[@orbytautomation/cli](https://www.npmjs.com/package/@orbytautomation/cli)** — Command-line interface for Orbyt (Coming Soon...)
625
- - **[@dev-ecosystem/core](https://www.npmjs.com/package/@dev-ecosystem/core)** — Shared types and utilities
626
-
627
- ---
628
-
629
- ## Links
176
+ workflow:
177
+ steps:
178
+ - id: step1
179
+ uses: shell.exec
180
+ with:
181
+ command: echo "hello"
182
+ ```
630
183
 
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)
184
+ ## Related
635
185
 
636
- ---
186
+ - ../README.md
187
+ - ../docs/execution-modes.md
188
+ - ../WORKFLOW_SCHEMA.md
637
189
 
638
190
  ## License
639
191
 
640
- MIT
192
+ MIT