@orbytautomation/engine 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +607 -34
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # @orbytautomation/engine
2
2
 
3
- Universal workflow automation engine for executing YAML-based workflows with an adapter-driven architecture.
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 '@orbytautomation/engine';
27
+ import { OrbytEngine } from "@orbytautomation/engine";
15
28
 
16
- // Create engine instance
17
29
  const engine = new OrbytEngine();
18
30
 
19
- // Run a workflow
20
- const result = await engine.run('./workflow.yaml');
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
- console.log('Workflow completed:', result.status);
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
- ## Features
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
- - 🚀 **YAML Workflow Definitions** - Define workflows in human-readable YAML
28
- - 🔌 **Universal Adapter System** - Extensible adapter framework for any action type
29
- - 📊 **DAG Execution** - Automatic dependency resolution with parallel execution
30
- - 🔄 **Retry Logic** - Configurable retry strategies (fixed, linear, exponential backoff)
31
- - ⏱️ **Timeout Management** - Step and workflow-level timeout enforcement
32
- - 🪝 **Lifecycle Hooks** - User-defined hooks at workflow and step events
33
- - 📡 **Event Bus** - Internal pub/sub system for observability
34
- - 🧩 **Context Engine** - Variable interpolation and runtime context
35
- - 🧪 **Dry-run Mode** - Validate and plan without execution
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
- ## Basic Usage
193
+ ##### `registerAdapter(name, adapter)`
38
194
 
39
- ### Simple Workflow Execution
195
+ Register a custom adapter.
40
196
 
41
197
  ```typescript
42
- import { OrbytEngine } from '@orbytautomation/engine';
198
+ import { createAdapter } from "@orbytautomation/engine";
43
199
 
44
- const engine = new OrbytEngine({
45
- logLevel: 'info',
46
- maxConcurrentWorkflows: 5
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
- const result = await engine.run('./workflow.yaml', {
50
- variables: {
51
- inputFile: './data.json',
52
- outputDir: './output'
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
- if (result.status === 'success') {
57
- console.log('✓ Workflow completed successfully');
58
- } else {
59
- console.error('✗ Workflow failed:', result.error);
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 Repository](https://github.com/0xshariq/orbyt)
66
- - [Documentation](https://github.com/0xshariq/orbyt#readme)
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbytautomation/engine",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Orbyt - Automation Engine Framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -39,7 +39,7 @@
39
39
  "node": ">=22.0.0"
40
40
  },
41
41
  "dependencies": {
42
- "@dev-ecosystem/core": "^0.1.0",
42
+ "@dev-ecosystem/core": "^0.3.1",
43
43
  "node-cron": "^4.2.1",
44
44
  "zod": "^4.3.6"
45
45
  },